# I2C Essentials **I2C** (Inter-Integrated Circuit) — a two-wire bus protocol for communicating with sensors, displays, and other devices. ## How I2C Works Two wires: - **SDA** — Serial Data (bidirectional) - **SCL** — Serial Clock (driven by the controller) Multiple devices can share the same two wires. Each device has a unique **address** (7 bits = up to 128 devices on one bus). ``` Controller (ESP32-C3) │ │ SDA ┤ ├ SCL │ │ ┌────┴──┴────┐ │ I2C Bus │ ├────────────┤ │ │ Sensor A Sensor B (addr 0x68) (addr 0x44) ``` --- ## Key Concepts | Concept | What It Means | |---------|--------------| | **Controller** | The device that initiates communication (our ESP32-C3) | | **Target** | The device being addressed (sensors on the uFerris board) | | **Address** | 7-bit identifier for each device (e.g., `0x68`) | | **Write** | Controller sends data to a target | | **Read** | Controller reads data from a target | | **Clock Speed** | How fast data transfers: 100 kHz (standard), 400 kHz (fast) | --- ## The Driver Crate Pattern This is where the `embedded-hal` abstraction becomes powerful: ``` esp-hal ──implements──→ embedded_hal::i2c::I2c trait ↑ │ uses │ Driver crate ──────→ takes generic `impl I2c` (e.g., icm42670) ``` The driver crate doesn't import `esp-hal`. It only depends on the `embedded-hal` *trait*. This means: - The driver works on ESP32, nRF52, STM32, RP2040 — any chip with an `I2c` implementation - You can switch chips without changing your driver code - This is the whole point of the abstraction layers from Part 1 --- ## Configurations | Setting | Options | docs.rs Location | |---------|---------|-----------------| | Clock frequency | 100 kHz, 400 kHz, custom | `Config::with_frequency()` | | SDA/SCL pins | Any GPIO with I2C capability | `.with_sda()`, `.with_scl()` | | Timeout | Bus timeout duration | `Config::with_timeout()` | --- ## Controls | Method | What It Does | |--------|-------------| | `write(addr, &[u8])` | Send bytes to a device | | `read(addr, &mut [u8])` | Read bytes from a device | | `write_read(addr, &[u8], &mut [u8])` | Write then read in one transaction | --- ## What's on the uFerris Board? Your uFerris board has I2C sensor(s) connected. You'll discover exactly which ones in the first exercise — by scanning the bus. Check your pinout card for the **SDA** and **SCL** pin assignments.
The Embedded Rustacean · Rust Week 2026