2

Code as shown below. I am unable to get the 16-bit data. Can someone help me identify my mistake?

byte spiTransfer(volatile byte data) {
  SPDR = data;
  while (!(SPSR & _BV(SPIF)));
  return SPDR;
}
#define DOUT      (50) 
#define DIN       (51)
#define SCLK      (52)
#define CS_AD7705 (53)
#define DRDY (4)

void setup() {
  Serial.begin(9600);
  pinMode(DOUT, OUTPUT);
  pinM ode(DIN, INPUT);
  pinMode(SCLK,OUTPUT);
  pinMode(CS_AD7705,OUTPUT);
  pinMode(DRDY,INPUT);
  SPCR = _BV(SPE) | _BV(MSTR) | _BV(CPOL) | _BV(CPHA) | _BV(SPI2X) | _BV(SPR1) | _BV(SPR0);
  delay(10);
  digitalWrite(CS_AD7705, LOW);
  spiTransfer(00010000); //setup register
  spiTransfer(01100110);
  spiTransfer(00100000); //clock register
  spiTransfer(00001000);
  digitalWrite(CS_AD7705, HIGH);
}

void loop() {
  unsigned int data=0;
  digitalWrite(CS_AD7705,LOW); // enable device
  while(!digitalRead(DRDY));
  data = spiTransfer(00111000);  // select ch1 and setup read 16-bit data register
  data = spiTransfer(0)<<8;
  // Get the most significant 8 bits
  Serial.println("data : "+data);
  data |= spiTransfer(0); // Get the least significant 8 bits
  digitalWrite(CS_AD7705, HIGH); // release device
  delay(1000);
  Serial.println(data, HEX);
}
  • 1
    Why mess around with registers like that? Why not just use the SPI library - that's what it's there for. – Majenko Sep 12 '16 at 9:49
1

I think the main problem is the values you are passing to spiTransfer(). By the way they are written I think you think you are passing binary values, you aren't you are passing decimal values. So

data = spiTransfer(00111000);  // select ch1 and setup read 16bit data   

should be

data = spiTransfer(B00111000);  // select ch1 and setup read 16bit data  

The number needs prefixing with a B

Also passing a volatile parameter to this function looks wrong to me, especially when you only pass in constants.

  • 2
    Actually, numbers starting with 0 are octal, not decimal. And you should avoid "B<xxxxxxxx>" since they are Arduino-specific macros. Instead you should use the (standard these days) 0b<xxxxxxxx> format. – Majenko Sep 12 '16 at 9:48
  • Personally I'd write it in hex, but ... :) – Code Gorilla Sep 12 '16 at 10:01
  • Binary is better when you're working with registers - you can visualise the bits in the register easier. – Majenko Sep 12 '16 at 10:02
  • even though using B as prefix the AD7705 is not taking inputs from potentiometer. can some one help me .i has left vref(+) and vref(-) open – vignajeth kk Sep 14 '16 at 4:36
0

I've been trying to get one of these working too. I think before you can read the data register, you have to tell the COMMs register your intention to do so.

// Select channel to read:  
// write to comm reg selecting channel and 
// setting up next op to be a read from data reg
SPI.transfer( DRDY_DONT_CARE | REG_DATA | STDBY_OFF | COMMS_READ | CHAN_AIN1 );
//  Do two 8-bit reads, MSByte first  
highByte = SPI.transfer(0xff);
lowByte  = SPI.transfer(0xff);

adcValue0 = highByte << 8;
adcValue0 = adcValue0 | lowByte;

Still, I've had sketchy and intermittent success reading the ADC. The looping code seems to lose sync with the ADC; I've been speculating that reading ASAP following DRDY going True is important.

Have you verified that your SPI interface is working? You can read the 24-bit calibration data, which should match the documented values. Doing so verifies that the SPI reads and writes properly, unless the SPI interface behaves differently for different functions. Are you using genuine Analog Devices silicon, or one of the widely available knock-offs (TM7705, like mine)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.