Skip to content

Arduino Audio DAC Options

ProtoBoardWithDACsDAC is short for Digital to Analog Converter. In this article we play around the code Michael Smith created for a PWM based DAC. I modified his code so that other DAC options could be tried. I compare the 8-Bit PWM DAC with the R2R DAC at various numbers of bits. You might be surprised at how well a 4-bit DAC sounds. This article includes several sound samples for the various DAC options and demonstrates some software abstraction that allows for multiple DAC options.

This article is part of the series on Arduino Sound Generation. I decided to drop the Part 1, 2, 3 distinction as much of the content is not dependent on the previous articles.

Related articles:

  • Using PWM to do sound Link
  • Using timer interrupts Link
  • Playing a Melody Link
  • Getting ready for sound projects Link
  • Creating sound, what are the options? Link

Of all the various methods of sound generation the DAC method seems most versatile to me. As mentioned before DAC is a common short name for Digital to Analog Converter. Basically a binary/digital value is converted to an analog/voltage value. An 8-Bit DAC would convert a binary value in the range of 0 to 255 into an analog voltage from 0 to 5V. The exact voltage range of the conversion is dependent on the DAC configuration but for most things we will play with, 0 to 5V will work.

DAC Biasing for +/- swing
Since analog signals, especially sound, needs to swing plus and minus around 0V we often bias the DAC so that mid scale is considered 0V. If the DAC outputs from 0 to 5V then we usually bias the signals so that 2.5V is translated to 0V. If we generate our output signals so that half scale is 2.5V then we can AC couple the output to get a +/- 2.5V swing.

The half scale biasing may be a bit confusing but really it’s easy once you get the general idea. We just call 1/2 scale zero so that any numbers above 1/2 are positive and below are negative. For an 8 bit converter we can use the MSB as a sign bit to make this happen. Consider that decimal 128 is 10000000 in binary. Note that the MSB is set and this is basically half scale of the possible 0-255 range. Think of the MSB as a sign bit, it’s one for positive values and 0 or negative.

Using this 1/2 scale bias we can convert any digital number that might represent sound data into a value to load into a DAC. The first step is to convert the number into the range of +/-127 and add 128 to it. In this example that will make the analog version swing from 0 to 5V with the original zero point set at 2.5V. We can remove that 2.5V bias in the hardware with a simple series capacitor.

A/C Coupling
The series capacitor is not even needed in most applications. For example I use my sound card line input to do these experiments. This input has a series capacitor. The series capacitor is used to provide A/C coupling. This just means that the signal swings evenly around 0V. The +/- voltage swing is enforced about the average DC level by the capacitor. Of course there is a frequency response for the series capacitor but the value of the capacitor is usually high enough so that it will not be a problem for audio frequency ranges.

Filtering the DAC output

This diagram shows the circuit I used between the various DAC outputs and my PC sound card input. The series resistor and capacitor to ground form a simple filter to knock off the high frequency noise caused by the DAC switching instantly between the voltage values. It removes the high frequency components. The 100K variable resistor (POT) lets me adjust the output voltage level for each DAC. A line input should be kept in the 1V Peak to Peak range or +0.5 to -0.5 range. Since the sound card has A/C coupling I only need to adjust the amplitude using this POT as a voltage divider. Also note that I connected both the right and left side inputs to the filtered output.

PWM Output
There is no additional parts required to implement the PWM sound output. Michael Smith’s PWM code generates PWM at about 60KHz. This high frequency is easily filtered with the filter described above. You really don’t even have to have this filter as the sound card has input filters. Even if you wanted to drive a speaker, you would not need to filter this as the speaker would filter it. It simply can not respond to the 60KHz.

The fact that very little to no external circuitry is needed for PWM sound generation makes this a very good option for microcontroller projects. PWM sound is also called PCM or pulse code modulation. PCM has the added benefit of being very easy to make powerful amplifiers for it. You should be able to generate high quality sound at high volumes using a simple class C audio amplifier and some simple filtering. I hope to demonstrate this in a future article.

Here is a sample of Michael Smith’s PWM sound output from an Arduino. The first file is with the filter circuit described above. The second is unfiltered except for what the sound card does on it’s line input. Compare this with the 6-Bit R2R DAC described later. The graphic shows the wave shape captured with Audacity.

