31 I2C: Bring-Up and Diagnosis
More
Depth: Practitioner
Progress saves as you read. Mark sections complete as you go; your progress appears in the sidebar.
31.1 Start With the Situation
This section: Start With the Situation — The bus rules are known, but a real sensor still may not answer.
The bus rules are known, but a real sensor still may not answer. The team must run a repeatable bring-up, inspect timing and pull-ups, and separate address, wiring, arbitration, and device faults.
31.2 Overview
This section: Overview — This route turns I2C theory into sensor bring-up and fault diagnosis evidence.
This route turns I2C theory into sensor bring-up and fault diagnosis evidence.
This is part 2 of 2. Review I2C: Transactions and Bus Design when you need the first route.
31.3 Learning Objectives
This section: Learning Objectives
By the end of this chapter, you will be able to:
- bring up a BME280 on an I2C bus
- diagnose pull-up and clock-stretching failures
- verify arbitration and transaction evidence
| 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. |
This section:
Checkpoint: 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.
This section: — The labs show whether devices answer.
The labs show whether devices answer. The remaining design question is whether the electrical edge speed gives those answers enough timing margin.
31.4 Check I²C Arbitration
This section: 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:
- What happens if both masters try to send a START condition simultaneously?
- 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 mechanism avoids the direct high-versus-low driver contention that push-pull outputs could cause if wired together incorrectly. The trade-off is that RC charging through pull-up resistors limits rise time. Standard-mode I2C reaches 100 kHz and Fast-mode reaches 400 kHz; supported devices and bus conditions can also permit Fast-mode Plus at 1 MHz or High-speed mode at 3.4 MHz. SPI’s push-pull lines commonly run at tens of MHz.
Verify Your Understanding:
- Check rise time, not arbitration delay: with 400 pF bus capacitance and 4.7 kΩ pull-ups, the 30%-to-70% rise time is 0.8473 × 4,700 Ω × 400 pF = 1.59 µs. This exceeds Standard-mode’s 1.0 µs limit and Fast-mode’s 0.30 µs limit. Even 2.2 kΩ gives 0.746 µs at 400 pF, still too slow for Fast-mode; reduce capacitance or choose a pull-up within the device’s sink-current limit.
- Smaller pull-ups give faster rise times, but no fixed resistor works for every bus. At 100 pF, 10 kΩ gives 0.847 µs and meets the Standard-mode rise-time limit; at the same load, 2.2 kΩ gives 0.186 µs and meets Fast-mode’s limit if the connected devices can sink the resulting current.
31.5 Quiz: I2C Protocol
This section: Quiz: I2C Protocol — Read Figure 31.1 to check the three levels these questions draw on: the wiring, the address byte, and what happens when the bus is shared.
Read Figure 31.1 to check the three levels these questions draw on: the wiring, the address byte, and what happens when the bus is shared.
The physical band shows one SDA and SCL pair reaching an Arduino controller and two devices, a sensor at 0x76 and a display at 0x3C. Only the device whose address matches answers, and the other ignores the transaction. The data band works that address into a byte. The 7-bit address is doubled and the read/write bit is added, so 0x76 becomes 0xEC to write and 0xED to read, with an acknowledge after each byte. The shared-bus band at the foot of Figure 31.1 covers the rest. A device can hold the clock low to buy time, and a controller that loses arbitration backs off.
31.6 Calculate Pull-Up Resistors
This section: Calculate Pull-Up Resistors — Choosing the right pull-up resistor value is the single most common source of I2C failures.
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:
- Minimum resistor (max current): For this Standard/Fast-mode example, use a device rated to sink 3 mA while keeping V
OLat or below 0.4 V. With 3.3 V supply: R_min = (VDD- VOL) / Isink= (3.3 - 0.4) / 0.003 = 967 Ω ≈ 1 kohm. Check the actual devices’ limits. - Maximum resistor (rise time): The specified rise-time interval is from 30% to 70% of VCC. Rise time depends on bus capacitance.
Rise time formula:
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.3 V, 53 pF bus at 400 kHz, the calculated pull-up window is 967 Ω to 6.68 kohm. The common 4.7 kohm default falls inside this window, which is why it works for most short buses; recheck if capacitance grows.
When 4.7 kohm does NOT work:
| Scenario | Problem | Fix |
|---|---|---|
| Longer cable | Cable adds capacitance that depends on its construction; at 4.7 kohm the rise time can fail | Use 2.2 kohm (above the 967 Ω floor) or reduce speed to 100 kHz; check total capacitance |
| Many devices (>8) | Each pin can add up to 10 pF (UM10204 Ci), pushing the bus over its capacitance budget | Use 2.2 kohm pull-ups after checking the total load |
| Mixed voltage domains | A device’s input or output limits do not match the bus voltage | Check both datasheets; use a suitable level shifter when required |
| High-speed mode (3.4 MHz) | SCLH rise is 10–40 ns at 100 pF; SDAH has its own rise-time limit | The active Hs controller’s current-source pull-up drives SCLH; SDAH uses Rp |
| Breadboard prototype | Added contacts and jumpers raise capacitance | Use 2.2 kohm and 100 kHz; measure rise time on the assembled bus |
Debugging tip: If I2C works at 100 kHz but fails at 400 kHz, the pull-up/capacitance rise time is the most common cause; also check clock stretching and device speed support. A scope shows rounded edges (too slow) or ringing.
This section:
Checkpoint: 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.
This section:
Common Pitfalls
This section: 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. If SDA is stuck LOW while SCL can toggle, the controller should send nine SCL pulses; if SDA remains LOW, reset the device or cycle power. Fix: implement a bus recovery routine in firmware that generates 9 SCL pulses to reset any locked slave device.
31.7 Label the Diagram
This section: Label the Diagram
31.8 Code Challenge
This section: Code Challenge
31.10 I2C Bring-Up Record
This section: I2C Bring-Up Record — A reliable I2C build has a short verification record before firmware assumptions harden.
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.
31.11 Rise Time Sets the Real I2C Speed
This section: Rise Time Sets the Real I2C Speed — I2C looks digital in code, but the rising edge is analog.
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.
31.12 Knowledge Check
This section: Knowledge Check
31.13 Summary
This section: 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)
31.14 What’s Next
This section: 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 |
31.15 Key Takeaway
This section: 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.
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.
Find help
3 reviewed answers.
Where should I start in a module?
Open the module page from the sidebar to see its chapters in order. Use the module map to return to a topic you need.
Modules and pathsReviewed
What can I try when a project does not work?
Check the symptom, then work through the diagnostic steps. Keep the error message and the smallest example that reproduces it.
When you are stuckReviewed
How do interactive examples work?
Use the interactive guide to check how examples and simulations work before changing your project.
Interactive examples guideReviewed
