Skip to content

How to Enable I2C on Raspberry Pi

I2C (Inter-Integrated Circuit, pronounced "I-squared-C") is a two-wire serial bus used to connect low-speed peripherals — sensors, displays, EEPROMs — to a microcontroller or SoC. It uses two lines: SDA (data) and SCL (clock). Each device on the bus has a unique 7-bit address (0x00–0x7F), and communication follows a master/slave model where the Raspberry Pi acts as the master.

Understanding Device Tree Overlays

The Linux kernel uses a device tree — a data structure that describes the hardware on the board — to discover which peripherals exist and how they are connected. The base device tree shipped with the Raspberry Pi describes the default configuration, but some peripherals (like I2C) are disabled by default. Instead of modifying the base tree, you can apply a device tree overlay that merges additional nodes or property changes at boot time. For example, adding dtoverlay=i2c1 (or dtparam=i2c_arm=on) to config.txt tells the bootloader to merge an overlay that enables the I2C controller node and configures the correct GPIO pins for SDA and SCL. The kernel then sees the I2C bus as an active device and loads the appropriate driver.

For a deeper look at device tree syntax, overlays, and how the kernel matches devices to drivers, see the Device Tree and Drivers Reference.

Check If I2C Is Already Enabled

Check for available I2C interfaces:

ls /dev/i2c*

If nothing shows up the I2C interface is not enabled.

linux@eslinux:~ $ ls /dev/i2c*
ls: cannot access '/dev/i2c*': No such file or directory

Check If I2C Kernel Module is Loaded

Open a terminal and run list kernel modules:

lsmod | grep i2c
Info

lsmod lists all currently loaded kernel modules — chunks of driver code that the kernel loaded to support specific hardware or features. The grep i2c filter shows only modules related to I2C. If no I2C modules appear, the kernel has not yet been told to enable the I2C subsystem.

Expected output (example):

i2c_brcmstb            12288  0

If nothing else is shown, I2C is not yet enabled.


Enable I2C via raspi-config

To enable the I2C interface:

sudo raspi-config

Then navigate:

Interface Options → I2C → Yes → Finish

Reboot your Raspberry Pi to apply changes:

sudo reboot
Load I2C Kernel Modules Manually

If the modules are not loaded automatically, load them manually: Uncomment the following line in /boot/firmware/config.txt

dtparam=i2c_arm=on
dtparam stands for device tree parameter — it tells the kernel's device tree which hardware peripherals to enable at boot. Setting i2c_arm=on activates the ARM-side I2C controller.

To load them automatically at boot:

echo i2c-dev | sudo tee -a /etc/modules
Why sudo tee instead of sudo echo >>? The >> redirect is handled by your current (non-root) shell, so sudo echo "text" >> /protected/file fails with "Permission denied." Using sudo tee -a runs tee as root, so the write to the protected file succeeds.


Login again via SSH

ssh linux@192.168.x.y

Install I2C Utilities

Make sure the necessary tools and libraries are installed:

sudo apt update
sudo apt install -y i2c-tools python3-smbus git
  • i2c-tools: command-line utilities for I2C
  • python3-smbus: Python library for I2C communication. SMBus (System Management Bus) is a subset of I2C with stricter timing and protocol rules — most I2C sensors work fine over SMBus.
  • git: to version control and access source repositories

Verify I2C Bus is Active

Check for available I2C interfaces:

ls /dev/i2c*

Expected output:

/dev/i2c-1  /dev/i2c-20  /dev/i2c-21

Then scan the appropriate I2C bus for connected devices:

i2cdetect -y 1

The -y flag skips the interactive confirmation prompt (safe for most devices). The 1 is the bus number — on Raspberry Pi, I2C bus 1 corresponds to GPIO2 (SDA, Pin 3) and GPIO3 (SCL, Pin 5).

This shows a grid with detected I2C addresses. It will probably be empty until you connect a sensor:

linux@eslinux:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Troubleshooting: i2cdetect shows no devices
  • Check wiring: ensure SDA→GPIO2 (Pin 3) and SCL→GPIO3 (Pin 5) connections are solid
  • Check pull-up resistors: I2C requires pull-ups on SDA and SCL (most breakout boards include them)
  • Check config.txt: verify dtparam=i2c_arm=on is present in /boot/firmware/config.txt
  • Reboot: I2C changes in raspi-config or config.txt require a reboot to take effect

Connect the MCP9808 temperature module

Connect the MCP9808 temperature module using cables to the RPI following the pinout.

Pinout

You can find the pinout of the Raspberry Pi here.

Connecting a Temperature Sensor (MCP9808) to Raspberry Pi:

Temperature Sensor Pin Connect to Raspberry Pi Notes
+3V3 3.3V (Pin 1) Power supply
GND GND (Pin 6) Ground connection
SDI GPIO2 (Pin 3) I2C data line
SCK GPIO3 (Pin 5) I2C clock line
Alert - Alert pin
Warning

The MCP9808 operates at 3.3V only. Connect it to the 3.3V pin (Pin 1), not the 5V pin (Pin 2). Applying 5V will damage the sensor.

Note

Always consult your sensor's datasheet for proper connection details.


Now scan the appropriate I2C bus again for connected devices:

i2cdetect -y 1

The MCP9808 have to show up at the address 0x18:

linux@eslinux:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Example Python Code to Use I2C

Create a test script in Python top read and decode the temperature.

import smbus

bus = smbus.SMBus(1)
address = 0x18  # MCP9808 default I2C address

# MCP9808 temperature register
# 0101 =Temperature register (TA)
TEMP_REG = 0x05

# Read 2-byte word from the temperature register
raw_temp = bus.read_word_data(address, TEMP_REG)

# Decode following the EXAMPLE 5-1: SAMPLE INSTRUCTION CODE
# Byte-swap: the MCP9808 sends data in big-endian order (most significant
# byte first), but SMBus read_word_data returns it in little-endian order
# (least significant byte first). This swap puts the bytes back in the
# correct order for decoding.
raw_temp = ((raw_temp << 8) & 0xFF00) + (raw_temp >> 8)
raw_temp &= 0x1FFF

celsius = raw_temp & 0x0FFF
celsius /= 16.0
if raw_temp & 0x1000:
    celsius -= 256

print(f"Temperature: {celsius:.2f} °C")

How to decode the sensor values can found in the MCP9808 documentation.

Note: You can find further details about SMBus here