can't get SPI to return correct results

Hi guys. i want to get a 16bit external ADC (AD7715) to work with an Arduino Nano. so far i’ve gotten it all hooked up, but the problem is it doesn’t return the correct result. it either returns 0 or a constant number.

i’ve uploaded the schematic of what i have right now.

what have i done wrong? any help is appreciated, and sorry if this is not the right place for this, didn’t know where to post this.

here is what i got:

#include <SPI.h>

const int DRDY = 8;
const int CS = 10;
int adcRead = 0;

void setup() {
  Serial.begin(19200);
  pinMode(DRDY, INPUT);
  pinMode(CS, OUTPUT);
  
  // start the SPI library:
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE3);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  digitalWrite(CS, LOW);
  SPI.transfer(0x10);
  SPI.transfer(0x6c); // 0x6c => Unipolar, 0x68 => bipolar
  digitalWrite(CS, HIGH);
}

void loop(){
  while(digitalRead(DRDY) != HIGH){
    digitalWrite(CS, LOW);
    SPI.transfer(0x38);
    byte b1 = SPI.transfer(0);
    byte b2 = SPI.transfer(0);
    digitalWrite(CS, HIGH);
    adcRead = b1 << 8 | b2;
    Serial.println(adcRead);
    delay(500);
  }
}

Hi nd saga,

Is your nano earth and ADC earth connected?

G

Zardof:
Hi nd saga,

Is your nano earth and ADC earth connected?

G

yes. this setup is purely for testing out the ad7715. since this is my first time using it.

Hi,

I thought this chip came in two types. The -3 and the -5 . Have you the right one?

G

Zardof: Hi,

I thought this chip came in two types. The -3 and the -5 . Have you the right one?

G

yes, the one i got is AD7715ANZ-5

bdsafa:
Hi guys. i want to get a 16bit external ADC (AD7715) to work with an Arduino Nano. so far i’ve gotten it all hooked up, but the problem is it doesn’t return the correct result. it either returns 0 or a constant number.

i’ve uploaded the schematic of what i have right now.

what have i done wrong? any help is appreciated, and sorry if this is not the right place for this, didn’t know where to post this.

code not tested (since I don’t have the hardware) but would this make any difference? I have this coded from the sample on the datasheet:

#include <SPI.h>

const int DRDY = 8;
const int CS = 10;
int adcRead = 0;

void setup() {
  Serial.begin(19200);
  pinMode(DRDY, INPUT);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);

  // start the SPI library:
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE3);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  
  while (digitalRead(DRDY) != HIGH); /*Check ADC is not busy and ready to receive instruction */
  
  digitalWrite(CS, LOW);
  SPI.transfer(0x10); /* set the gain to 1, standby off and set the next operation as write to the setup  register */ 
  digitalWrite(CS, HIGH);

  while (digitalRead(DRDY) != HIGH); /*Check ADC is not busy and ready to receive instruction */

  digitalWrite(CS, LOW);
  SPI.transfer(0x6c); // 0x6c => Unipolar, 0x68 => bipolar
  digitalWrite(CS, HIGH);

}

void loop() {
  byte b1, b2;

  while (digitalRead(DRDY) != HIGH); /*Check ADC is not busy and ready to receive instruction */

  digitalWrite(CS, LOW);
  SPI.transfer(0x38); /*set the next operation for 16 bit read from the data register */
  digitalWrite(CS, HIGH);

  while (digitalRead(DRDY) != LOW); /* wait for /DRDY to go low */

  digitalWrite(CS, LOW);
  b1 = SPI.transfer(0); /* Read ADC MSByte */
  b2 = SPI.transfer(0); /* Read ADC LSByte */
  digitalWrite(CS, HIGH);

  adcRead = (b1 << 8) | b2;
  Serial.println(adcRead);
  delay(500);

}

sherzaad:
code not tested (since I don’t have the hardware) but would this make any difference? I have this coded from the sample on the datasheet:

