Loading header...

I²C — Inter-Integrated Circuit

I²C (pronounced "eye-squared-see", also written IIC or TWI) solves a specific problem: how do you connect many devices using as few wires as possible?

  • UART needs 2 wires per device
  • SPI needs 4 wires plus one extra chip-select wire per slave
  • I²C connects up to 127 devices using just 2 shared wires

That is the entire reason I²C exists — maximum devices, minimum wires.


The Core Idea — Every Device Has an Address

Instead of a chip-select wire for each device, I²C uses addresses. Every I²C device has a built-in 7-bit address assigned by its manufacturer. The master puts this address on the bus at the start of every message. Every device on the bus hears it, but only the one with the matching address responds. All others stay silent.

flowchart TD classDef master fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef slave fill:#dcfce7,stroke:#16a34a,color:#14532d classDef bus fill:#fef9c3,stroke:#ca8a04,color:#713f12 M["Master (MCU)\nSends address on bus\nbefore every message"]:::master BUS["SDA + SCL\n(just 2 wires shared by everyone)"]:::bus S1["MPU-6050\nAddress: 0x68\n'That's me!'"]:::slave S2["BMP280\nAddress: 0x76\n'Not me — staying quiet'"]:::slave S3["SSD1306\nAddress: 0x3C\n'Not me — staying quiet'"]:::slave M --> BUS BUS --> S1 BUS --> S2 BUS --> S3

The Two Wires

I²C uses only two signal wires:

Wire Name Purpose
SDA Serial Data Carries the actual data bits
SCL Serial Clock Clock pulses generated by the master

Both wires are shared by every device on the bus.


Open-Drain and Pull-up Resistors

I²C uses a special electrical design called open-drain. No device is allowed to actively push the line HIGH. Instead, resistors (connected to the power supply) hold both wires HIGH by default. Any device can pull a wire LOW, but only the resistors can release it back to HIGH.

flowchart TD classDef pwr fill:#fee2e2,stroke:#dc2626,color:#7f1d1d classDef res fill:#fef9c3,stroke:#ca8a04,color:#713f12 classDef bus fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef dev fill:#dcfce7,stroke:#16a34a,color:#14532d VCC["3.3V or 5V power supply"]:::pwr R1["4.7kΩ pull-up\nresistor"]:::res R2["4.7kΩ pull-up\nresistor"]:::res SDA["SDA wire\n(shared by all)"]:::bus SCL["SCL wire\n(shared by all)"]:::bus D1["Device 1"]:::dev D2["Device 2"]:::dev D3["Device 3"]:::dev VCC --> R1 --> SDA VCC --> R2 --> SCL SDA --> D1 SDA --> D2 SDA --> D3 SCL --> D1 SCL --> D2 SCL --> D3

How a Full I²C Transaction Works

Every I²C message follows this exact structure:

sequenceDiagram participant M as Master participant B as Bus (everyone hears this) participant S as Slave at 0x68 M->>B: START condition (SDA drops while SCL is HIGH) Note over B: All slaves wake up and listen M->>B: Address byte: 0x68 + Write bit B->>S: "Is that your address?" S->>M: ACK (pulls SDA LOW for 1 clock = "yes, that's me") M->>B: Register address byte (which register to write/read) S->>M: ACK ("got it") M->>B: Data byte (what to write into that register) S->>M: ACK ("received") M->>B: STOP condition (SDA rises while SCL is HIGH) Note over B: Transaction complete, bus is free

START and STOP — The Handshake Signals

These two special conditions are how the master announces it is starting or finishing a message. They are distinguished by what happens on SDA while SCL is HIGH — which is normally forbidden during data transfer.

flowchart LR classDef start fill:#fee2e2,stroke:#dc2626,color:#7f1d1d classDef stop fill:#dcfce7,stroke:#16a34a,color:#14532d START["START condition\n─────────────────\nSCL is HIGH\nSDA goes HIGH → LOW\n\n'I am about to talk'"]:::start STOP["STOP condition\n─────────────────\nSCL is HIGH\nSDA goes LOW → HIGH\n\n'I am done talking'"]:::stop START --> STOP

Between START and STOP, data bits are only allowed to change when SCL is LOW.


The Address Byte — Who Are You Talking To?

The very first byte after START is always the address byte. It contains two pieces of information packed together:

flowchart LR classDef addr fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef rw fill:#fee2e2,stroke:#dc2626,color:#7f1d1d A["7-bit device address\n(bits 7 down to 1)\ne.g. 0x68 = 1101000"]:::addr RW["R/W̄ bit\n(bit 0)\n0 = I want to WRITE\n1 = I want to READ"]:::rw A --> RW

So if you want to write to an MPU-6050 (address 0x68), the address byte is 0x68 shifted left by 1, with a 0 on the end = 0xD0.
If you want to read from it, shift left and add 1 = 0xD1.


