← all lessons
Single-Ended Buses · SPI & I²C · #35 of 48

I²C Transactions, Stretching & Recovery

The 9th Clock, the Held Line, and the Stuck Bus

You wire the wrist-IMU on your robot hand to the ESP32 over two thin wires, run the scan, and the sensor never answers. The pull-ups are fine. The address is right. You scope the lines and find SDA stuck flat against ground, refusing to rise no matter how long you wait. Nothing is broken. The bus is simply frozen mid-word, a sensor still spelling out a byte to a master that walked away.

On I²C, a conversation is not done until both sides agree it is done.

Most of the time you think about I²C as addresses and bytes. But every byte rides on a tiny ritual of handshakes, and the bus only works because each side honors that ritual exactly. The thesis of this lesson is an ordering rule, the same kind that governs every shared line: on I²C, control of the bus passes back and forth one bit at a time, and recovery means walking the lines through the rest of the ritual they were stuck in, never just yanking power and hoping.

By the end, you can

  1. Explain what happens on the 9th clock and distinguish an ACK from a NACK
  2. Describe clock stretching and why a master must wait on a held SCL
  3. Diagnose a stuck bus and recover it by clocking SCL up to 9 pulses, then issuing a STOP
  4. Resolve an address conflict using an address-select pin or an I²C multiplexer
  5. Walk the will-not-ACK debug ladder from rise time to address conflict

Intuition first

Think of I²C as two people sharing a single string between two tin cans, except the string can only ever be pulled taut, never pushed. Pull it and it goes low; let go and a spring (the pull-up) lets it drift high. Because either person can pull at any time, the rule has to be: a let-go only wins if nobody else is pulling. If one person is still holding the string down, the other sees it low no matter what they intended.

That single fact explains the whole lesson. The acknowledge is a planned moment where the listener pulls the string to say “got it.” Clock stretching is the listener pulling the clock string to say “wait, I’m not ready.” And a stuck bus is a listener who got interrupted mid-sentence, still holding the data string down, waiting for clock pulses that will never come because the master rebooted and forgot the conversation was even happening.

The cure is never force. You do not push the string high (you cannot anyway). You finish the sentence for the stuck talker by sending the clock pulses it was waiting on, until it has said its last bit and finally lets go.

The 9th clock: ACK and NACK

I²C sends data eight bits at a time, most significant bit first. After those eight bits, the roles flip for exactly one clock period. The receiver becomes the talker for a single bit, called the 9th clock.

Here is the rule, and it is worth memorizing because half of all I²C debugging lives here: the receiver pulls SDA LOW to acknowledge. A low on the 9th clock is an ACK, “I heard you, keep going.” If SDA instead stays high during that 9th clock, that is a NACK.

A NACK is not always an error. It means one of three things depending on who is listening:

  1. The device is absent. You addressed 0x68 and nothing at 0x68 pulled SDA low on the address byte’s 9th clock. No such device, or it is not powered, or its address-select pin is set differently than you assumed.
  2. The device is busy. Some parts (an EEPROM mid-write, a sensor mid-convert) NACK because they genuinely cannot take more right now.
  3. End of read, on purpose. When the master is reading from a device, the master sends the ACK after each byte. On the very last byte it wants, the master deliberately sends a NACK to tell the device “stop talking, I have enough,” and then issues a STOP.

So the same high-on-the-9th-clock means “you’re not there” when you’re writing an address, and “I’m done reading you” when you’re finishing a read. Context is everything. An I²C bus scan is nothing more than walking every address 0x08 through 0x77, sending the address byte, and recording which ones answer the 9th clock with a low.

Clock stretching: the held line as a request for time

A master generates the clock. But because SCL is open-drain and pulled up, any device on the bus can hold it low simply by not letting go. When a slave that needs more time holds SCL LOW after a byte, it is saying “do not start the next bit yet.” This is clock stretching, and it is a legal, designed-in flow-control mechanism.

The master’s obligation is simple and absolute: after it releases SCL to let it float high, it must wait until it actually sees SCL go high before it does anything else. If a slave is stretching, SCL stays low, and the master just waits. Only when the slave finally releases does the line rise, and only then does the master continue.

This is why “release the clock and assume it went high” is a bug. A bit-banged I²C driver that toggles SCL high and immediately marches on, without reading SCL back to confirm it rose, will trample a slow slave that was still thinking. Hardware I²C peripherals on the ESP32 handle this for you, which is one good reason to prefer them over a hand-rolled software bus when a device is known to stretch.

Portrait of Herman Schutte, co-inventor of the I²C bus
Herman Schutte Co-invented the I²C bus at Philips in 1980 with Ad Moelands, originally named COMIC, a two-wire scheme that let a microcontroller run a whole network of chips on just a clock wire and a data wire.

The stuck bus and how to walk it free

Now the failure from the Hook. Picture a read in flight: the master has been clocking bytes out of the wrist-IMU, the IMU is driving SDA to send its data, and right then the master resets (a watchdog fires, you press the reset button, the firmware reflashes). The master vanishes mid-byte.

