Electronics Design AU
CommunicationsEmbedded Systems

What Is I2C (Inter-Integrated Circuit)?

Last updated 25 June 2026 · 3 min read

Direct Answer

I2C (Inter-Integrated Circuit) is a two-wire synchronous serial bus — SDA for data and SCL for clock — that allows a controller to address multiple peripheral devices over the same pair of lines using a 7-bit or 10-bit device address, instead of needing a dedicated chip-select per device like SPI.

Detailed Explanation

I2C uses just two signal lines shared by every device on the bus:

  • SDA (Serial Data) — carries both directions of data, time-multiplexed.
  • SCL (Serial Clock) — generated by whichever device is currently acting as controller (in standard mode, a fixed primary controller).

Every transaction starts with a START condition, followed by a 7-bit (or extended 10-bit) address plus a read/write bit, then one or more data bytes, each acknowledged by the receiver, ending with a STOP condition. Because the address is transmitted on the bus itself, any number of peripherals can share the same two wires — there's no per-device chip-select like SPI requires.

Standard speed grades are 100 kHz (Standard Mode), 400 kHz (Fast Mode), 1 MHz (Fast Mode Plus), and 3.4 MHz (High Speed Mode), though most general-purpose sensors and EEPROMs only support up to Fast Mode.

Practical Examples

A common board might have an I2C temperature sensor, an I2C EEPROM, and an I2C-controlled GPIO expander all wired to the same two SDA/SCL pins on the microcontroller, each with a distinct fixed or configurable address. The firmware addresses each one individually over the shared bus rather than needing a separate pair of wires per device.

This is exactly why I2C is popular for sensor-heavy designs: adding another I2C peripheral often costs zero additional GPIO pins, as long as its address doesn't collide with something already on the bus.

Design Considerations

  • Pull-up resistor sizing: typical values are 2.2 kΩ–4.7 kΩ, but the correct value depends on bus capacitance (trace length, number of devices) and target speed — too weak a pull-up limits rise time at high speed, too strong increases power draw and ringing.
  • Address collisions: check every device's address space before committing to a bus layout, especially with fixed-address sensors from the same vendor family. Where only two devices need to communicate point-to-point, UART is a simpler alternative with no addressing or pull-up requirements — though it cannot serve a shared bus.
  • Bus capacitance limits: the I2C spec caps total bus capacitance (400 pF for standard/fast mode), which limits practical trace length and device count without a bus buffer.
  • Clock stretching support: some peripherals pause SCL to indicate they need more time; confirm your microcontroller's I2C peripheral (and any bit-banged implementation) actually supports this, or transfers can corrupt silently.
  • Choosing between I2C, SPI, and UART: for a structured comparison of when each protocol is the better choice, see SPI vs I2C vs UART: which to use.
  • I2C on Raspberry Pi: for enabling I2C via device tree overlay, sizing pull-ups for a CM4 carrier board, and using i2cdetect, see Raspberry Pi GPIO Interfacing.
  • Commercial peripheral integration: Integrating multiple I2C peripherals into a production device involves driver development, bus diagnostics, and error recovery — Zeus Design's embedded firmware team handles this kind of hardware-software integration for commercial products.

Common Mistakes

  • Omitting pull-up resistors entirely because the bus "seems to work" on the bench with parasitic capacitance, then failing intermittently in production.
  • Two peripherals sharing a fixed address with no multiplexer or alternate-address strategy planned for.
  • Ignoring NACK responses from the bus and assuming a write succeeded — see what a real NACK-on-every-address failure looks like in practice for how to diagnose it systematically.
  • Running at 400 kHz with pull-up resistors and trace lengths only validated at 100 kHz.

Frequently Asked Questions

Why does I2C need pull-up resistors?
I2C uses open-drain outputs on both SDA and SCL, meaning devices can only pull the line low, never drive it high. External pull-up resistors are required to return the lines to a high (idle) state, and this is also what allows multiple devices to share the bus safely.
Can two I2C devices share the same address?
Not on the same bus segment. If two peripherals have a fixed, identical address, you need an I2C multiplexer/switch, a level-translating bus splitter, or to choose a peripheral variant with an alternate address (many sensors expose an address-select pin for exactly this reason).

References

Related Questions

Related Forum Discussions