two ADS1115 on the same Arduino


I have two project on arduino that work ok separatly on their own arduino board but I want to put them together on the same arduino and same LCD.

Each of my sensor are connected to their own ADS1115.

Is it possible to install two ADS1115 on One Arduino ? I made the first one work on 0x48 and the second on 0x49 so they have a different address.


How do I put that in the code ? I need to give them a different name and then set different gain and scalefactor for each.

Yes. Read the datasheet.

There is section 9.5.1:

I 2 C Address Selection
The ADS111x have one address pin, ADDR, that configures the I 2 C address of the device. This pin can be
connected to GND, VDD, SDA, or SCL, allowing for four different addresses to be selected with one pin, as
shown in Table 4. The state of address pin ADDR is sampled continuously. Use the GND, VDD and SCL
addresses first. If SDA is used as the device address, hold the SDA line low for at least 100 ns after the SCL line
goes low to make sure the device decodes the address correctly during I 2 C communication.

Basically, you get 4 different addresses depending on if you attach pin 1 of the ADS111x to either GND, VCC, SDA or SCL. The address is dependent on the pin you tie pin 1 to is in a table in section 9.5.1 of the datasheet.

PS: I would tie the first IC pin1 HIGH for address 1001001 and the other IC with pin1 tied to GND for address 1001000.

OK...I didn't read the whole of your post...but I will be back soon with a more through software solution.

Hi Johnny

I found how to renamed and address them independently in the code but I'm still looking on how to set a different gain and scalefactor for each of them.

Another user told me that it's possible to simply connect my two sensors on the same ADS1115 since it is a 4 channels. they are different sensor. One is 0-10 volts output and the second is working with differential ma

But I don't have any code example on how to set the gain and scalefactor independently for each channel.

Know you use 0-4volt for the pressure sensor, but that could be changed to suit the other measurement.
Don't know why/how you have connected the 'millivolt' sensor.
Don't know which library you use.
The Adafruit library might do one differential and one (or two) single-ended at the same time.

raw1 = ads.readADC_Differential_0_1(); // first two inputs differentail
raw2 = ads.readADC_SingleEnded(2); // third input single ended

NOT tested!

I understand, it is not easy to help someone with all those ???

For now it's working fine with two ADS1115 so I won't try to do it with only one.

Thanks for the help you gave me since Yesterday.

Now I'm reading and searching on how to:

Installing a few button to:

Installing button #1 to switch on and off my compressor (On Off with the same button)

Button #2 will switch on a relay until I press button #2 again (that one will be to open and close my oxygen solenoid valve)

I need a button #3 that will start a relay/timer. press the button and it begin the timer.
6 minutes off / half a second on / 6 minutes off / half a minute on, until I press button #3 again

When I will be done with those 3 buttons, I need to find a way to make the compressor stop when I reach 3,200 PSI. The oxygen solenoid need to stop 5 second before the compressor

Finally, I want to see all that on my iPhone via wi-fi and or Bluetooth and control the same thing remotely.

Nice project for a first time.

I may have some questions on the way :slight_smile:

Seems an easy task for an ESP8266-12 based Arduino (Wemos/NodeMCU) and a single ADS breakout board.

Indeed. NodeMCU and a single ADS1115 would do great for a project like this.

If you can afford to lose some resolution and scale factors are not too different (it seems you have a 0-10V and a 0-4V signal so that seems OK) you can set it to the lowest gain and connect both sensors to the same ADS1115. Saves one component.

Otherwise indeed create two ADS1115 objects with different name (use the Adafruit library, for example), say ADS1 and ADS2, each with their respective I2C address, and then you can use them independently in your code.

For your buttons: do a search on this forum on how to connect buttons and how to debounce them (to prevent you relay from switching off instantly). The code is simple.

Hi Leo,

I have two ESP8266 and two Feather Huzzah ESP8266. I will keep my actual project with the Arduino UNO and add later the ESP8266 to it for the wi-fi.

So far so good,

I have 3 buttons installed and each one control a LED. I will replace the LEDs for relays when my tests are finish.

I have condition (If PSI > 3200) it will LOW the LED 1
same thing for LED2 with the oxygen %

Now my bug is the following

I want the LED no 3 to blink when I push the button no 3 but I don't want the delay of the blinking to delayed the rest of the program

I want six minutes off and then 1 second on, ( six minutes off, one second on ) like that until I press the button #3 again.

I'm sure that there is a better way to blink a led without "blinking the program at the same time"

Still reading on Google :slight_smile:

Check out "blink without delay"


Yes I’m looking at that subject. Since I already have a code for all the other options, it’s hard to see for me on where I can apply the example to my existing code.

Since I only received my first Arduino 3 days ago and I never program any code before, I have to fight with a lot of unknown here.

