Post Go back to editing

No output from AD5791, difficulty interfacing with AD5791

Hi

I'm trying to interface an AD5791-EVAL with an Arduino, and I am not able to get the DAC to output any voltage, it is always 0, or specifically 0.2mV. I also had tried with a Raspberry Pi with same result.

The AD5791, is connected to the SPI interface of an Arduino Duo. The EVAL is powered with 3.3V from a lab supply (EVAL board is using 200mA at 3.3V), and all jumpers are in default position, specifically, using the onboard ADP5070 and low noise regulators, using the ADR445 reference daughter board. Jumper set (as default) to connect VCC to IOVCC. All other jumpers all default as per EVAL-AD5791SDZ User Guide. Due is self powered, the GND on the Duo is connected to the DGND on the EVAL, 8 or 9 on J12.

Reset, CLR and MISO (SDO) are left open, SDI is connected to the Arduino MOSI, SYNC is connected to a digital pin, LDAC is connected to a digital pin on the Duo, SCKL is connected to the Arduino SPI SCKL.

LDAC is set to 0 (low) permanently via the digital pin, then I write to the control register 001000000000000000000010 (R/!W=0, A=010, LIN=0000, SDODIS=0, BIN/2sC=0, DACTRI=0, OPGND=0, RBUF=1), then I write to the DAC register 000111111111111111111111 (R/!W=0, A=001, D=11111111111111111111), I set data to max, I don't care about the value at this point, just making sure I got the communication right.

Example code for Arduino:


#include <SPI.h>

#define CS_AD5781 10
#define LDAC_AD5781 11

void setup() {

pinMode(CS_AD5781, OUTPUT);
pinMode(LDAC_AD5781, OUTPUT);

digitalWrite(CS_AD5781, HIGH);

digitalWrite(LDAC_AD5781, LOW);

SPI.begin();
}

void write_spi_ad5791(unsigned char data[3])
{
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE1));

digitalWrite(CS_AD5781, LOW);

SPI.transfer(data[0]);
SPI.transfer(data[1]);
SPI.transfer(data[2]);

digitalWrite(CS_AD5781, HIGH);

SPI.endTransaction();
}

void loop() {
// 001000000000000000000010
// R/!W=0
// A=010
// LIN=0000
// SDODIS=0
// BIN/2sC=0
// DACTRI=0
// OPGND=0
// RBUF=1
// R/!W=0, A=010, LIN=0000, SDODIS=0, BIN/2sC=0, DACTRI=0, OPGND=0, RBUF=1
unsigned char control_reg[3] = {32, 0, 2};
write_spi_ad5791(control_reg);

// 000111111111111111111111
// R/!W=0
// A=001
// D=11111111111111111111
unsigned char dac_reg[3] = {31, 255, 255};
write_spi_ad5791(dac_reg);

delay(5000);
}

Example code for Raspberry Pi (in the Pi case, SYNC is connected to SPI CE0):

wiringPiSetup();
wiringPiSPISetupMode(0, 100000, 1);
pinMode(DAC_LDAC_PIN, OUTPUT);
digitalWrite(DAC_LDAC_PIN, LOW);

// 001000000000000000000010
// R/!W=0
// A=010
// LIN=0000
// SDODIS=0
// BIN/2sC=0
// DACTRI=0
// OPGND=0
// RBUF=1
// R/!W=0, A=010, LIN=0000, SDODIS=0, BIN/2sC=0, DACTRI=0, OPGND=0, RBUF=1
spi_buf[0] = 32;
spi_buf[1] = 0;
spi_buf[2] = 2;
result = wiringPiSPIDataRW(SPI_CHANNEL_0, spi_buf, 3);

// 000111111111111111111111
// R/!W=0
// A=001
// D=11111111111111111111
unsigned char dac_reg[3] = {31, 255, 255};
spi_buf[0] = 31;
spi_buf[1] = 255;
spi_buf[2] = 255;
result = wiringPiSPIDataRW(SPI_CHANNEL_0, spi_buf, 3);

Pi and Arduino waveforms are identical, I attached the Arduino ones.

I attached the scope waveforms as well, which contain DIN (MOSI of Arduino Duo), SCLK, and SYNC, in that order. In the waveforms, you can see the first write to the control register, SYNC, going high, then the second write to the DAC register. 

What am I doing wrong here?

Most SPI hardware sends 8 bits per word, for 24 bits that's 3 words, as you can see in the waveforms, could that be causing an issue here with AD5791?



edit
[edited by: iontodirel at 7:20 AM (GMT -4) on 1 Apr 2021]
Parents
  • Ok I made it work, turns out the error was in the code. First of all, I need binary offset, the EVAL supplied +-10V for the reference inputs, so LIN=1100, and lastly, the correct code for others:

    // 001000000000001100110010 -> offset binary, LIN=1100, SDODIS=1 -> 32, 3, 50
    unsigned char control_reg[3] = {32, 3, 50};
    write_spi_ad5791(control_reg);

    // +10V
    unsigned char dac_reg[3] = {31, 255, 255};
    write_spi_ad5791(dac_reg);

    delay(5000);

    // -10V
    unsigned char dac_reg2[3] = {16, 0, 0};
    write_spi_ad5791(dac_reg2);

    delay(5000);

    // -5V
    unsigned char dac_reg3[3] = {19, 255, 255};
    write_spi_ad5791(dac_reg3);

    delay(5000);

    // +5V
    unsigned char dac_reg4[3] = {27, 255, 255};
    write_spi_ad5791(dac_reg4);

    delay(5000);

Reply
  • Ok I made it work, turns out the error was in the code. First of all, I need binary offset, the EVAL supplied +-10V for the reference inputs, so LIN=1100, and lastly, the correct code for others:

    // 001000000000001100110010 -> offset binary, LIN=1100, SDODIS=1 -> 32, 3, 50
    unsigned char control_reg[3] = {32, 3, 50};
    write_spi_ad5791(control_reg);

    // +10V
    unsigned char dac_reg[3] = {31, 255, 255};
    write_spi_ad5791(dac_reg);

    delay(5000);

    // -10V
    unsigned char dac_reg2[3] = {16, 0, 0};
    write_spi_ad5791(dac_reg2);

    delay(5000);

    // -5V
    unsigned char dac_reg3[3] = {19, 255, 255};
    write_spi_ad5791(dac_reg3);

    delay(5000);

    // +5V
    unsigned char dac_reg4[3] = {27, 255, 255};
    write_spi_ad5791(dac_reg4);

    delay(5000);

Children
No Data