33  I2C Protocol

networking-core
wired
comm
i2c

33.1 Start With Many Chips Sharing Two Wires

I2C is useful because one controller can talk to many nearby devices using only SDA and SCL. The shared bus works only when addresses, pull-ups, capacitance, timing, and acknowledgements all stay inside the design limits.

Follow one read from controller to sensor and back. The story shows why a missing ACK, slow edge, duplicate address, or stretched clock is not a mystery; it is a specific bus promise being broken.

Key Concepts
  • I²C (Inter-Integrated Circuit): A two-wire synchronous serial bus using SDA (data) and SCL (clock) lines; supports multiple devices on the same bus with unique 7-bit or 10-bit addresses
  • Master/Slave Architecture: I²C uses a master device (typically a microcontroller) that initiates all transactions and one or more slave devices (sensors, ADCs) that respond
  • Open-Drain Signalling: I²C lines are open-drain; devices can only pull the line low; pull-up resistors (typically 4.7 kΩ) bring the line high when released
  • Address Conflict: Two I²C devices with the same address on the same bus cause communication failures; I²C address is typically fixed in hardware or set by address pins
  • Clock Stretching: A mechanism where a slave device holds SCL low to pause the master, giving the slave more time to prepare data
  • I²C Speed Modes: Standard mode (100 kbps), Fast mode (400 kbps), Fast-mode Plus (1 Mbps), High-speed mode (3.4 Mbps)
  • I²C Multiplexer: A device (e.g., TCA9548A) that allows multiple devices with the same I²C address to coexist on one bus by switching between sub-buses

33.2 In 60 Seconds

I2C (Inter-Integrated Circuit) is a 2-wire synchronous bus protocol using SDA (data) and SCL (clock) with pull-up resistors, supporting up to 112 usable devices on a single bus via 7-bit addressing (112 of the 128 possible addresses are available; 16 are reserved). It runs at 100 kHz (standard), 400 kHz (fast), or 3.4 MHz (high-speed) and is ideal for connecting multiple low-speed sensors and displays to a microcontroller with minimal wiring. Common issues include address conflicts, missing pull-ups, and clock stretching by slow devices.

Phoebe the physics guide

Phoebe’s Why

This chapter’s own \(R_{min}=(V_{DD}-V_{OL})/I_{OL}\) formula for the pull-up looks like plain Ohm’s law, but it is really a voltage divider in disguise. The pull-up resistor and the open-drain transistor pulling the line low sit in series between \(V_{DD}\) and ground, exactly like the two legs of any divider, and the bus’s LOW voltage \(V_{OL}\) is simply the voltage that divider leaves across the transistor’s own tiny on-resistance. Seen that way, the datasheet’s 0.4 V and 3 mA are not two independent numbers; they imply a maximum on-resistance for the pulling transistor, and the “safe” pull-up range this chapter derives is really the divider staying inside that resistance budget.

The Derivation

Treat the pulling transistor as a small on-resistance \(R_{on}\) in series with the pull-up, forming a divider across \(V_{DD}\):

\[V_{OL} = V_{DD}\,\frac{R_{on}}{R_{pu}+R_{on}}\]

The datasheet’s guaranteed sink rating implies a maximum on-resistance directly:

\[R_{on,max} = \frac{V_{OL,max}}{I_{OL,max}}\]

and current continuity around the same loop, \(I_{OL}=(V_{DD}-V_{OL})/R_{pu}\), reproduces this chapter’s own pull-up floor:

\[R_{pu,min} = \frac{V_{DD}-V_{OL,max}}{I_{OL,max}} \]

Worked Numbers: This Chapter’s Own 3.3 V, 0.4 V, 3 mA Spec

  • Implied transistor on-resistance: \(R_{on,max}=0.4/0.003=133\ \Omega\) – a number this chapter’s own \(R_{min}\) formula uses implicitly but never states
  • Self-consistency check: at the chapter’s own \(R_{pu,min}=967\ \Omega\) with \(R_{on}=R_{on,max}=133\ \Omega\), the divider gives \(V_{OL}=3.3\times133/(967+133)=0.400\) V – exactly the 0.4 V spec limit, confirming the “Ohm’s law” formula above is really this divider at its worst case
  • Margin at the common 4.7 k\(\Omega\) pull-up: even using the worst-case \(R_{on}=133\ \Omega\), \(V_{OL}=3.3\times133/(4700+133)=0.0910\) V – more than 4x below the 0.4 V spec, which is why 4.7 k\(\Omega\) never comes close to a LOW-level fault even though it sits well above this chapter’s own 967 \(\Omega\) floor

33.3 Learning Objectives

