Wrong voltages with DAC MCP4725 driven by Mega250

Hello, I Use 2 sparkfun DAC's (MCP4725). and drive the with testDACSpec.ino (1.5 KB)

I have 2 of them on the Mega. I did not cut the pull up resistors on one of them since it seems to give problems only when using 3 or more.
My problem is that the voltage on the output is not what I would expect. I expect a voltage related to the given value in the table.
Theese are the measured voltages:

address(hex)=61 lookup=0 lookupWa=200 an.value=496 voltage=2.54
address(hex)=61 lookup=1 lookupWa=400 an.value=509 voltage=2.43
address(hex)=61 lookup=2 lookupWa=800 an.value=494 voltage=2.51
address(hex)=61 lookup=3 lookupWa=1000 an.value=506 voltage=2.43
address(hex)=61 lookup=4 lookupWa=2000 an.value=508 voltage=2.48
address(hex)=61 lookup=5 lookupWa=3000 an.value=753 voltage=3.67
address(hex)=61 lookup=6 lookupWa=4000 an.value=880 voltage=4.28
address(hex)=61 lookup=7 lookupWa=4095 an.value=876 voltage=3.97
I also need 0.5V and 4.5 V and cannot produce them. The output has no load at the moment. My arduino powers on the USB.I provide 5V for the DAC's coming from the "5V" on the mega.
Thanks for suggestions.

It would be good to ask a moderator to move your post into a more appropriate forum, such the the Programming Questions...

And then post your code directly, using code tags. It will help people help you

It may be better to install the Adafruit library for that device since this:

  Wire.write(simpleTab[lookup] >> 4);        // the 8 most significant bits...
  Wire.write((simpleTab[lookup] & 15) << 4); // the 4 least significant bits...

isn't doing what you think. Compare that to the adafruit library version

@patpin, your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advise on) your project :wink: See About the Installation & Troubleshooting category.

Even if it is a sparkfun?

From what I can see the spark fun circuit uses the board supply voltage as a reference , as the Arduino 5v pin is unlikely to be spot on 5v , that could well be the issue .

Have a look at the spark fun schematic and a read of the data sheet for the chip to check

yes. it is the same chip using the same i2c protocol.

Thanks. I have downloaded it at github and installed it in my libraries folder of the my sketchbook folder as mentioned in preferences. I had this error:

  • D:\DATA-MEDION\Arduino\SoftwarePP\libraries\Adafruit_MCP4725/Adafruit_MCP4725.h:10:10: fatal error: Adafruit_BusIO_Register.h: No such file or directory
  • #include <Adafruit_BusIO_Register.h>
    and resolved it by downloading this one at github.
    Now the code is testDACSpecAda.ino (1.7 KB)
    and serial monitor still gives non lineair voltages:
    address(hex)=61 lookup=0 lookupWa=200 an.value=497 voltage=2.45
    address(hex)=61 lookup=1 lookupWa=400 an.value=511 voltage=2.54
    address(hex)=61 lookup=2 lookupWa=800 an.value=504 voltage=2.44
    address(hex)=61 lookup=3 lookupWa=1000 an.value=522 voltage=2.52
    address(hex)=61 lookup=4 lookupWa=2000 an.value=508 voltage=2.48
    address(hex)=61 lookup=5 lookupWa=3000 an.value=752 voltage=3.57
    address(hex)=61 lookup=6 lookupWa=4000 an.value=884 voltage=4.36
    address(hex)=61 lookup=7 lookupWa=4095 an.value=882 voltage=4.30

I checked the voltage with DVM: 4.96V; Also strange that the voltage at 4095 is lower than at 4000...
I guess it should be 4.96V .
A few minutes later:
address(hex)=61 lookup=0 lookupWa=200 an.value=497 voltage=2.43
address(hex)=61 lookup=1 lookupWa=400 an.value=505 voltage=2.49
address(hex)=61 lookup=2 lookupWa=800 an.value=520 voltage=2.43
address(hex)=61 lookup=3 lookupWa=1000 an.value=511 voltage=2.56
address(hex)=61 lookup=4 lookupWa=2000 an.value=509 voltage=2.49
address(hex)=61 lookup=5 lookupWa=3000 an.value=745 voltage=3.62
address(hex)=61 lookup=6 lookupWa=4000 an.value=893 voltage=4.29
address(hex)=61 lookup=7 lookupWa=4095 an.value=891 voltage=4.32