This is my code to read One Air pressure sensor (PSI)
to read an Oxygen sensor (O2)
To send the result to a LCD 16,2
One button to calibrate the O2 sensor
3 buttons to control 3 LED

All this is working but now I need to make the LED #3 to flash when I press the button #3

six minute off, one second on, six minutes on one second off until I press the button again

This code is coming from 3 different person and example on the web. I’m sure that one day
I will clean it but for now I’m just happy that it’s working not so bad

//#define _DEBUG

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <RunningAverage.h>

#define RA_SIZE 20
RunningAverage RA(RA_SIZE);

Adafruit_ADS1115 ads_O2 (0x49);
Adafruit_ADS1115 ads_PSI (0x48);

// activer les LED et boutons
int pinButton1 = 8;
int LED1 = 3;
int stateLED1 = LOW;
int stateButton1;

int pinButton2 = 9;
int LED2 = 4;
int stateLED2 = LOW;
int stateButton2;

int pinButton3 = 10;
int LED3 = 5;
int stateLED3 = LOW;
int stateButton3;

// debounce
int previous = LOW;
long time = 0;
long debounce = 300;

// section pour le PSI
int16_t rawADCvalue; // The is where we store the value we receive from the ADS1115
float scalefactor = 0.1250F; // This is the scale factor for the default +/- 4096 Volt Range we will use
float PSI = 0.0; // The result of applying the scale factor to the raw value

LiquidCrystal_I2C lcd(0x27,16,2); // your i2c address might differnt. if not working try scanning i2c first.

const int buttonPin=2; // push button
//const int ledPin = 13; // led
double calibrationv;
float multiplier;

int programState = 0;
int buttonState;
long buttonMillis = 0;
const long intervalButton = 2000; // 2 sec button hold to calibration

