To use I2C on Raspberry Pi, enable the interface via raspi-config, connect SDA to GPIO 2 (Pin 3) and SCL to GPIO 3 (Pin 5), and ensure 4.7kΩ pull-up resistors are present on both lines. The default bus speed is 100 kHz, and devices are addressed via 7-bit hex values (e.g., 0x76). While the Pi's internal pull-ups exist, they are 50kΩ—far too weak for reliable I2C communication, making external pull-ups or breakout boards with integrated resistors mandatory.
The Physical Layer: Wiring and Pull-Up Requirements
I2C (Inter-Integrated Circuit) is an open-drain protocol. This means devices can only pull the signal line to ground (LOW); they cannot actively drive it HIGH. To return the line to a HIGH state, a pull-up resistor connected to the voltage rail is required.
The Raspberry Pi operates at 3.3V logic. Therefore, your pull-up resistors must tie SDA and SCL to the Pi's 3.3V pin (Pin 1), never the 5V pin. Feeding 5V into GPIO 2 or 3 will permanently damage the Broadcom SoC's input protection diodes.
For standard mode (100 kHz), a 4.7kΩ resistor is the baseline. If you are running fast mode (400 kHz) or chaining multiple sensors (which increases bus capacitance), step down to 2.2kΩ. The I2C specification mandates a maximum sink current of 3mA. At 3.3V, a 1kΩ resistor would draw 3.3mA, violating the spec and potentially causing logic LOWs to float above the 0.8V threshold. Stick to the 2.2kΩ–4.7kΩ range.
The physical wiring for a standard Raspberry Pi I2C bus (Bus 1) is as follows:
- SDA (Data): GPIO 2 (Physical Pin 3)
- SCL (Clock): GPIO 3 (Physical Pin 5)
- VCC: 3.3V (Physical Pin 1) or 5V (Physical Pin 2) depending on sensor requirements (see level shifting notes below)
- GND: Any ground pin (e.g., Physical Pin 6)
I2C Bus Mechanics and Protocol Alternatives
Before chaining a dozen sensors, you must understand the physical limits of the bus. I2C is designed for on-board communication, not long-distance runs. Below is the mechanical specification sheet for standard I2C implementations.
| Parameter | Standard Mode | Fast Mode | Fast Mode Plus |
|---|---|---|---|
| Wires Required | 2 (SDA, SCL) + Power/Ground | ||
| Max Clock Speed | 100 kHz | 400 kHz | 1 MHz |
| Addressing | 7-bit (128 addresses, ~16 reserved) or 10-bit | ||
| Max Bus Capacitance | 400 pF | ||
| Practical Distance | ~1 meter | ~30 cm | ~10 cm |
Which Protocol Fits Your Project?
I2C is not the only game in town. Choosing between I2C, SPI, and UART depends entirely on your distance, speed, and device count requirements.
| Criteria | I2C | SPI | UART |
|---|---|---|---|
| Device Count | High (up to 112 on 7-bit bus) | Low (requires individual Chip Select wire per device) | Point-to-Point (1-to-1) |
| Wiring Complexity | 2 shared wires | 3 shared + 1 per device | 2 wires (TX/RX) per pair |
| Max Speed | 1 MHz (practical limit on Pi) | 10+ MHz (limited by Pi GPIO toggle rate) | ~115,200 baud (standard) |
| Best Use Case | Multiple low-speed environmental sensors | High-throughput displays, ADCs, SD cards | GPS modules, serial consoles, long-distance RS-485 |
For a deeper look at the electrical timing requirements, refer to the official NXP I2C Bus Specification (UM10204).
Minimal Working Exchange: Python and Hardware Setup
Let's bypass heavy abstraction libraries and perform a raw I2C register read. We will query the WHO_AM_I register of an MPU-6050 accelerometer/gyroscope. This register (hex 0x75) should return 0x68 if the chip is alive and communicating.
Wiring the MPU-6050
- VCC to Pi 3.3V (The MPU-6050 has an internal LDO and tolerates 3.3V-5V, but we use 3.3V to keep the I2C data lines at 3.3V logic).
- GND to Pi GND.
- SDA to Pi GPIO 2.
- SCL to Pi GPIO 3.
- AD0 to GND (Sets I2C address to
0x68. If tied to VCC, address becomes0x69).
Python Code (smbus2)
Install the lightweight smbus2 library via terminal: pip install smbus2. Ensure I2C is enabled in raspi-config under Interface Options.
import smbus2
import sys
import time
# Raspberry Pi I2C Bus 1 is the default for GPIO 2/3
I2C_BUS = 1
MPU6050_ADDR = 0x68
WHO_AM_I_REG = 0x75
EXPECTED_ID = 0x68
try:
bus = smbus2.SMBus(I2C_BUS)
except FileNotFoundError:
print("Error: I2C bus not found. Is I2C enabled in raspi-config?")
sys.exit(1)
try:
# Read a single byte from the WHO_AM_I register
device_id = bus.read_byte_data(MPU6050_ADDR, WHO_AM_I_REG)
if device_id == EXPECTED_ID:
print(f"Success! MPU-6050 detected. WHO_AM_I returned: {hex(device_id)}")
else:
print(f"Warning: Device responded, but ID is {hex(device_id)} (Expected {hex(EXPECTED_ID)})")
except OSError as e:
print(f"I2C Communication Failed: {e}")
print("Check wiring, pull-up resistors, and ensure the device address is correct.")
finally:
bus.close()
Sniffing, Debugging, and Classic Failures
When the bus fails, the Pi rarely gives you a helpful error message; it just throws an OSError: [Errno 121] Remote I/O error. Here is how to systematically debug the physical and logical layers.
Step 1: The Software Sniffer
Run i2cdetect -y 1 in the terminal. This sweeps the bus and prints a grid of addresses. If you see your device's hex address, the physical layer is intact. If the grid is entirely --, you have a physical wiring or pull-up failure.
Step 2: Diagnosing Classic Failures
- Missing Pull-Up Resistors: If SDA/SCL float,
i2cdetectwill either hang indefinitely or show every single address as occupied (00through77). Verify 4.7kΩ resistors are present. - Address Clashes: If you connect two BME280 sensors, both default to
0x76. The Pi cannot differentiate them, resulting in corrupted data. Fix: Desolder the address jumper on one board, or use a TCA9548A I2C Multiplexer to isolate them on separate sub-buses. - Clock Stretching (The Pi's Achilles Heel): Some sensors (like the SHT31 or certain OLEDs) hold the SCL line LOW to "stretch" the clock while they process data. The Broadcom hardware I2C controller on the Pi does not support clock stretching reliably, leading to dropped bytes. Fix: Use a software I2C (bit-banging) library, or switch to a sensor that doesn't stretch the clock.
- Baud Mismatch: Running 400kHz on long, unshielded jumper wires causes signal reflections and rise-time failures. Drop back to 100kHz if you encounter intermittent
Errno 121errors.
For hardware-level sniffing, connect a $15 logic analyzer (like a Saleae clone) to SDA and SCL, and use PulseView / Sigrok to decode the I2C packets visually. This instantly reveals if the Pi is sending the correct 7-bit address and R/W bit.
Frequently Asked Questions
How do I change the I2C baud rate on Raspberry Pi?
In Raspberry Pi OS Bookworm and newer, open /boot/firmware/config.txt (on older Bullseye releases, it is /boot/config.txt). Add or modify the following line at the bottom of the file:
dtparam=i2c_baudrate=400000
Reboot the Pi. You can verify the new clock speed by checking the device tree: cat /sys/class/i2c-adapter/i2c-1/of_node/clock-frequency. Note that increasing the baud rate requires lower pull-up resistor values (e.g., 2.2kΩ) to overcome bus capacitance.
Can I connect 5V I2C sensors to Raspberry Pi 3.3V GPIO?
No. While some 5V sensors will accept a 3.3V HIGH signal as valid, their SDA/SCL pull-ups will be tied to 5V. When the sensor pulls the line HIGH, it will feed 5V back into the Pi's GPIO pins, which are strictly limited to 3.3V. You must use a bidirectional logic level shifter (such as a BSS138 MOSFET-based shifter or a TXS0108E chip) between the Pi and the 5V sensor to translate the voltage domains safely.
Why does i2cdetect show UU instead of a hex address?
A UU in the i2cdetect grid means the address is currently reserved by a loaded Linux kernel driver. Common culprits include RTC (Real Time Clock) modules like the DS3231 or EEPROMs that the OS has claimed at boot. To communicate with the device via Python, you must first unload the conflicting kernel module using rmmod (e.g., sudo rmmod rtc_ds1307), or interact with it via the appropriate Linux subsystem (like /dev/rtc0) rather than raw I2C.
What is the maximum cable length for I2C on a Raspberry Pi?
Standard I2C is limited to about 1 meter at 100 kHz due to capacitive loading on the wires. At 400 kHz, practical limits drop to roughly 30 cm. If you need to run an I2C sensor 5 meters away to a weather station, do not use raw I2C. Instead, use an I2C bus extender chip like the P82B715, which converts the signal to a differential current-mode interface, or switch entirely to an RS-485 transceiver for long-haul serial communication.






