Using the ADS1115: A precision 16 bit ADC with Amazing Accuracy. Instantly improve your analog measurements with high resolution
capability.
ADS1115: A high precision 16bit ADC with differential or single ended inputs.
How to simply measure voltage to Amazing Accuracy.
Is accurate to 0.01%(typ) - including all error sources.
Has a real resolution of 15bits (the MSB bit is the sign bit).
Very low active current ~150uA (typ).
Four single ended, or two differential inputs.
The ADS1115 is a precise 16bit ADC with four multiplexed inputs - You
can use each input on its own, or in pairs for differential measurements. It
has an internal calibrated reference for high accuracy.
This ADS1115 tutorial shows you how to setup the libraries to drive
the chip, and take readings using different Programmable Gain Amplifier (PGA) gain settings. It also
covers how the device is able to measure small negative voltage even though it
only operates using a single supply. This makes it useful as a current sink or source measuring device.
Important things to know about the chip:
Has 16 bit resolution (It is actually ±15 bit - See here).
Can detect from 0.187mV to 7.8uV depending on the PGA Setting.
Can sample from 8 to 860 SPS.
Has an internal voltage reference.
Has an internal PGA (Programmable Gain Amplifier).
Does not have an external reference - you use the internal reference via the PGA gain control to select the desired voltage range it is basically a stand-alone accurate device!
Note: The unusual thing about
this chip is that it uses fixed voltage ranges set by the PGA gain.
Unlike other ADCs you choose the gain to select an allowed voltage
range. See section "PGA Gain Settting"
This device has a stated typical accuracy of 0.01% (but it has
a maximum accuracy of 0.15%). This accuracy includes all sources of
error (voltage reference, Gain error, offset and noise).
[1] FSR ±2.048V
[2] Includes all errors from voltage reference and PGA.
ADS1115 Block diagram
Image from data sheet [http://www.ti.com/lit/ds/symlink/ads1115.pdf]
ADS1115 Pinout
ADS1115 Accuracy
The interesting diagram that shows the real capability of the device is Figure 19 from the datasheet:
Total Error vs Input signal
Notice how the accuracy of the system includes all error sources:
gain error,
differential input error,
offset error,
and noise.
ADS1115 I2C ADDR
You can setup the ADS1115 with one of four addresses, so you can place 4 ADS1115 chips on a single I2C bus:
0x48, 0x49, 0x4a, 0x4b.
The addressing control is unusual in that you only need to use one input pin as the address control pin - this is the pin labelled 'ADDR'.
Normally you would need two inputs to switch between 4 addresses but the
ADS1115 16-bit ADC uses a clever scheme. The single address input is sampled continuously
and if you connect it to GND, VDD, SDA or SCL you can set the address
from 0x48, 0x49, 0x4a, 0x4b respectively.
ADS1115 Power Saving
Continuous mode
The ADS1115 has an impressive quiescent current of 150uA when in
continuous conversion mode. In this mode you can let the ADS1115 sample
from between 8Hz and 860Hz.
Warning: In continuous mode. A change in the configuration register (the
main setup control element) will not affect the current reading, only
the next one.
Single-shot mode
The default mode of the ADS1115 is single shot mode where the
device wakes up, takes a measurement, and then goes back to sleep. While
asleep, the chip only draws a typical current of 0.5uA. Since the device
enters this mode at power up there will not be a surge of startup
current.
Note: The command interface remains active in power down mode, so you can still get the data out of the chip!
This chip and mode is ideal for battery operated equipment where
precision is needed. It is also useful for space constrained designs
since the ultra small package (X2QFN) is only 2 mm x 1.5 mm x 0.4 mm
Performance and noise trade-off
Low Speed averaging
If you run the ADS1115 at low speed the internal sampling rate is not
lowered, since this is how delta sigma converter operates, by
oversampling. The internal oscillator is set at 1MHz, and reduced to 250kHz for the ADC clock.
While in active mode, samples are gathered continuously. These
samples are averaged internally which improves noise performance. It
also saves you processing time i.e. you won't have to perform the
averaging in the microcontroller.
So if you want the best noise
performance, run the sample rate at 8Hz (the lowest sample rate).
TIP: For the best noise performance run the chip at 8SPS.
The only disadvantage of the low sampling rate is that the device
must be on continuously so power is always being used. If you are more
concerned with saving power, and are not too worried about noise
performance, you can implement burst mode operation.
High speed Speed Burst mode
Under microcontroller control, you can implement burst mode to save
power. The data sheet suggests that you will use 1/100th the power used
in continuous mode. So you could get a 1.5uA average current use.
This is a similar idea to a joule thief circuit where a burst of
energy stored in an inductor pulses an LED for a short time. You get
enough usable light but at reduced average power.
To simulate the 8SPS rate as above you would make the ADS1115 take a
single shot reading every 125ms (1/125e-3 = 8) 8 Hz (you would set this
repeat rate from a timer within the microcontroller code).
You would also set the
SPS rate of the ADS1115 to 860Hz to get a high speed capture. Of course you can change
the time between captures to every second or every hour for further
power savings.
The single shot reading should only take 1.2ms leaving the rest of
the period with the ADS1115 in low current mode. This is the ads1115
conversion delay and is stated in the datasheet.
Note: The ADS1115 takes approx 25us to power up - pretty good!
Using the ALERT/READY pin
There are two uses for the ALERT/Ready pin. The first is "comparator
threshold" alert (the default mode). The second is "ADC reading ready" alert. You
have to set up some registers to operate the ADC ready ALERT mode.
Threshold detection
The ADS1115 has an internal comparator which outputs a signal to the
ALERT pin (the default mode). You can use this
feature to automatically detect out of range conditions (set by
threshold registers). The COMP_QUE register allows you to specify how
many conversions exceed upper or lower bounds before the alert is
asserted.
The ALERT pin requires a pull-up resistor since it is an open-drain pin.
The comparator has two thresholds (high and low). When the input
signal is between thresholds the ALERT signal is set high (window
comparator mode). You can invert the Alert output signal using COMP_POL.
ADC Ready Interrupt Signal
The alternative use of this pin is as a ADC ready signal. If you set
up the pin as an ADC ready signal you can then feed this into an
external interrupt pin on a microcontroller so that it can fetch the ADC
reading.
The other way to detect if the ADC has completed is to read a
register value (Config register bit 15) but of course this takes a lot more time because an
I2C transaction must take place.
Note: The conversion ready signal is an 8us wide (high) pulse and indicates the conversion is available on the falling edge.
To set the chip into conversion ready mode set the following registers:
Set the MSB of the high threshold register to 1
[e.g. Hi_thresh = 0x8000].
Set the MSB of the low threshold register to 0
[e.g. Lo_thresh = 0x0000].
Set the Comparator queue control bits to 00 (anything but 0x11)
[e.g. COMP_QUE[1:0]=0].
Config Reg & = Config Reg 0x0003; // Clear b0, b1.
Note: You will still need a pull-up resistor on the Alert/Ready pin.
Input Multiplexor
You use the input multiplexor to select between 4 single ended inputs
0 ~ FSR or two differential inputs ±FSR. There is however another MUX
mode that uses AIN3 as the reference for AIN0, AIN1 and AIN2 as
differential inputs to that reference.
You can see the MUX on the left of the diagram below:
Its not that clear from the diagram but the MUX has 3 modes:
Input signal referenced to ground (All 4 inputs are selectable)
AIN0(+) ~ GND(-),
AIN1(+) ~ GND(-),
AIN2(+) ~ GND(-).
AIN3(+) ~ GND(-).
Two Differential inputs:
AIN0(+) ~ AIN1(-),
AIN2(+) ~ AIN3(-).
Three referenced inputs:
AIN0(+) ~ AIN3(-),
AIN1(+) ~ AIN3(-),
AIN2(+) ~ AIN3(-).
See the datasheet "Config Register" to control this operation.
PGA Gain setting
The gain setting register in the ADS1115 does have standard
values e.g. x2 x4 etc. (except for the highest at 2/3), it is easier to think of the resolution and
range capability of the Full Scale Reading. This is how the datasheet
is arranged - because the device uses an internally fixed voltage
reference.
You just have to choose the best range that gets near to your measured signal.
You can not change the FSR value by adding an external reference
voltage as you do with other ADCs. The ranges and resolutions are shown
in the table below.
Full Scale Range FSR
Resoultion (1 LSB)
±6411mV
187.5uV
±4096mV
125uV
±2048mV
62.5uV
±1024mV
31.25uV
±512mV
15.625uV
±256mV
7.8125uV
Full Scale Resolution
Although the ADS1115 has 16 bit resolution capability, it uses two's
complement to
represent a value (the MSB represents the sign bit). This is really a
15bit resolution ADC capable of negative and positive voltage
measurement (within the GND to VDD supply limitation)! But note that the input can go to 300mV below ground.
This leaves you with 15 bit resolution for an input signal from GND
to positive full-scale-voltage and 15 bit resolution for GND to negative
full-scale-voltage. However the ADS1115 can only measure -300mV below
ground.
The real use of the ±15bit resolution is when you use differential
mode and a level shifting opamp to move the input signal into the GDN to
VDD range. There is one exception to this:
To get a ±FSR you can use the 256mV range (See below), or use an input opamp to level shift and scale the input, or use a differential input (See also differential operation below). Alternatively use one input as a reference for the other two inputs (See Input Multiplexor section).
Note: 15 bit resolution still a very accurate resolution to
have as you can see from the table above.
As described above, the measurable input voltage goes down to minus 300mV.
At the lowest PGA gain value you can use the full scale
resolution of the device (±256mV) and this also fits into the -300mV
measurement capability of the ADS1115.
Therefore you can make a current measuring device that is capable of
measuring sink and source currents, even with only this single supply chip. To do this you would use an
appropriate measuring resistor and make a differential measurement
across it. Negative voltage capability testing results are here.
Choosing a higher PGA gain still allows you to measure the negative value, just at a lower resolution.
A Note on the PGA settings
The programmable gain settings register (PGA) allows 8 values but the
last 3 values all provide the same gain, resulting in a FSR of 256mV
for PGA values of 5, 6 and 7.
So there are 6 usable settings that allow FSRs of ±6.144V, ±4.096V,
±2.048V, ±1.024V, ±0.512V, ±0.256V.
Input Voltage Range
The absolute maximum voltage inputs are:
-0.3V ~ 7V
The measurement voltage range is:
GND - 0.3V ~ VDD + 0.3V.
Remember that the measurement ranges are fixed so the maximum
measurable input voltage is ±6.144V.However the input can never go below
GND-0.3V so the range is -300mV ~ 6.144V.
This sounds a bit strange - Why design a chip that has half its range missing at high gain? There are two reasons:
You can allow an input to -300mV, and the full PGA gain range is usable below 256mV (see next section).
The chip was probably designed for a symmetrical voltage supply and is now adapted to a single supply (2V ~ 5V) operation.
Testing negative voltage input
I was not sure that the negative voltage could be measured, especially
using the single supply of the ADS1115. The datasheet does
indicate that it is capable of measuring from -256mV and not blowing up
with a voltage above -300mV.
It turns out that this is true, since I tested an input by carefully
attaching a -5V source to a 10k pot and adjusting the wiper (ensuring
that it did not go below -300mV) for values -100mV, -260mV
For the -260mV measurement you can see that the full scale is reached
for the FSR of 256mV which is what you would expect - this is for PGA
gain setting of 256mV (since 260mV is higher than the range capability
of 256mV).
You can also see
that the -100mV reading is measured correctly for all PGA gains.
So this confirms that the ADS1115 can read negative voltages down to
its minimum measurement capability of -256mV without a separate power
supply.
Note: The ADS1115 arduino code for this output is available further down the page.
ADS1115 ADC FSR
The full scale value for a positive output will be:
0x7FFF
The full scale value for a negative output will be:
0x8000
The plus one ADC value is 0x0001 and the minus one value is 0xFFFF (minus 2 is 0xFFFE).
Warning: For single ended measurements you can still get a negative ADC value because of device offset, when measuring 0V.
What's the deal with differential?
A differential measurement uses two inputs one for the low side and
one for the high side voltage so you can measure a voltage difference at
any point in a circuit. Normal single ended measurements (Ardiuno ADC)
can only measure a voltage referenced to ground.
You can have a single set of differential inputs or two (as below):
Two Differential inputs:
AIN0(+) ~ AIN1(-),
AIN2(+) ~ AIN3(-).
You typically measure across a small,
accurate, resistance to determine current flow. The ADS1115 can measure
positive and negative voltages.
Note: Use differential measurement to eliminate noise.
The differential measurement is an instantaneous measurement achieved
by using a difference amplifier (opamp) within the device. The great
advantage of this measurement is that it eliminates common mode noise error since
the noise signal across the measured element, will be the same. So noise
is subtracted out.
The other reason for using a differential measurement is that you may want to measure a voltage not
referenced to ground e.g. a current sense resistor is not connected on
one side to ground, but is somewhere else in your circuit. This is a
so-called high side measurement i.e. where both measurement voltages are
nowhere near zero.
Note: Only using the differential mode can you obtain the full scale
of the ADC. i.e. in single shot mode you can only achieve output codes 0
~ 32767 but with differential you can achieve output codes ±32767.
Software
Arduino IDE : Version 1.8.9+
I2Cdev library
The I2Cdevlib has ADS1115 library code as well as code for many other devices.
This library has a lot of features, supported chips, and can operate
on multiple processors but it is a little more involved to install and
you can not use the automatic Arduino zip file installer.
ADS1115 Arduino Library
Unzip the file (ic2devlib-master) then navigate to the Arduino
directory within ic2devlib-master. Copy the directories ADS1115 and
I2Cdev to the Arduino libraries directory, usually found here (on
windows):
C:\Users\<User name>\Documents\Arduino\libraries
Library code Warning
Constants for the 256mV range have been set to the rounded values.
Navigate to ADC1115.h and change the following lines:
See section "9.3.3 Full-Scale Range (FSR) and LSB Size" of the datasheet.
Hardware
Components
Arduino Uno R3.
ADS1115 breakout board.
Connection wires.
100nF capacitor.
10k pot.
Connections
For testing use an Arduino Uno and connect it as follows:
Arduino
ADS1115
5V
VDD
GND
GND
A5
SCL
A4
SDA
GND
ADDR
2
ALRT
Wiper of 10k pot.
A1
Note: Connect the ends of the 10k potentiometer to 5V and GND. Connect 100nF capacitor across 5V and GND.
ADS1115 Breadboard layout
Arduino Example using the ADS1115
Example Sketch 1
You can test the ADS1115 by polling it using the following program:
To see register status information, edit ads1115.h to allow debug output by un-commenting the following line:
//#define ADS1115_SERIAL_DEBUG
Type the letter s in the serial monitor to see register status.
Note: I changed the pollAlertReadyPin() code so that if it fails then
the ads1115 is re-initialised (see code below). When turning the PC on and off the
registers were reset, and the Queue registers set to 11: disabling the
alert ready pin. Now, if this error occurs the chip is restarted correctly.
// I2C device class (I2Cdev) demonstration Arduino sketch for ADS1115 class
// Example of reading two differential inputs of the ADS1115 and showing the value in mV
// 2016-03-22 by Eadf (https://github.com/eadf)
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2016-03-22 - initial release
//
// 2019-4-30
// JFM modified for re-initialising and output of multiple PGA resolutions for
// comparison of readings. Also when debug is active serial receiving 's'
// outputs register values.
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
Wiring the ADS1115 Module to an Arduino UNO
ADS1115 --> UNO
VDD 5V
GND GND
SCL A5 (or SCL)
SDA A4 (or SDA)
ALRT 2
*/
#include "ADS1115.h"
ADS1115adc0(ADS1115_DEFAULT_ADDRESS);
// Wire ADS1115 ALERT/RDY pin to Arduino pin 2
constintalertReadyPin=2;
voidinit_ads1115(){
Serial.println("Testing device connections...");
Serial.println(adc0.testConnection()?"ADS1115 connection successful":"ADS1115 connection failed");
adc0.initialize();// initialize ADS1115 16 bit A/D chip
// We're going to do single shot sampling
adc0.setMode(ADS1115_MODE_SINGLESHOT);
// Slow things down so that we can see that the "poll for conversion" code works
adc0.setRate(ADS1115_RATE_8);
// Set the gain (PGA) +/- 6.144v
// Note that any analog input must be higher than â¬0.3V and less than VDD +0.3
adc0.setGain(ADS1115_PGA_6P144);
// ALERT/RDY pin will indicate when conversion is ready
pinMode(alertReadyPin,INPUT_PULLUP);
adc0.setConversionReadyPinMode();
// To get output from this method, you'll need to turn on the
//#define ADS1115_SERIAL_DEBUG // in the ADS1115.h file
#ifdef ADS1115_SERIAL_DEBUG
adc0.showConfigRegister();
Serial.print("HighThreshold=");Serial.println(adc0.getHighThreshold(),BIN);
Serial.print("LowThreshold=");Serial.println(adc0.getLowThreshold(),BIN);
#endif
}
voidsetup(){
//I2Cdev::begin(); // join I2C bus
Wire.begin();
Serial.begin(115200);// initialize serial communication
init_ads1115();
}
/** Poll the assigned pin for conversion status
*/
voidpollAlertReadyPin(){
for(uint32_ti=0;i<100000;i++)
if(!digitalRead(alertReadyPin))return;
Serial.println("Failed to wait for AlertReadyPin, it's stuck high!");
// If gets stuck do -something = init.
init_ads1115();
}
voidloop(){
adc0.setMultiplexer(ADS1115_MUX_P1_NG);
adc0.setGain(ADS1115_PGA_6P144);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: ");Serial.print(adc0.getMilliVolts(false),3);Serial.print("mV\t");
Serial.println(" PGA: 6144 mv acc: 187.5uV");
adc0.setGain(ADS1115_PGA_4P096);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: ");Serial.print(adc0.getMilliVolts(false),3);Serial.print("mV\t");
Serial.println(" PGA: 4096 mv acc: 125uV");
adc0.setGain(ADS1115_PGA_2P048);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: ");Serial.print(adc0.getMilliVolts(false),3);Serial.print("mV\t");
Serial.println(" PGA: 2048 mv acc: 62.5uV");
adc0.setGain(ADS1115_PGA_1P024);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: ");Serial.print(adc0.getMilliVolts(false),3);Serial.print("mV\t");
Serial.println(" PGA: 1024 mv acc: 31.25uV");
adc0.setGain(ADS1115_PGA_0P512);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: ");Serial.print(adc0.getMilliVolts(false),3);Serial.print("mV\t");
Serial.println(" PGA: 512 mv acc: 15.625uV");
adc0.setGain(ADS1115_PGA_0P256);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: ");Serial.print(adc0.getMilliVolts(false),3);Serial.print("mV\t");
Serial.println(" PGA: 256 mv acc: 7.8125uV");
Serial.print("Alert/RDY ");Serial.println(digitalRead(alertReadyPin));
Serial.println();
if(Serial.available()){
charchr=Serial.read();
//Serial.print("Serial received"); Serial.print(chr);Serial.println("<<");
switch(chr){
case's':adc0.showConfigRegister();break;
//default: Serial.println(">>");Serial.print(chr);Serial.println("<<");
}
}
delay(500);
}
How to get accurate DHT22 digital humidity sensor readings with an Arduino. Did you know it also measures temperature as Well? Find out why, in this page...
A PIR sensor lets your Arduino sense movement without contact. This tutorial covers PIR sensor basics, connecting one to an Arduino board and coding a motion detector.
Arduino Hall Effect Sensor: Add magnetic sensing superpowers to your Arduino projects with an easy-to-use hall effect sensor. With full code and layout...
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.