8-Bit PWM Sound Sample: filtered and unfiltered.

Michael Smith’s sound program uses a sound sample that is very broad spectrum. This makes it very good for testing DAC configurations and playing with sampling rates. The graphic below shows the spectrum plot for the sound file above. This plot was also done in Audacity using the unfiltered 6-Bit R2R DAC sample.R2R6BSprectrum


Wikipedia has a great article about R2R ladders so I don’t need to cover it in a lot of detail. The diagram here shows my 6-Bit R2R DAC circuit. As you can see I chose 10K as my R value making the 2R 20K. The basic idea is that the R2R ladder is a voltage divider where each resistor either pulls up or down on the output resistor. DAC chips use a similar method with current sources internally to do the digital to analog conversion.

Remember that this type of DAC has an output impedance of 10K or the value of R for the R2R network. This means it can not drive loads. For these experiments, driving the sound card link input, did not require a buffer.

I modified Michael’s code so that I could try out other DAC configurations. I created a SetDAC(int value) method that would be called in the sample output ISR routine. This way I could simply change that function to use a different DAC.

With the new SetDAC function called from the ISR I created two versions, one that used the PWM and one that used the 6-Bit R2R DAC. I actually set up the ISR to call both SetDAC methods so I could easily switch between the two and hear the differences. I also tried several different bit configurations. Listen to the sound samples below for 6, 4, 2, and even 1 bit resolution. I was surprised at how well the 4-bit DAC sounded. Even with a single bit DAC you can hear the sound. I wonder how well a sampled voice would sound with a single bit.

These sample include both a filtered and unfiltered version. If you look at the waveform in Audacity or other sound editor program you will see the flat sample points for the lower resolution DAC configurations.

R2R DAC Sound:
6-Bit Filtered and Unfiltered
4-Bit Filtered and Unfiltered
2-Bit Filtered and Unfiltered
1-Bit Filtered and Unfiltered



This plot below shows the 4-Bit R2R DAC waveform in Audacity. Note the downward slope you see on each flat section where the DAC value stayed constant for a brief time. This is actually caused by the A/C coupling of the line input. These areas are flat on a regular oscilloscope.4BitR2RTime

As a test I placed the 8-Bit PWM and 6-Bit R2R DAC outputs on my O-Scope and set one to invert and add. The two waveforms were nearly identical. I think the two sound the same as well.

I want to do some stereo sound experiments and I think the 4-Bit DAC might be good enough for most of my experiments. Two 4-Bit DAC channels can be done with a single 8 bit port which leaves other I/O pins available for control.

After all these experiments I believe it’s safe to say that we can do sound generation on the Arduino. I plan to show some sampling techniques in the next article which will provide nice audio tones we can use to play music.

Source Code:

Future Experiments:

  • Interfacing the dual 8-Bit DAC from my AVR O-Scope Clock.
  • Generating a pure sin wave output from a sin table.
  • Using a phase accumulator method to control the output sample rate.
  • Using the phase accumulator method to play music.
  • Playing notes via MIDI commands.
  • Using the phase accumulator method to change the frequency of sampled sounds.
  • Trying sampled sounds that include spoken words.
  • Stereo outputs.
  • Doing phase/delay experiments with the Stereo outputs.
  • Building a simple power amp output for the PWM output.

Comments please:

  • Did I miss something about the R2R or PWM DAC options?
  • An experiment to try?
  • Suggestions for future articles?
  • How would you use sound output in a project?
  • Errors or typos?

Posted in Arduino, Ideas, Microcontroller, Projects.