The IMU does not know the master is gone. It is in the middle of transmitting a byte, holding SDA at whatever the current bit demanded, waiting for the next SCL pulse to clock out the following bit. If that next bit happens to be a 0, SDA is held low and stays there. When the master comes back and tries to issue a START (pull SDA low while SCL is high), it cannot, because SDA is already low. The bus looks dead. Every transaction NACKs or hangs.

The recovery is the heart of this lesson, and it follows directly from the tin-can intuition: finish the slave’s byte for it. The master takes manual control of SCL (often by bit-banging the pin as a plain GPIO) and clocks SCL up to 9 pulses. Each pulse walks the confused slave one bit further through the byte it was stuck in. Within at most 9 clocks the slave reaches the end of its byte and its acknowledge slot, releases SDA, and the line floats high again. The master then issues a clean STOP condition (let SCL go high, then let SDA go high) to formally end the orphaned transaction. Now START works, and the bus is alive.

See it: a transaction and a stuck line

Read the two sketches below as time flowing left to right. Underscores are a line held low (someone is pulling), and the high stretches are the line floating up to the pull-up rail. The first is a healthy address-and-ACK; the second is the frozen bus you recover by clocking it out.

HEALTHY WRITE: master addresses 0x68, slave ACKs on the 9th clock
                A6  A5  A4  A3  A2  A1  A0  R/W  ACK
SCL  ‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾‾   (master drives clock)
SDA  ‾\__1___1___0___1___0___0___0___0(W)__|___   bit8 = slave pulls LOW = ACK
       S = start (SDA falls while SCL high)        9th clock low → device is there

STUCK BUS: master reset mid-read; slave still holds SDA low, no START possible
SCL  ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾   (idle: master came back, wants to START)
SDA  ________________   (slave frozen mid-byte, SDA pinned LOW, START impossible)

RECOVERY: bit-bang SCL up to 9 pulses, slave finishes its byte and releases SDA
SCL  _|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_   (1..9 manual clock pulses)
SDA  ____________________________________/‾  SDA finally floats high → issue STOP
                                          P = STOP (SDA rises while SCL high)

The debrief: notice that nowhere did we drive a line high. We only ever let go or pulled low, because that is all open-drain allows. Recovery is not an override. It is patience plus the clock pulses the slave was promised, delivered late.

Address conflicts: two devices, one name

I²C addresses are mostly fixed by the silicon. A given temperature sensor might only live at 0x48. Put two of the same part on one bus and they both answer 0x48, both pull the 9th clock low at once, and you can never talk to one without the other. The bus is not broken, it is ambiguous, and ambiguity on a shared line is its own kind of stuck.

Two clean fixes:

During an I²C bus scan, the device at address 0x3C never pulls SDA low on the 9th clock of its address byte. What does that tell you?

A master reset mid-read and now SDA sits stuck low so no START can be issued. What is the correct recovery?

Lab: the will-not-ACK debug ladder

