56 I2C Protocol
56.2 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
For Beginners: The I2C Protocol
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.
Sensor Squad: The Two-Wire Wonder!
“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.”
56.3 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
56.4 I2C Overview
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
56.4.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 |
56.5 Why I2C is Popular
Advantages:
- Only 2 wires (minimal pin usage)
- Multiple devices on same bus
- Simple addressing (each device has unique address)
- Bidirectional (master can read/write to slaves)
- Well-supported by sensors, displays, EEPROMs
56.6 I2C Signals
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)
56.7 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.
56.8 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 |
Finding device addresses:
Optional I2C Scanner Checklist
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. |
56.9 I2C Communication Protocol
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)
56.10 I2C Write Transaction
Steps:
- Master sends START
- Master sends slave address + write bit (0)
- Slave acknowledges (ACK)
- Master sends register address
- Slave ACKs
- Master sends data byte
- Slave ACKs
- Master sends STOP
56.11 I2C Read Transaction
Steps:
- Master sends START
- Master sends slave address + write bit (0)
- Slave ACKs
- Master sends register address to read from
- Slave ACKs
- Master sends REPEATED START (restart without releasing bus)
- Master sends slave address + read bit (1)
- Slave ACKs
- Slave sends data byte(s); master ACKs each except the last
- Master sends NACK on final byte (signals end of read)
- 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.
56.12 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.
Optional MPU6050 Build Checklist
| 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. |
56.13 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
Putting Numbers to It
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.
56.14 Hands-On Lab: I2C Scanner
Objective: Find all I2C devices connected to your ESP32/Arduino.
Optional Scanner Lab Workflow
| 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. |
56.15 Hands-On Lab: BME280 Temperature Sensor
Objective: Read temperature from BME280 sensor via I2C.
Optional BME280 Lab Workflow
| 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. |
56.16 Knowledge Check: I2C Multi-Master Arbitration
Understanding Check: I2C Multi-Master 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 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.
56.17 Quiz: I2C Protocol
56.18 Worked Example: Pull-Up Resistor Calculation
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): 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
- 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.
Common Pitfalls
1. Using the Wrong Pull-Up Resistor Value
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.
2. Forgetting That I²C Devices Must Have Unique Addresses
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.
3. Not Handling I²C Bus Lockup in Firmware
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.
56.18.1 Label the Diagram
56.18.2 Code Challenge
56.19 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)
56.20 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 |