#include <SPI.h>

const int DRDY = 8;
const int CS = 10;
int adcRead = 0;

void setup() {
  Serial.begin(19200);
  pinMode(DRDY, INPUT);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);

// start the SPI library:
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE3);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
 
  while (digitalRead(DRDY) != HIGH); /*Check ADC is not busy and ready to receive instruction /
 
  digitalWrite(CS, LOW);
  SPI.transfer(0x10); /
set the gain to 1, standby off and set the next operation as write to the setup  register */
  digitalWrite(CS, HIGH);

while (digitalRead(DRDY) != HIGH); /*Check ADC is not busy and ready to receive instruction */

digitalWrite(CS, LOW);
  SPI.transfer(0x6c); // 0x6c => Unipolar, 0x68 => bipolar
  digitalWrite(CS, HIGH);

}

void loop() {
  byte b1, b2;

while (digitalRead(DRDY) != HIGH); /*Check ADC is not busy and ready to receive instruction */

digitalWrite(CS, LOW);
  SPI.transfer(0x38); /*set the next operation for 16 bit read from the data register */
  digitalWrite(CS, HIGH);

while (digitalRead(DRDY) != LOW); /* wait for /DRDY to go low */

digitalWrite(CS, LOW);
  b1 = SPI.transfer(0); /* Read ADC MSByte /
  b2 = SPI.transfer(0); /
Read ADC LSByte */
  digitalWrite(CS, HIGH);

adcRead = (b1 << 8) | b2;
  Serial.println(adcRead);
  delay(500);

}

nope, the reading didn’t change.

in datasheet, it says:

DATA REGISTER (RS1, RS0 = 1, 1)
The data register on the part is a read-only 16-bit register that contains the most up-to-date conversion result from the AD7715. If the communications register data sets up the part for a write operation to this register, a write operation must actually take place to return the part to where it is expecting a write operation to the communications register (the default state of the interface). However, the 16 bits of data written to the part will be ignored by the AD7715.

you see, it just tells you to send 0x38 code and read data, it doesn’t tell the address. in some codes, in order to read data they even use SPI.transfer(255);

btw, i changed part of your code, since otherwise, it wouldn’t print anything. this part :

void loop() {
  byte b1, b2;

  while (digitalRead(DRDY) != HIGH);

  digitalWrite(CS, LOW);
  SPI.transfer(0x38);
  digitalWrite(CS, HIGH);

  while (digitalRead(DRDY) != HIGH); /* [THIS PART CHANGED FROM LOW TO HIGH */

  digitalWrite(CS, LOW);
  b1 = SPI.transfer(0);
  b2 = SPI.transfer(0);
  digitalWrite(CS, HIGH);

  adcRead = (b1 << 8) | b2;
  Serial.println(adcRead);
  delay(500);

}
while (digitalRead(DRDY) != HIGH); /* [THIS PART CHANGED FROM LOW TO HIGH */

according to the timing diagram in the datasheet (page 30). this is wrong.

DRDY need to be LOW FIRST before you perfrom SPI comm to request read information.

hence why I had coded it as:

while (digitalRead(DRDY) != LOW);

if you not getting any output, then that probably means your ADC does not have any data to output! ;)

sherzaad: according to the timing diagram in the datasheet (page 30). this is wrong.

DRDY need to be LOW FIRST before you perfrom SPI comm to request read information.

hence why I had coded it as:

while (digitalRead(DRDY) != LOW);

well, you are right on that, but according to figure10 (page 31), after transfering 0x38, there is no need to wait for drdy to go low, since its already low, so i was thinking to remove that line.

sherzaad: if you not getting any output, then that probably means your ADC does not have any data to output! ;)

it does output data, but wrong ones, it flickers between 0 and 100 or so and not responsive to the input.

ok did some digging, it seems DRDY pin not switching correctly. it sticks to LOW even after CS goes HIGH. :o