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.
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.
Pull-up resistors are not optional. Without them, SDA and SCL will float at random voltages and nothing will work. Most breakout sensor modules already include them. If using bare chips, you must add 4.7kΩ resistors from SDA to VCC and from SCL to VCC yourself.
How a Full I²C Transaction Works
Every I²C message follows this exact structure:
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.
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:
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).
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.
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.
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