Is it coding or hardware issue?

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

    dac.init();

    // The channels are turned off at startup so we need to turn the channel we need on
    dac.turnOnChannelA();
    dac.turnOnChannelB();

    // We configure the channels in High gain
    // It is also the default value so it is not really needed
    dac.setGainA(MCP4822::High);
    dac.setGainB(MCP4822::High);
    Serial.begin(9600);
    pinMode (A0,INPUT);
    pinMode (A1, INPUT);
    pinMode (A2, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    
  if (digitalRead(A0)==HIGH)
  c=4;  
  if(digitalRead(A1)==LOW && digitalRead(A2)==LOW)
  dac.setVoltageA(c);
  dac.updateDAC();
   
  if (digitalRead(A1)==HIGH)
  d=5;
  if (digitalRead(A0)==LOW && digitalRead(A2)==LOW)
  dac.setVoltageA(d);
  dac.updateDAC();
  
  if (digitalRead(A2)==HIGH)
  e=6;  
  if(digitalRead(A0)==LOW && digitalRead(A1)==LOW)
  dac.setVoltageA(e);
  dac.updateDAC();  
}

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.)

cheers,
Marrc

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.

Hi,
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...

Hi,
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

7.3-3.5=3.8mv
8.3-4.5=3.8mv
9.3-6.5=2.8mv

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?
cheers,
Marrc

Hi,
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() {
    dac.init();
    dac.turnOnChannelA();
    dac.setGainA(MCP4822::High);
}

void loop() {
    static int  val = 0;

    dac.setVoltageA(c);
    dac.updateDAC();

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

    delay (10);
}

Hi,
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..

Hi,
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: