I'm using a ADS1113 delta-sigma 16-bit ADC to sample a bipolar signal from a force sensor at 50Hz, and I have found a weird phenomenon.
When the signal negative or positive, there is no issue, but when the signal crosses over zero, the signal seem to be held in place for a bit before the sampling continues as seen below (and even weirder it's not always at 0, just near 0):
I have checked the analog signal on an oscilloscope and this does not happen, it only happens when I digitize the signal using ADS1113, and plot the results. I could adjust the bias of the signal such that the signal is positive or negative, but because of the dynamic range of the signal, this cannot be guaranteed always. Has anyone faced this issue? It seems like a sample & hold issue of some sort, but I cannot find any solution. Any comments or suggestions are greatly appreciated, thanks!
Settings:
MCU: ESP32WROOM - uses interrupt routine to request single-shot data from ADS1113
ADS1113 settings: single-shot mode (as defined by aAdafruit_ADS1X151
library)
AFE + ADS1113 circuit schematic:
int16_t Adafruit_ADS1X15::readADC_SingleEnded(uint8_t channel) {
if (channel > 3) {
return 0;
}
// Start with default values
uint16_t config =
ADS1X15_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
ADS1X15_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
// ADS1X15_REG_CONFIG_CLAT_LATCH |
ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
ADS1X15_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
// ADS1X15_REG_CONFIG_CMODE_WINDOW |
ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
// ADS1X15_REG_CONFIG_MODE_CONTIN;
// Set PGA/voltage range
config |= m_gain;
// Set data rate
config |= m_dataRate;
// Set single-ended input channel
switch (channel) {
case (0):
config |= ADS1X15_REG_CONFIG_MUX_SINGLE_0;
break;
case (1):
config |= ADS1X15_REG_CONFIG_MUX_SINGLE_1;
break;
case (2):
config |= ADS1X15_REG_CONFIG_MUX_SINGLE_2;
break;
case (3):
config |= ADS1X15_REG_CONFIG_MUX_SINGLE_3;
break;
}
// Set 'start single-conversion' bit
config |= ADS1X15_REG_CONFIG_OS_SINGLE;
// Write config register to the ADC
writeRegister(ADS1X15_REG_POINTER_CONFIG, config);
// Wait for the conversion to complete
while (!conversionComplete())
;
// Read the conversion results
return getLastConversionResults();
}