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);
}
-
1Why mess around with registers like that? Why not just use the SPI library - that's what it's there for.Majenko– Majenko2016年09月12日 09:49:56 +00:00Commented 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.
-
2Actually, 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– Majenko2016年09月12日 09:48:11 +00:00Commented Sep 12, 2016 at 9:48
-
Personally I'd write it in hex, but ... :)Code Gorilla– Code Gorilla2016年09月12日 10:01:41 +00:00Commented 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– Majenko2016年09月12日 10:02:28 +00:00Commented 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(-) openvignajeth kk– vignajeth kk2016年09月14日 04:36:54 +00:00Commented 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
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)?