Wiring diagram needed !

Maybe your 0v isn’t at the chip or you have a volt drop along a ground connection ?
Using the output of a couple of analog pins as a power supply, as per the sketch, is not great IMO as 0v /5v could be noisy or not even 0v . ( USB 5v will be noisy)

What is the voltage at the sparkfun board between 0v and supply pins ? And when you measure output measure between the sparkfun board Ov and the output , not at the Arduino or supply

Data sheet also shows offset values for the output (0.75% of full scale ) and other non linearity specs

I can not confirm your issue. When I run your code with the 0x60 address of my mcp4725 I see expected results.

//#include <Wire.h>
#include <Adafruit_MCP4725.h> // na install steeds IDE heropenen

Adafruit_MCP4725 dac;
// after scann.: I2C device found at address 0x60  !
//               I2C device found at address 0x61  !

int lookup = 0;//variable for navigating through the tables
int address=0x60;
int readV=A0;
const int numb=8;
int simpleTab[numb] = 
{
  200,400,800,1000, 2000,3000,4000,4095 // 
};
float v[numb];


void setup()
{ pinMode(A0,INPUT);
  //Wire.begin();
  dac.begin(0x60);

  // Set A2 and A3 as Outputs to make them our GND and Vcc,
  //which will power the MCP4725
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);

  digitalWrite(A2, LOW);//Set A2 as GND
  digitalWrite(A3, HIGH);//Set A3 as Vcc
  Serial.begin(57600);
  Serial.println();
}
//---------------------------------------------------
void loop()
{
  //Wire.beginTransmission(MCP4725_ADDR);
  //Wire.beginTransmission(address);
  //Wire.write(64);                     // cmd to update the DAC
  dac.begin(0x60);
  Serial.print("address(hex)=");Serial.print(address,HEX);
  Serial.print("  lookup=");Serial.print(lookup);
  Serial.print("  lookupWa=");Serial.print(simpleTab[lookup]);
  //Wire.write(simpleTab[lookup] >> 4);        // the 8 most significant bits...
  //Wire.write((simpleTab[lookup] & 15) << 4); // the 4 least significant bits...
  dac.setVoltage(simpleTab[lookup], false);
  //Wire.endTransmission();
  delay(10);

  Serial.print("  an.value=");Serial.print(analogRead(readV));
  v[lookup]=analogRead(readV)*5.0/(float)1024;
  Serial.print("  voltage=");Serial.println(v[lookup]);
  delay(3000);
  lookup++;
  if (lookup==numb) lookup=0;
  //if (lookup ==1) lookup=0; else lookup = 1;// (lookup + 1) & 511;
}

address(hex)=60 lookup=0 lookupWa=200 an.value=48 voltage=0.24
address(hex)=60 lookup=1 lookupWa=400 an.value=99 voltage=0.48
address(hex)=60 lookup=2 lookupWa=800 an.value=198 voltage=0.97
address(hex)=60 lookup=3 lookupWa=1000 an.value=249 voltage=1.22
address(hex)=60 lookup=4 lookupWa=2000 an.value=499 voltage=2.44
address(hex)=60 lookup=5 lookupWa=3000 an.value=750 voltage=3.66
address(hex)=60 lookup=6 lookupWa=4000 an.value=1002 voltage=4.89
address(hex)=60 lookup=7 lookupWa=4095 an.value=1022 voltage=4.99

I would remove the dac.begin() from loop(), but that does not appear to be the cause of your issue.

It would appear that you have a wiring rather than code issue, or perhaps a defective module.

The supply over one of the analog ports was changed to a LM7805 for both DAC's; nothing changed. I upload the wiring diagram

