Learning Goals 5 min
UART is point-to-point — one sender, one receiver, two wires per direction. I²C is a multi-drop bus — one "controller" can talk to up to 127 different "peripherals" sharing the same two wires. That's how you can have an OLED, a temperature sensor, an RTC and a motion sensor all on the same SDA/SCL pair. By the end of this lesson you will:
- Name the two I²C wires (SDA, SCL), their roles, and explain why both need pull-up resistors.
- Walk through an I²C transaction on paper: start condition, 7-bit address + R/W bit, ACK, data bytes, stop condition.
- Look up the I²C address of three common classroom devices (OLED, BMP280, MPU-6050) and explain why two devices with the same default address can't share a bus without an address change.
Warm-Up 10 min
On your UNO, locate A4 and A5 on the analog header. Those are the UNO's hardware I²C pins:
- A4 = SDA (Serial DAta)
- A5 = SCL (Serial CLock)
The UNO also exposes them on a separate header just past the digital pins (labelled SDA/SCL) on R3 boards — the two headers are the same pins, electrically.
Three-question warm-up
- Why does UART need 2 wires per device (TX/RX), but I²C needs only 2 wires total for many devices?
- What advantage does having a shared clock wire (SCL) give over UART's asynchronous design?
- If everyone is on the same wire, how does device A know a message was meant for it and not device B?
Reveal
- I²C is half-duplex (only one direction at a time) and uses a shared data wire with arbitration rules. UART is full-duplex, so it needs separate wires for each direction.
- With a shared clock, both ends are timed by the same edges. No baud-rate mismatch possible. The receiver doesn't need to guess bit boundaries; they're obvious from the clock.
- Every transaction starts with the address of the target device. All devices "hear" the address but only the matching one responds. Like a hotel switchboard reading the room number before forwarding the call.
New Concept · The bus, the wires, the transaction 25 min
The two wires
| Wire | Role | UNO pin |
|---|---|---|
| SDA | Serial Data — bytes flow here, bidirectional | A4 (and the SDA header pin) |
| SCL | Serial Clock — pulses generated by the controller | A5 (and the SCL header pin) |
| GND | Common ground (every I²C device needs this) | any GND |
Two wires per bus, not per device. Wire SDA from the controller to all peripherals; same for SCL. Add as many devices as you like in parallel.
Pull-up resistors — mandatory
I²C is an open-drain bus. Each device can pull the wires down to GND, but cannot push them up to VCC. To make "HIGH" happen, an external pull-up resistor (typically 4.7 kΩ) sits between each wire and VCC. Without pull-ups, the wires never go above ~0 V and the bus doesn't work.
Most breakout boards (OLEDs, BME280s, ADXL345s) include pull-ups on board, so you usually don't add your own. But if your bus has only sensor chips and no breakouts, add a pair of 4.7 kΩ pull-ups between SDA/VCC and SCL/VCC.
The anatomy of one transaction
- START: controller pulls SDA LOW while SCL is still HIGH. (A "falling edge on SDA while SCL is HIGH" is the start signal — illegal at any other time, so it's unambiguous.)
- Address byte: 7 address bits + 1 R/W bit. R/W = 0 means controller will WRITE next; R/W = 1 means controller will READ next.
- ACK: the addressed peripheral pulls SDA LOW for one clock to acknowledge.
- Data byte(s): 8 bits at a time, each followed by an ACK from the recipient.
- STOP: controller releases SDA HIGH while SCL is HIGH. (A "rising edge on SDA while SCL is HIGH" — opposite of START.)
A typical "read a temperature from a BMP280" involves three transactions: WRITE the register number, then START again with a READ, then read the two bytes of the temperature.
Addresses — 7 bits = 128 possible, ~120 usable
The first 8 of the 128 addresses (0x00–0x07) are reserved by the I²C spec. The rest are first-come, first-served by chip manufacturers. Some are very popular and clash:
| Device | Default address | Alternate |
|---|---|---|
| SSD1306 OLED (128×64) | 0x3C | 0x3D (if a solder jumper is moved) |
| BMP280 (pressure/temp) | 0x76 | 0x77 (SDO pin to VCC) |
| MPU-6050 (IMU) | 0x68 | 0x69 (AD0 pin to VCC) |
| DS3231 RTC | 0x68 | (none — clashes with MPU-6050!) |
| PCF8574 I/O expander (LCD backpack) | 0x20–0x27 | set with three address-select pins |
The DS3231 + MPU-6050 clash is a classic: you cannot use both on the same I²C bus with default settings — you have to physically modify one to use its alternate address.
Speed
Three standard speeds:
- Standard mode: 100 kHz. The Arduino default. Works everywhere.
- Fast mode: 400 kHz. Most modern chips support this. Set with
Wire.setClock(400000). - Fast mode plus: 1 MHz. Niche; few cheap chips.
Slower than SPI (next lesson) but faster than UART at typical baud rates. Plenty for sensors and small displays.
Worked Example · Decode a transaction on paper 20 min
You won't wire anything today (we'll plug devices in tomorrow). Today we trace what would happen on the wires when you ask an OLED "clear yourself".
Scenario
SSD1306 OLED at address 0x3C. The "clear display" command is one byte: 0xAE (turn off) — well actually the real init sequence is many bytes; for our trace we'll send one command byte.
Step 1 — START
Both wires were idle (HIGH). The controller pulls SDA LOW first, then pulls SCL LOW. Clock now starts toggling.
Step 2 — Send address byte 0x3C with R/W = 0 (write)
0x3C = 0b0111100. Shift left one bit and append R/W: 0b01111000 = 0x78. That's the byte that actually goes on the wire.
The controller pulses SCL 8 times. On each clock pulse, the wire briefly has the correct data bit on it: 0, 1, 1, 1, 1, 0, 0, 0 (MSB first, unlike UART's LSB-first).
Step 3 — ACK
9th SCL pulse: the OLED pulls SDA LOW for this clock to say "I'm here, I'll listen". If no device pulls SDA LOW, the line stays HIGH — which is a "NACK" (no acknowledge), and the controller knows nothing's at that address.
Step 4 — Send data byte 0xAE
0xAE = 0b10101110. Send MSB-first: 1, 0, 1, 0, 1, 1, 1, 0. 8 clock pulses, OLED reads each bit.
Step 5 — ACK
9th clock: OLED pulls SDA LOW to confirm receipt.
Step 6 — STOP
The controller raises SCL HIGH, then raises SDA HIGH. The bus is idle again.
Total bytes on the wire
2 data bytes (address + command) + 2 ACK bits + the START and STOP framing. At 100 kHz that's ~200 µs for the whole transaction. For perspective: at 9600 baud UART, sending the same 2 bytes would take ~2 ms — about 10× slower.
What a logic analyser would show
If you had a $10 USB logic analyser plugged on SDA and SCL during the transaction, you'd see a clean clock train of 18 pulses (9 for each byte), with SDA flickering between HIGH and LOW. Most logic analyser software automatically labels "START", "0x78", "ACK", "0xAE", "ACK", "STOP". A useful piece of gear once you graduate to debugging multi-device I²C buses.
Try It Yourself · Five paper questions 15 min
An MPU-6050 sits at I²C address 0x69. What byte appears on the wire as the "address + R" byte for a read?
Reveal
0x69 = 0b1101001. Shift left + R/W = 1: 0b11010011 = 0xD3. That's the byte sent on SDA.
You're using 4.7 kΩ pull-ups on a 5 V bus. What current flows from VCC through the pull-up when a device pulls SDA LOW (essentially 0 V at the chip)?
Reveal
I = V / R = 5 V / 4.7 kΩ ≈ 1 mA. Per wire, while LOW. Two wires = up to 2 mA total. Trivial — that's why the bus can have lots of devices without overloading anything.
You need to read a temperature sensor (1 byte every 1 second) and drive a 128×64 OLED (lots of pixels). Should you use I²C or SPI?
Reveal
For just the sensor, I²C is plenty (2 ms latency at 100 kHz). For the OLED alone, SPI's 8–10 MHz speed would refresh much faster — useful if you're animating. For the combination, sharing one I²C bus is much simpler than running two SPI ports. Most school projects pick I²C for both. (We do exactly that in L03-19 with the SSD1306.)
You want a DS3231 RTC and an MPU-6050 on the same bus. Both default to 0x68. What's the simplest fix?
Reveal
The MPU-6050 has an AD0 pin: tie it to VCC and its address becomes 0x69 instead of 0x68. Now no clash. The DS3231 doesn't offer an alternate address — that's why you change the IMU, not the RTC. The hard alternative: use two separate I²C buses (only the Mega and ESP32 have multiple).
Your code sends a byte to address 0x3C, but no OLED is connected. What happens on the wire and how would your sketch detect this?
Reveal
The address byte goes out, the controller pulses the 9th clock waiting for ACK, but no device pulls SDA LOW. The line stays HIGH = NACK. The Wire library's endTransmission() returns a non-zero error code (specifically 2 for "received NACK on address"). Check the return value: if (Wire.endTransmission() != 0) Serial.println("no device");. The I²C scanner in L03-18 uses exactly this trick on every address 1–127 to find what's out there.
Mini-Challenge · Plan a 3-device I²C bus 10 min
You're designing a small weather station. Plan an I²C bus that carries:
- An SSD1306 OLED for the display (address 0x3C).
- A BMP280 for pressure + temperature (address 0x76).
- A DS3231 real-time clock for timestamps (address 0x68).
For each:
- Confirm no address clashes — you should be fine, all three are unique.
- Note which I²C pins on the UNO each connects to: same SDA (A4) and SCL (A5), all in parallel.
- Decide on pull-up plan: if all three are breakout boards with their own pull-ups, you may have too many pull-ups in parallel (effective resistance drops, current rises). Two on the bus is usually fine; three is sometimes too low. The fix: cut the pull-up traces on two of the three boards (usually solder-jumpers — check each board's docs).
Sketch the wiring on paper: three breakout boards, each with VCC / GND / SDA / SCL labels, and a UNO at the top with A4 and A5 connected to the bus. SDA/SCL travel from the UNO to all three in parallel.
This sketch will become reality in the L04-12 IoT Room Monitor project — same bus, with an ESP added for WiFi reporting.
Recap 5 min
I²C is two-wire, shared, half-duplex, addressable. SDA carries data, SCL carries the clock from the controller. Every byte is acknowledged. Every transaction starts with a 7-bit address + R/W bit so each peripheral knows whether it's being spoken to. 100 kHz default; 400 kHz on most modern chips. Pull-ups (typically 4.7 kΩ) are mandatory on both lines. Address clashes are the #1 bug — scan first (next lesson). Tomorrow we use the Wire library to actually scan the bus and find out what's connected.
- I²C (Inter-Integrated Circuit)
- A two-wire serial bus invented by Philips for chip-to-chip communication. Pronounced "eye-squared-see" or "eye-two-see".
- SDA / SCL
- Serial DAta and Serial CLock. The two wires of every I²C bus, shared between all devices.
- Controller / peripheral
- Modern names (replacing the older "master"/"slave" terminology). The controller generates the clock and addresses; peripherals respond.
- Open-drain
- A pin that can pull a wire LOW but can't push it HIGH — requires an external pull-up to VCC. Lets multiple devices share a wire without conflicts (the wire is HIGH unless someone pulls it LOW).
- Pull-up resistor
- A resistor (typically 4.7 kΩ for I²C) between a wire and VCC. Provides the "HIGH" state on an open-drain line.
- 7-bit address
- The device-identifying number on an I²C bus — 0 to 127. Usually shown as a hex value like 0x3C.
- R/W bit
- The 8th bit of the address byte. 0 = controller wants to write next, 1 = controller wants to read next.
- ACK / NACK
- Acknowledge / Not Acknowledge. After every byte, the recipient pulls SDA LOW for one clock to ACK. No-pull = NACK = "not here" or "no more data, please".
- START / STOP
- The two special signals that frame an I²C transaction. START = SDA falls while SCL is HIGH; STOP = SDA rises while SCL is HIGH.
- Address scan
- The technique of attempting to write to every address 1–127 and checking the ACK bit to discover which devices are on the bus. We'll use the standard
i2c_scannersketch in L03-18.
Homework 5 min
- Find one I²C device in your kit (OLED, RTC, sensor breakout, LCD with I²C backpack). Look up its default I²C address.
- Wire it on paper to a UNO: VCC, GND, SDA → A4, SCL → A5. Don't plug anything in yet.
- If you have two or more I²C devices, check for address clashes. If you find a clash, look up how to change one of the addresses (usually a solder bridge or a jumper to VCC).
- Read ahead to ARD-L03-18 (The Wire Library). Tomorrow we run the bus scanner that finds everything connected.
Bring back next class:
- Your I²C device(s) and the default-address notes.
- Your paper wiring plan.