Blog · How-to

How to enable i2c on the Raspberry Pi

How-to

The Pi ships with i2c switched off. Two minutes turns it on, verifies it, and sets a sane speed — then every sensor tutorial on the internet starts working.

Step 1

Enable i2c with raspi-config or config.txt

The friendly way:

sudo raspi-config
# Interface Options  →  I2C  →  Yes

Or the direct way — add one line to the boot config (Bookworm and later use /boot/firmware/config.txt; older releases use /boot/config.txt):

dtparam=i2c_arm=on

Reboot either way. The bus appears as /dev/i2c-1. (Both routes are documented in the official Raspberry Pi configuration docs, alongside every other config.txt option.)

Step 2

Verify with i2cdetect

sudo apt install i2c-tools
i2cdetect -y 1

With a sensor wired to GPIO2 (SDA, pin 3) and GPIO3 (SCL, pin 5), its address shows up in the grid — here's how to read the output, and the address list tells you what you're looking at. Nothing showing? The 7-step checklist finds it. One nicety: the Pi has 1.8 kΩ pull-ups soldered on those pins, so pull-up worries mostly don't apply.

To use the bus from Python without sudo:

sudo adduser $USER i2c   # then log out and back in

Reading the output

What the i2cdetect grid is telling you

The grid confuses people the first time, because it shows every address from 0x00 to 0x7F even though only 0x08–0x77 is usable. Three things can appear in a cell:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --

The empty run at the start of row 00: and the short row 70: aren't bugs — those are the reserved ranges the spec keeps, so i2cdetect doesn't probe them.

Beyond detect

Read a register without writing any code

i2c-tools ships three more commands that most tutorials never mention, and they're the fastest way to prove a sensor works before you write a line of Python:

# read one register: bus 1, device 0x76, register 0xD0 (BME280 chip-ID)
i2cget -y 1 0x76 0xD0
# -> 0x60   (0x60 = BME280, 0x58 = BMP280 — you just identified the chip)

# dump every register on the device
i2cdump -y 1 0x76

# write a byte: bus 1, device 0x76, register 0xF4, value 0x27
i2cset -y 1 0x76 0xF4 0x27

i2cget is genuinely the fastest chip-ID check there is — one command tells you whether the "BME280" you bought is really a BMP280, which is the single most common substitution on the market. Careful with i2cset, though: it writes real registers, and a wrong value can put a device into an odd mode until you power-cycle it.

From Python

Reading an i2c sensor from Python with smbus2

With the bus enabled and your user in the i2c group, smbus2 is the usual route:

pip install smbus2
from smbus2 import SMBus

with SMBus(1) as bus:                      # /dev/i2c-1
    chip_id = bus.read_byte_data(0x76, 0xD0)
    print(hex(chip_id))                    # 0x60 -> BME280

    # multi-byte read: 3 bytes starting at 0xF7
    data = bus.read_i2c_block_data(0x76, 0xF7, 3)
    print([hex(b) for b in data])

If that raises PermissionError, the group change hasn't taken effect — log out and back in. If it raises OSError: [Errno 121] Remote I/O error, nothing ACKed at that address: the device isn't there, isn't powered, or is at a different address than you think. Run i2cdetect again and trust the grid over the datasheet.

More buses

A second i2c bus on the Pi with dtoverlay=i2c-gpio

Two sensors with the same fixed address and no jumper? You don't have to buy a multiplexer — the Pi can bit-bang a second bus on any two spare GPIOs:

# /boot/firmware/config.txt
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=23,i2c_gpio_scl=24

After a reboot that appears as /dev/i2c-3, and i2cdetect -y 3 scans it. Put the clashing device there and the conflict disappears — at the cost of two GPIOs and some CPU, since the kernel is toggling the lines in software rather than using dedicated hardware.

That software driver has a bonus: it honours clock stretching correctly, which the Pi's hardware controller famously doesn't. If a CCS811 or BME680 is giving you corrupt reads, moving it to an i2c-gpio bus fixes both problems at once. Remember these GPIOs have no pull-up resistors — unlike GPIO2/3, which have the Pi's 1.8 kΩ pair fitted — so the device's own breakout must provide them, or you add your own.

Step 3 (optional)

Raspberry Pi i2c speed, and the one Pi gotcha

The default clock is 100 kHz. For Fast-mode devices:

dtparam=i2c_arm=on,i2c_arm_baudrate=400000

The gotcha: the Pi's hardware controller has a long-standing clock-stretching bug. Most sensors never stretch and never notice — but if yours does (CCS811, BME680), you'll see corrupted reads that no rewiring fixes. The workarounds live in that article. Ready to populate the bus? Start with the best i2c sensors for the Pi.

Questions

Raspberry Pi i2c FAQ

Which GPIO pins are i2c on the Raspberry Pi?

SDA is GPIO2 (physical pin 3) and SCL is GPIO3 (physical pin 5), on every 40-pin Pi. Those two pins also carry the Pi's built-in 1.8 kΩ pull-up resistors, so a bare sensor with no pull-ups of its own still works.

Do I need to run my Python script with sudo to use i2c?

No — add your user to the i2c group instead: sudo adduser $USER i2c, then log out and back in. Scripts then access /dev/i2c-1 without root.

What does UU mean in i2cdetect output?

It means a kernel driver has already claimed that address, so i2cdetect skipped probing it rather than risk disturbing a device someone else is talking to. UU is good news: something is there and it's bound to a driver. You'll see it on a hardware RTC after loading its overlay. It also means your own script can't grab that address directly — the driver owns it, and you go through the driver's interface instead.

Why is /dev/i2c-1 missing after I enabled i2c?

Almost always a missing reboot — the dtparam line is read at boot, so nothing changes until you restart. If it's still absent after that, check you edited the right file: Bookworm and later use /boot/firmware/config.txt, while older releases use /boot/config.txt. Editing the wrong one is silent, which is what makes it confusing. Confirm with ls /dev/i2c-* and lsmod | grep i2c_bcm2835.

Should I raise the bus speed to 400 kHz?

Only if a device is slow at the default 100 kHz and everything on the bus supports Fast-mode. Add i2c_arm_baudrate=400000 to the dtparam line and reboot. If anything gets flaky, drop back — reliability beats speed for sensor reads.

Can I have more than one i2c bus on a Raspberry Pi?

Yes — dtoverlay=i2c-gpio bit-bangs an extra bus on any two spare GPIOs, appearing as /dev/i2c-3 or similar. It's the standard fix for two devices with the same fixed address when you don't want a multiplexer. It also happens to honour clock stretching correctly, since the kernel drives the lines in software, which is why it doubles as the workaround for the Pi's stretching bug.

My sensor is detected but reads fail randomly on the Pi. Why?

If the sensor uses clock stretching (CCS811 and BME680 are the famous ones), the Pi's hardware i2c controller mishandles it. Lower the baudrate drastically, or switch that device to the software-i2c overlay — full detail in our clock-stretching article.