By the end of this section, you will be able to:

  • Explain I2C Architecture: Describe the two-wire bus structure with SDA and SCL, and justify why open-drain outputs require pull-up resistors
  • Calculate Pull-Up Resistor Values: Apply the RC rise-time formula to select appropriate resistor values for a given bus capacitance and speed mode
  • Distinguish I2C Addressing: Identify how 7-bit addresses map to write and read bytes, and select device addresses to avoid bus conflicts
  • Implement I2C Transactions: Explain the read and write transaction sequences (START, address frame, ACK, data, STOP) and translate them into test steps
  • Diagnose I2C Failures: Analyze bus-level symptoms — missing ACK, slow rise times, address conflicts, clock stretching — and identify their root causes
  • Build I2C Applications: Plan and verify sensor/display connections over a shared I2C bus before writing firmware

I2C (pronounced eye-squared-see) is a simple way to connect multiple sensors and chips using just two wires. Think of it as a shared phone line where each device has its own phone number – the main controller calls each device by its address and they take turns sharing information. It is one of the most common ways to connect sensors in IoT projects.

“I love I2C!” said Sammy the Sensor. “I only need two tiny wires – SDA for data and SCL for the clock – to talk to Max. And I am not alone on those wires. There can be up to 112 of us sensors sharing the same two wires!”

Max the Microcontroller explained how it works. “I am the master. When I want Sammy’s temperature reading, I send his address – say 0x48 – on the bus. Only Sammy responds. Then I send a request, and he sends back the data. Everyone else stays quiet because it was not their address.”

“The pull-up resistors are super important though,” warned Lila the LED. “The wires need them to work properly. If you forget the pull-ups, nothing talks! It is the number one beginner mistake with I2C. And sometimes two sensors accidentally have the SAME address – then you get conflicts.”

“I2C is not the fastest,” admitted Bella the Battery, “only 100 to 400 kHz for most IoT work. But it is incredibly simple – just two wires for dozens of sensors! Perfect for when you have a temperature sensor, a humidity sensor, a pressure sensor, and a display all connected to one microcontroller. Minimal wiring, maximum flexibility.”

33.4 Prerequisites

Before diving into this chapter, you should be familiar with:

  • Wired Communication Fundamentals: Understanding of synchronous communication, multi-drop topology, master-slave architecture
  • Digital Electronics: Understanding of open-drain outputs and pull-up resistors
Chapter Roadmap

Follow one shared I2C bus from wiring to release:

  1. First identify why SDA, SCL, open-drain outputs, and pull-ups make many devices share two wires.
  2. Then map each device to a unique address and translate the 7-bit address into write and read bytes.
  3. Next walk the START, ACK, repeated START, data, and STOP sequence that makes a real transaction work.
  4. After that use scanner and BME280 labs to turn bus symptoms into evidence.
  5. Finally calculate pull-up limits and build a reliability record for speed, capacitance, lockup, and recovery.

Checkpoints recap the main design decisions; collapsed material deepens the same path.


33.5 I2C Overview

Start with the physical promise: every device sees the same two wires, so the bus only works if each participant releases the lines and waits its turn.

I2C (IIC, I-squared-C) is a popular multi-device communication bus developed by Philips (now NXP) in the 1980s.

Pronunciation: “I-squared-C” or “I-two-C”

Full name: Inter-Integrated Circuit

33.5.1 Characteristics

Feature Value
Wires 2 only (SDA + SCL)
Topology Multi-drop (bus)
Sync/Async Synchronous (SCL = clock)
Duplex Half-duplex (SDA is bidirectional)
Speed 100 kHz (standard), 400 kHz (fast), 1 MHz (fast+), 3.4 MHz (high-speed)
Distance <1 meter (same PCB or short cable)
Devices Up to 112 (7-bit addressing) or 1024 (10-bit)
Master/Slave Multi-master capable

I2C physical wiring diagram showing SDA and SCL lines with pull-up resistors to VCC, connecting master and multiple slave devices in parallel bus configuration

I2C physical connections showing SDA and SCL with pull-up resistors
Figure 33.1: Physical I2C wiring: two lines (SDA and SCL) run across all devices on the bus. Pull-up resistors hold both lines HIGH by default; any device can pull a line LOW using its open-drain output.

33.7 I2C Signals

I2C bus wiring diagram showing SDA and SCL lines connecting one master microcontroller to multiple slave devices, with pull-up resistors on both lines to VCC, illustrating the multi-drop open-drain bus topology
Figure 33.2: I2C Bus Wiring with Pull-Up Resistors

SDA (Serial Data):

  • Bidirectional data line
  • Carries address and data
  • Open-drain (requires pull-up resistor)

SCL (Serial Clock):

  • Clock signal from master
  • Slaves can hold it LOW (“clock stretching”) to slow master
  • Open-drain (requires pull-up resistor)

