Unstable dac op

hi guys!
I am trying to generate milli-volt signals using dac mcp4822 but unfortunately the results are not as expected.
my code is pretty basic,

#include <MCP48xx.h>
// Define the MCP4822 instance, giving it the SS (Slave Select) pin
// The constructor will also initialize the SPI library
// We can also define a MCP4812 or MCP4802
MCP4822 dac(10);
// We define an int variable to store the voltage in mV so 100mV = 0.1V
int voltage = 0;
unsigned int c,d,e,f;

void setup() {
  // We call the init() method to initialize the instance


    // The channels are turned off at startup so we need to turn the channel we need on

    // We configure the channels in High gain
    // It is also the default value so it is not really needed
    pinMode (A0,INPUT);
    pinMode (A1, INPUT);
    pinMode (A2, INPUT);

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(A0)==HIGH)
  if(digitalRead(A1)==LOW && digitalRead(A2)==LOW)
  if (digitalRead(A1)==HIGH)
  if (digitalRead(A0)==LOW && digitalRead(A2)==LOW)
  if (digitalRead(A2)==HIGH)
  if(digitalRead(A0)==LOW && digitalRead(A1)==LOW)

here is a overview of my circuit connections:

additionally i have connected 3 pulldown resistors 1 each to pin A0,A1 and A2 of nano.
I am using a 7805 for generating 5v which in turn is powered by a 9v battery.
here is a table of the observed outputs:

serial no c/d/e value expected o/p observed o/p
01 5 5 3.5/ 6.3/7.3
02 6 6 4.5/ 7.3/8.3
03 7 7 6.5/8.3/9.3

all values in mV.
as one can see for serial no 1 when c=5 op in the range of 3.5mV to 7.3mV and so on...
a difference of more than 50%.

i need to generate in range of 5-10mV only...any suggestions are welcome...

(P.S: i am using a reliable multimeter. hardware is on BB.)


Hi Marrc

Please clarify the type of Arduino. Your diagram says Uno, text says Nano.

Please clarify the type of 9V battery, is it PP9 size? These batteries are generally not suitable for Arduino circuits.

You mention pull-down resistors and I guess you also have pushbuttons. Please include these in your schematic so we can see how they are wired. You can remove the pull-down resistors and use the built-in pull-up resistors if you connect your buttons between Arduino pins and ground.

Your code looks too have been written by someone with no familiarity with C/C++ language. Do you understand the use of { } in C/C++?

How are you connecting the 7805 regulator? Please include that in your schematic.

Can you please post a FULL schematic of your project?
A hand drawn circuit on paper would be more than adequate.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

i am using arduino nano schematic and code are copied from somewhere :wink: though i cant quite see why a 9v battery is unsuitable for my purpose i am using a rechargable 9v battery similar to this

pulldown needed to execute

if (digitalRead(A0)==LOW && digitalRead(A2)==LOW)

schematic coming up in couple of days...

What is the application that you need mV?

You may need to generate Volts rather than mV from the DAC then use a potential divider and output buffer to get your desired range and precision.

Lets do some maths;
4096 bits, 5V reference/supply.
1 bit = 5/ 4096 = 0.0012Volts
1 bit is 1.2mV.
You are seeing a 1mV difference, that is 1bit and what is the accuracy of your DMM?
That is pretty good I would say.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

i am seeing a difference of around 3-5 mV . please see table of observations in my first post.

serial no c/d/e value expected o/p observed o/p
01 5 5 3.5/ 6.3/7.3
02 6 6 4.5/ 7.3/8.3
03 7 7 6.5/8.3/9.3


i am trying to build a calibrator.
DMM i am using has a resolution of 0.1mV.

I did not say unsuitable for your purpose, we do not know enough about your project overall. But many beginners come to the forum for help with circuits not working as expected and the reason is frequently PP9 batteries. This type of battery has a high internal resistance and cannot supply very much current. If more than a little current is drawn, the voltage quickly drops. This type of battery is suitable for smoke alarms and not much else!

The other disadvantage of 9V batteries us that if you use a linear regulator like 7805 or the regulator built into the Nano, almost half the battery's capacity will be wasted as heat by the regulator.

Warning: the batteries you posted the link to are not in fact rechargeable!

