Blog · Deep dive

i2c clock stretching, explained

Deep dive

The controller owns the clock — except when it doesn't. Clock stretching is the one place a target device pushes back, and it's behind a whole family of "works on Arduino, flaky on Pi" mysteries.

The mechanism

How i2c clock stretching works: a target says "wait"

i2c lines are open-drain: anyone can hold a line low, nobody can force it high. Clock stretching exploits that on SCL. After each bit or byte, the controller releases the clock line expecting the pull-ups to lift it — but a target that needs more time simply keeps SCL pinned low. The controller is supposed to notice the line hasn't actually risen and wait. When the target lets go, the clock resumes and the transaction continues as if nothing happened.

target holds SCL low — controller waits SCL normal clocks clock resumes

Who needs this? Chips with firmware inside. A bare register file (BME280, BH1750, DS3231) answers instantly and never stretches. But sensors that run their own microcontroller — the CCS811 and BME680 air-quality parts are the classic examples — sometimes need milliseconds to cook a result mid-read, and stretching is the only in-band way to ask for it.

It's not just hardware controllers that get this wrong. A bit-banged (software) i2c implementation only honours stretching if it actually reads SCL back after releasing it and waits for the target to let go. Toggle the pin on a fixed delay instead — a shortcut plenty of hand-rolled bit-bang code takes — and the target's stretch is ignored outright, not just mistimed. It's a different bug from the Pi's below, with the same symptom.

The famous bug

The Raspberry Pi i2c clock-stretching bug

The Pi's BCM283x hardware i2c controller doesn't genuinely watch SCL rise — it samples on a fixed internal schedule. If a target begins a stretch in a narrow window around the sample point, the controller proceeds as though the clock had ticked, shifting bits early and corrupting the byte silently: no error flag, just wrong data. The quirk has persisted across Pi generations, which is why "CCS811 + Raspberry Pi" threads all end the same way.

Three workarounds, best first:

1. Choose non-stretching sensors. For air quality on a Pi, an SCD40 measures real CO₂ and doesn't stretch — it's the pick in our Pi sensor roundup for exactly this reason.

2. Slow the bus right down. dtparam=i2c_arm_baudrate=10000 widens every timing window ~10×, so most stretches land harmlessly. Crude but often sufficient — sensor reads don't need bandwidth (where to set this).

3. Software i2c. dtoverlay=i2c-gpio,bus=3 bit-bangs a new bus on any two GPIOs entirely in the kernel, which tracks SCL properly and honours stretches. Costs CPU and tops out slower, but it's correct.

Diagnosing this blind is miserable — the failure is intermittent and data-dependent. On a logic analyzer it's unmistakable: you see SCL held low by the target while the controller barrels on regardless.

Questions

Clock stretching FAQ

What is clock stretching in one sentence?

A target device holds the SCL line low to say 'wait — I'm not ready,' pausing the controller mid-transaction until it releases the line. It's legal, in-spec behaviour, possible because i2c lines are open-drain.

Which devices use clock stretching?

Mostly sensors with a microcontroller inside that needs computation time mid-read: the CCS811 and BME680 air-quality sensors are the notorious ones, and SHT3x sensors offer a clock-stretching mode. Simple register-based chips (BME280, BH1750, DS3231) generally never stretch.

What exactly is the Raspberry Pi clock-stretching bug?

The BCM283x hardware i2c controller samples SCL at fixed intervals instead of tracking the line's true release. If a device stretches at just the wrong moment, the controller clocks the next bit too early and the byte is corrupted — silently. It's a silicon quirk that's been present across Pi generations.

How do I work around it on the Pi?

Three options, in order of preference: pick a sensor that doesn't stretch; drop the baudrate hard (10 kHz makes the timing windows so wide most stretches fit); or bit-bang the bus with the software overlay dtoverlay=i2c-gpio, which respects stretching correctly at the cost of CPU time.

Is clock stretching allowed forever, or is there a timeout?

Bare i2c sets no limit — a hung target can stall the bus indefinitely, which is why controllers add their own timeouts. SMBus (the stricter PC cousin of i2c) caps stretches at 35 ms by spec.

Do bit-banged i2c libraries support clock stretching?

Not automatically — it depends entirely on how the code toggles SCL. A correct bit-bang implementation drives SCL low, releases it, then reads it back and waits until it actually goes high before continuing; that's what lets a target hold it down. A naive one just toggles the pin on a fixed delay without ever reading it back, which silently ignores stretching. The Linux kernel's own i2c-gpio driver (what dtoverlay=i2c-gpio loads) does this correctly — plenty of hand-rolled Arduino or microcontroller bit-bang code doesn't.