33.8 Pull-Up Resistors

Critical requirement: Both SDA and SCL need pull-up resistors to VCC.

Typical values:

  • 4.7 kohm - Most common (400 kHz, few devices, short traces)
  • 2.2 kohm - For longer cables, many devices, or fast mode
  • 10 kohm - For very short cables, few devices, 100 kHz only

Why needed? I2C uses open-drain outputs - can only pull LOW, not HIGH. Pull-up resistors provide the HIGH level. See the detailed calculation in the Worked Example section for guidance on choosing the right value.


Packet PeteCheckpoint: Shared Bus Basics

You now know:

  • I2C gets its pin savings from two shared lines, SDA and SCL, rather than one private wire per peripheral.
  • Open-drain signalling means devices pull low or release; pull-up resistors create the high level.
  • That same sharing makes capacitance, pull-up strength, and bus length design constraints.

The wiring is only half the contract. Once every device is attached to SDA and SCL, the controller still needs a way to choose exactly one responder.

33.9 I2C Addressing

Each device on the bus needs a unique 7-bit address.

Address space:

  • 7-bit addresses: 0x08 to 0x77 (112 addresses)
  • Some addresses reserved (0x00-0x07, 0x78-0x7F)

Common I2C device addresses:

Device Address (Hex) Address (Decimal)
OLED Display (SSD1306) 0x3C or 0x3D 60 or 61
BME280 (Temp/Humidity) 0x76 or 0x77 118 or 119
MPU6050 (IMU) 0x68 or 0x69 104 or 105
RTC DS3231 0x68 104
EEPROM 24C256 0x50 - 0x57 80 - 87
Try It: I2C Address Frame Decoder

Finding device addresses:

Use an I2C scanner when a board powers up but a sensor library cannot find its device.

Step What you check Expected evidence
1. Power and ground Sensor VCC and GND match the controller voltage Sensor board powers on; no hot components
2. Bus wiring SDA to SDA, SCL to SCL, shared ground Scanner can probe the bus without lockup
3. Pull-ups SDA and SCL have pull-ups to the correct voltage Lines idle HIGH on a meter or oscilloscope
4. Address scan Probe addresses from 0x08 to 0x77 Known devices appear at their documented addresses
5. Conflict check Compare detected addresses against the design Duplicate addresses are resolved with address pins or a mux

Example scan result:

Detected address Likely device What to do next
0x3C OLED display Use the OLED library with address 0x3C.
0x76 BME280/BMP280 Use the sensor library with address 0x76.
No addresses Wiring, pull-up, or power problem Check SDA/SCL order, VCC, ground, and pull-up resistors.

33.10 I2C Communication Protocol

Artistic representation of I2C signal timing showing START condition (SDA falling while SCL high), data transmission with clock synchronization, ACK/NACK bits after each byte, and STOP condition (SDA rising while SCL high). Demonstrates master-controlled clock stretching by slow slave devices

I2C Signal Timing
Figure 33.3: I2C protocol timing: START and STOP conditions frame each transaction, with data sampled on SCL rising edge. The acknowledgment bit after each byte confirms successful reception.

Start and Stop Conditions:

Bus event SDA behavior SCL behavior Meaning
Idle bus HIGH HIGH Pull-up resistors are holding both lines released.
START HIGH to LOW Stays HIGH The controller claims the bus and begins a transaction.
Data bit Stable while sampled Pulses LOW/HIGH The receiver reads SDA while SCL is HIGH.
STOP LOW to HIGH Stays HIGH The controller releases the bus after the transaction.

Data Transfer (1 byte + ACK):

Phase Who drives SDA? What the receiver checks
8 data bits Transmitter Bits arrive MSB first while SCL pulses.
ACK clock Receiver Pulls SDA LOW for ACK, leaves it HIGH for NACK.
Next byte or STOP Controller Continues with another byte, a repeated START, or STOP.

Data transfer rules:

  • SDA can only change when SCL is LOW
  • SDA is sampled when SCL is HIGH
  • Data transmitted MSB first (most significant bit first)
Complete I2C transaction timing showing start condition, 7-bit slave address, R/W bit, acknowledge, data bytes with ACK after each byte, and stop condition for write and read operations
Figure 33.4: I2C communication protocol timing showing complete transaction

33.11 I2C Write Transaction

I2C write transaction sequence diagram showing master sending START condition, 7-bit slave address with write bit (0), register address byte, data byte, each followed by slave ACK, then STOP condition
Figure 33.5: I2C Write Transaction Sequence

Steps:

  1. Master sends START
  2. Master sends slave address + write bit (0)
  3. Slave acknowledges (ACK)
  4. Master sends register address
  5. Slave ACKs
  6. Master sends data byte
  7. Slave ACKs
  8. Master sends STOP

33.12 I2C Read Transaction

I2C read transaction sequence diagram showing master sending START, slave address with write bit, register address byte with ACK, then REPEATED START, slave address with read bit, slave sending data bytes, master sending NACK on last byte, then STOP condition
Figure 33.6: I2C Read Transaction with Restart Condition

Steps:

  1. Master sends START
  2. Master sends slave address + write bit (0)
  3. Slave ACKs
  4. Master sends register address to read from
  5. Slave ACKs
  6. Master sends REPEATED START (restart without releasing bus)
  7. Master sends slave address + read bit (1)
  8. Slave ACKs
  9. Slave sends data byte(s); master ACKs each except the last
  10. Master sends NACK on final byte (signals end of read)
  11. Master sends STOP

The Repeated START (step 6) is essential: it lets the master switch from write mode (selecting the register) to read mode (receiving data) without another device claiming the bus in between.


Packet PeteCheckpoint: Addressed Transactions

You now know:

  • A normal 7-bit bus uses usable addresses from 0x08 to 0x77, so duplicate module defaults must be planned before wiring.
  • Address 0x76 becomes 0xEC for the write phase and 0xED for the read phase because the direction bit is part of the first bus byte.
  • A register read is a two-phase exchange: write the register pointer, issue repeated START, then read the returned data before STOP.

With the bus grammar in place, the next question is practical: can the real board prove that those frames are reaching real devices?

33.13 Arduino/ESP32 I2C Example

The transaction diagrams and address explorer above are the beginner path. Use this sketch only when you are ready to test a real I2C sensor.

Task I2C concept being tested Success evidence
Wire SDA/SCL correctly Shared two-wire bus Scanner detects 0x68 or 0x69.
Wake the sensor Write transaction to a control register The device stops reporting sleep/default values.
Select the X-axis register Write phase before a register read Logic trace shows address + write, register byte, repeated START.
Read two data bytes Repeated START and read phase Two bytes arrive and combine into a signed acceleration value.
Repeat slowly first Stable bus before performance tuning Values update without missing ACKs or bus lockups.

ESP32 wiring reference:

ESP32 pin Sensor pin Note
GPIO 21 SDA Data line; add a pull-up if the sensor board lacks one.
GPIO 22 SCL Clock line; keep wires short for reliable fast mode.
3.3 V VCC Match the sensor module voltage.
GND GND All I2C devices need a shared ground.

33.14 Clock Stretching

Problem: Slave needs more time to process data.

Solution: Slave holds SCL LOW to pause communication.

Step What happens on SCL What the controller should do
Controller releases SCL SCL should rise HIGH Wait for the line to actually go HIGH.
Device needs more time Device holds SCL LOW Do not force the next clock edge.
Device finishes processing Device releases SCL Resume the transaction.
Timeout exceeded SCL remains LOW too long Reset or recover the bus.

Use case: Slow sensors (temperature readings take time), EEPROM write operations.


Practical Tips

Avoiding Address Conflicts:

  • Check device datasheets before buying
  • Many sensors have address select pins (A0, AD0) to change address
  • Use I2C scanner sketch to verify addresses
  • Plan device selection to avoid conflicts

Common Conflicts:

  • 0x68: MPU6050, DS1307/DS3231 RTC → Use MPU6050 AD0 pin for 0x69
  • 0x76/0x77: BMP280, BME280, BME680 → Use SDO pin
  • 0x27/0x3F: LCD backpack modules → Check board

Pull-up Resistors:

  • 4.7k: Most common (400 kHz)
  • 2.2k: Long cables or many devices
  • 10k: Short cables, few devices

Pull-up resistor values aren’t arbitrary—they’re calculated from RC time constant requirements.

For I2C fast mode (400 kHz), the rise time must be under 300 ns (from 0 V to 70% of VCC, the I2C sampling threshold). With typical bus capacitance \(C_{bus} = 50\) pF (3 devices + PCB traces):

\[t_r = 0.8473 \times R_{pull} \times C_{bus}\]

Solving for maximum resistance:

Step Value
Rise-time limit 300 ns
Bus capacitance 50 pF
Maximum pull-up 300 ns ÷ (0.8473 × 50 pF) = 7,080 Ω

The I2C spec also requires minimum current drive capability of 3 mA at 0.4 V LOW level. With 3.3 V supply:

Step Value
Available voltage across pull-up 3.3 V - 0.4 V = 2.9 V
Allowed sink current 3 mA
Minimum pull-up 2.9 V ÷ 0.003 A = 967 Ω

