ADS1115 I2C external ADC with ESP32 in Arduino IDE

This guide shows you how to interface external adc AD1115 with ESP32 to measure analog voltage with high accuracy. ADS1115 provides data over I2C communication. It  consists of four analog channels. At the end of this guide, I will provide an example of analog voltage measurement with ADS1115 and ESP32.ADS1115 external ADC interfacing with ESP32

Why we need to use external ADC with ESP32?

Although, ESP32 has two built-in ADC modules namely; ADC0 and ADC1 and each channel is of 12-bits. But, the main issue of ESP32 ADC’s is that it has a non-linear characteristics and it exhibits non-linear behavior as explained in already posted ESP32 ADC tutorial. It can not differentiate between 1mv and 2mv signals which means it offers very low resolution. In order to resolve these issues,  we can use external high resolution programmable ADC IC.

Reasons to use External analog to digital converter are mentioned below:

Low resolution issue  : Other than the issue of  non-linear behavior and low resolution of built-in analog to digital converter,  ESP32 has all excellent features required for internet of things project. Therefore, we can used an external ADC with this development board to resolve problem of measuring analog signal with high accuracy.

Interfacing issues : For example, you want to interface LM35 temperature sensor with ESP32, you can not connect it directly due to low resolution and inaccurate behavior of built analog to digital converter of ESP32.  LM35 temperature sensor gives output of 1mv per one degree centigrade of temperature. Built-in adc can not measure 1mV accurately and so is ESP32.

Introduction to ADS1115 External ADC

  • ADS1115 is a 16-bit analog to digital converter that consists of four analog channels.
  • It can be used in to measure both positive and negative voltages.
  • It works in  Single Ended, Differential and comparator mode. In single ended differential mode, it is used to measure positive voltages only and in comparator mode, it can measure both positive and negative voltages ( useful when you want to measure voltage of battery).
  • It works on I2C communication. We can interface it with any microcontroller having I2C communication support.
  • It has a programmable comparator.
  • It can be used in four modes.

ADS1115 is a 16 bit I2C ADC having four analog channels. It provides output in signed integer format.  From total 16 bits, one bit is assigned for positive and negative number. Therefore, only 15 bits are used to measure the voltage and ADC resolution is calculated according to according to 15 bits.

  • We get 2^15 = 32,768 possible output values for every analog input.
  • Possible output digital values will be between 0-32767.
  • These 15 bits are used to get the magnitude of voltage through I2C communication.
  • The weight of every bit can be defined with  Programmable Gain Amplifier (PGA) by setting a reference voltage value.
  • In default mode, the reference voltage value is +/-6.144 volts.
  •  0 volts represents 0 digital value and 6.144 volts represents 32767 as a digital value.
  • But we can not measure 6.144 volts directly with this chip. The maximum voltage which we can measure depends on the supply voltage to chip which is 5.5 volts in case of ADS1115.

Resolution of ADS1115

  • The resolution of this external ADC is calculated by dividing 6.144  with 32767 which is equal to 0.1875mV.
  • So the minimum analog voltage we can measure with ADS1115 external I2C ADC is 0.1875mV which is almost 50% greater accuracy than built-in analog to digital converter module of ESP32.

Pinout of ADS1115

ADS1115 external ADC pinout

It consists of four pins and table below shows functionality of each pin.

Pin name Functionality
Vdd ( Power supply pin)   Connect power supply between 2.2 – 5.5 volts
GND ( Common reference pin )   Connect with ground pin of power supply
SCL  I2C SCL ( serial clock pin)
SDA I2C SDA ( Serial data pin)
ADDR I2C slave select pin or address
ALRT Alert/Ready
A0 Analog channel 0
A1 Analog channel 1
A2 Analog channel 2
A3 Analog channel 3

Addressing modes can be set in four different mode by connecting address pin with SCL, SDA, GND or VDD.  Table below provides description on connection of address pin with SCL, SDA, GND or VDD pin according to value of address.

ADDR pin value  Connection with Pin
0x48 Connect address pin to GND
0x49 Connect address pin to VDD
0x4A Connect address pin to SDA
0x4B Connect address pin to SCL

ADDR pin is used for selection of four different devices with one pin. So, we can connect it with any of four pins listed in table. You can explore further about addressing modes by reading datasheet.

Datasheet ADS1115

ADS1115 library in Arduino IDE

we will be using Arduino IDE to program ESP32. If you are using Arduino IDE first time with ESP32, you can check this tutorials:

