Tool/software:
Hi,
I am trying to measure 4 load cell's data (4 differential outputs; unipolar supply) at 400 SPS with gain 64 for a force platform. I have designed a breakout board for ADS1261 to connect all the load cells to it, amplify the raw data, and do the A/D conversion.
In the Schematic (the attached file), you can see that I have hard-wired the START, RESET, PWDN pins to DVDD and the CS pin to GND to keep the ADC always powered on, active and selected for serial communication. Now I am trying to establish the SPI communication between ADS1261 and Teensy 4.1 MCU. Teensy has a default SPI bus comprising pin 11(MOSI), 12(MISO), 13(SCLK) and 10(CS). Teensy's pin 11 (MOSI) is connected to the DIN pin of ADS, pin 12 (MISO) to the DOUT of ADS, pin 13 (SCLK) to the SCLK of ADS, pin 10 (CS) to the GND and pin 2 (GPIO) to the DRDY of ADS. I have defined all the necessary register assignment and Commands for conversion (you could check the attached code text; it is for one channel) still the ADS is not responding and MCU is reading some garbage values. Note: only one ADS is connected on the SPI bus, the bus is not shared among multiple slave devices. No internal reference is set, AVDD is set as reference. ADS chip id is getting identified as 0x81.
I am unable to understand where I have done wrong. It would be great if you could help me to resolve the issue.
With regards,
Charles
Code:
#include <SPI.h>
// Teensy 4.1 SPI0 default pins
#define DRDY_PIN 2
SPISettings spiSettings(1000000, MSBFIRST, SPI_MODE1);
#define INTER_COMMAND_DELAY_US 50
// Enable this to debug raw data and status
#define DEBUG_RAW_BYTES true
void safeDelay() {
delayMicroseconds(INTER_COMMAND_DELAY_US);
}
void writeRegister(uint8_t reg, uint8_t val) {
safeDelay();
SPI.beginTransaction(spiSettings);
SPI.transfer(0x40 | reg); // WREG command
SPI.transfer(0x00); // Write 1 register
SPI.transfer(val);
SPI.endTransaction();
}
uint8_t readRegister(uint8_t reg) {
safeDelay();
SPI.beginTransaction(spiSettings);
SPI.transfer(0x20 | reg); // RREG command
SPI.transfer(0x00); // Read 1 register
uint8_t val = SPI.transfer(0xFF);
SPI.endTransaction();
return val;
}
bool waitForDRDY(unsigned long timeout_ms = 1000) {
unsigned long start = millis();
while (digitalRead(DRDY_PIN) == HIGH) {
if ((millis() - start) > timeout_ms) return false;
delayMicroseconds(10);
}
return true;
}
int32_t readADCData(bool &statusOK) {
uint8_t status;
uint8_t data[4];
safeDelay();
SPI.beginTransaction(spiSettings);
SPI.transfer(0x12); // RDATA command
status = SPI.transfer(0xFF); // Read status byte
for (int i = 0; i < 4; ++i) {
data[i] = SPI.transfer(0xFF);
}
SPI.endTransaction();
// Debug print
if (DEBUG_RAW_BYTES) {
Serial.print("STATUS: 0x"); Serial.print(status, HEX);
Serial.print(" | Bytes: ");
for (int i = 0; i < 4; i++) {
Serial.print("0x"); Serial.print(data[i], HEX); Serial.print(" ");
}
Serial.println();
}
statusOK = !(status & 0x80); // Bit 7 = 1 indicates ADC error
// Combine bytes
int32_t val = ((int32_t)data[0] << 24) |
((int32_t)data[1] << 16) |
((int32_t)data[2] << 8) |
((int32_t)data[3]);
return val;
}
void setupADS1261() {
delay(100); // Wait for power-up
SPI.beginTransaction(spiSettings);
SPI.transfer(0x06); // RESET command
SPI.endTransaction();
delay(10);
writeRegister(0x01, 0x02); // POWER: Internal reference off
delay(10);
writeRegister(0x02, 0x28); // MODE0: SINC3, 400 SPS
writeRegister(0x03, 0x00); // MODE1: Single-shot mode
writeRegister(0x04, 0x70); // MODE2: 4-byte + SPITIM ON + STATUS ON
delay(10);
uint8_t mode2 = readRegister(0x04);
Serial.print("MODE2 register readback = 0x");
Serial.println(mode2, HEX);
writeRegister(0x10, 0x06); // GAIN1: Gain = 64
writeRegister(0x11, 0x23); // INPMUX: AIN2 - AIN3
delay(50); // Let it settle
}
void triggerSingleConversion() {
safeDelay();
SPI.beginTransaction(spiSettings);
SPI.transfer(0x08); // START command
SPI.endTransaction();
}
void setup() {
Serial.begin(115200);
delay(100);
pinMode(DRDY_PIN, INPUT);
SPI.begin();
Serial.println("Initializing ADS1261...");
// Read ID
uint8_t id = readRegister(0x00);
Serial.print("Chip ID = 0x"); Serial.println(id, HEX);
if (id != 0x80 && id != 0x81) {
Serial.println("Invalid ID. Check SPI wiring.");
while (1);
}
setupADS1261();
Serial.println("ADS1261 initialized.");
}
void loop() {
triggerSingleConversion();
if (!waitForDRDY(1000)) {
Serial.println("DRDY timeout");
delay(500);
return;
}
bool statusOK = false;
int32_t adc_raw = readADCData(statusOK);
if (statusOK) {
Serial.print("ADC Raw = ");
Serial.println(adc_raw);
} else {
Serial.println("ADC Status Error Detected!");
}
delay(500);
}