CuriousScientist0 / ADS1256

An Arduino-compatible library for the ADS1256 24-bit analog-to-digital converter.
MIT License
31 stars 11 forks source link

High-speed differential measurements are sporadically invalid #15

Closed BenjaminPelletier closed 2 months ago

BenjaminPelletier commented 2 months ago

After the fix in #14, I still observe a bad measurement once every few seconds when cycling quickly through differential measurements at high speed.

I connect AIN0 to 3.3V and all other inputs to ground and then use the sketch below. I then observe things like:

 BAD11289:      0       0       5531085 12
 BAD12838:      -1      -1      5531256 27
 BAD14734:      123329  6291969 -4123141        123329
 BAD23362:      5531142 0       -4123141        123329
 BAD23363:      32      -41     -9      30
 BAD28877:      123329  6291969 -4123141        123329
 BAD38441:      123329  6291969 -4123141        123329
 BAD49433:      123329  6291969 -4123141        123329
 BAD65066:      -1      -1      5531326 25
 BAD74140:      0       0       5531157 24
 BAD88048:      123329  6291969 -4127237        123329
 BAD90418:      123329  6291969 -4127237        123329
 BAD90569:      123329  6291969 -4127237        123329
 BAD98508:      0       0       5531387 -6
 BAD101868:     5531085 -1      -4123653        123329
 BAD101869:     3       -27     -26     64
 BAD114441:     -1      -1      5531154 16
 BAD116223:     123329  6291969 -4122117        123329
 BAD122136:     5531233 -1      -4112389        123329

I notice just 5 different failure modes, but will try to characterize them in more detail later.

Differential stress test sketch (threshold constants may need to be tweaked depending on setup):

#include <ADS1256.h>

const uint8_t ADC_DRDY = 2;
const uint8_t ADC_RESET = 0;
const uint8_t ADC_PDWN = 8;
const uint8_t ADC_CS = 10;
const float ADC_VREF = 5.0f;
ADS1256 adc(ADC_DRDY, ADC_RESET, ADC_PDWN, ADC_CS, ADC_VREF);

int32_t value1, value2, value3, value4;
uint32_t n_total = 0;
uint32_t n_bad = 0;
unsigned long t_next_print;
const unsigned long PRINT_PERIOD_MS = 10000;
const long THRESHOLD_ZERO = 500;
const long LOWER_THRESHOLD_33V = 5500000;
const long UPPER_THRESHOLD_33V = 5600000;

void setup()
{
  Serial.begin(115200);

  while (!Serial)
  {
    ; //Wait until the serial becomes available
  }

  Serial.println("Differential stress test: this sketch expects AIN0 to be tied to 3.3V and AIN1+ to all be tied to ground");
  adc.InitializeADC();
  Serial.println("Initialized.");

  adc.setPGA(PGA_1);
  adc.setDRATE(DRATE_30000SPS);

  Serial.println("Configured.");
  delay(1000);
  t_next_print = millis() + PRINT_PERIOD_MS;
}

void loop()
{
  value1 = adc.cycleDifferential();
  value2 = adc.cycleDifferential();
  value3 = adc.cycleDifferential();
  value4 = adc.cycleDifferential();
  n_total++;
  if (value1 < LOWER_THRESHOLD_33V ||
      value1 > UPPER_THRESHOLD_33V ||
      abs(value2) > THRESHOLD_ZERO ||
      abs(value3) > THRESHOLD_ZERO ||
      abs(value4) > THRESHOLD_ZERO) {
    n_bad++;
    Serial.print(" BAD");
    Serial.print(n_total);
    Serial.print(":\t");
    Serial.print(value1);
    Serial.print("\t");
    Serial.print(value2);
    Serial.print("\t");
    Serial.print(value3);
    Serial.print("\t");
    Serial.print(value4);
    Serial.println();
  }
}
BenjaminPelletier commented 2 months ago

This appears to have been a hardware issue with my setup. When I changed wires to tap all the signals for my logic analyzer, the problem went away.

CuriousScientist0 commented 2 months ago

Just to double-check.

Is this relevant for the waitForDRDY() function, or for the new code you introduced? I will also look at the code in a few minutes and check things on my side.