I've connected my ADS1115 to an Arduino Uno as in the diagram (Vdd - 5V, Gnd - Gnd, SDA/SCL - SDA/SCL), all powered from the USB on a PC, with A0-3 unconnected, and am getting readings of around 3000 (i.e. 3000/65535 on 5V supply = 0.23V) from all four analog pins. Then if I connect them to 3.3V output on the arduino they give me only 17625 (i.e. 1.34V) i.e. about 40% of the full range I expected. If I try with a seperate 5V supply, it's still the same problem. Why is this?
P.S. sorry the code format below isn't very good, but basically it reads the four pins by
int16_t V1 = ads.readADC_SingleEnded(PIN)
.
#define THERMISTORPIN1 0
#define THERMISTORPIN2 1
#define SHELLPTPIN 2
#define SPAREPIN 3
#include < Wire.h >
#include < Adafruit_ADS1015.h >
Adafruit_ADS1115 ads(0x48); //16 bit ADC add-on for arduino for better temperature resolution
float Voltage = 0.0;
void setup(void)
{
Serial.begin(9600);
ads.begin();//
}
void loop(void)
{
int16_t V1;
int16_t V2;
int16_t V3;
int16_t V4;
long cumV1;
long cumV2;
long cumV3;
long cumV4;
float avgV1;
float avgV2;
float avgV3;
float avgV4;
//take readings of voltages between resistor and thermsitor
int i=0;
while(i<6) {
V1 = ads.readADC_SingleEnded(THERMISTORPIN1); //5 readings to allow the arduino capacitors to equalize with the pin voltage, to increase accuracy
V2 = ads.readADC_SingleEnded(THERMISTORPIN2);
V3 = ads.readADC_SingleEnded(SHELLPTPIN);
V4 = ads.readADC_SingleEnded(SPAREPIN);
i++;
delay(10);
}
while(6<=i && i<16) {
cumV1+= ads.readADC_SingleEnded(THERMISTORPIN1); //multiple measurements from which to take an average, to increase precision
cumV2+= ads.readADC_SingleEnded(THERMISTORPIN2);
cumV3+= ads.readADC_SingleEnded(SHELLPTPIN);
cumV4+= ads.readADC_SingleEnded(SPAREPIN);
i++;
delay(10);
}
avgV1=cumV1/10;
avgV2=cumV2/10;
avgV3=cumV3/10;
avgV4=cumV4/10;
//print out information to serial monitor on laptop
Serial.print(V1);
Serial.print(" ");
Serial.print(V2);
Serial.print(" ");
Serial.print(V3);
Serial.print(" ");
Serial.println(V4);
Serial.print(" ");
Serial.print(avgV1);
Serial.print(" ");
Serial.print(avgV2);
Serial.print(" ");
Serial.print(avgV3);
Serial.print(" ");
Serial.println(avgV4);
//Serial.println();
delay(1000);
}
-
first off, single ended readings are only 15 bit. secondly, providing 3.3v will limit the measurement to 3.3v; 66% of 5v.dandavis– dandavis2018年02月15日 12:34:54 +00:00Commented Feb 15, 2018 at 12:34
1 Answer 1
Your readings are correct because you have the default gain set. You have incorrectly assumed that you can convert the ADC reading from your 16-bit ADC to Volts by dividing by 2^16 - 1
. Your ADC has gain settings to have more accurate readings for certain voltage intervals. If we look at the example sketch, we see
void setup(void)
{
Serial.begin(9600);
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();
}
Your ADC has a default gain of 2/3, or 0.1875mV per count. You say when you connect 3.3V to the pin, you get a reading of 17625. Thus we have
17625 * 0.1875 / 1000.0 [V]
= 3.3046875 [V]
Which is a correct reading. A reading on a floating pin (nothing attached) is irrelevant. Use the correct factors from above to convert your read ADC value to voltage.
Side note: In line
avgV1=cumV1/10;
You have the float avgV1
on the left and cumV1
(a long
) divided by 10 on the right; this will do a integer division. Make sure to divide by 10.0f
if you want a floating point average.
Side note 2:
These factors do make sense. If you apply positive 6.144V on the 2/3rd gain setting, you will read the maximum positive value of a int16_t
, i.e. 2^15-1 = 32767 (solve above formula for the count). If you apply -6.144V, you get -32768; thus the full 16-bit number space is used. On differnt gain settings it analogous.