As mentioned in previous sections, ADS1115 communicates data to ESP32 over I2C communication. We need to use I2C pins of  ESP32 to read data. To handle communication and receive measured voltage over I2C, we can use ADS1115 library of Adafruit. Follow these steps to install library.

  • To install library, open your Arduino IDE and follow this menu Sketch Include Library > Manage Libraries and click on manage libraries.
  • After that type “Adafruit in search bar” and select ADS1X15 to install it.
  • After installing library click on close button and restart Arduino IDE. ADS1115 Arduino library

Interfacing ADS1115 external ADC with ESP32

Now make the connections according to this layout given below:

ADS1115 external ADC with ESP32

ESP32  ADS1115 external ADC
GPIO21 ( SDA Pin ) SDA
GPIO22 ( SCL Pin )  SCL
Analog voltage signal A0

ESP32 GPIO21 and GPIO22 is used for I2C communication. Connect Analog signal to which voltage you want to measure with A0 pins of ADS1115.

Code to measure analog voltage

Now open your Arduino IDE and paste this code to code editor window. After compiling code, upload it to ESP32 by clicking on upload button.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);
float Voltage = 0.0;

void setup(void) 

void loop(void) 
int16_t adc0;

adc0 = ads.readADC_SingleEnded(0);
Voltage = (adc0 * 0.1875)/1000;

Serial.print("AIN0: "); 
Serial.print("\tVoltage: ");
Serial.println(Voltage, 7); 

  • After uploading code, open serial monitor, you will see the output of voltage and adc0 on the serial monitor.
  • For demonstration, I have connected vdd pin of ESP32 with analog channel zero.
  • As you can see, we are getting close to 3.3 volts on serial monitor which is operating voltage of ESP32 board, you can verify this output by measuring voltage on VDD pin of ESP32 with the help of voltmeter. ADS1115 output voltage on serial monitor

Code working

First two lines used to add the library of ADS1115 and I2C communication.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

First line defines the sesnor type and address mode, we are using ADS1115. But this library can be used with other versions like ADS10115. Second line declare a variable of float type to store voltage value.

Adafruit_ADS1115 ads(0x48);
float Voltage = 0.0;

Inside the setup() function, Serial.begin() function defines the baud rate of 9600 and ads.begin() function starts to read adc value.


Inside the loop() function , first we initialize the 16 bit long integer variable adc0 which is used to store output of analog channel zero.

int16_t adc0;

ds.readADC_SingleEnded(0) function read analog channel zero adc value and store this value in adc0 integer variable. This statement converts (adc0 * 0.1875)/1000 adc value into voltage where 0.1875 is a resolution of ADS1115.

adc0 = ads.readADC_SingleEnded(0);
Voltage = (adc0 * 0.1875)/1000;

Serial.print() functions prints value of ADC and voltage on serial monitor. delay() function adds a delay of one second after every reading.

Serial.print("AIN0: ");
Serial.print("\tVoltage: ");
Serial.println(Voltage, 7);

In summary, in this tutorial, you learned the following concepts:

  • Introduction to ADS1115 external I2C based ADC
  • How to use it with ESP32
  • How to measure voltage with ADS1115 and ESP32

You can check ESP32 projects also:

