This one is about the wire, not the chip. Nothing below changes with the board you picked, which is why the chip and language switches are not on it. They come back on the ESP32 pages this one sits underneath.
I2C, start to stop
Two wires, a hundred devices, and one rule that holds the whole thing together — data may only change while the clock is low. The two moments that break the rule on purpose are how every message begins and ends.
Drag through one transaction. Watch where SDA is allowed to move, and what happens at the ninth bit when nothing is there to answer.
Two wires, and neither of them can push
SDA carries data, SCL carries the clock, and both are open-drain: a device can pull the line down to ground, and that is all it can do. Nothing ever drives a line high. A pull-up resistor does that, quietly, whenever everybody lets go.
This sounds like a limitation and it is the entire design. Two devices pulling at once is harmless — the line just goes low — so a shared bus cannot destroy itself, and any device can interrupt a clock by holding it down. Compare that with SPI, where two outputs on one wire are two outputs fighting.
It also means a bus with no pull-ups does not half-work. It never gets back to high, so it never works at all.
The rule, and the two exceptions
SDA may only change while SCL is low. The receiver reads SDA on the rising edge of the clock, so anything that moves while the clock is high is not data.
That leaves two illegal transitions free to mean something else, and they mean the only two things a bus needs outside of data:
- START — SDA falls while SCL is high. Every device on the bus wakes up and starts counting bits.
- STOP — SDA rises while SCL is high. The bus is free again.
Everything between them is one transaction, and no other master may interrupt it.
The nine-bit byte
Bytes on I2C are nine bits long. Eight from the sender, then one where the sender lets go of SDA and waits.
If a device is there and understood, it pulls SDA low for that ninth clock — the ACK. If nothing pulls it down, the pull-up leaves it high, and that high is a NACK. Nothing has errored; nobody answered.
This is what "sensor not found" actually is.
Wire.endTransmission() returning 2 means the address byte got no
ACK. Not a crash, not a timeout — a wire that stayed high for one clock cycle.
Reading the first byte
The first byte after START is seven address bits, most significant first, then one direction bit: 0 to write, 1 to read. Every device compares those seven bits against its own address and exactly one should answer.
Because the address occupies the top seven bits of that byte, datasheets
disagree about what to call it. 0x3C shifted left is 0x78, and both numbers get
printed as "the address" of the same OLED. Arduino's Wire library wants the
7-bit form. If a device does not respond and its datasheet says 0x78, halve it.
The smallest transaction that does anything
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin(); // SDA, SCL, internal pull-ups off
for (uint8_t a = 8; a < 120; a++) {
Wire.beginTransmission(a);
if (Wire.endTransmission() == 0) // 0 means somebody ACKed
Serial.printf("found 0x%02X\n", a);
}
}
void loop() {}That is a scanner, and it is the first thing to run on any I2C build. It sends START, an address, and STOP — no data at all — and lists whoever answered. If your device is not in the list, no library is going to help you; the wiring is wrong, the address is wrong, or the part is not powered.
What it costs
Two pins, whatever you connect. Around 400 kHz in practice, so it is for registers and readings, not for pushing pixels — a display refreshed over I2C is noticeably slower than the same one over SPI.
The two things that go wrong are both about the shared bus rather than the protocol: two devices claiming one address, and too many pull-ups fighting each other. Those are the next two pages.
Edit this page — content/esp32/i2c-start-to-stop.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.