ESP32/Buses/31. I2C
Your chip
Your language
Buses · 31 of 81

I2C

Two wires, up to a hundred sensors, and one number per device that the factory chose for you. Everything that goes wrong with I2C is either that number colliding, or the two resistors that make the bus work at all.

/esp32/i2c · arduino · S3

Two wires and a name each

Every device on the bus has a 7-bit address. The board calls one out, that device answers, everybody else stays quiet. There is no negotiation and no way to change an address in software — it is set at the factory, sometimes with one pin you can tie high or low.

Wire.beginTransmission on every address, 1 to 126
2 replied
Plug something in
Devices wired
2
Addresses answering
2
0x3C, 0x76 — every device on its own number. Run this sketch before any other I2C code. An address that appears here is a wiring proof; a library that then fails is a library problem, and you have just cut the search in half.

The two resistors

SDA and SCL are never driven high. Devices only pull them down, and a pair of resistors pulls them back up — which is what lets several devices share a wire without destroying each other.

Almost every breakout board has 4.7 kΩ resistors on it already. That is fine for one board and a problem for four, because they end up in parallel: four modules means about 1.2 kΩ, which is strong enough that a device cannot pull the line low properly. Unsolder the pairs from all but one.

On the ESP32 specifically

  • Any two pins. Wire.begin(sda, scl) — you are not stuck with fixed ones.
  • Two buses. Wire and Wire1, entirely independent. This is the cleanest fix for an address collision.
  • Start at 100 kHz. Move to 400 kHz once it works, not before. Half of "I2C is unreliable" is a bus running at 400 kHz on wires meant for 100.
On your S3
ChipXtensa LX7 · 2 × 240 MHz
Board settingESP32S3 Dev Module
Default I2CSDA 8 · SCL 9
Watch out forThe port vanishes after upload

The code

Run this before any sensor library, every time. It answers one question - is the device electrically there - and it separates wiring problems from software ones in ten seconds.

i2c_scan.ino
#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);          // SDA, SCL - any pins you like
  Wire.setClock(100000);       // start slow. 400000 once it works

  Serial.println("scanning...");
  for (uint8_t a = 1; a < 127; a++) {
    Wire.beginTransmission(a);
    if (Wire.endTransmission() == 0)
      Serial.printf("found 0x%02X\n", a);
  }
}

void loop() {}

Wire.begin(sda, scl) lets you pick any two pins on the ESP32, which most Arduino boards cannot do. Wire1 gives you a second, entirely separate bus.

When it does not work

The scanner finds nothing

Check three things in this order - SDA and SCL swapped, no pull-up resistors on the bus, and the module not actually powered. A dead sensor is almost never the answer.

One sensor works and adding a second breaks both

They share an address. The scanner still shows one entry, so the bus looks healthy while both chips answer at once. Move one with its address jumper, or put it on Wire1.

It works with short jumpers and fails on a metre of cable

Capacitance. The pull-ups cannot charge the line fast enough between clock edges. Drop to 100 kHz, use stronger pull-ups, or shorten the cable - I2C was designed for centimetres.

Reads return 0xFF or freeze the sketch

The bus is stuck, usually because a device was reset mid-transaction and is still holding SDA low. Toggling SCL nine times releases it - most libraries have a recover function that does exactly that.

Where this goes next

I2C trades speed for wires. The next page is the other end of that trade - four wires, and a hundred times the throughput.

SPI

Edit this page — content/esp32/i2c.mdx

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse ESP32 on the forum