Arduino Uno AD5696 DAC almost working

Hi all,

my first post to forum so I hope it’s in the appropriate section!

Overarching goal of my project is to make triple gas blender (Air, N2, CO2) regulated by trimpots writing values to LCD (for user) and outputting 0-5v to my mass flow controllers. I started with PWM but the controllers didn’t play nice with the UNO output signal. I then went the DAC route and purchased a AD5696 quad DAC (AD5696 16-Bit 4-Channel Digital to Analog Converter I2C Mini Module - and I2C shield (I2C Shield for Arduino Uno -

I finally have all the bits talking to one another, much thanks to many of your forum posts. However, the voltage output from the DAC isn’t quite right. The AD5696 uses a 16-bit binary input (Decimal 0-65535) to provide 0-5v output (PDF attached) but it reaches 5V prematurely at around 43000. From 43000 to 65535 the DAC output remains at 4.97V. Writing 0 to DAC gives ~20mv. It’s almost like the gain of the DAC output is off. I suppose I could add code to account for the gain difference (Plan B) but wanted to see if I could approach the problem head on.

Looking for some guidance on how to troubleshoot this problem. I have included trimmed down code below for one input / DAC output.

PS. I’m am a developmental physiologist by profession and have only be using Arduino for past 2 months. Take it easy on an old man please. Things I have tried. Power supply instead of USB. Different DAC channels. Manual writing values to DAC. The pin settings on the DAC (ADDR, PULL UP and J1 are all in default “off” position.

#include <Wire.h>;
const int flowIn;

void setup()
Serial.begin (9600);

void loop()
// Read Flow
int flowIn = analogRead(A0); //read the input on analog pin (0-1023)
float flowOut = flowIn * (500.0 / 1023.0); // maximum total flow will be 500 ml/min
float flowOutDAC = flowOut * (65535.0 / 500.0); // conversion of ml/min to decimal
unsigned int flowOutDAC2 = int(flowOutDAC); //get rid of zero’s for DAC write

Serial.print("flowIn = “); Serial.print(flowIn);
Serial.print(” flowOut = “); Serial.print(flowOut);
Serial.print(” flowOutDAC = “); Serial.println(flowOutDAC);
Serial.print(” flowOutDAC2= "); Serial.println(flowOutDAC2);

//CHANNEL 1 (VoA on board)
Wire.beginTransmission(0x0c); //Binary 00001100 (address of DAC - printed on the circuit board - confrimed with I2C scanner on UNO)
Wire.write(0x31); ///// channel one Binary 00110001 (command 0011 - write to DAC; 0001 channel 1 address; tables 7 and 8 of AD5696 chipset for reference)
Wire.write(flowOutDAC2 >> 8); // send MSB data byte >> right shift 8. 0000011111101000 becomes 00000111
Wire.write(flowOutDAC2 << 8); // send LSB data byte << left shift 8. 0000011111101000 becomes 11101000


AD5696_5694.pdf (741 KB)

At first blush your problem seems to be hardware and not software related. My question is what are you using for Vref since it sets up the step size for the DAC output. If Vref is too high the DAC output will hit the high rail voltage (5volts) too soon and max out resulting in the output voltage stalling at the high rail limit.