ADS1115 Pin Read Errors

I have an interesting misbehavior occurring in multiple ADS1115 breakout boards sold by Adafruit, and I'm wondering why this could be.

I hope a verbal description of my circuit is sufficient, it is simple enough.

The ADS1115 board uses I2C communication to send its reads to the microcontroller, which for my implementation is an Arduino MEGA. Thus I have connected SCL-SCL and SDA-SDA. Additionally, I am supplying the ADS1115 with 5v on the VDD pin, and have linked GND-GND on the two boards. I have not connected the ADDR pin to anything as the chip defaults to an I2C address of 0x48, accounted for in the library provided by Adafruit. I have attached pulldown resistors to the same GND line shared by the boards to each AIN0-3 pin.

Under these conditions, using the example program (to remove any ambiguity present in my own code)

#include <Adafruit_ADS1X15.h>

 Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads;     /* Use this for the 12-bit version */

void setup(void) 
{
  Serial.begin(115200);
  Serial.println("Hello!");
  
  Serial.println("Getting single-ended readings from AIN0..3");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
  
  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  
  ads.begin();
}

void loop(void) 
{
  int16_t adc0, adc1, adc2, adc3;

  adc0 = ads.readADC_SingleEnded(0);
  adc1 = ads.readADC_SingleEnded(1);
  adc2 = ads.readADC_SingleEnded(2);
  adc3 = ads.readADC_SingleEnded(3);
  Serial.print("AIN0: "); Serial.println(adc0);
  Serial.print("AIN1: "); Serial.println(adc1);
  Serial.print("AIN2: "); Serial.println(adc2);
  Serial.print("AIN3: "); Serial.println(adc3);
  Serial.println(" ");
  
  delay(1000);
}

I see the following output:

03:03:14.087 -> Hello!
03:03:14.087 -> Getting single-ended readings from AIN0..3
03:03:14.087 -> ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)
03:03:14.087 -> AIN0: -3
03:03:14.087 -> AIN1: -3
03:03:14.087 -> AIN2: -3
03:03:14.087 -> AIN3: -3

This is all fine and well (negative values are a little weird, but for reading voltages that will work out to zero and be calibrated out).

However, when I attach 3v3 from the MEGA to AIN0 I see this:

03:04:53.658 -> Hello!
03:04:53.658 -> Getting single-ended readings from AIN0..3
03:04:53.658 -> ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)
03:04:53.658 -> AIN0: 17783
03:04:53.658 -> AIN1: 17783
03:04:53.658 -> AIN2: 17783
03:04:53.658 -> AIN3: 17783

Okay... weird. The code clearly shows I am sampling each pin separately, exactly as is intended. Perhaps with delays (delays lower than 2 had no effect) inserted between each read:

adc0 = ads.readADC_SingleEnded(0);
  delay(2);
  adc1 = ads.readADC_SingleEnded(1);
  delay(2);
  adc2 = ads.readADC_SingleEnded(2);
  delay(2);
  adc3 = ads.readADC_SingleEnded(3);
  delay(2);

I find:

03:06:18.220 -> Hello!
03:06:18.220 -> Getting single-ended readings from AIN0..3
03:06:18.220 -> ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)
03:06:18.265 -> AIN0: 11
03:06:18.265 -> AIN1: 11
03:06:18.265 -> AIN2: 17758
03:06:18.265 -> AIN3: 17758

Jumping up to delay(10):

03:08:23.979 -> Hello!
03:08:23.979 -> Getting single-ended readings from AIN0..3
03:08:24.025 -> ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)
03:08:24.072 -> AIN0: -6
03:08:24.072 -> AIN1: 17756
03:08:24.072 -> AIN2: -4
03:08:24.072 -> AIN3: -2

And now I see that despite reading AIN0, the output is only realized when I try to read another pin afterward. For further proof, if I change the code to:

  adc0 = ads.readADC_SingleEnded(0);
  delay(10);
  adc1 = ads.readADC_SingleEnded(1);
  delay(10);
  adc2 = ads.readADC_SingleEnded(0);
  delay(10);
  adc3 = ads.readADC_SingleEnded(3);
  delay(10);

the output becomes:

03:10:18.070 -> Hello!
03:10:18.070 -> Getting single-ended readings from AIN0..3
03:10:18.070 -> ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)
03:10:18.116 -> AIN0: 0
03:10:18.116 -> AIN1: 17758
03:10:18.116 -> AIN2: 0
03:10:18.116 -> AIN3: 17758

Moving the 3v3 line to AIN3 now yields:

03:11:13.814 -> Hello!
03:11:13.814 -> Getting single-ended readings from AIN0..3
03:11:13.814 -> ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)
03:11:13.859 -> AIN0: 17792
03:11:13.859 -> AIN1: 8
03:11:13.859 -> AIN2: 9
03:11:13.859 -> AIN3: 9

Only sampling one pin yields the correct result every time.


What bothers me is that although this problem is present, it is repeatable and reliably off-by-one. Why? Could the transistors have failed in the process of soldering? These boards worked just fine initially, and, for what it's worth read out correct voltages.

Additionally, the necessary delays for sampling are far too long for my use case. I am fairly certain I will need to replace all of these at this point.

Has anyone encountered this problem before?

Someone has: ADS 1115 (16bit I2C ADC) gives output on wrong channel - #8 by adwsystems

However that line is not present in the current version of the library, nor any mention of delay at all.

I'm afraid I'm not expert enough to track down where this is being done now, if at all...

You only need to pulldown UNUSED pins. What value resistors did you use?

10k. The reason I am pulling down all pins is that I am attempting to diagnose how these boards behave now that I have indications of problems existing.

And indeed, there are times where the values will float up to 400 bits or 0.08V out of nowhere. As soon as I probe the terminals, this float disappears and zeroes itself, and doesn't come back. This seems highly irregular to me.

Why read pulled down pins, they will (should) read 0?

But they don't always, and they even move around randomly despite being pulled down. I am just trying to display as much information about the state of the board per loop as possible right now. This configuration isn't the planned use case, but I am able to see the input on one pin having an effect on the read values of other pins, so I am iteratively testing every configuration I can think of. I happened to find these problems with this one.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.