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() {
  pinMode(DOUT, OUTPUT);
  pinM ode(DIN, INPUT);
  SPCR = _BV(SPE) | _BV(MSTR) | _BV(CPOL) | _BV(CPHA) | _BV(SPI2X) | _BV(SPR1) | _BV(SPR0);
  digitalWrite(CS_AD7705, LOW);
  spiTransfer(00010000); //setup register
  spiTransfer(00100000); //clock register
  digitalWrite(CS_AD7705, HIGH);

void loop() {
  unsigned int data=0;
  digitalWrite(CS_AD7705,LOW); // enable device
  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
  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
    Commented Sep 12, 2016 at 9:49

2 Answers 2


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
    Commented Sep 12, 2016 at 9:48
  • Personally I'd write it in hex, but ... :) Commented Sep 12, 2016 at 10:01
  • Binary is better when you're working with registers - you can visualise the bits in the register easier.
    – Majenko
    Commented Sep 12, 2016 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 Commented Sep 14, 2016 at 4:36

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
//  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 and acknowledge you have read our privacy policy.

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