Arduino 10 Bit Analog Output




Dr James Moxham is a general medical practitioner in Blackwood, Australia. His interests include ...

Standard pwm output from the Arduino has an 8 bit resolution. This project improves the resolution for an analog output to around 10 bits, plus has a much faster settling time and allows up to six analog outputs. The project uses only one resistor and one capacitor and one arduino pin, and uses a software trick where an analog input pin can be turned into an output, then used to charge or discharge a capacitor, and then turned back into an input to read back the value.

If you add a standard RC low pass filter to the pwmout signal on an arduino the output looks noisy on a CRO, and fluctuates considerably if another arduino samples the voltage. Fancy multipole filters use lots of components. Adding a very large RC filter (eg 100k and 100uF) means it can be ten seconds for the output to stabilise, plus you have to be careful about internal leakage within the capacitor, using tantalum capacitors instead of electrolytics.

This circuit does all the clever work in software and uses a 10k resistor and a 1uF greencap capacitor. Sample the voltage on the capacitor, rapidly charge or discharge to near the correct value, eg 50 millivolts, then apply brief charge or discharge pulses of around 1 microsecond to keep the value correct. Settling time is around 1 millisecond which is 100,000 times faster than using a large RC on pwmout. The self discharge of a greencap polyester capacitor or a tantalum means that 1 microsecond adjustments are only needed every five or ten seconds.

Stray RF can be an issue so it helps to keep the leads short. Even so, there can be some errors with the ADC on an arduino so to improve this, take twenty samples and take the average.

Perhaps this has already been done before? Anyway, it is a nifty little circuit and code that I am using in a couple of practical circuits, mainly as a simple way of sending information between Arduino's as an analog voltage.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1:

Be the First to Share


    • Assistive Tech Contest

      Assistive Tech Contest
    • Reuse Contest

      Reuse Contest
    • Made with Math Contest

      Made with Math Contest

    8 Discussions


    1 year ago

    Very neatly done. You sort of re-discovered delta-sigma modulation but in a very clever, application-specific way. I’ll see if I can interest one of my electrical engineering students in characterizing this.

    David, AD8Y

    Faculty advisor Case Amateur Radio Club, W8EDU

    1 reply
    James MoxhamDkazdan

    Reply 1 year ago

    Thankyou for your kind words, and yes, it is based on delta-sigma. I'd be interested to see if an electrical engineer can improve this. Cheers, James Moxham


    2 years ago

    Nice technique. Do you have a schematic to attach? Thanks.

    5 replies
    James Moxhamacheide

    Reply 2 years ago

    Good idea. I'll try doing this in text, hopefully this makes sense:

    Connect pin A0 to one end of the 10K resistor. Connect the other end of the resistor to the +ve of the capacitor (either end, if non polarised). Then the other end of the capacitor to Gnd.

    OmniventJames Moxham

    Reply 2 years ago


    If you want to use the output for anything but feeding a high impedance meter, you should consider adding a rail-rail (in as well as out) op-amp to buffer the signal.

    Have a nice day :)

    James MoxhamOmnivent

    Reply 2 years ago

    Good point. I've used old-skool CA3140 op amps as they can swing rail to rail. And yes, you have to be very careful with loading the output - all of my multimeters load it too much. Another Arduino is ok though, but there one little catch there - with thin hookup wire powering boards, there is a little bit of voltage drop in the gnd wire as that second arduino is using ?30mA to power itself, so the readings become slightly higher than they should be. Thick ground wires will minimise this.

    I need to do more experiments, but I think it might be something like a voltage follower, then a twisted pair of wires with the Vout and Gnd, then at the other end a unity gain differential amplifier.

    OmniventJames Moxham

    Reply 2 years ago

    Hi again,

    CA3140 (and the dual version CA3240) is still a great op-amps within their capabilities, but unfortunately, the price has sky-rocketed, at least in DK, which is pretty odd, when you can get good (/better) replacements much cheaper.

    I assume the loading that you mention, is without the buffer(?) as even the worst present day DMMs has an input impedance of 1M (10M on most).

    The output impedance of the CA3140 is around 60 Ohms, very high in this day and age, but even that shouldn't matter, as the feedback includes this in the loop.

    If the error is a steady measure over the entire range (like e.g. 5mV too little) the problem is likely offset, which can be trimmed out (10k trimmer from pin 1 to pin 5 with the wiper to pin 4).

    If you feed both boards directly from your power source (i.e. supply terminals of each goes all the way to the supply, rather than being fed of one another) and make it with proper filtering, then one board can sag its supply without much influence on the other - just keep a good low impedance ground (with each terminated at the supply as well).

    While twisting the wire can reduce radiated noise effects (if using long wires), there's no need for a differential amplifier/buffer. The effective output impedance will be very low (your 60 Ohm is before 100% negative feedback, so the real Zout will be much less than 1 Ohm [in theory under 1mOhm])

    First thing is to make sure you have a proper power supply and when that's done, I think the rest will follow by itself.

    Have a nice day :)