This gives a range of 967 Ω to 7,080 Ω for a 50 pF bus. The standard 4.7 kΩ falls well within this range—which is why it works reliably for most setups. With 100 pF bus capacitance (many devices or long traces), the maximum drops to ~3.5 kΩ, so 2.2 kΩ pull-ups are needed.


33.15 Hands-On Lab: I2C Scanner

Objective: Find all I2C devices connected to your ESP32/Arduino.

Stage Student action Evidence to record
Baseline Scan with no external sensor attached No unexpected addresses, or only built-in board devices.
Add display Connect SSD1306 OLED New address appears at 0x3C or 0x3D.
Add sensor Connect BME280/BMP280 New address appears at 0x76 or 0x77.
Conflict test Add a second device with the same address if available Scanner still shows one address, but both devices may respond at once.
Fix Change address pin or use an I2C multiplexer Each device becomes uniquely selectable.

Sample scan interpretation:

Scanner output Meaning Next action
0x3C, 0x76 OLED and BME280 are both visible Start the sensor/display application.
Only 0x3C Sensor not responding Check BME280 power, SDA/SCL order, and address pin.
No addresses Bus-level fault Check pull-ups, ground, VCC, and whether SDA/SCL are swapped.

33.16 Hands-On Lab: BME280 Temperature Sensor

Objective: Read temperature from BME280 sensor via I2C.

Stage What to do What success looks like
Confirm address Scan for 0x76 or 0x77 The address matches the sensor’s SDO pin setting.
Initialize driver Start the BME280 library with the detected address Startup message reports the sensor is ready.
Read slowly Request temperature, humidity, and pressure every 2 seconds Values change smoothly and remain physically plausible.
Compare environment Warm the sensor with your hand or move it near airflow Temperature/humidity respond in the expected direction.
Diagnose failure If readings fail, inspect bus and address first Most failures are wrong address, missing pull-ups, or swapped wires.
Symptom Likely cause Fix
“Sensor not found” Wrong address or wiring Try 0x76 and 0x77; recheck SDA/SCL and power.
Readings freeze Bus lockup or clock stretching timeout Slow the bus, shorten wires, and add bus recovery.
Values are unrealistic Wrong sensor/library mode Verify the exact BME280/BMP280 module and driver settings.

Packet PeteCheckpoint: Bring-Up Evidence

You now know:

  • A scanner proves address-level ACK behavior, not that every register read, sensor mode, or timeout path is correct.
  • A useful lab record names wiring, voltage, pull-ups, observed addresses, and one successful transaction before the driver is trusted.
  • If the same sensor appears only at a lower speed, the failure points toward timing, capacitance, pull-ups, or clock stretching rather than cloud or application code.

The labs show whether devices answer. The remaining design question is whether the electrical edge speed gives those answers enough timing margin.

33.17 Check I²C Arbitration

Check I²C Arbitration

Scenario: You’re designing a robotics platform with two microcontrollers (ESP32 and Arduino) that both need to control a shared OLED display (I2C address 0x3C) and BME280 sensor (0x76). Both MCUs operate as I2C masters on the same bus with 4.7k pull-ups.

Think about:

  1. What happens if both masters try to send a START condition simultaneously?
  2. Why doesn’t this cause electrical damage to the devices?

Key Insight: I2C uses wired-AND arbitration through open-drain outputs. When multiple masters transmit simultaneously, any device pulling SDA LOW wins (LOW overrides HIGH). During arbitration, masters compare transmitted bits to actual bus state:

  • Master transmits 1 (releases line HIGH)
  • Bus reads 0 (another master pulled LOW)
  • First master detects mismatch → backs off gracefully
  • No electrical conflict because open-drain outputs never drive HIGH (only pull LOW or float)

This elegant mechanism prevents bus damage. Push-pull outputs (like SPI) would short VCC to GND if two devices drive opposite levels, potentially destroying the chips. The trade-off: RC charging through pull-up resistors limits rise time, restricting I2C to ~400 kHz vs SPI’s 80+ MHz.

Verify Your Understanding:

  • Calculate arbitration delay: With 400 pF bus capacitance and 4.7 kΩ pull-ups, rise time = 0.8473 × 4,700 Ω × 400 pF = 1.59 µs. Since the I2C standard-mode clock period is 10 µs (100 kHz), this rise time is marginal; for reliable multi-master operation at 400 kHz (2.5 µs period), the rise time budget of 300 ns would be exceeded—requiring 2.2 kΩ pull-ups or reducing bus capacitance.
  • Why faster rise times require smaller pull-ups: At 100 kHz (standard mode), 10k resistors work. At 400 kHz (fast mode), 2.2k needed for adequate rise time.

33.18 Quiz: I2C Protocol

Quiz Questions


