Interpreting external ADC values with Arduino


I'm interfacing the ADS7956, which is a 10 bit 12 channel ADC, with the Arduino Uno using SPI. I'm able to establish successful communication with the device, but the values seem incorrect. I'm supplying the channel voltage with a digital power supply (which is working, as I've verified its voltage with a voltmeter.) I've also verified that the data the Arduino recieves, which I then print, is the same as the data output by the device by checking it on an oscilloscope from the ADC side of the connection. All the connections to the chip seem functional too.

The ADC is a 10 bit device, and according to the datasheet, it sends the MSB first on a falling SCLK edge, the first 4 bits are the channel address, then the subsequent 10 are my converted data and the last two bits are useless. So, when I mask out the top 4 bits and shift the result right 2 bits, that should give me the 10-bit conversion result. I'm using Arduino's SPI.transfer16 to get the 16-bit result, then masking and shifting it to the 10 bit value. I also use SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE1)) according to the device data sheet for mode and maximum clock speed.

For a 2.5 V range, I would then expect the result for a 2.5 volt channel voltage to be 1023, or 1111111111b. What I'm getting instead is 872, or 1101101000b. When my voltage is higher than this, I also get 872. Other values are similarly "off".

Any ideas on why this could be happening would be much appreciated. Is there a different way to interpret the data from a chip like this?


That's a pretty complicated chip - read the datasheet a few more times end-to-end and it'll
probably become clearer... One thing its worth doing is googling for some code already out
there to drive it, then you have a known good set of register values to program into the device
(this is very useful for TFT screen controllers for instance). Complex chips are more likely to
have silicon bugs too, which aren't always 'fessed up in the datasheet in an obvious way.