21 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Matt says

    Thanks for the interesting sound examples and comparisons! πŸ™‚

    Just a few things:

    “PWM sound is also called PCM or pulse code modulation” –
    Not true at all. PCM is like ordinary .wav data.

    Berni: “This is actually how MIDI works, playing samples at different speeds” –
    Truly incredible! MIDI doesn’t do any sound.

    Good luck in the future! πŸ™‚

  2. Dan says

    Have you considered using PWM on each line of the 4 bit R2R DAC to extend it’s resolution? Given enough clock speed it should be simple enough.

  3. Berni says

    I had some problems with MIDI input, only MIDI output worked.

    Anyway for those that want a good software for MIDI and audio check this
    Very nicely made piece of software that has a free trial of 30 days but is still functional afterwards it just displays a “buy me” message

  4. Berni says

    Well use it as a MIDI instrument, but i cant seam to get the PC to synthesize stuff it gets in to the midi port.

  5. dfowler says


    What would you control on the PC with the MIDI accelerometer?

  6. dfowler says


    Good catch, its fixed now. Thanks.


  7. korp says

    I believe there’s a typo in “Consider that decimal 128 is 1000000 in binary.”. Should be an additional 0 there, right?

  8. Berni says

    Oh and one idea i had is to try and connect that accelerometer to a PCs MIDI port.

  9. follower says

    Another useful article for the series, although I must admit a few of the terms used were unfamilar to me.

    One of the ideas I’ve had for using sound is to use it to provide a non-visual user interface by way of sampled speech.

    I’ve got a “spy pen camera” that uses such an interface–I blogged about it and the post includes a link to the (rather poor) sound.

    The principle advantage is the ability to have an interface that doesn’t require the space a LCD would take up. Plus it’s just kinda cool. πŸ™‚


  10. Berni says

    Yes but i donut use the integrated card i use a PCI one witch is much better.Those seam to have mostly kept the gameport and also most of there ports do have MIDI support.

  11. dfowler says


    It seems like modern PCs have lost the 15 Pin game port connector where the old MIDI interface was. I bought a USB to MIDI device to play with. Does anyone have a suggestion for an easy software tool to use with MIDI for these kinds of experiments?


  12. Berni says

    I found out that yes my sound card dose have MIDI support on gameport.Meaby i can hack it

  13. Berni says

    I have to check if my sound card has MIDI, It has a game port but im not sure if it has MIDI in it.Or if the port aculy works at all since i never plugged anything in it yet.

  14. dfowler says


    I hope to show this in the next article. I refer to it as phase accumulation but that is just a fancy way of saying that we resample the sound at different rates to play it back at different frequencies.

    I would love to have this work with MIDI but I have no experience with MIDI. I did purchase a USB MIDI interface to play with. I need to find a simple program to use with it. Something that is easy to send notes commands from.


  15. dfowler says


    The space is only a problem for sampled sound. There is plenty of space to store a sin table and output notes using phase accumulation to output at different frequencies. If the music was stored as a sequence of notes, it should be no problem to have long melodies.

  16. dfowler says


    I will double check this Collin. The file names are as expected but maybe I got the names wrong when I recorded. My filter had only a small effect on the sound of the PWM. The input filter on the sound card did most of the work.


  17. Berni says

    Well all you do for playing a melody is loop a small sample of the instruments sound and play it back at different speed.You can even do it polyphonic if the thing is fast enough.

    This is actually how MIDI works, playing samples at different speeds.

  18. pK - says

    I think a little trick can be done. You told about a 1MB EEPROM and reading samples but no much space to do. Maybe can be great if you really generate diferent kind of sound note and we store a midi-like file on eeprom. Well, not real sound, but can play long melodies πŸ™‚

  19. Collin Mel says

    Another great article. Thanks so much for continuing this series!
    btw – It sounds like the 8-bit PWM filtered/unfiltered sample links are reversed.

  20. dfowler says


    Good idea. I need to get one of these chips. I wonder if a serail DAC could be used in combination with the serial memory so that the uC just acts as a control function. Data might be output from the serail memory and piped directly into the DAC without passing through the uC.

    I will look at this memory, if it has an auto address increment it may be easy to do this. Idealy, it has an auto increment that can be configuerd to step by 1 or more bites at a time.


  21. Berni says

    I would suggest you try playing sound out of a EEPROM.Microchip gives free samples of 1Mbit EEPROM with a fast SPI bus. 1Mbit will hold 15 seconds of 8bit 8Khz audio

    I also saw serial DACs with a buffer that holds a few KB of samples and the DAC automatically reads then according to the clock input.This means you can just send the data to it in big chunks.

    If you ask me the best way to do it is PWM, since it provides great quality no external components its very fast and easy to amplify