Complete I2C protocol overview showing physical layer (two-wire bus), data layer (address frame with R/W bit, data frames with ACK), and logical layer (master-slave communication with clock stretching and arbitration for multi-master scenarios)

I2C Protocol Overview
Figure 33.7: I2C provides a simple, efficient interface for connecting low-speed peripherals like sensors, EEPROMs, and displays. Its two-wire design minimizes PCB routing complexity while supporting multiple devices.

33.19 Calculate Pull-Up Resistors

Choosing the right pull-up resistor value is the single most common source of I2C failures. Too high and the bus cannot rise fast enough; too low and the devices cannot sink enough current to pull the bus low.

The constraints:

  1. Minimum resistor (max current): I2C spec limits sink current to 3 mA at VOL = 0.4 V. With 3.3 V supply: R_min = (VDD - VOL) / Isink = (3.3 - 0.4) / 0.003 = 967 Ω ≈ 1 kohm
  2. Maximum resistor (rise time): The bus must rise from 0V to 70% of VCC within the rise time specification. Rise time depends on bus capacitance.

Rise time formula:

\[t_r = 0.8473 \times R_{pull} \times C_{bus}\]

Where the maximum rise time is 1000 ns for standard mode (100 kHz) and 300 ns for fast mode (400 kHz).

Calculating bus capacitance:

Capacitance source Typical value Example contribution
Controller SDA/SCL input 5-10 pF ESP32 pins: 10 pF
Sensor/display input 5-10 pF each BME280: 5 pF; SSD1306: 8 pF
PCB trace 1-2 pF/cm 15 cm trace at 2 pF/cm: 30 pF
Jumper wires 50-100 pF/m Keep jumpers short for fast mode
Example total Sum all connected loads ESP32 + BME280 + SSD1306 + trace ≈ 53 pF

Maximum resistor for 400 kHz (fast mode):

Calculation step Value
Fast-mode rise-time limit 300 ns
Estimated bus capacitance 53 pF
Denominator 0.8473 × 53 pF = 44.9 pF
Maximum pull-up value 300 ns ÷ 44.9 pF = 6.68 kohm

Result: For this 3-device bus at 400 kHz, use pull-ups between 967 Ω and 6.68 kohm. The standard 4.7 kohm falls comfortably in the middle – which is why 4.7 kohm is the universal default recommendation.

When 4.7 kohm does NOT work:

Scenario Problem Fix
Long cable (>30 cm) Bus capacitance >200 pF, rise time too slow at 4.7k Use 2.2 kohm or reduce speed to 100 kHz
Many devices (>8) Combined capacitance >100 pF Use 2.2 kohm pull-ups
3.3V bus with 5V tolerant device Logic thresholds mismatch Use level shifter, not just pull-up changes
High-speed mode (3.4 MHz) Rise time budget only 40 ns (≤ 100 pF load); passive pull-ups cannot charge fast enough Use current-source active pull-ups; passive resistors cannot meet the HS-mode rise-time spec
Breadboard prototype Breadboard adds 20-50 pF per row Use 2.2 kohm and limit to 100 kHz

Debugging tip: If I2C works intermittently or only at 100 kHz but fails at 400 kHz, the pull-up resistor value is almost always the cause. An oscilloscope on SDA/SCL will show rounded rising edges (too slow) or ringing (too fast), confirming the diagnosis.

Try It: I2C Pull-Up Resistor Calculator
Packet PeteCheckpoint: Pull-Up Window

You now know:

  • Pull-ups are a range, not a default copied blindly from a breakout board.
  • For the worked 3.3 V, 53 pF, 400 kHz example, the safe window is about 967 ohm to 6.68 kohm, which explains why 4.7 kohm is usually comfortable.
  • When the bus gets longer or gains devices, check the rise-time budget before changing firmware delays or sensor libraries.

Common Pitfalls

Pull-up resistors that are too weak (>10 kΩ) cause slow rising edges that fail at higher speeds. Resistors too strong (<1 kΩ) consume excessive power and may damage open-drain outputs. Fix: calculate the pull-up value based on bus capacitance and target speed; 4.7 kΩ is a safe default for 100 kbps on short buses.

Adding a second I²C temperature sensor with the same address as the first causes them to respond simultaneously, corrupting data. Fix: check address settings (hardware address pins or software configuration) before combining multiple devices of the same type on one bus.

A power glitch during an I²C transaction can leave the SDA line stuck low, locking the bus. The master cannot reset the bus without clocking SCL 9 times to free the stuck slave. Fix: implement a bus recovery routine in firmware that generates 9 SCL pulses to reset any locked slave device.

33.20 Label the Diagram

33.21 Code Challenge

33.22 I2C Shared-Bus Reliability Record

