Efficient Audio Playback on Arduino Using ROM and R-2R DAC

 Arduino microcontrollers are widely used for a variety of projects, including those that require audio output. However, the limited amount of RAM on an Arduino can make it difficult to store and play high-quality audio samples. One solution to this problem is to store the audio samples in the Arduino's Read-Only Memory (ROM) and retrieve them as needed.

When storing audio samples in Arduino ROM, it is important to consider the format of the data. The most common format for audio samples is pulse-code modulation (PCM), which encodes the amplitude of a sound wave at regular intervals. Other formats, such as compressed formats like MP3, cannot be used as they require more processing power to decode. 

To encode audio in PCM one can use audacity software. In the software audio is first recorded(time length should be small) with a sampling rate of 16bps and 8bits/sample.and then saved as a .raw file with 8bits/sample. The size of the audio is calculated as follows.

Audio Size =  sampling rate x audio time length = 16bits/sec x 1.6sec =22.4KB. 

Below picture shows saving the audio data in RAW(header-less) header and Unsigned 8 bit PCM encoding format.

The next step is to convert this raw PCM encoded audio into a C header file in order to use in the Arduino program. Say have saved it as soundtest.raw file from the Audacity software, then use the following link program to convert the soundtest.raw file to audio .h header file.

https://code.google.com/archive/p/bin2h/downloads

To use this program, save the soundtest.raw file into the same folder as the bin2h.exe program folder. Next open up the bin2h.exe application from the command prompt and type in bin2h soundtest.raw soundtest.h and hit enter. This will create the header file soundtest.h in the same folder. 

 

Once the audio samples have been stored in the Arduino's ROM, they can be retrieved and sent to a digital-to-analog converter (DAC) for conversion to an analog signal. The circuit used in this example is an R-2R ladder DAC, which is a simple and inexpensive method of converting digital values to an analog voltage. The R-2R ladder DAC circuit is connected to the Arduino's digital port D, where the retrieved audio sample data is sent.

After the audio samples have been converted to an analog signal by the R-2R ladder DAC, they are passed through a low-pass filter (LPF) to remove any unwanted high-frequency noise. The LPF is used to remove the high-frequency noise that is introduced during the digital to analog conversion.

The filtered analog signal is then sent to an operational amplifier (op-amp) buffer, which provides additional gain and improves the overall signal-to-noise ratio. The op-amp buffer is used to boost the weak analog signal that is produced by the R-2R ladder DAC circuit.

Finally, the amplified analog signal is sent to a speaker, where it is converted into sound waves that can be heard by the user. The speaker is connected to the op-amp buffer circuit.

The following shows the circuit diagram of connecting PORT D on Arduino to R-2R ladder DAC, then the LPF, a potentiometer, an op-amp buffer and then to a speaker.

Arduino R-2R DAC circuit diagram


 In the above circuit diagram, a R-2R ladder digital-to-analog converter (DAC) consisting of 2.2kOhm and 4.7kOhm register is connected to Arduino Uno. The R-2R ladder DAC is a simple and inexpensive method of converting digital values to an analog voltage. The diagram shows a series of resistors connected in a ladder configuration, with the top of the ladder connected to a voltage source and the bottom of the ladder connected to ground. The digital input is connected to the Arduino, which uses digital output pins to control the flow of current through the ladder. The analog output is taken from the point where the ladder connects to the voltage source. The resistance of the resistor in R-2R ladder is twice the resistance of the resistor in R. The binary value of the digital input is used to determine which resistors in the ladder to activate, which in turn determines the output voltage.

Arduino Program Code for Audio Sample in ROM

This following code is a simple program written to retrieve audio data stored in ROM and send to PORT D of Arduino where a digital-to-analog converter (DAC) is connected.

#include "audio.h"

short i = 0;

void setup() {
  // put your setup code here, to run once:
  DDRC = 255;
}

void loop() {
  // put your main code here, to run repeatedly:
   PORTC = pgm_read_byte(&(data[i++]));
  if(i >= sizeof(data))
      i = 0;
    delayMicroseconds(62);
}

The first line "#include "audio.h"" includes the header file "audio.h", which likely contains data and other information used by the program.

The next line "short i = 0;" declares a variable "i" of data type short and assigns it an initial value of 0.

The "setup()" function is executed once when the program is first run. It contains a single line of code "DDRD = 255;", which sets all of the pins on the Arduino's digital port D as outputs.

The "loop()" function is executed repeatedly while the program is running. It contains three lines of code:

  1. "PORTD = pgm_read_byte(&(data[i++]));" reads a byte of data from an array called "data" using the "pgm_read_byte" function, and assigns it to the digital port D. It also increments the value of "i" by 1.
  2. "if(i >= sizeof(data))" checks whether the value of "i" is greater than or equal to the size of the "data" array.
  3. "i = 0;" If the value of "i" is greater than or equal to the size of the "data" array, it resets the value of "i" to 0.
  4. "delayMicroseconds(62);" This line of code is used to pause the execution of the program for 62 microseconds.

Ov
erall, this program outputs a sequence of digital values stored in an array called "data" in audio.h to the digital port D, in order to control the output of a DAC. The size of the data array is used to determine when to start over again with the first value, and the delayMicroseconds is used to control the rate at which the data is output.

Next you should add the audio.h header in Arduino fromSketch>Add File....

add audio header file
 Following shows screenshot of the audio.h header file.

audio header file

 Now compile and upload the program code above. You should hear the audio stored in Arduino ROM played and heard from the speaker.

In conclusion, storing audio samples in Arduino ROM is a great way to play high-quality audio on an Arduino microcontroller. By using an R-2R ladder DAC, LPF, op-amp buffer and speaker, it is possible to produce high-quality sound output with minimal noise. The retrieved audio data is sent to the digital port D, where it is processed by the external R-2R DAC, LPF, op-amp buffer and speaker to produce the final audio output.

Post a Comment

Previous Post Next Post