The ESP32 I2C pins allow developers to connect a wide range of modules and sensors using just two wires. Whether you’re building a weather station, a smart home interface, or just learning microcontroller communication, mastering I2C is essential.
This article explores:
- Default and custom I2C pins on ESP32
- Connecting an I2C LCD (with code)
- Using multiple but different I2C devices
- Handling multiple and same I2C devices on the ESP32
What is I2C?
I2C (Inter-Integrated Circuit) is a 2-wire serial communication protocol with:
- SDA: Serial Data Line
- SCL: Serial Clock Line
It supports multiple devices (slaves) on the same bus, all identified by unique 7-bit addresses.
Read more about I2C Communication: Basics of the I2C Communication Protocol
ESP32 I2C Pins
The ESP32 supports dual I2C interfaces, and pins can be assigned dynamically.
Signal | Default GPIO |
---|---|
SDA | GPIO21 |
SCL | GPIO22 |
You can override them using:
Wire.begin(SDA_pin, SCL_pin);

Refer to the image above to locate all GPIO pins on your ESP32 development board. The pins with light green color are I2C Pins.
Example: Connecting an I2C LCD
Let’s wire a 16×2 I2C LCD to ESP32.
Wiring
LCD Pin | ESP32 Pin |
---|---|
VCC | 3.3V or 5V |
GND | GND |
SDA | GPIO21 |
SCL | GPIO22 |
Code Example
//ESP32 I2C Pins
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// I2C address 0x27 is common; use scanner to verify
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
Wire.begin(21, 22); // Set custom SDA, SCL if needed
lcd.begin();
lcd.backlight();
lcd.print("Hello ESP32!");
}
void loop() {}
Use an I2C scanner sketch to identify your module’s I2C address.
Using Multiple I2C Devices on a Single ESP32 Bus
Case 1: Different I2C Devices
You can connect multiple different I2C devices as long as:
- Each device has a unique I2C address
- All devices share the same SDA and SCL lines
Example:
- MPU6050 sensor (0x68)
- I2C LCD (0x27)
- BME280 sensor (0x76)
Wire.begin(21, 22); // One bus for all
// Use each device's specific library with its address
This setup works natively on ESP32 with no conflicts.
Case 2: Multiple Devices of the Same Type
If you want to use two or more devices of the same type (e.g., two identical LCDs or sensors), you face address conflicts.
Option 1: Change Device I2C Address (If Supported)
Some modules let you set a new address using solder jumpers.
Example:
The BME280 sensor often allows choosing between 0x76 and 0x77 by connecting the SDO
pin to GND or VCC.
Option 2: Use a Software I2C on Different GPIOs
You can create multiple I2C buses using different GPIOs:
#include <Wire.h>
TwoWire I2C_1 = TwoWire(0);
TwoWire I2C_2 = TwoWire(1);
void setup() {
I2C_1.begin(21, 22); // SDA, SCL
I2C_2.begin(17, 16); // Another pair of GPIOs
}
Use libraries that support custom TwoWire
instances. Example:
sensor.begin(0x76, &I2C_1); // First sensor
sensor2.begin(0x76, &I2C_2); // Second sensor, same address but on a different bus
Summary Table
Setup | Use Case | Notes |
---|---|---|
One I2C Bus, Multiple Devices | Different I2C modules | Must have unique addresses |
One I2C Bus, Same Devices | Only possible if address is configurable | Not all modules support it |
Multiple I2C Buses | Multiple same-address devices | Requires TwoWire instances |
Final Thoughts
The ESP32 I2C pins provide powerful, flexible options for interacting with multiple devices—whether different or identical. With dual I2C support and customizable GPIO assignments, the ESP32 is ideal for complex I2C networks.
Use the pinout image above as your hardware reference, and refer to the ArduinoYard tutorial on I2C LCD with ESP32 to get started with real-world example.