I turned an Arduino Protoshield into a digital-to-analog converter with only a few extra parts. It’s proved a lot of fun for audio experimentation and a great way to learn about what DACs do and how they do it.

What’s DAC?
Digital to analog converters, or DACs, are used to create varying voltage levels from binary off/on signals. Used in a variety of circuit applications, DACs are most commonly known for the role they play in generating audio. There’s a lot of DAC chips out there capable of interfacing with Arduino via data protocols such as serial, i2C, etc. – but if want to learn more with a hands-on approach, consider the simple and affordable R/2R DAC circuit –

The “R/2R” stands for ‘Resitance / 2xResistance’ referring to the resistor values used in the circuit – 10K, and 20K. The R/2R DAC effectively gives each pin a different voltage output value, so using 8 pins we have 8 different levels we can combine to shape our output signal. Precise R/2R DACs use an output buffer stage but we’ll skip this for our simple version.

Hit the jump below for more info and pictorial –Build dat DAC!
First assemble your base protoshield from the thorough instructions over at – BUT, if you want to follow this how-to, don’t install the female headers on the top of the board (go ahead and install the 3-pin female header on the bottom). The R/2R DAC can be assembled on a protoshield with a breadboard, but I recommend the following method for enhanced sturdiness/reusability.

Materials needed

  • Resistors 10 x 10K & 8 x 20K

  • Trimpot 10K – labelled “103”
  • Jack 1/8″ stereo or mono, panel or board-mount can be used, phono or 1/4″ would work as well
  • Hook-up wire, 24 – 22AWG (I prefer solid core, 3 or 4 different colors is best)
  • Soldering iron & solder
  • Wire snips & wire stripper tools
  • Protoshield kit
  • Arduino

got all that? Ok – onto the making . . .

Extend those pins
Cut 8 pieces of solid core wire about 40mm long each and strip about 5mm from each end.

Wires Place
Place the wire pieces so they connect pins 0 – 7 to the top row of long solder pads on the board.

Solder and clip each wire lead on the reverse side of the board.

Climb the R/2R ladder
Resistorshorz Clearance
Next, place 20K resistors connecting each of the seven top long pads to the bottom row of pads, bending each lead to secure them before soldering. Try to keep them raised up above the 5V & GND rails below. On the other side of the board solder, and clip the leads.

Resistorsvert2 Crop
Now place 10K resistors between the bottom row of long pads. These need to mounted standing up (vertically) in order to fit. For the leftmost resistor, use the bottom hole of the last pad – leaving a spot for our output signal as pictured above.

Place the remaining 20K resistor connecting GND to the intersection of pin 0’s 10 and 20Ks as pictured above. Bend, solder, clip and rejoice in your new R/2R ladder!

Put in the output
Jack Place-1
Jack Groundsolder
I’m using a PCB-mount style 8″ stereo jack I used doesn’t fit into the standard hole size used on the protoshield :/ That’s ok, at least the ground conductor at the front of the jack fits. I snipped the right channel lead off (since I’m only interested in mono sound here) and bent the left channel soldering it to one hole on the board – and securing the jack in place by soldering the ground lead.

Jack Bothwires
Now cut and strip another piece of wire for the output signal, I chose to use red. While you’re at it, cut and strip 2 more for our signal ground and trimpot wiring.
Connect the signal and ground leads to the output jack from the sources across the board as pictured. Bend, solder, clip, repeat.

Trimpot placement
Pot Place
Place your trimpot on the board with the 2 outside leads connecting to 5V and GND and the middle lead to an isolated pad – turn the board over and solder into place.

Potwire Place
Lastly wire the middle lead of the trimpot to the analog 0 pad on the shield – solder and trim as per usual

Testing …

Now connect the board to your arduino and load up this sketch – R2R Synth Test

Hook up to a speaker/amplifier (as always, keep volume low at first). You’ll know everything works when you hear a rough tone controllable by the trimpot’s setting. Take a look at the code to see how it’s being generated – experiment with changing it to achieve different sounds.

Scanning the Arduino forums a bit I found Hotcarrier’s code for a 1kHz sine wave generator. After a bit of hacking I got it working as a variable tone generator.
You can check it out here – 1 kHz sine gen potpitch

Here’s a pic of the sketch’s output on the ol’ O-scope –


I’ll add a list of other compatible sketches here – Please stay tuned!

  • signaljammer

    It seems that your parallel port goes all zeros upon transition, judging from your scope output. You may be well-served to add a low-pass-filter (lpf) on your output. This can be integrated into your (output) buffer amplifier.

    The R-2R ladder needs to be relatively unloaded, anyway.

  • Collin Cunningham

    @signaljammer – Thanks for the tip. I have used a low-pass filter before but I wanted this project to be very simple, so I didn’t include one here.
    I also omitted a buffer stage for the same reason. If anyone wants to though there are details here –

    Update: added a line to the intro specifying lack of buffer etc


    Nice tutorial.

    The first commenter pointed out that scope shows an edge going low in between steps. This will always occur when using digitalWrite to activate pins in sequence. Since you’re using the whole port from pin 0 to 7, you might as well use PORTD to write all the lines at the same instant. For example, put “DDRD = B11111111;” in your initialization, and then at each voltage change put “PORTD = B00000010;” (the second voltage step).

    Also, please note that the beauty of an R2R ladder is the ability to turn a binary number directly into an analog value. So if you had loop with variable “A” counting from 0 to 255, then “PORTD = A;” would result in a steady ramp up in the output voltage. Now you can directly apply math functions to create things like triangle waves, sine waves, or arbitrary waveforms.

  • Collin Cunningham

    @macetech – Right on – this is exactly why I made it an 8-bit DAC, even though a 6-bit would have been easier. PORTD style code is on its way – hence the “stay tuned” =)

  • pp6

    Collin, great tutorial! It’s a great way to understand DACs so I think I’ll include it as an exercise in a workshop I’m doing in June.

    I’m wondering if it is possible to do that with PWM signals. What would happen if you change an analog value faster than 490 times/s ? (being 490Hz the aprox. frequency of the Arduino)

  • Collin Cunningham

    @pp6 – glad you found it useful!

    Regarding >490hz PWM switching:
    I think you’d basically end up truncating the PWM signal. It takes the PWM time to present its voltage approximation and since the Arduino would be changing the analogWrite value faster than it could be written (as 2 parts – high & low) – only the beginning of each PWM wave would actually be presented. You’d observe some modulation toward the low end of the PWM sweep. Definitely a good learning investigation activity tho.

  • Tony

    Is your sine wave really as accurate as it looks on that scope?? Mine is always a little off, not exactly the right shape…
    How critical are the resistance values? Mine are not exactly R/2R…

  • Collin Cunningham

    @Tony – upon close inspection, my sine isn’t perfect – but for the most part it’s pretty ‘on’

    using precise resistor values def helps – 1% tolerance (usually blue) are best.

  • Hector Segura

    First – thank you for the info – found yesterday
    2nd – will change? you ask to stay tuned …
    3rd – first image R/2R 1st resistor horizontal(left one) must be 20k not 10k
    Again thanks for the webpage

  • Ahamed Bacar

    hey where I can download the code source of your project ? and the wiring of your project ?

  • bob