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?