Calculate MOD (Maximum Operating Depth)
float max_po1 = 1.40;
float max_po2 = 1.60;
float cal_mod (float percentage, float ppo2 = 1.4) {
return 10 * ( (ppo2/(percentage/100)) - 1 );

int read_sensor(int x=0) {
int16_t millivolts = 0;
if (x == 0) {
millivolts = ads_O2.readADC_Differential_0_1();


void setup(void)


//input output 3 boutons
pinMode(pinButton1, INPUT);
pinMode(LED1, OUTPUT);

pinMode(pinButton2, INPUT);
pinMode(LED2, OUTPUT);

pinMode(pinButton3, INPUT);
pinMode(LED3, OUTPUT);

#ifdef _DEBUG


// 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_O2.begin(); // ads1115 Pour O2 initialize
ads_PSI.begin(); // ads1115 pour PSI initialize

multiplier = 0.0625F;

// multiplier = 0.1250F;


for(int cx=0; cx<= RA_SIZE; cx++) {

calibrationv = EEPROMReadInt(0);
if (calibrationv < 100) calibrationv=calibrate(0);

void EEPROMWriteInt(int p_address, int p_value)
byte lowByte = ((p_value >> 0) & 0xFF);
byte highByte = ((p_value >> 8) & 0xFF);

EEPROM.write(p_address, lowByte);
EEPROM.write(p_address + 1, highByte);

unsigned int EEPROMReadInt(int p_address)
byte lowByte =;
byte highByte = + 1);

return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);

int calibrate(int x){

double result;
for(int cx=0; cx<= RA_SIZE; cx++) {

result = RA.getAverage();
result = abs(result);
EEPROMWriteInt(x, result); // write to eeprom

return result;

void analysing(int x, int cal, String txt) {
double currentmv;
double result;
double mv = 0.0;

currentmv = RA.getAverage();
currentmv = abs(currentmv);

result = (currentmv / cal) * 20.9;
if (result > 99.9) result = 99.9;
mv = currentmv * multiplier;

if (mv < 0.02) {
lcd.print("Sensor error! ");
} else


lcd.print("% ");

lcd.print("Pression = ");


Serial.print("Oxygen “);
Serial.print(”% ");

if (result > 30)
stateLED2 = LOW;

// lcd.setCursor(0,1);
// lcd.print("MOD ");
// lcd.print(cal_mod(result,max_po1),1);
// lcd.print("m ");
// lcd.print(cal_mod(result,max_po2),1);
// lcd.print("m ");


void loop(void)

// section pour le PSI
rawADCvalue = ads_PSI.readADC_SingleEnded(0);
PSI = (rawADCvalue * scalefactor) -35.0;

if (PSI > 500)
stateLED1 = LOW;
stateLED2 = LOW;



// Serial.print("Raw data pressure = “);
// Serial.print(rawADCvalue);
Serial.print(”\tPSI = ");



unsigned long currentMillis = millis();
buttonState = digitalRead(buttonPin);

if (buttonState == LOW && programState == 0) {
buttonMillis = currentMillis;
programState = 1;
} else if (programState == 1 && buttonState == HIGH) {
programState = 0;

if(currentMillis - buttonMillis > intervalButton && programState == 1) {
calibrationv=calibrate(0); // calibration
programState = 1;
analysing(0,calibrationv,"O2 ");


//bouton 1
stateButton1 = digitalRead(pinButton1);
if(stateButton1 == HIGH && previous == LOW && millis() - time > debounce) { //if button is pressed and LED is off
if(stateLED1 == HIGH){
stateLED1 = LOW;
} else {
stateLED1 = HIGH;
time = millis();
digitalWrite(LED1, stateLED1);
previous == stateButton1;

// bouton 2
stateButton2 = digitalRead(pinButton2);
if(stateButton2 == HIGH && previous == LOW && millis() - time > debounce) { //if button is pressed and LED is off
if(stateLED2 == HIGH){
stateLED2 = LOW;
} else {
stateLED2 = HIGH;
time = millis();
digitalWrite(LED2, stateLED2);
previous == stateButton2;

//bouton 3
stateButton3 = digitalRead(pinButton3);
if(stateButton3 == HIGH && previous == LOW && millis() - time > debounce) { //if button is pressed and LED is off
if(stateLED3 == HIGH){
stateLED3 = LOW;
} else {
stateLED3 = HIGH;
time = millis();

digitalWrite(LED3, stateLED3);
previous == stateButton3;



Or use a Timer pin as the LED out and use the hardware to generate the “blinks”, completely removing the software barrier for the toggling. If this pin is still available of course.

I am unsure what I have done wrong here…but I must be missing something, but here is an example (some could maybe fix this) that should have given a “500ms” toggle of an LED (On for 500ms, off 500ms, on etc…)

void setup() {



void loop() {

void LED_ON(){

TCCR1A , TCCR1B = 0;
TCCR1A |= (1<<COM1A0);  // Set the pin to "toggle".

TCCR1B |=(1<<WGM12);    // CTC mode = WGM13:0 = 13(0) 12(1) 11(0) 10(0) = "4".

TCCR1B |=(1<<CS12) | (1<<CS10); // Set the 16Mhz to divide by 1024 = 16Khz "ticks" = 64uS per tick.

// Now say we want to go "On->Off" every 500ms (half seconds...):
// 500ms / 64uS =~ 7812 "ticks".
// So now we set the 16 bit register (has a high byte and low) to equal 7812:

 unsigned int compare_value = 7812;
byte LB = compare_value;
byte HB = compare_value >> 8;

OCR1AH = HB;       // Shift 8 bits right to get the 8 most significant in to the 8bit register half.
OCR1AL = LB;               // Takes the last 8 bits of the value in to the low byte.

I can see that your code is in a scroll box. My code take a lot of space. I'm new to this forum.

How do I enter my code in a scroll box like yours ?


I can see that your code is in a scroll box. My code take a lot of space. I'm new to this forum.

How do I enter my code in a scroll box like yours ?


enclose it with [ c o d e] and [/ c o d e] (no spaces).

I have two ESP8266 and two Feather Huzzah ESP8266. I will keep my actual project with the Arduino UNO and add later the ESP8266 to it for the wi-fi.

Don't add the ESP. Replace it with the ESP.
The MCU of the ESP is far more powerful than an Uno.

Migrating from a 5volt Arduino to a 3.3volt Arduino requires hardware changes.
Different voltage dividers and settings for the ADS1115, and maybe a different display.
You might have to start all over with an ESP based board.


But I don't want to start from zero. Everything is working for now
and I need my compressor to work next Wednesday.

I don't have the wi-fi conexion for now but it was not important
at the beginning.

I will continue the way I am and I will see what need to be improve
and I'm sure I will find some. (code etc...)


except for the more powerful MCU, Is it possible to make the UNO communicate
with the ESP8266 and have full wi-fi conexion and feature ?

I have two model,

The ESP8266 with a USB conexion and a second 8266 smaller and that one
doesn't have any usb port.

Except for the USB, what is the difference ?

Yes, an ESP module can work as WiFi bridge.
The module with USB probably has an onboard 3.3volt supply.
I use my (bare) ESP8266-12 modules stand-alone. never used them for WiFi only.
Somebody else has to answer that question.

I often now just use esp8266 as it has an 80MHz clock and a WiFi chip. They are 3.3V but many components are available in 3.3V logic. The 80MHz is a nice bonus over the 16MHz of an UNO.

The ADS1115 can be used directly with the ESP8266, no changes needed. The display may be a bigger problem, operating at 5V only. Software needs some minor changes (mostly adding yield() calls to keep the tcp/ip part happy).

Most components can operate on both 3.3V and 5V, many only on 3.3V nowadays.