Post Go back to editing

AD7787 - SPI with an Arduino not receiving valid data

Category: Software
Product Number: AD7787

Hello everyone,

I am trying to setup an Arduino with SPI to an AD7787 for testing before I use it in my project. I cannot get a valid data response from it, though. I am hoping for some assistance —many thanks for considering my request.  AD7787

I have a DAC plugged into the AIN2 channel of the AD7787, and the DAC output is steadily decreasing over 1.3 seconds. I have confirmed the dac output via a scope. The DAC is also on the SPI bus. 

My transaction looks like this:

Begin transaction

Write CS low

Send 0x11 (Select mode register, channel AIN2)

Send 0x84 (Request single conversion, unipolar mode, unbuffered)

Wait for dReady pin to read zero

Send 0x39 (Select the data register, read, channel AIN2)

Read byte

Read byte

Read byte

Write CS high

End transaction

Is my communication incorrect?

I have posted the code I'm using as well. 

//INO*****************************************
#include "AD7787.h" 
#include "AD5664.h"
#include <SPI.h>

#define ad7787CSPin 9
AD7787 ad7787;
#define ad5664CSpin 10
AD5664 ad5664;

// the setup function runs once when you press reset or power the board
void setup() 
{
    pinMode(ad7787CSPin, OUTPUT);
    pinMode(ad5664CSpin, OUTPUT);
    pinMode(27, INPUT);//MISO Reading pin 
    digitalWriteFast(ad7787CSPin, HIGH);
    digitalWriteFast(ad5664CSpin, HIGH);
    Serial.begin(9600);
    SPI.begin();
    while (!Serial) {}
    Serial.printf("It begins\r\n");
    ad5664.initializeSPI(4000000, ad5664CSpin);
    ad5664.reset();
    ad7787.initializeSPI(5500000, ad7787CSPin);
    ad7787.reset();
    delay(500);
}

// the loop function runs over and over again until power down or reset
void loop() 
{
    uint32_t reply = 0;
    uint16_t dacValue = 0;
    ad5664.setDAC(0, dacValue);
    delay(130);
    for (int index = 0; index < 10; index++)
    {
        Serial.printf("DAC> %u\r\n", dacValue);
        reply = ad7787.singleConversion();
        Serial.printf("Data received> %u\r\n", reply);
        dacValue += 6550;
        ad5664.setDAC(0, dacValue);
        delay(130);
    }
    delay(2000);
}

//AD7787 ******************************************************

#include "AD7787.h"

AD7787::AD7787()
{
	return;
}

void AD7787::initializeSPI(int speed, int cs)
{
	pSettings = new SPISettings(speed, MSBFIRST, SPI_MODE3);
	pinCS = cs;
	return;
}

uint32_t AD7787::singleConversion()
{
	uint32_t result = 0;
	bool adcRunning = true;

	SPI.beginTransaction(*pSettings);
	digitalWriteFast(pinCS, LOW);//SS low
	char buff[2] = { (MODE_R | 1), (SnCONv | UNIPOLAR | UBUFMODE) };
	SPI.transfer(buff[0]);//CR: MR //h11
	SPI.transfer(buff[1]);//MR: Single Conv, unipolar, unbuffered //h84
	while (adcRunning)
	{
		if (digitalReadFast(27) == 0)
		{ adcRunning = false; }
	}
	//Read out the data 
	SPI.transfer((3 << 4) | (1 << 3) | 1);//Access data reg //h39
	result = readData();
	digitalWriteFast(pinCS, HIGH);//SS high
	SPI.endTransaction();
	return result;
}

uint32_t AD7787::readData()
{
	uint32_t adcResult = 0;
	uint8_t receivedBytes[3] = { 0 };
	receivedBytes[0] = SPI.transfer(0x0);
	adcResult |= receivedBytes[0];
	adcResult = adcResult << 8;
	receivedBytes[1] = SPI.transfer(0x0);
	adcResult |= receivedBytes[1];
	adcResult = adcResult << 8;
	receivedBytes[2] = SPI.transfer(0x0);
	adcResult |= receivedBytes[2];
	Serial.printf("Bytes> 1: %u, 2: %u, 3: %u\r\n", receivedBytes[0], receivedBytes[1], receivedBytes[2]);
	return adcResult;
}

void AD7787::reset()
{
	SPI.beginTransaction(*pSettings);
	digitalWriteFast(pinCS, LOW);
	SPI.transfer(0xFF);
	SPI.transfer(0xFF);
	SPI.transfer(0xFF);
	SPI.transfer(0xFF);
	digitalWriteFast(pinCS, HIGH);
	SPI.endTransaction();
	return;
}

The response I am getting from running it.