When a device refuses to ACK, resist the urge to swap parts at random. Walk this ladder in order, because each rung rules out a whole class of fault:

  1. Scope the rise time and pull-ups. Bad edges look like missing devices. Confirm SDA and SCL actually reach a clean high within spec (this is exactly what lesson #34 measured). A line that never rises cannot carry an ACK.
  2. Check for a stuck-low line. If SDA or SCL idles low with no traffic, something is holding it. Run the 9-clock recovery and re-test before anything else.
  3. Decode the address and the 9th-clock ACK. Capture the address byte. Is it the address you meant (7-bit vs 8-bit!)? Does any device pull the 9th clock low? A logic analyzer earns its keep here (that is lesson #36).
  4. Check clock-stretch tolerance. If the device stretches and your driver does not wait for SCL to rise, you will read garbage or NACKs. Switch to the hardware I²C peripheral or add the read-back.
  5. Suspect an address conflict. If two identical parts share the bus, neither is individually addressable. Set their ADDR pins differently or put them behind a mux.

Finish with a one-line verdict per rung (“rise OK, no stuck line, address 0x68 ACKs, no stretch, single device”) so the next person knows what you already ruled out.

Open-drain arbitration, why a let-go never beats a pull, and the deeper math of the held line

The single electrical fact under everything in this lesson is the open-drain (or open-collector) wiring of SDA and SCL. A device outputs a logic 0 by switching a transistor on and pulling the line to ground; it outputs a logic 1 by turning the transistor off and letting the line float, whereupon the pull-up resistor drags it up to the rail. A line is never actively driven high. This is what lets many devices share two wires without ever short-circuiting against each other: at worst two of them pull low at once, which is harmless, while a pull-low always wins over a let-go.

That asymmetry is the engine of both arbitration and clock stretching. Formally, the bus computes a wired-AND of every device’s output. If device ii drives value di{0,1}d_i \in \{0, 1\} (where 1 means “released”), the line sits at

line=idi=minidi\text{line} = \bigwedge_i d_i = \min_i d_i

so the line is high only if every device has let go, and low if any device pulls. On SDA this gives arbitration: two masters transmitting at once each watch the line, and the first to send a 1 while seeing a 0 has lost (someone else pulled harder) and silently drops out, its message uncorrupted because the winner saw exactly what it expected. On SCL the same wired-AND gives clock stretching: the effective high time of the clock is gated by the slowest releaser, so a slave that keeps pulling SCL down stretches the period until it is ready.

The rise itself is never instant. SCL and SDA climb through the RC formed by the pull-up RpR_p and the total bus capacitance CbC_b, so the voltage recovers as

V(t)=Vcc(1et/(RpCb))V(t) = V_{cc}\left(1 - e^{-t / (R_p C_b)}\right)

and the time to cross a logic threshold scales with RpCbR_p C_b. This is why the spec caps total bus capacitance at 400 pF400\ \text{pF} and why a stretched, multi-drop bus eventually fails to make clean edges: the held-low intervals are free, but every release has to pay an RC tax to get back up. Lesson #34 measured exactly that edge; this lesson is what happens after the edge, when the bits land and the handshake runs.

One note where engineering practice has moved past the historical record. The 1980 patents and the early specs used the words master and slave for the two roles. Revision 7 of the I²C specification (2021) renamed them controller and target; the electrical behavior is identical and the words map one-to-one. This lesson uses the older master/slave terms because they still dominate datasheets, ESP-IDF APIs, and bench conversation, but you will see controller/target in newer documents and they mean the same thing.

Grounded in Wikipedia: “I²C” (CC BY-SA).

Key takeaways

  • The 9th clock is the acknowledge: a receiver pulls SDA low to ACK; SDA staying high is a NACK (absent, busy, or end-of-read).
  • Clock stretching is a slave holding SCL low to buy time; the master must wait until it actually sees SCL go high before continuing.
  • A stuck bus (SDA pinned low after a mid-byte master reset) is recovered by clocking SCL up to 9 pulses to finish the slave's byte, then issuing a STOP.
  • Open-drain means a line is only ever pulled low or released (never driven high); recovery is patience plus clocks, not force.
  • Two devices at one address need an address-select pin or an I²C mux to become individually addressable.
Practice 1 warm-up

You run an I²C bus scan and your code reports a device at 0x76 but nothing at 0x77, even though your board has two of the same sensor on it. On the wire, what physically distinguishes the 0x76 “found” result from the 0x77 “not found” result?

Show worked solution

On the address byte for 0x76, some device pulled SDA low on the 9th clock (an ACK), so the scan recorded it as present. On the address byte for 0x77, SDA stayed high on the 9th clock (a NACK), so nothing answered there. The likely cause: both sensors are identical parts and their ADDR select pins are set the same way, so both landed on 0x76 and the second one never got its own address. Set one sensor’s ADDR pin to the other state so it moves to 0x77.

Practice 2 core

Your firmware resets in the middle of reading a 6-byte block from the IMU. After reset, every transaction hangs and the scope shows SDA flat low, SCL idle high. Write the exact recovery sequence, and explain why driving SDA high with a GPIO is the wrong move.

Show worked solution

Recovery: take manual control of SCL as a GPIO and send up to 9 clock pulses (toggle SCL low-high-low, watching SDA after each). The stuck slave is mid-byte; up to 8 data clocks plus 1 ack clock walk it to the end of its byte, at which point it releases SDA and the line floats high. Once SDA is high, issue a STOP: let SCL go high, then let SDA go high. The bus is now idle and START works again.

Driving SDA high with a GPIO is wrong because I²C is open-drain: no device ever drives a line high. The slave is actively pulling SDA low; if you drive SDA high you create direct contention (your push-pull high fighting the slave’s pull-low), which dumps current through both output stages and can damage a pin. The protocol’s only legal way up is to let the slave release, which the 9 clock pulses cause.

Practice 3 stretch

A microcontroller-based slave clock-stretches after every byte while its firmware decides whether to ACK. Your bit-banged master toggles SCL high and immediately samples the next bit without reading SCL back. Describe the failure this produces, and give two fixes.

Show worked solution

The failure: when the master “releases” SCL and marches on, the slave is still holding SCL low (stretching). Because SCL never actually rose, the master’s idea of “the clock is high now” is a lie. It samples SDA during a clock period the slave never saw as a valid high, so bits get read at the wrong moments. The result is shifted, corrupted data or spurious NACKs, intermittent and maddening because it only bites when the slave’s firmware happens to be slow on that byte.

Fix 1: after releasing SCL, read the SCL pin back in a loop and wait until it actually reads high (with a timeout) before sampling SDA or starting the next bit. That honors the stretch. Fix 2: stop bit-banging and use the hardware I²C peripheral on the ESP32, which implements the wait-for-SCL-high behavior in silicon and handles stretching correctly without firmware effort.

A frozen I²C bus looks like a dead one, but it is really a conversation paused mid-word, one device still patiently spelling out a byte to a master that walked away. You do not revive it by shouting or by force. You pick up where the silence fell, send the clock pulses that were promised, and let the talker say its last bit and finally let go. On a shared line, the way out is never to override the other side. It is to finish what was started, one clock at a time.

full glossary →