Overview
The ADS1115 is a 16-bit, 4-channel analog-to-digital converter (ADC) from Texas Instruments with a built-in programmable gain amplifier (PGA). It turns microcontrollers with weak or missing analog inputs — like the Raspberry Pi and ESP32 — into precision measurement platforms, and it dramatically upgrades the 10-bit ADC on an Arduino Uno. It communicates via I2C and supports four single-ended channels or two differential pairs.
ShillehTek's pre-soldered ADS1115 module ships with male headers attached, works from 2.0V to 5.5V, and exposes all four analog inputs (A0–A3) along with SCL, SDA, ADDR, and ALRT. The ADDR pin selects one of four I2C addresses (0x48–0x4B), so up to four ADS1115s can share one I2C bus for 16 total channels. The ALRT pin is a programmable comparator output that can fire an interrupt when a reading crosses a threshold.
This manual walks you through the specs, pinout, wiring for Arduino, ESP32, Raspberry Pi, and the Pico, a working "hello world" example per platform, and FAQs on gain settings, sample rates, and address selection.
At a Glance
Specifications
| Parameter | Value |
| ADC IC | Texas Instruments ADS1115 |
| Resolution | 16-bit (15 bits + sign in differential) |
| Channels | 4 single-ended or 2 differential |
| Operating Voltage | 2.0V - 5.5V |
| Communication | I2C (up to 3.4 MHz) |
| I2C Address Options | 0x48 (GND), 0x49 (VDD), 0x4A (SDA), 0x4B (SCL) |
| Programmable Gain | ±6.144V, ±4.096V, ±2.048V, ±1.024V, ±0.512V, ±0.256V |
| Data Rate | 8, 16, 32, 64, 128, 250, 475, 860 SPS |
| Input Impedance | ~10 MΩ |
| Current Consumption | ~150 μA (continuous mode) |
| Pin Count | 10 (VDD, GND, SCL, SDA, ADDR, ALRT, A0, A1, A2, A3) |
| Board Format | Pre-soldered with male headers |
Pinout Diagram
Wiring Guide
Arduino Wiring
The ADS1115 runs from the Arduino Uno's 5V rail and communicates over I2C on A4/A5. Leave ADDR unconnected or tied to GND for address 0x48.
| Module Pin | Arduino Pin | Details |
|---|---|---|
| VDD | 5V | Power |
| GND | GND | Ground |
| SCL | A5 (SCL) | I2C clock |
| SDA | A4 (SDA) | I2C data |
| ADDR | Not connected / GND | Address = 0x48 |
| ALRT | Optional digital pin | Comparator alert output |
| A0 - A3 | Analog sources | 0 to VDD |
ESP32 Wiring
The ADS1115 is especially useful with the ESP32 because the ESP32's built-in ADC is noisy and non-linear. Use this module for precision readings.
| Module Pin | ESP32 Pin | Details |
|---|---|---|
| VDD | 3.3V | Power |
| GND | GND | Ground |
| SCL | GPIO 22 | Default I2C SCL |
| SDA | GPIO 21 | Default I2C SDA |
| ADDR | Not connected / GND | Address = 0x48 |
| ALRT | Any free GPIO | Optional interrupt |
| A0 - A3 | Analog sources | 0 to 3.3V |
Raspberry Pi Wiring
The Raspberry Pi has no analog inputs, so pairing it with the ADS1115 is the standard way to read analog sensors on the Pi. Enable I2C with sudo raspi-config.
| Module Pin | Raspberry Pi Pin | Details |
|---|---|---|
| VDD | 3.3V (Pin 1) | Power |
| GND | GND (Pin 6) | Ground |
| SCL | GPIO 3 (Pin 5) | I2C1 SCL |
| SDA | GPIO 2 (Pin 3) | I2C1 SDA |
| ADDR | GND | Address = 0x48 |
| ALRT | Optional GPIO | Interrupt output |
| A0 - A3 | Analog sources | 0 to 3.3V |
i2cdetect -y 1. The default address is 0x48.
Raspberry Pi Pico Wiring
The Pico already has three ADC inputs, but the ADS1115 adds four more true-16-bit channels with programmable gain — far more precise than the Pico's internal ADC.
| Module Pin | Pico Pin | Details |
|---|---|---|
| VDD | 3.3V (Pin 36) | Power |
| GND | GND (Pin 38) | Ground |
| SCL | GP1 (Pin 2) | I2C0 SCL |
| SDA | GP0 (Pin 1) | I2C0 SDA |
| ADDR | GND | Address = 0x48 |
| ALRT | Any free GP | Optional interrupt |
| A0 - A3 | Analog sources | 0 to 3.3V |
Code Examples
Arduino
// ADS1115 - Read all 4 single-ended channels
// Requires: Adafruit ADS1X15 Library
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;
void setup() {
Serial.begin(9600);
while (!Serial);
if (!ads.begin(0x48)) {
Serial.println("Failed to initialize ADS1115.");
while (1);
}
// PGA = +/- 4.096V => 1 bit = 0.125 mV
ads.setGain(GAIN_ONE);
Serial.println("ADS1115 ready.");
}
void loop() {
int16_t raw[4];
float volts[4];
for (int i = 0; i < 4; i++) {
raw[i] = ads.readADC_SingleEnded(i);
volts[i] = ads.computeVolts(raw[i]);
Serial.print("A");
Serial.print(i);
Serial.print(": ");
Serial.print(raw[i]);
Serial.print(" ");
Serial.print(volts[i], 4);
Serial.print(" V ");
}
Serial.println();
delay(500);
}
ESP32
// ADS1115 on ESP32 via I2C (GPIO21 SDA, GPIO22 SCL)
// Requires: Adafruit ADS1X15 Library
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
if (!ads.begin(0x48)) {
Serial.println("ADS1115 not found.");
while (1);
}
ads.setGain(GAIN_ONE); // +/- 4.096V
Serial.println("ADS1115 ready.");
}
void loop() {
for (int i = 0; i < 4; i++) {
int16_t raw = ads.readADC_SingleEnded(i);
float v = ads.computeVolts(raw);
Serial.printf("A%d: raw=%d %.4f V\n", i, raw, v);
}
Serial.println();
delay(500);
}
Raspberry Pi
# ADS1115 on Raspberry Pi via I2C
# Install: pip install adafruit-circuitpython-ads1x15
# Enable I2C: sudo raspi-config -> Interface Options -> I2C
import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c, address=0x48)
ads.gain = 1 # +/- 4.096V
chans = [AnalogIn(ads, ADS.P0),
AnalogIn(ads, ADS.P1),
AnalogIn(ads, ADS.P2),
AnalogIn(ads, ADS.P3)]
while True:
for i, ch in enumerate(chans):
print(f"A{i}: raw={ch.value} {ch.voltage:.4f} V")
print("-" * 30)
time.sleep(1)
Raspberry Pi Pico (MicroPython)
# ADS1115 on Raspberry Pi Pico via I2C0 (GP0 SDA, GP1 SCL)
# Upload an ads1x15.py driver to the Pico filesystem first.
from machine import I2C, Pin
from ads1x15 import ADS1115
import time
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
print("I2C scan:", [hex(d) for d in i2c.scan()])
# gain=1 -> +/- 4.096V full scale
adc = ADS1115(i2c, address=0x48, gain=1)
while True:
for channel in range(4):
raw = adc.read(channel1=channel)
volts = raw * 4.096 / 32767
print("A{}: raw={} {:.4f} V".format(channel, raw, volts))
print("-" * 30)
time.sleep(1)