Problem with SPI connection to TI ADS8681 programmable ADC

Hello Forum,

I’m trying to establish a SPI connetcion to the programmable analog digital converter TI ADS8681. In the future I wish to adress several
ADCs connected in a daisy chain (see ADC data sheet p.38). But as a first step I set up a connection to a single ADC, according to figure 71 (see ADC data sheet p.37). I want to connect a “aa battery” to the ADC to simulate an input. Then I hope to read the ADCs digital output via SPI. Finally the output shall be send to the serial port of a PC. My wiring is shown in the picture attached.

I wrote a code to cnfigure the ADC via its command registers and read the converted digital values.
But I have some trouble to reead those values via SPI.

Sadly I am new to arduino, microelectronics and C/C++ all together. Therefore I hope for a little help from this forum.

I’d like to thank for any help in advance.

// Read out a TI ADS8681 (ADC)
// Arduino MKR 1010 WIFI
// August 2020
// by SPL

#include <SPI.h>
// Arduino SPI Libray

// MISO
// SCK
// MOSI
const int CS = 7;
// set SPI Pins

void setup() {
// define Baud rate for serial data transfer
Serial.begin(9600);

pinMode(MISO, INPUT);
pinMode(MOSI,OUTPUT);
pinMode(SCK, OUTPUT);
pinMode(CS, OUTPUT);
// set the SPI-Pin as an output/input:

digitalWrite(CS, HIGH);
// set CS to idle

writeRegister(0x08,0b00000000,0b00000000);
// define SPI Mode; address of the SDI_CTL_REG Register (hex) and define SPI Mode, ADC data sheet p. 51
// matches ARDUINO SPI Mode0

writeRegister(0x14,0b00000000,0b00000001);
// define Measurement Range 10,24 V, see p. 54 ADC data sheet;
}

void loop() {
read_adc_to_serial();
delay(5);
//read ADC and send result to serial
}

void read_adc_to_serial() {
byte package_read [4];
// define read variable

SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
// initialize SPI & SPI Settings defines speed Maximum in Hz, dataOrder and dataMode
// speed Maximum in Hz: 10 kHz, see ADW Data Sheet 6.6 (p. 11)
// dataOrder : MSBFIRST, see ADW Data Sheet 7.4.1.3 (p. 38)
// dataMode : ADC Data Sheet (p. 45);

digitalWrite(CS, LOW);
// CS low to start data transfer

//package_read[0] = shiftIn(MISO,SCK,MSBFIRST);
//package_read[1] = shiftIn(MISO,SCK,MSBFIRST);
//package_read[2] = shiftIn(MISO,SCK,MSBFIRST);
//package_read[3] = shiftIn(MISO,SCK,MSBFIRST);
// read shift register via “listening”

package_read[0] = SPI.transfer(0b00000000);
package_read[1] = SPI.transfer(0b00000000);
package_read[2] = SPI.transfer(0b00000000);
package_read[3] = SPI.transfer(0b00000000);
// read shift register via SPI library

digitalWrite(CS, HIGH);
// CS high to stop data transfer

SPI.endTransaction();
//end SPI

Serial.println(package_read[0], DEC);
Serial.println(package_read[1], DEC);
Serial.println(package_read[2], DEC);
Serial.println(package_read[3], DEC);
// print out data to serial;

delay(1);
// delay t_cycle-min for ADS8681, see p. 665 & 11 ADC data sheet
}

void writeRegister(byte thisRegister, byte thisValue1, byte thisValue2) {
// adopted from https://www.arduino.cc/en/Tutorial/BarometricPressureSensor
// see ADC programming p.43 data sheet

byte dataToSend = thisRegister;

SPI.beginTransaction(SPISettings(1000, MSBFIRST, SPI_MODE0));
// initialize SPI & SPI Settings defines speed Maximum in Hz, dataOrder and dataMode
// speed Maximum in Hz: 10 kHz, see ADW Data Sheet 6.6 (p. 11)
// dataOrder : MSBFIRST, see ADW Data Sheet 7.4.1.3 (p. 38)
// dataMode : ADC Data Sheet (p. 45);

digitalWrite(CS, LOW);
// take the chip select low to select the device:

byte package1 [4] = {0b11010000,dataToSend,thisValue1,thisValue2};
// opcode, see p. 43 ADC data sheet

SPI.transfer(package1,4);
//Send register location & value

digitalWrite(CS, HIGH);
// set chip select high to de-select

SPI.endTransaction();
//end SPI
}

