TL;DR: I am not getting the correct values back from the AD7811 ADC. I am giving the ADC an input from my benchtop PSU (Tenma 72-2540) into analog input 1, and getting various (and always wildly incorrect) results back (although there is some consistency to it, read on!). I have additional questions about the part that might be better suited to a separate post.
More detail on the problem
I wanted to quickly test the AD7811 ADC with my Arduino Mega 2560 as I plan to use the AD7811 for a hobby project, and it is slightly different to the only SPI ADC I’ve used before (no dedicated “slave select” per se on the AD7811, has a combination of Conversion Start, Receive Frame Start and Transmit Frame Start). By tying CONVST, RFS and TFS together, it seems that it should operate similar to the way Slave Select normally works for SPI devices. I won’t be using the Mega in my final project, it was just faster to get it up and running.
Circuit Here is a diagram of my circuit, it is implementing the “Typical Connection Diagram” found on page 10 of the datasheet. (I’ve also included a screenshot of this underneath my circuit)
Photographs of connections
Here are some shots showing how I’ve got everything connected.
Code
#include <SPI.h>
const int convst = 42; // CONVST pin on AD7811 connected to Pin 42 on Arduino
uint16_t return_val = 0;
// value to transfer to the control register (see page 7 of the datasheet)
uint16_t control = 0B1011000011;
void setup() {
// start the SPI library:
SPI.begin();
SPI.beginTransaction(SPISettings(2000, MSBFIRST, SPI_MODE0));
pinMode(convst, OUTPUT);
digitalWrite(convst, HIGH);
Serial.begin(9600);
}
void loop() {
digitalWrite(convst, LOW); // Initiate the conversion process. Since TFS is also brought low, MOSI data is latched into the ADC (page 16)
SPI.transfer(control>>2); // Transfer first 8 MSB of control settings (page 7 datasheet) i.e. 0B10110000
SPI.transfer(control<<6); // Transfer last 2 bits of control settings i.e. 0B11000000
delayMicroseconds(3); // Conversion process takes at most 2.3us
digitalWrite(convst, HIGH);// Bring CONVST, RFS and TFS high. First sentence of page 16 indicates that this would cause the result to be put on the SPI bus
delayMicroseconds(1);
return_val = SPI.transfer16(0); //read the 10 bit result
return_val = return_val >> 6; //SPI.transfer16 stores our result as a 16 bit number, but ADC only has 10bit resolution. Rightshift by 6 to correct this error.
Serial.println("Return");
Serial.println(return_val); //print the value that we got back
delay(1000);
}
Returned values
As I said in the TL;DR, the values I get back are always “wrong” (perhaps “not what I expected” is better), but they’re not necessarily the same values each time. For instance, feeding in 1VDC to Input 1 of the ADC, I get values 617, 616, 105 and 104 as my return values that I am printing to serial out (this is after I bitshift by 6 to the right). There’s no real discernible pattern, however it’s always one of these 4 values. For 1VDC input, and with Vref at 5VDC, I would expect about 204 or 205 as the return value (1/5 * 1024). If I change to 2VDC input, I get 722, 721, 210, 209.
Scope captures
- Proof that the control register is being written to (MOSI line)
The control settings appear to be leaving the Arduino on the MOSI line. There’s a “glitch” (terminology?) that occurs when transferring 0 from SPI.transfer16(): see the shot below, there’s a short spike of ~300ns duration around the falling edge of the 8th clock cycle. I’m not sure why this is occurring, I’m telling the Arduino to write a 0 for this transaction. Blue is SLCK, Red is MOSI (pin 51 Arduino)
- MISO line
Naturally, I wanted to check the response from the ADC. Blue is SCLK, Red is MISO (pin 50 on Arduino)
I’ve noticed that, occasionally, there is an exponential decay over the last 7 clock cycles (and then some). I’m not sure what to make of this, but it doesn’t look good.
- Chip selection
Red is CONVST, RFS and TFS (tied together). Once that goes low, serial clock starts ticking, and data is transferred (in the manner shown in the scope captures above). Blue is SLCK, Red is CONVST/RFS/TFS (pin 42)
- Checking analog input 1
The input to the ADC looks to be clean, I have bypassed with a 10nF capacitor to help clean up the input.
I am still pretty new to doing my own digital designs, second time using SPI, so I’d really appreciate any pointers or advice! If there’s any information I’m missing that you need, I’ll get it for you. I’m keen to improve wherever I can, including my troubleshooting skills!