Guide no. 22
Two wires to connect dozens of sensors and displays: how it works, which resistors you need, what to do when two modules have the same address and how to find the ones connected.
By Ada Intelisano · informaticait.it technical team
- Two lines, SDA (data) and SCL (clock), shared by all the devices. The controller (the board) calls, the targets answer.
- Each target has a 7-bit address: two devices with the same address cannot share the same bus.
- The outputs can only pull LOW: you need pull-up resistors to VDD. For the ESP32 Espressif recommends 2 to 5 kΩ.
- The scanner tries every address and prints the ones that answer: it is the first thing to do when a sensor stays silent.
How it works
The outputs of I²C devices are open-drain: they can connect the line to ground, never to VDD. When the bus is idle the two Rp hold SDA and SCL HIGH; whoever needs to transmit pulls them LOW. This way nobody ever ends up in a short circuit, even if two devices talk at once. The NXP specification calls the device that generates the clock the controller and the one being called the target (once known as master and slave).
Every exchange begins with a START (SDA falls while SCL is high). Then come the 7 address bits, one bit saying whether the controller wants to write (0) or read (1), and the ninth clock pulse, during which the called target holds SDA LOW: that is the ACK, “I'm here”. If nobody answers, the line stays high (NACK). It ends with a STOP.
The pins on the boards
| SDA | SCL | Notes | |
|---|---|---|---|
| Arduino UNO | A4 | A5 | also on the two pins next to AREF; Wire.begin() |
| ESP32-DevKitC | GPIO 21 | GPIO 22 | other pins with Wire.begin(sda, scl) |
The pull-up resistors
The right value lies between two limits, both in the NXP specification. The minimum is set by the current an output must be able to sink (3 mA): Rmin = (VDD − 0.4 V) ÷ 3 mA, that is about 1 kΩ at 3.3 V and 1.5 kΩ at 5 V. The maximum is set by the capacitance of the wires and devices: the higher it is, the slower the rising edge. Rmax = tr ÷ (0.8473 × Cb).
| Bus capacitance | 50 pF | 100 pF | 200 pF | 400 pF |
|---|---|---|---|---|
| Standard, 100 kHz (tr 1000 ns) | 23.6 kΩ | 11.8 kΩ | 5.9 kΩ | 2.95 kΩ |
| Fast, 400 kHz (tr 300 ns) | 7.1 kΩ | 3.5 kΩ | 1.8 kΩ | 885 Ω |
Rmax calculated by us with the formula from NXP UM10204. Each pin adds up to 10 pF, and the wires add more.
Addresses of the most common modules
| Device | Address | How to change it |
|---|---|---|
| ADS1115 (A/D converter) | 0x48–0x4B | ADDR pin to GND, VDD, SDA or SCL |
| BME280 (pressure, temperature, humidity) | 0x76 / 0x77 | SDO pin to GND or to VDDIO |
| SSD1306 (OLED display) | 0x3C / 0x3D | SA0 pin (D/C#) |
| DS3231 (clock) | 0x68 | fixed |
| AHT20 (temperature, humidity) | 0x38 | the datasheet gives no alternatives |
| SHT4x (temperature, humidity) | 0x44 / 0x45 / 0x46 | depends on the version you buy (A, B or C) |
If two identical modules have a fixed address, you use a multiplexer such as the TCA9548A: eight separate channels, and the controller opens the one it needs. The TCA9548A itself has an address from 0x70 to 0x77.
Long cables and connectors
I²C was designed to stay on one board. The specification does not set a length: the limit is the capacitance, 400 pF in Standard and Fast mode. NXP talks about “a few meters”. If you need longer distances: lower the speed, use lower pull-ups, or an extender such as the P82B715 (about 50 m) or a differential buffer such as the PCA9615, which SparkFun uses with Ethernet cables. For long wires NXP recommends not running SDA and SCL side by side: SDA, VDD, GND, SCL is better.
Qwiic and STEMMA QT are the same 4-pin JST SH connector with the same colors: black GND, red V+, blue SDA, yellow SCL. Qwiic is 3.3 V only, STEMMA QT accepts 3 to 5 V.
Wiring: ESP32 with two modules
The DS3231 and the ADS1115 are plugged into the same breadboard and connected with four wires: power, ground, SCL and SDA. The ADS1115's ADDR pin goes to ground to get address 0x48. The scanner will find 0x48 and 0x68.
The scanner
// I2C scanner: tries every address from 0x08 to 0x77 and prints the ones that respond. // Same sketch for Arduino UNO (SDA = A4, SCL = A5) and ESP32 (SDA = GPIO 21, SCL = GPIO 22). #include <Arduino.h> #include <Wire.h> void setup() { Serial.begin(115200); Wire.begin(); } void loop() { int found = 0; Serial.println("Scanning the I2C bus..."); for (uint8_t address = 0x08; address <= 0x77; address++) { Wire.beginTransmission(address); uint8_t result = Wire.endTransmission(); // 0 = someone answered with ACK if (result == 0) { Serial.print(" device at address 0x"); if (address < 16) Serial.print('0'); Serial.println(address, HEX); found++; } else if (result == 4) { Serial.print(" unknown error at 0x"); Serial.println(address, HEX); } } if (found == 0) Serial.println("No devices: check wires, power supply and pull-ups"); Serial.println(); delay(5000); }
The scan starts at 0x08 and stops at 0x77: addresses 0x00 to 0x07 and 0x78 to 0x7F are reserved by the specification. endTransmission() returns 0 if the device answered, 2 if the address got no answer (NACK), 4 for other errors, 5 for a timeout.
Common mistakes
| What happens | Why | Fix |
|---|---|---|
| The scanner finds nothing | SDA and SCL swapped, ground or power missing | check the four wires, then the pull-ups |
| It finds the module at a different address than expected | jumper or address pin in another position | use the address found in the sketch |
| Two identical modules, only one answers | same address | change the address if you can, otherwise TCA9548A |
| Works on the bench, hangs with long wires | too much capacitance: the rising edge is slow | lower pull-ups, lower speed, extender |
| The sketch hangs on a reading | bus stuck because of a device | Wire.setWireTimeout() on the UNO, then find the cause |
| 5 V module on an ESP32 | the module's pull-ups go to 5 V | power it at 3.3 V if it allows that, or use a level shifter |
Useful products
Other guides
- Resistor colour code and tolerances
- N-channel and P-channel MOSFETs
- Bipolar transistor (BJT) or MOSFET?
- Relays: how to drive them and how much current they draw
- THT and SMD/SMT components
- XIAO board pinouts
- LEDs: forward voltage and series resistor
- The multimeter: measuring voltage and current
- Wemos D1 mini: first steps
- MOSFET module with Arduino and ESP32
- Relay module with Arduino and ESP32
- 3D printing filaments: PLA, PETG and fibre-filled versions
- Analog and digital: the differences
- ADS1115: 16-bit converter with Arduino and ESP32
- From bits to real values: converting sensor readings
- DS3231 RTC clock with Arduino and ESP32
- Linear or switching regulator: which one to choose
- Step-down, step-up and buck-boost: choosing the right module
- Voltage divider: reading voltages higher than 5 V or 3.3 V
- Pull-up, pull-down and bounce: wiring a button properly
- 3.3 V and 5 V logic levels: getting an ESP32 and an Arduino to talk
- Lithium batteries: voltages, charging and protection
- ESP32 power consumption and deep sleep: how long the battery lasts
- Temperature sensors compared
- ESP32: which pins to use and which to avoid
- Getting started with the ESP32 in Arduino IDE 2 and PlatformIO
- SSD1306 OLED display and 16×2 I²C LCD with Arduino and ESP32
- PIR motion sensor and HC-SR04 ultrasonic sensor
- Date and time from the Internet with the ESP32: NTP, Italian time zone and daylight saving time
- MicroSD data logger: saving measurements to CSV
- Solar-powered ESP32: panel, charger and the numbers for Italy
- Web server on the ESP32: control a relay from your phone
- Your first LED: wire it up and make it blink
- The button: let Arduino decide
- The potentiometer: turn a knob and read its value
- Soft light: adjusting the brightness of an LED
- The buzzer: playing notes and melodies
- The traffic light: three LEDs in sequence
- The thermometer: reading the temperature with the TMP36
- The servo motor: moving an arm with Arduino
- The night light: the photoresistor and your first decision
- The relay: switching on a light bulb with Arduino
- The LCD display: making Arduino write
- The electronic dice: your first complete project
- The RGB LED: every color from three lights
- The joystick: two-axis control with a shield
- The LED ring: twelve colors from a single pin
- The DC motor: driving it with a MOSFET
- Soil moisture: the plant that asks for water
- The stepper motor: turn exactly as far as you want
- The parking sensor: faster and faster beeps
- The 7-segment display: big, bright numbers
- Automatic watering: the plant that waters itself
- The keypad: a lock with a secret code
- Networked weather station: values and chart on your phone
- A Telegram bot on the ESP32: your home from your phone
- MQTT with the ESP32: the language of connected devices
- Updating the ESP32 over Wi-Fi (OTA)
- ESP-NOW: two ESP32 boards talking without a router
- WebSocket with the ESP32: the LED that follows the slider
- Readings on a Google sheet, with deep sleep
- WiFiManager: choose the Wi-Fi from your phone
- Bluetooth LE with the ESP32: the phone without a network
- The camera in your browser with the ESP32-S3
- A portable Bluetooth speaker you build yourself
- Bluetooth desktop speakers, 2 × 20 W
- Stereo MP3 player with two buttons
- The shelf that plays music: a Visaton exciter
- How to solder well
- How much does it draw? Current and power with the INA219
- Load-cell scale with the HX711
- CO2 traffic light: when to open the windows
- RFID card door opener
- GPS: track logger on microSD
- LoRa: how far does it go? A range test with two boards
- Battery weather sign with an e-paper display
- Web radio with an ESP32 and an I2S amplifier
- Getting started with the Raspberry Pi Pico 2 in MicroPython
- Your first amplifier: the LM386 and a speaker
- Talking Arduino: the DFR0760 speech synthesis module
- The spectrum of your music on an LED matrix
- Drawing with 64 LEDs: the 8×8 matrix with the MAX7219
- A real voltage: the 12-bit MCP4725 DAC
- The heartbeat on Arduino: an ECG with the AD8232