I'm missing an SPI.begin() call in your setup() routine.

Please post a wiring diagram where pin numbers are readable (use a higher resolution).

The wiring ist updaten, thank you for the advice.

As I added the SPI.begin() behind "digitalWrite(CS, HIGH);// CS high to stop data transfer" I recieve the following signal on the serial monitor:

12:38:22.248 -> 0
12:38:22.248 -> 0
12:38:22.248 -> 0
12:38:22.248 -> 0
12:38:22.248 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 255
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.283 -> 0
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 0
12:38:22.317 -> 0
12:38:22.317 -> 0
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.317 -> 255
12:38:22.351 -> 0
12:38:22.351 -> 0
12:38:22.351 -> 0
12:38:22.351 -> 0
12:38:22.351 -> 255
12:38:22.351 -> 255
12:38:22.351 -> 255
12:38:22.351 -> 255
12:38:22.351 -> 255
12:38:22.351 -> 255
12:38:22.351 -> 255
12:38:22.351 -> 255

The signal varies and always contains zeros and blocks of 255.
If the battery is not connected to the ADC there are zeros in majority. If I connect it, there are 255 in majoty.

This is not hte kind of signal I was expecting, because there is no noise. In addition the zeros for the case of a connected battery are confusing.

  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  // initialize SPI & SPI Settings defines speed Maximum in Hz, dataOrder and dataMode
  // speed Maximum in Hz: 10 kHz, see ADW Data Sheet 6.6 (p. 11)
  // dataOrder          : MSBFIRST, see ADW Data Sheet 7.4.1.3 (p. 38)
  // dataMode           : ADC Data Sheet (p. 45);

The SPI speed is defined in chapter 6.8, you could go up to 67MHz. As you set it to 1MHz your comment is simply wrong.

You’re reading the voltage of a floating pin. What do you expect as the result? Attach a voltage (p.e. from a sensor) and read again.

I corrected the the comment, thanks.

For the case of a floating pin I get that. But for the case of a connected aa Battery (~1,5 V) and the
measurement range of ±10,24 V this seemed iritating for me. I adjusted the code of the read_adc_to_serial:

void read_adc_to_serial() {
byte dataFrame [4];
// initialise

digitalWrite(CS, LOW);
// CS low to start data transfer

SPI.transfer(dataFrame,4);

// read shift register in variable ‘dataFrame’;

digitalWrite(CS, HIGH);
// CS high to stop data transfer

word package_read = dataFrame[0]<<8 | dataFrame[1];
Serial.println(package_read, DEC);
// convert and print out data to serial;

delay(1);
// delay t_cycle-min for ADS8681, p. 665 & 11 ADC data sheet
}

The ‘SPI.beginTransaction(SPISettings(100, MSBFIRST, SPI_MODE0));’ is now part of the setup and I convert the data output (p. 44 ADC Data Sheet) to a word. This leads to a constant Result of 65535, the maximum value of a word.

For the measurement range of ± 10,24 V and the battery voltage of ~1,5 V I would have expected another result. In addition there is no noise.

In addition I added a definition for the DATA_OUT_CTL_REG, as the all 1 bits a a mode of this register. (p.53 ADC data sheet) So the Register definition section looks like this right now:

writeRegister(0x08,0b00000000, 0b00000000);
// define SPI Mode; address of the SDI_CTL_REG Register (hex) and define SPI Mode, ADC data sheet p. 51, matches ARDUINO SPI Mode0

writeRegister(0x10,0b00000000, 0b00000000);
// define DATA_OUT_CTL_REG;

writeRegister(0x14,0b00000000, 0b000000000);
// define Measurement Range ±10,24 V, see p. 54 ADC data sheet;

Sadly this didn’t lead to a different result than 65535.

  byte dataFrame [4];  
  // initialise

The initialization is important but you don't do it.

I would try to write a different value to a register and then read that value back. If that doesn't work, a hardware problem might be worth considering.