Arduino R2R DAC: Circuit Tuning

I’ve spent my last two posts making some important improvements to the code for my Digital to Analog converter. I’ve converter the code to write directly to the PORT register to speed up my updates and implemented timer interrupts to improve my timing. These are both vast improvements but there’s still one more area that desperately needs my attention before I start building out the features of my new oscillator. That area is the circuit.

Today I’ll be working to hammer out two big issues I’ve been having with the circuit. The first I identified back when I first introduced this project, that is the lack of consistency in the values of the various voltage steps. Once that’s squared away I’d like to have a look at buffering the output so I can start driving a speaker (or other analog load) with the DAC.

The Resistance

Original DAC Output

Ideally when stepping through the voltages of my DAC (as I do with my saw wave function) I should be seeing a smooth staircase on my oscilloscope. Unfortunately looking at the output above we see this is not exactly the case. The issue here has to do with the tolerance of the resistors. Had this original design been more than a proof of concept I would have ordered low tolerance resistors special for the task. Instead in my rush I used what was available in my parts drawer. Unfortunately this meant the values of my resistors varied quite widely from the 100 and 200 ohms I had planned.

My approach here is pretty low-tech. I drew a quick schematic of the circuit and using my multimeter marked down the actual resistance of each resistor. Diagram in hand I started measuring the other 100 ohm resistors I had on hand. When I found one closer to the target resistance than what was on my diagram I switched them out and updated the diagram. Since I had limited resistors available I wasn’t able to get the values exactly but it still made a substantial difference.

New DAC output

Looking at the new output above the steps still aren’t perfect but they are substantially closer to the idealized staircase we are looking for. Each of the 16 steps is now clearly visible and differentiated.

Another approach you can take to bypass these issues is trimmer pots. If you replace each resistor with a trimmer potentiometer you can dial in the exact resistance you want up to the resolution of the trimmer.

Buffering

If you know anything about me it’s that I like to make noise. It’s sort of my jam. Sadly though if you’ve tried to connect this circuit as it stands to a speaker you may have been sorely disappointed to find nothing coming out. This simply won’t do!

The issue here is with the current in my circuit. Digital pins (both on the Arduino and otherwise) put out a tiny amount of current. The absolute maximum available from any digital pin on the Arduino is 40.0 mA.

If we consider the case of a 1W 8ohm speaker (similar to a cheap computer speaker) being driven at 5V we’ll find that it needs about 200mA to run (1W/5V = 0.2A = 200mA). Clearly we need to step things up a notch.

4-bit DAC Circuit

My solution here was to add an LM358 op-amp to buffer the signal. Since the output of the Arduino is already 5V I didn’t need any gain so I set this up as a “Unity Gain Amplifier”. One issue I did encounter is that the output range of the LM358 does not cover the full 5V range I’m supplying it with. I found the signal became saturated at about 4.1-4.2V. To combat this I added the potentiometer to work as a voltage divider and attenuate the signal slightly before it enters the amplifier.