Notes / Communication Protocols
I2C: many chips on two wires
Two wires (SCL and SDA), 7-bit addresses, ACK and pull-up resistors. How I2C, the standard for sensors, works and how to recover when it gets stuck.
Structure
Every chip shares two wires, SCL (clock) and SDA (data), and the wires are open-drain with pull-up resistors. Anyone can pull a line LOW, and when nobody pulls, the pull-up makes it HIGH.
One read
START → address (7 bits) + W → ACK → register number → ACK
→ repeated START → address + R → ACK → data → ACK … → last data → NACK → STOP
- ACK: the receiver pulls SDA LOW on the 9th clock to say "received"
- If no chip has that address a NACK comes back, which lets you check connections (an I2C scan)
Choosing pull-up resistors
| Too large | Too small |
|---|---|
| Slow rising edges that fail at high speed | Exceeds the current a chip can sink when pulling LOW |
4.7 to 10 kΩ is typical for 100 kHz and 2.2 to 4.7 kΩ for 400 kHz. If the bus capacitance (wire length, number of chips) is large, go smaller.
Clock stretching
A slave that is not ready can hold SCL LOW to make the master wait.
When the bus hangs
If the MCU resets in the middle of a transfer, a slave can be left holding SDA LOW. Add bus recovery code that toggles SCL nine times as a GPIO at start-up to free the slave.
In a picture: start, address, ACK
Data changes only while SCL is LOW. SDA changes while SCL is HIGH in just two cases, start (falling) and stop (rising), so these two conditions can be told apart from data.
Open-drain and pull-ups
The two I2C lines are HIGH through the pull-up resistors when nobody pulls them. Devices can only pull LOW. So two devices driving at once never short, and a slave can hold SCL to make the master wait (clock stretching).
The pull-up value is set by the speed and the bus capacitance.
| Speed | Common values |
|---|---|
| 100 kHz | 4.7 kΩ to 10 kΩ |
| 400 kHz | 2.2 kΩ to 4.7 kΩ |
A large resistor lengthens the rise to HIGH and rounds the corners of the waveform. If the rising part looks like a gentle curve on the oscilloscope, reduce the resistor. When every module carries its own pull-ups, connecting several puts them in parallel and the value can become too small.
3D labRun what you have read so far→Reading a register takes two steps
// 1) a write tells the chip which register to read
// 2) a repeated start (start again without a stop), then read
i2c_start();
i2c_write((0x68 << 1) | 0); // address + write
i2c_write(0x3B); // register number
i2c_start(); // repeated start
i2c_write((0x68 << 1) | 1); // address + read
hi = i2c_read(ACK);
lo = i2c_read(NACK); // NACK on the last byte
i2c_stop();
7-bit and 8-bit addresses
If the datasheet says 0x68, that is the 7-bit address; on the wire it goes out shifted by one as 0xD0 (write) and 0xD1 (read). Some vendors write 0xD0 in their documents, so if there is no response, first try shifting the address one bit either way. Also check which form your library expects.
Code that revives a stuck bus
If the master resets while a slave is sending data, the slave waits for the next clock while holding SDA LOW. The master sees the bus as busy and cannot do anything.
// switch SCL to GPIO, clock it up to 9 times until the slave releases SDA, then issue a stop
for (int i = 0; i < 9 && !sda_read(); i++) { scl_low(); delay_us(5); scl_high(); delay_us(5); }
Product firmware must include this recovery code and a timeout on every I2C operation.
Problems that come up in practice
- An address scan finds nothing: check for missing pull-ups, swapped SDA and SCL, and missing power, in that order
- Two sensors with the same address: without an address-select pin you need an I2C multiplexer
- Long cables: the capacitance grows and 400 kHz becomes unstable. Lower the speed or use a buffer