. On both DAC's VCC I have 4.96V.
If DAC is defective then both have to be defective since:
address(hex)=60 lookup=0 lookupWa=200 an.value=491 voltage=2.48
address(hex)=60 lookup=1 lookupWa=400 an.value=493 voltage=2.55
address(hex)=60 lookup=2 lookupWa=800 an.value=490 voltage=2.54
address(hex)=60 lookup=3 lookupWa=1000 an.value=492 voltage=2.42
address(hex)=60 lookup=4 lookupWa=2000 an.value=506 voltage=2.47
address(hex)=60 lookup=5 lookupWa=3000 an.value=732 voltage=3.65
address(hex)=60 lookup=6 lookupWa=4000 an.value=865 voltage=4.24
address(hex)=60 lookup=7 lookupWa=4095 an.value=876 voltage=4.24
address(hex)=60 lookup=0 lookupWa=200 an.value=511 voltage=2.48
after rerunning code for address 0x61:
address(hex)=61 lookup=0 lookupWa=200 an.value=514 voltage=2.43
address(hex)=61 lookup=1 lookupWa=400 an.value=518 voltage=2.55
address(hex)=61 lookup=2 lookupWa=800 an.value=521 voltage=2.42
address(hex)=61 lookup=3 lookupWa=1000 an.value=520 voltage=2.39
address(hex)=61 lookup=4 lookupWa=2000 an.value=506 voltage=2.47
address(hex)=61 lookup=5 lookupWa=3000 an.value=749 voltage=3.67
address(hex)=61 lookup=6 lookupWa=4000 an.value=881 voltage=4.32
address(hex)=61 lookup=7 lookupWa=4095 an.value=887 voltage=4.32
address(hex)=61 lookup=0 lookupWa=200 an.value=522 voltage=2.43
address(hex)=61 lookup=1 lookupWa=400 an.value=495 voltage=2.54
address(hex)=61 lookup=2 lookupWa=800 an.value=513 voltage=2.54
address(hex)=61 lookup=3 lookupWa=1000 an.value=521 voltage=2.52
address(hex)=61 lookup=4 lookupWa=2000 an.value=507 voltage=2.47
address(hex)=61 lookup=5 lookupWa=3000 an.value=748 voltage=3.57
address(hex)=61 lookup=6 lookupWa=4000 an.value=859 voltage=4.32
address(hex)=61 lookup=7 lookupWa=4095 an.value=797 voltage=4.22
I measure no voltage drop between GRN at 12V supply and at DAC's...

Thanks for doing the test!! I guess both will be defective...
Was it a Sparkfun DAC that you used for the test?

Much easier/better to just install it directly from the library manager within the IDE.