I2C works because every device shares the same two wires and follows the same electrical rule: devices may pull SDA or SCL low, but pull-up resistors bring the lines high again. That makes the bus simple, but it also means one wrong device, weak pull-up, duplicate address, voltage mismatch, or stuck line can affect every device on the bus. The firmware call that says read register 0xF7 from address 0x76 only succeeds when the physical bus, address phase, ACK bits, timing, and recovery assumptions all hold together.

Good I2C design is therefore not just picking a library. It is a bus health record: addresses are unique, pull-ups fit the capacitance and speed, voltage levels match, transactions ACK, and firmware can recover when a slave leaves SDA low. That record matters most in IoT nodes where several low-speed parts share the bus: a BME280 sensor, an EEPROM, a real-time clock, and an OLED display may all look independent in software, but electrically they are attached to the same SDA/SCL pair.

The overview decision is whether the bus boundary is appropriate for the job. I2C is a strong fit for short, local, board-level communication where the controller owns the transaction schedule and peripherals are close enough that capacitance stays controlled. It becomes fragile when a design treats it like an installation cable, mixes voltage domains casually, hides duplicate fixed addresses behind library defaults, or adds modules until the pull-ups can no longer produce clean edges at the chosen speed.

I2C transaction sequence showing START, address, ACK, register data, repeated START, read data, NACK, and STOP phases across shared SDA and SCL lines

I2C transaction sequence showing START, address, ACK, register data, repeated START, read data, NACK, and STOP phases across shared SDA and SCL lines
Figure 33.8: I2C reliability is built from linked layers: shared open-drain wiring, an address byte with a read/write bit, ACK slots after each byte, and transaction framing with START, repeated START, and STOP conditions.

Two shared wires: SDA carries address and data. SCL provides timing. Every attached device sees both lines, so wiring length, module count, connector quality, and breadboard capacitance accumulate into one bus limit.

Open-drain signalling: Devices only pull low. Pull-ups create high levels, set rise time, and determine whether standard mode, fast mode, or Fast-mode Plus is realistic for the assembled hardware.

Addressed turns: Only the addressed device should ACK and respond. Duplicate fixed addresses make two devices answer at once; reserved addresses and shifted address bytes create equally confusing scanner results.

Core trade-off: I2C saves pins and wiring, but it trades that simplicity for shared-bus limits: short distance, bounded capacitance, unique addresses, voltage-domain discipline, and careful recovery from stuck or slow devices. When those limits are too tight, the engineering fix is usually to slow the bus, split it, add a TCA9548A-style multiplexer, move a noisy or distant device to another interface, or change the board layout before firmware workarounds hide a fragile design.

33.23 I2C Bring-Up Record

A reliable I2C build has a short verification record before firmware assumptions harden. The record proves the physical wiring, electrical timing, address map, and recovery behavior under the target clock speed. Start it before sensor-driver integration: record the board voltage, the microcontroller pins assigned to SDA and SCL, the pull-up source, the expected device addresses, and the clock rate that the final product will use.

The practitioner mistake is to treat an I2C scanner result as complete proof. A scan only proves that some device pulled ACK during the address phase. It does not prove the register map is correct, that read/write bytes are formed correctly, that clock stretching is handled, that the bus survives reset timing, or that the same wiring will work at 400 kHz after all devices and cables are installed.

Check What to record Failure it catches
Physical path Controller pins, connector order, shared ground, VDD, level shifter if used, and the final cable or PCB route Swapped SDA/SCL, floating ground, 5 V sensor on a 3.3 V bus, or breadboard-only success
Address scan Observed 7-bit addresses, expected devices, and any reserved or duplicate addresses Wrong address constants, duplicate modules, or missing devices
Pull-up range VDD, estimated capacitance, selected resistor, target speed, and measured rise time when possible Slow edges at 400 kHz or excessive sink current from too-strong pull-ups
Transaction proof START, address byte, ACK, register select, repeated START, read/write data, and STOP behavior Sending the unshifted address byte, missing ACKs, or incorrect read/write direction
Recovery path Bus timeout, nine SCL recovery pulses, device reset behavior, and retry limit Firmware hanging forever after a power glitch or stuck SDA line
Release condition Pass/fail evidence at the final speed with all sensors, display modules, and enclosures connected A prototype that works on the bench but fails after the production harness or housing is fitted

Before coding: Confirm voltage compatibility, shared ground, pull-ups, address pins, and cable length. These are hardware facts, not software preferences, and they should be visible in the schematic or bring-up log before the first driver abstraction is trusted.

During bring-up: Run a scanner, then capture at least one successful register read and one expected failure path such as no device at an unused address. Use the device datasheet register, not only a high-level sensor library example.

Before release: Test at the final clock speed with all devices attached, then verify timeout and bus-recovery code instead of assuming the library handles lockup. Repeat after warm reset and power interruption because stuck-SDA faults often appear during startup sequencing.