ACK and NACK — Did You Get That?

After every single byte (including the address byte), the receiver must confirm it got the byte. It does this by pulling SDA LOW for one clock pulse = ACK (acknowledged). If SDA stays HIGH = NACK (not acknowledged).

flowchart TD classDef ack fill:#dcfce7,stroke:#16a34a,color:#14532d classDef nack fill:#fee2e2,stroke:#dc2626,color:#7f1d1d ACK["ACK — SDA pulled LOW by receiver\n─────────────────────────────────\nMeans: 'I got that byte, keep going'\nSlave sends ACK after address match\nSlave sends ACK after data received\nMaster sends ACK after each read byte (more bytes coming)"]:::ack NACK["NACK — SDA stays HIGH\n─────────────────────────────────\nMeans one of three things:\n• No device at that address (wrong address)\n• Device busy or not ready\n• Master is done reading (after last byte)"]:::nack ACK --> NACK

Writing to a Device — What the Master Does

Example: writing a value to a configuration register on a sensor.

want to write to sensor at address 0x68:

  send START
  send address byte  →  0x68 + write bit
  wait for ACK       →  slave confirms it heard
  send register byte →  which register to configure (e.g. 0x1A)
  wait for ACK       →  slave confirms
  send data byte     →  the value to write (e.g. 0x03)
  wait for ACK       →  slave confirms
  send STOP
  done

Reading from a Device — What the Master Does

Reading is slightly more complex because you first need to tell the device which register you want to read, then switch direction and actually read it.

sequenceDiagram participant M as Master participant S as Slave (0x68) M->>S: START + address 0x68 + WRITE S->>M: ACK M->>S: Register number to read from (e.g. temperature register) S->>M: ACK Note over M,S: Repeated START — change direction without releasing bus M->>S: START + address 0x68 + READ S->>M: ACK S->>M: Sends data byte 1 M->>S: ACK (I want more bytes) S->>M: Sends data byte 2 M->>S: NACK (I'm done, stop sending) M->>S: STOP

The Repeated START (sending another START without a STOP in between) is how the master switches from writing to reading without releasing the bus.


I²C Speeds

Mode Speed Common use
Standard 100 kHz Most sensors, EEPROMs, RTCs
Fast 400 kHz When 100k is too slow
Fast-mode Plus 1 MHz High-speed modern sensors

The speed is set on the master by configuring how quickly it generates clock pulses. Slower is always safer — if a device is misbehaving, try dropping to 100 kHz.


I²C Address Conflicts

Many sensors of the same type share the same default address. Two BMP280 pressure sensors would both be at 0x76 — they would both respond at the same time and corrupt each other's data.

flowchart TD classDef prob fill:#fee2e2,stroke:#dc2626,color:#7f1d1d classDef sol fill:#dcfce7,stroke:#16a34a,color:#14532d PROB["Problem:\nTwo identical sensors,\nboth at address 0x76"]:::prob S1["Solution 1 — Address pin\nMany chips have an ADDR pin\nTie it HIGH → address changes (e.g. 0x77)\nTie it LOW → stays at default (0x76)\nNow you have 0x76 and 0x77 — no conflict"]:::sol S2["Solution 2 — I²C Multiplexer (TCA9548A)\nA special chip that acts like a switch\nConnect 8 buses to it\nMaster tells it 'switch to bus 3'\nNow only devices on bus 3 are reachable\nUse this when address pins aren't enough"]:::sol S3["Solution 3 — Use SPI instead\nIf the device supports both SPI and I²C\nSwitch it to SPI mode and use chip-select\nNo address conflicts possible"]:::sol PROB --> S1 PROB --> S2 PROB --> S3

Common I²C Devices

Device Address What it does
MPU-6050 0x68 or 0x69 3-axis accelerometer + gyroscope
BMP280 0x76 or 0x77 Barometric pressure + temperature
SSD1306 0x3C or 0x3D 128×64 OLED display
DS3231 0x68 Real-Time Clock
AT24C32 0x50–0x57 32 Kbit EEPROM
ADS1115 0x48–0x4B 16-bit 4-channel ADC
PCF8574 0x20–0x27 8-bit GPIO expander

Practical Tips

  • No pull-up resistors = nothing works at all — this is the #1 cause of I²C not working
  • Run a bus scanner first — before writing any device-specific code, find out which addresses actually respond on your bus. It confirms your wiring is correct
  • Address 0x68 conflict — both MPU-6050 and DS3231 use 0x68 by default. You cannot use both without using the address pin or a multiplexer
  • Keep wires short — I²C bus capacitance increases with wire length. Over 30 cm starts to get unreliable at 100 kHz; over 1 metre is risky
  • 4.7kΩ pull-ups are the safe default — at 400 kHz fast mode you can drop to 2.2kΩ for better signal shape

Previous: ← SPI — Serial Peripheral Interface