Now both DAC's function (There were wiring errors and softw errors. )
Code is nowtestDACSpecAda.ino (1.4 KB)
Still I have a problem: When I put both DAC's on the print, none is correct (errors as in first post: no linearity). Then I have cut the pull up R's from the 0x60 DAC first : no help; This one alone still functions but not when the 0x61 DAC is also inserted. Then I have als cut the pull-ups of the 0X61 DAC; problem remains +- the same: they function both well but only when the other one is not inserted.
So when both are installed (and cut!) I get;
address(hex)=60 lookup=0 lookupWa=200 an.value=46 voltage=0.22
address(hex)=60 lookup=1 lookupWa=400 an.value=73 voltage=0.58
address(hex)=60 lookup=2 lookupWa=800 an.value=211 voltage=1.01
address(hex)=60 lookup=3 lookupWa=1000 an.value=229 voltage=1.20
address(hex)=60 lookup=4 lookupWa=2000 an.value=484 voltage=2.46
address(hex)=60 lookup=5 lookupWa=3000 an.value=738 voltage=3.56
address(hex)=60 lookup=6 lookupWa=4000 an.value=877 voltage=4.28
address(hex)=60 lookup=7 lookupWa=4095 an.value=872 voltage=4.24
and for 0x61: no low voltages and no linearity!
address(hex)=61 lookup=0 lookupWa=200 an.value=881 voltage=4.29
address(hex)=61 lookup=1 lookupWa=400 an.value=843 voltage=4.23
address(hex)=61 lookup=2 lookupWa=800 an.value=866 voltage=4.17
address(hex)=61 lookup=3 lookupWa=1000 an.value=850 voltage=4.23
address(hex)=61 lookup=4 lookupWa=2000 an.value=828 voltage=4.20
address(hex)=61 lookup=5 lookupWa=3000 an.value=839 voltage=4.16
address(hex)=61 lookup=6 lookupWa=4000 an.value=987 voltage=4.82
address(hex)=61 lookup=7 lookupWa=4095 an.value=989 voltage=4.83
I have tried a pull up of 10K on the SDA and SCL (after cutting the original ones on both DAC's) and the voltages where always around 2.5V for both DAC's.

What happens if you read them on two different inputs instead of both on A0?

Hi,
Here is @patpin 's code.

//#include <Wire.h>
#include <Adafruit_MCP4725.h> // na install steeds IDE heropenen
// als beide samen erin dan werkt die van x60 niet en die van x61 ook nt; ook nt na cutten van pullup R in x60
// als elk afzonderlijk dan werken beide ook die 0x60 met gecutte pull ups;
// ook de 0x61 gecutt: werkt ook afzonderlijk; met de gecutte 0x60 erbij werkt de 0x61 nt juist en ook de 0x60 is nt juist.
// Poging doen met pull ups

Adafruit_MCP4725 dac;
// after scann.: I2C device found at address 0x60  !
//               I2C device found at address 0x61  !

int lookup = 0;//variable for navigating through the tables
int address;
int readPin = A7;
const int numb = 8;
int simpleTab[numb] =
{
  200, 400, 800, 1000, 2000, 3000, 4000, 4095 //
};
float v[numb];


void setup()
{
  pinMode(A7, INPUT);
  address = 0x60;
  Serial.begin(57600);
  Serial.println();
}
//---------------------------------------------------
void loop()
{
  dac.begin(address);
  Serial.print("address(hex)=");
  Serial.print(address, HEX);
  Serial.print("  lookup=");
  Serial.print(lookup);
  Serial.print("  lookupWa=");
  Serial.print(simpleTab[lookup]);
  dac.setVoltage(simpleTab[lookup], false);
  delay(10);
  Serial.print("  an.value=");
  Serial.print(analogRead(readPin));
  v[lookup] = analogRead(readPin) * 5.0 / (float)1024;
  Serial.print("  voltage=");
  Serial.println(v[lookup]);
  delay(3000);
  lookup++;
  if (lookup == numb) lookup = 0;
}

To add code please click this link;

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

The code only addresses one of the DAC's at a time; I also used A7: same result; I always check with DVM: same result.

Hi,
Can you please post picture(s) of your project so we can see your component layout?

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

Hi, @patpin
Can you run this code please, it shouldn't make any difference but I have lengthened the time between setting the DAC and reading it.
I have also added some extra data points at the top end of your table.

//#include <Wire.h>
#include <Adafruit_MCP4725.h> // na install steeds IDE heropenen
// als beide samen erin dan werkt die van x60 niet en die van x61 ook nt; ook nt na cutten van pullup R in x60
// als elk afzonderlijk dan werken beide ook die 0x60 met gecutte pull ups;
// ook de 0x61 gecutt: werkt ook afzonderlijk; met de gecutte 0x60 erbij werkt de 0x61 nt juist en ook de 0x60 is nt juist.
// Poging doen met pull ups

Adafruit_MCP4725 dac;
// after scann.: I2C device found at address 0x60  !
//               I2C device found at address 0x61  !

int lookup = 0;//variable for navigating through the tables
int address;
int readPin = A7;
const int numb = 10;
int simpleTab[numb] =
{
  200, 400, 800, 1000, 2000, 3000, 4000, 4025, 4060, 4095 //
};
float v[numb];


void setup()
{
  pinMode(A7, INPUT);
  address = 0x60;
  Serial.begin(57600);
  Serial.println();
}
//---------------------------------------------------
void loop()
{
  dac.begin(address);
  Serial.print("address(hex)=");
  Serial.print(address, HEX);
  Serial.print("  lookup=");
  Serial.print(lookup);
  Serial.print("  lookupWa=");
  Serial.print(simpleTab[lookup]);
  dac.setVoltage(simpleTab[lookup], false);
  delay(100);
  Serial.print("  an.value=");
  Serial.print(analogRead(readPin));
  v[lookup] = analogRead(readPin) * 5.0 / (float)1024;
  Serial.print("  voltage=");
  Serial.println(v[lookup]);
  delay(2900);
  lookup++;
  if (lookup == numb) lookup = 0;
}

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

Thanks for adapting the code. Unfortunately none of my DAC's is responding. I'll have to order new ones and also will be abroad for some time. I'll be back in a few weeks.
In the meantime I gave another question: how many amps can the output drive?