Escalation trigger: If the design needs long cables, many devices, high speed, or duplicate fixed addresses, add a multiplexer, reduce speed, split the bus, or choose a more suitable wired interface. For field wiring or noisy industrial cabinets, I2C is usually the wrong boundary; use it inside a board or short enclosure run, then bridge to CAN, RS-485, Ethernet, or a wireless link as the installation distance grows.

33.24 Rise Time Sets the Real I2C Speed

I2C looks digital in code, but the rising edge is analog. The line rises through a resistor into the total bus capacitance, so more devices, longer traces, jumpers, and breadboards all slow the transition from low to high. The receiver samples logic levels at clocked moments; if the edge is still rising, the bus can fail only at higher speed or only with every device attached. This is why the NXP I2C-bus timing limits specify rise-time budgets, not just clock rates.

The useful mental model is an RC charge curve. With a larger pull-up resistor, the device sinks less current when it pulls low, but the high transition is slower. With a smaller pull-up, the edge is faster, but every device must be able to pull the line below the valid-low threshold while sinking the extra current. A design that moves from 4.7 kohm to 2.2 kohm may fix a 400 kHz rise-time failure, but it also changes power and VOL margin.

Addressing and timing failures often look similar from firmware: a missing ACK. The debug path is to separate causes. If an address scan finds nothing, check power, ground, pull-ups, voltage, and address shifting. If a device appears at 100 kHz but fails at 400 kHz, inspect rise time and capacitance. If the bus hangs after resets, implement recovery pulses and timeouts before retrying the transaction.

The same physical rule explains multi-master arbitration. Each controller watches SDA while transmitting; if it releases the line high but another controller pulls it low, it has lost arbitration and must stop driving. That wired-AND behavior prevents direct output contention, but it does not make multi-master systems automatically simple. The software still needs ownership rules, bounded retries, and logging that distinguishes arbitration loss from a missing slave ACK.

Rise-time limit: The pull-up resistor and bus capacitance define whether the line reaches a valid high level before the next clock sample. Fast mode leaves far less time for the same edge than standard mode.

Clock stretching: A slave may hold SCL low while it prepares data. Firmware must tolerate this within a bounded timeout, and the timeout should be measured against the slowest real device on the bus.

Bus lockup: A reset or interrupted transaction can leave SDA low. The master needs an explicit recovery sequence, commonly clocking SCL until the slave releases SDA, then issuing STOP and reinitializing the peripheral.

Debug sequence: Probe idle levels first: both SDA and SCL should sit high at the correct voltage. Then check a START condition, the shifted address byte, and the ACK slot. Only after the electrical and frame evidence is clean should the investigation move to driver configuration, register addresses, or application-layer parsing.

33.25 Knowledge Check

33.26 Summary

This chapter covered I2C (Inter-Integrated Circuit) protocol:

  • Two-wire bus (SDA for data, SCL for clock) supports multiple devices
  • Open-drain outputs with pull-up resistors (typically 4.7k) enable multi-master operation
  • Pull-up value depends on bus capacitance – 4.7k works for most setups, use 2.2k for long cables or many devices
  • 7-bit addressing allows up to 112 devices on a single bus
  • Synchronous protocol with master-controlled clock and optional clock stretching
  • Half-duplex communication with START, STOP, and ACK/NACK conditions
  • Common devices: Temperature sensors (BME280), displays (SSD1306), IMUs (MPU6050), RTCs (DS3231)

33.27 What’s Next

Topic Chapter Description
Wired Protocol Foundations Wired Communication Fundamentals Review synchronous vs asynchronous, open-drain topology, and master-slave architecture before moving to SPI
High-Speed Peripherals SPI Protocol Learn the 4-wire full-duplex SPI bus used for SD cards, displays, and ADCs that need speeds far beyond I2C’s 3.4 MHz limit
Long-Distance Serial UART and RS-232 Serial Communication Explore point-to-point asynchronous serial communication used for GPS modules, debug consoles, and PC interfaces
Wired Protocol Survey Wired Communication Protocols Compare I2C, SPI, UART, CAN, and 1-Wire side-by-side to select the right protocol for your IoT design
LAN Connectivity Wired Access: Ethernet Extend from chip-level buses to LAN-scale wired networking with Ethernet, switches, and IEEE 802.3 standards
Protocol Stack Context OSI and TCP/IP Layered Models Situate I2C at the physical and data-link layers of a full networking stack to understand how it fits into larger IoT architectures

33.28 Key Takeaway

I2C is useful for short, shared-board communication, but pull-ups, bus capacitance, addressing, clock speed, and stuck-bus recovery limit how far it can stretch.