Language: EN

como-usar-i2c-raspberry-pi

What is I2C and how to use it on Raspberry Pi

  • 5 min

In this article, we will see how to use the bus I2C with a Raspberry Pi to communicate with external devices.

The I2C protocol (Inter-Integrated Circuit) is a widely used communication standard in electronics for connecting low to medium speed devices (such as sensors, displays, and memories).

I2C is especially useful in IoT, robotics, and automation projects, where simple communication with multiple devices is required, with the advantage of only requiring two wires.

If you want to learn more about communication protocols on Raspberry Pi
check the Raspberry Pi Course read more ⯈

What is I2C?

I2C is a synchronous serial communication protocol that allows data transfer between devices using only two lines:

  • SDA (Serial Data Line): Bidirectional data line.
  • SCL (Serial Clock Line): Clock line that synchronizes the communication.

Additionally, I2C uses a unique addressing system for each device connected to the bus, allowing multiple devices to share the same bus without interference.

Each device has a unique address of 7 or 10 bits, allowing for the connection of up to 128 (7 bits) or 1024 (10 bits) devices on the same bus.

I2C supports different speeds, such as 100 kbps (standard mode), 400 kbps (fast mode), and up to 3.4 Mbps (high-speed mode).

Connecting I2C Devices

The Raspberry Pi has two dedicated pins for I2C:

  • GPIO 2 (SDA): Data pin
  • GPIO 3 (SCL): Clock pin

Connect the I2C devices to these pins, ensuring that all devices share a common ground (GND) connection.

On the other hand, the I2C protocol requires pull-up resistors on the SDA and SCL lines to ensure proper operation.

The Raspberry Pi includes internal pull-up resistors, but in some cases, especially with long cables or many devices, you may need to add external resistors (generally 4.7 kΩ).

Configuring I2C on Raspberry Pi

To use I2C on a Raspberry Pi, we first need to enable the protocol and configure the corresponding pins. Let’s see how to do it step by step.

Enabling I2C on Raspberry Pi

Open the terminal on your Raspberry Pi.

Run the following command to open the Raspberry Pi configuration:

sudo raspi-config

Go to Interfacing Options > I2C and select Yes to enable I2C. raspberry-pi-i2c

Reboot the Raspberry Pi to apply the changes:

sudo reboot

Installing I2C Tools

To interact with I2C devices, it is also very convenient to install the i2c-tools:

sudo apt update
sudo apt install i2c-tools

These tools allow us to scan for devices connected to the I2C bus and verify their operation.

For example, before communicating with a device, it is useful to scan the I2C bus to detect the addresses of the connected devices. Use the following command in the terminal:

i2cdetect -y 1

This command will display a table with the addresses of the detected devices. Something like this,

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

In this example, a device with the address 0x48 has been detected.

Communicating with I2C Devices

Once the I2C bus is configured, we can start to communicate with the connected devices. There are several libraries that can help us use I2C from our programs.

For example, the smbus2 library is a Python implementation for interacting with I2C devices. We install it by running:

pip install smbus2

Let’s see a basic example of how we can use it to read and write data to an I2C device using Python.

from smbus2 import SMBus

# I2C device address
DEVICE_ADDRESS = 0x48

# Create an instance of the I2C bus
bus = SMBus(1)

# Write a byte to the device
bus.write_byte(DEVICE_ADDRESS, 0x01)

# Read a byte from the device
data = bus.read_byte(DEVICE_ADDRESS)
print(f"Data read: {data}")

# Close the bus
bus.close()

In this example:

  • write_byte: Writes a byte to the device.
  • read_byte: Reads a byte from the device.

Practical Examples