I'm struggling to get an analogue devices AD7715 to work with an arduino R3. I have read the data sheet and example code a thousand times but I just can't see where I'm going wrong. Does anyone have any experience with this device that can help?
Here is the code:
// arduino SPI code for driving an ADC7715
// 11/06/2012
#include "SPI.h" // Uses the SPI library
#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO - not used, but part of builtin SPI
#define SPICLOCK 13 //sck
#define cs 10 //cs
int drdy=8; // I'm using digital pin 8 on the arduino for Data Ready Pin for data ready select
int del=200; // used for various delays
byte dataRegHighByte; //High part of data read in from ADC
byte dataRegLowByte; //Low part of data read in from ADC
int adcData; //value of adc register after combining the bytes received
void setup()
{
pinMode(cs, OUTPUT); // we use this for SS pin
pinMode(drdy, INPUT); // we use this for drdy pin
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
// AD7715 requires data to be sent MSB (most significant bit) first??
SPI.setDataMode(SPI_MODE0); // SCLK idle low (CPOL=0), MOSI read on rising edge (CPHI=0)
SPI.setClockDivider(SPI_CLOCK_DIV16); // ATmega328P at 16 MHz, so SPI = 1 MHz
Serial.begin(9600);
setupAD7715();
}
void setupAD7715()
{
digitalWrite(cs, LOW);
SPI.transfer(0x10); // set the gain to 1, standby off and set the next operation as write to the setup register
SPI.transfer(0x66); // set unipolar mode, buffer on, no filter sync, confirm clock as 2.4576MHz, set output rate to 50Hz and do a self calibration
digitalWrite(cs, HIGH);
if (drdy!=HIGH){
Serial.println("Data Ready pin has gone LOW!");
Serial.println("Self Calibration complete!");
delay(1000);
readADCDataRegister();
}
else Serial.println("Data Ready pin is HIGH");
}
void readADCDataRegister()
{
int adcRead;
digitalWrite(cs, LOW);
adcRead = SPI.transfer(0x38); // read the 1st byte
adcRead <<= 8; // shift the byte to the high 8 bits
adcRead |= SPI.transfer(0x38); // read the 2nd byte and OR to the low 8 bits of adcRead
digitalWrite(cs, HIGH);
Serial.print("Data has been read from ADC! :");
Serial.print("Data Received was: ");
Serial.println(adcRead,DEC);
delay(1000);
}
void loop()
{
readADCDataRegister();
}
I did read yor response and try out the code section you suggested. It made absolutely no difference whatsoever. I have also been looking at the datasheet and code example for the device and the manufacturers are suggesting to use a while statement for the polling of the /DRDy pin which is what ultimately the device requires to show that a register command has been received and processed.
{if(digitalRead(drdy) != HIGH) - your code for polling the /DRDy pin
digitalRead(dataReadyPin) /* wait for /DRDY to go low */
if (dataReadyPin == 0)
{
writeToADCDataRegister();
}
My code re-written after your help
while(!(dataReadyPin & 0x80)) /* wait for /DRDY to go low */
{
writeToADCDataRegister();
}
What I think the manufacturer recommends for polling the /DRDY pin
Your code snippet looks at the /drdy pin for a change of state from high to low which is one way of achieving what I did with my second code example. I accept my original code was incorrect but not my second effort after your assistance. None of the above made the device work which is why I asked for some more help. The issue is I think, with the device itself and not with the code as I have looked at the data lines using a logic analyser and I never see the /DRDY pin change state after sending an SPI command.
If anyone has any ideas, I'm open to suggestions on how to prove the device is working.
while(!(dataReadyPin & 0x80)) /* wait for /DRDY to go low */
does NOT wait for /DRDY to go low. It compares the value of dataReadyPin to 0x80. Since you have declared dataReadyPin to be an integer constant with a value of 8, the result of "8 & 0x80" is always zero and so the while loop will never terminate.
If you want to wait until Pin 8 goes low you need:
while(digitalRead(dataReadyPin)) /* wait for /DRDY to go low */
This will read the value of Pin 8 and if it is non-zero (HIGH) it will stay in the while loop. Once the value of pin 8 goes low, the while loop will terminate.
Thank you for you help in the coding. I still don't have the device working but I can now see the /DRDY pin going high and low sometimes on the logic analyser. I must be still doing something wrong in terms of the code. I also think I need to use a proper layout with a ground plane. My circuit is very jittery.
adcRead = SPI.transfer(0x38); // read the 1st byte
adcRead <<= 8; // shift the byte to the high 8 bits
adcRead |= SPI.transfer(0x38); // read the 2nd byte and OR to the low 8 bits of adcRead
digitalWrite(chipSelectPin, HIGH);
The correct code for reading the SPI is:
digitalWrite(chipSelectPin, LOW);
SPI.transfer(0x38); // send the reading instruction
adcRead = SPI.transfer(0); // read the 1st byte
adcRead <<= 8; // shift the byte to the high 8 bits
adcRead |= SPI.transfer(0); // read the 2nd byte and OR to the low 8 bits of adcRead
digitalWrite(chipSelectPin, HIGH);
SPI.endTransaction(); // - not obligatory, but may be
Hello Filipx_cz.
Thank you for your code...
may you can share the complete working code just to copy and paste?
i have found 10 pcb for pt100 with an AD7714 on it. The Pins MOSI, MISO, SCLK, SYNC and DRDY are inverted by an integrated IC. I am not sure if i can use the code in same way.
hopefully someone can help.