Correct. To use external or internal pull-ups, that line would need to change. But that is trivial and worthwhile to remove components from the circuit.

point taken ... i was going to come to the power supply part later once i achieved repeatability in dac op...but using the 7805 and 9v battery is the only method i know so far...(u r right i am beginner)
So tell me what is your assessment of my project? is it dowable like this?

Can I suggest as in post #5

This would be more desirable, generating mV around the resolution of the DAC is as you have found got some problems.
Have you tried a 0.1uF capacitor across the output of the DAC to suppress any noise?
Are you working with a protoboard or do you have a PCB or strip board construction.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

don't understand why you are conditionally checking 2 input pins.

on the multifunction shield i have, A1-A3 are used as button pins configure as INPUT_PULLUP. a LOW input indicates the button is pressed

if (LOW == digitalRead (A1))

if you're not sure about the output, why not generate a ramp waveform in setup() and look at the output

void setup() {

void loop() {
    static int  val = 0;


    val += 10;
    if (32000 < val)
        val = 0;

    delay (10);

Table of your results.

DAC Val Expected Out mV DAC Out min mV DAC Out max mV
1 5 6.1
2 6 7.3
3 7 8.5

Expected out =( 5 / 4096 ) * DACValue mV

I am finding it hard to read your "table".
It would be better if you drew it and posted an image.
Is your 5V, exactly 5.00V?

Have you got the bypass capacitors around the LM7805 as per the datasheet.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

had to quote ur txt for table..

Good, have you checked the output with higher values of DAC data, say 100 or 1000 or 3000 and checked what the output is and if you get any variance?

Tom... :smiley: :+1: :coffee: :australia:

[quote="marrc, post:13, topic:914372, full:true"]

table of observation for higher dac values. difference of up to 20mA.

Vref is 2.048 && Gain is 2.000 so
1 bit = 4.096/4096 = 1mV

The "expected" values are incorrect; The DAC Out Min are as you would expect; and the DAC out max are out by 20mV (not mA)

ie 20 * LSB.

Reloatively, that is a huge error.

My best guess is thet the 5V regulator is oscillating and introducing a LOT of noise. See the data sheet for the DAC

6.2 Power Supply Considerations
The typical application will require a bypass capacitor
in  order  to  filter  out  the  noise  in  the  power  supply
traces.  The  noise  can  be  induced  onto  the  power
supply's  traces  from  various  events  such  as  digital

switching  or  as  a  result  of  changes  on  the  DAC's
output.  The  bypass  capacitor  helps  to  minimize  the
effect of these noise sources. Figure 6-1 illustrates an
appropriate bypass strategy. In this example, two
bypass  capacitors  are  used  in  parallel:  (a)  0.1 μF
(ceramic)  and  (b)10 μF  (tantalum).

Hi, @johnerrington

Good, I basically started the table theme to get some normality into the results and get everybody on the same page.

Please post a circuit diagram of YOUR project?
Include component names and pin labels as well as your power sources.

Thanks.. Tom.... :grinning: :+1: :australia:

what type of battery should i use? a link to seller will be appreciated.

What you're measuring in mV on a breadboard will be quite random. Measuring mV accurately is hard. A good Multimeter is only one of the needed components.
You also need to get rid of everything around that could generate noise, take care of the routing of the leads of the multimeter and have a really good GND reference point.

So for one: get the impedance down, put a load on the analog output (resistor), also buffer it with a small capacitor. Select the same GND-Point for your measurmet and your load and the ADC (physically the same point, preferably directly on the pin! A few mm of line can already skew your result if there as any other load on the same rail, read the full datasheet of the part).

Make sure that the leads of the multimeter are tied together, make a twisted pair out od them. The more distance between those leads the more noise they will pick up. You might even want to put a small cap across the terminal on the multimeter to get rid of some of the noise...

About the voltage output: 1 digit is exactly 0.5mV (it has an internal reference of 2.048V and a resolution of 4096 digits).

So in german we say:"Wer misst, misst Mist" (the one who measures will measure crap). And that's true. Always! The are of measuring is to know how much crap you're measuring and either keeping it below a level that makes your measurment unuseable or to know how much crap you measure and correct for that.

Keep on trying! Marco