DAC> 0
Bytes> 1: 64, 2: 43, 3: 243
Data received> 4205555
DAC> 6550
Bytes> 1: 121, 2: 221, 3: 38
Data received> 7986470
DAC> 13100
Bytes> 1: 121, 2: 221, 3: 4
Data received> 7986436
DAC> 19650
Bytes> 1: 121, 2: 220, 3: 195
Data received> 7986371
DAC> 26200
Bytes> 1: 121, 2: 221, 3: 201
Data received> 7986633
DAC> 32750
Bytes> 1: 121, 2: 219, 3: 251
Data received> 7986171
DAC> 39300
Bytes> 1: 121, 2: 222, 3: 3
Data received> 7986691
DAC> 45850
Bytes> 1: 121, 2: 221, 3: 117
Data received> 7986549
DAC> 52400
Bytes> 1: 121, 2: 220, 3: 235
Data received> 7986411
DAC> 58950
Bytes> 1: 121, 2: 221, 3: 72
Data received> 7986504

Any help is greatly appreciated. Thank you. 



Changed SPI mode to 3
[edited by: Zip at 11:02 PM (GMT -4) on 19 Apr 2023]
  • Good news, everyone.

    I was able to get it working. 

    The relevant code is attached in case anyone else stumbles upon this in the future. 

    //AD7787
    
    #include "AD7787.h"
    AD7787::AD7787()
    {
    	return;
    }
    
    void AD7787::initializeSPI(int speed, int cs)
    {
    	pSettings = new SPISettings(speed, MSBFIRST, SPI_MODE3);
    	pinCS = cs;
    	return;
    }
    
    uint32_t AD7787::singleConversion()
    {
    	uint32_t result = 0;
    	bool adcRunning = true;
    	uint8_t status = 0;
    
    	SPI.beginTransaction(*pSettings);
    	SPI.transfer(0);//Clear buffer?
    	digitalWriteFast(pinCS, LOW);//SS low
    	uint8_t buff[2] = { (MODE_R | 0x1), (SnCONv | UNIPOLAR | UBUFMODE) };
    
    	SPI.transfer(buff[0]);//CR: MR //h11
    	SPI.transfer(buff[1]);//MR: Single Conv, unipolar, unbuffered //h84
    	while (adcRunning)
    	{
    		delayMicroseconds(10);
    		if (digitalReadFast(12) == 0)
    		{ adcRunning = false; }
    	}
    	//Check status
    	SPI.transfer(STAT_R);
    	status = SPI.transfer(0xFF);
    	//Read out the data 
    	SPI.transfer((3 << 4) | (1 << 3) | 1);//Access data reg //h39
    	result = readData();
    	digitalWriteFast(pinCS, HIGH);//SS high
    	SPI.endTransaction();
    	Serial.printf("StatusPost> %u\r\n", status);
    	return result;
    }
    
    uint32_t AD7787::readData()
    {
    	uint32_t adcResult = 0;
    	uint8_t receivedBytes[3] = { 0 };
    	receivedBytes[0] = SPI.transfer(0xFF);
    	adcResult |= receivedBytes[0];
    	adcResult = adcResult << 8;
    	receivedBytes[1] = SPI.transfer(0xFF);
    	adcResult |= receivedBytes[1];
    	adcResult = adcResult << 8;
    	receivedBytes[2] = SPI.transfer(0xFF);
    	adcResult |= receivedBytes[2];
    	return adcResult;
    }
    
    void AD7787::reset()
    {
    	SPI.beginTransaction(*pSettings);
    	digitalWriteFast(pinCS, LOW);
    	SPI.transfer(0xFF);
    	SPI.transfer(0xFF);
    	SPI.transfer(0xFF);
    	SPI.transfer(0xFF);
    	digitalWriteFast(pinCS, HIGH);
    	SPI.endTransaction();
    	return;
    }
    

  • //INO
    #include "AD7787.h" 
    #include "AD5664.h"
    #include <SPI.h>
    
    #define ad7787CSPin 9
    AD7787 ad7787;
    #define ad5664CSpin 10
    AD5664 ad5664;
    
    // the setup function runs once when you press reset or power the board
    void setup() 
    {
        pinMode(ad7787CSPin, OUTPUT);
        pinMode(ad5664CSpin, OUTPUT);
        digitalWriteFast(ad7787CSPin, HIGH);
        digitalWriteFast(ad5664CSpin, HIGH);
        Serial.begin(9600);
        while (!Serial) {}
        SPI.begin();
        Serial.printf("It begins\r\n");
        ad5664.initializeSPI(5500000, ad5664CSpin);
        ad5664.reset();
        ad7787.initializeSPI(5500000, ad7787CSPin);
        ad7787.reset();    
        delay(500);
    }
    
    // the loop function runs over and over again until power down or reset
    void loop() 
    {
        uint32_t reply = 0;
        uint16_t dacValue = 0;
        ad5664.setDAC(0, dacValue);
        delay(130);
        for (int index = 0; index < 10; index++)
        {
            Serial.printf("DAC> %u\r\n", dacValue);
            reply = ad7787.singleConversion();
            Serial.printf("Data received> %u\r\n", reply);
            dacValue += 6550;
            ad5664.setDAC(0, dacValue);
            delay(130);
        }
        delay(2000);
    }
    

  • Hi  ,

    Glad to hear you have resolved the issue. Feel free to post another thread if you have any questions.

    Regards,

    JC