19 thoughts on “ADS1115 I2C external ADC with ESP32 in Arduino IDE”

    • I found the way to connect up to four ADS1115 to the same I2C connection.

      This TI pdf tells how to do it.

      Here is a short form “how to”:
      I2C Address Selection
      The ADS111x have one address pin, ADDR, that configures the I2C 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 I2C communication.
      Table 4.
      ADDR Pin Connection and Corresponding Slave Address
      GND 1001000 (48)
      VDD 1001001 (49)
      SDA 1001010 (50)
      SCL 1001011 (51)

  1. Hi,

    Thanks for this, very interesting, I have a comment:

    You wrote:
    The scaling factor is .01V/°C. It mean for every 1°C, LM35 temperature sensor provides 100mV at the output.

    That should be 10mV for every 1C, not 100mV



    • Hi Tony,

      This code works straightforward with ESP8266 and even Arduino also. You just need to change I2c pins according to the selected development board and this is the beauty with Arduino IDE based codes and maximum number of codes are easily portable to other boards also.

  2. This code works for me with the up to date library:


    //Adafruit_ADS1115 ads(0x48);
    Adafruit_ADS1115 ads;
    float Voltage = 0.0;

    void setup(void)
    if (!ads.begin()) {
    Serial.println(“Failed to initialize ADS.”);
    while (1);

    void loop(void)
    int16_t adc0;

    adc0 = ads.readADC_SingleEnded(0);
    Voltage = ads.computeVolts(adc0);
    //Voltage = (adc0 * 0.1875)/1000;

    Serial.print(“AIN0: “);
    Serial.print(“\tVoltage: “);
    Serial.println(Voltage, 7);


  3. #include



    #define SENSOR_ID “2”
    #define SERVER_IP “”

    #ifndef STASSID
    #define STASSID “XXXXXX”
    #define STAPSK “XXXXXX”

    #include // Only needed for Arduino 1.6.5 and earlier
    #include “SH1106Wire.h” // legacy: #include “SH1106.h”
    #include “SH1106.h”

    SH1106 display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL

    #define DEMO_DURATION 3000
    typedef void (*Demo)(void);

    int demoMode = 0;

    const int potPin = 34;
    String apiPath=”http://” SERVER_IP “/api/StoreReading”;

    String reading=”-9999″;

    // GPIO where the DS18B20 is connected to
    const int oneWireBus = 4;

    #define USE_SERIAL Serial

    WiFiMulti wifiMulti;

    float SensorValue=0.000;
    Adafruit_ADS1115 ads;

    void setup(void)

    for(uint8_t t = 4; t > 0; t–) {
    USE_SERIAL.printf(“[SETUP] WAIT %d…\n”, t);
    USE_SERIAL.println(“Integrate Data Logger Sensor.”);
    USE_SERIAL.print(“Server IP: “);
    USE_SERIAL.print(“Sensor ID: “);
    wifiMulti.addAP(STASSID, STAPSK);
    // cpu frq. reduce
    void drawFontFaceDemo() {
    // Font Demo1
    // create more fonts at
    display.drawString(0, 20, reading+” PSI”);
    Demo demos[] = {drawFontFaceDemo};
    int demoLength = (sizeof(demos) / sizeof(Demo));
    long timeSinceLastModeSwitch = 0;

    void loop(void)
    // the display
    // draw the current demo method

    display.drawString(10, 128, String(millis()));
    // write the buffer to the display

    if (millis() – timeSinceLastModeSwitch > DEMO_DURATION) {
    demoMode = (demoMode + 1) % demoLength;
    timeSinceLastModeSwitch = millis();
    // wait for WiFi connection
    if(( == WL_CONNECTED)) {
    HTTPClient http;

    USE_SERIAL.print(“[HTTP] begin…\n”);
    // configure traged server and url
    //http.begin(“”, ca); //HTTPS
    http.begin(apiPath); //HTTP
    http.addHeader(“Content-Type”, “application/x-www-form-urlencoded”);

    String postData = “sensor_id=” SENSOR_ID “&reading=”+reading;

    int httpCode = http.POST(postData);
    USE_SERIAL.print(“[HTTP] POST…\n”);
    // start connection and send HTTP header

    // httpCode will be negative on error
    if(httpCode > 0) {
    // HTTP header has been send and Server response header has been handled
    USE_SERIAL.printf(“[HTTP] GET… code: %d\n”, httpCode);

    // file found at server
    if(httpCode == HTTP_CODE_OK) {
    String payload = http.getString();
    } else {
    USE_SERIAL.printf(“[HTTP] GET… failed, error: %s\n”, http.errorToString(httpCode).c_str());


    void ReadSensor(){
    int16_t adc0;
    //adc0 = ads.readADC_SingleEnded(0);

  4. I’m trying to use two ADS1115’s, one at 0x48, and one at 0x49…

    But the code example fails Adafruit_ADS1115 ads(0x48);

    Apparently that is no longer how you call out the address of the device.

    I can only get Adafruit_ADS1115 ads; to work, and I can’t see how to set the address for the 0x49.

    It looks to my newbie eye that the address is hard coded in the .h and the .cpp files.

    I’m SURE I’m missing something simple, but am quite stumped. Thank you….

  5. Please fix the ESP32 image in the interfacing diagram. The pin labels need to match the pins. This is still causing confusion after several years.

    • from ADS1115 datasheet :
      Analog input voltage AIN0,1,2 & 3 : from GND-0.3v to VDD+0.5V, so if VDD=5V, the max input voltage on AINx = 5.3V


Leave a Comment