En este artículo vamos a ver cómo usar el bus I2C con una Raspberry Pi para comunicarnos con dispositivos externos.
El protocolo I2C (Inter-Integrated Circuit) es un estándar de comunicación muy utilizado en electrónica para conectar dispositivos de velocidad baja - media (como sensores, pantallas y memorias).
I2C es especialmente útil en proyectos de IoT, robótica y automatización, donde se requiere una comunicación sencilla con múltiples dispositivos, con la ventaja de requerir únicamente dos cables.
Si quieres aprender más sobre I2C consulta,
¿Qué es I2C?
I2C es un protocolo de comunicación serial síncrono que permite la transferencia de datos entre dispositivos utilizando solo dos líneas:
- SDA (Serial Data Line): Línea de datos bidireccional.
- SCL (Serial Clock Line): Línea de reloj que sincroniza la comunicación.
Además, I2C utiliza un sistema de direcciones único para cada dispositivo conectado al bus, lo que permite que múltiples dispositivos compartan el mismo bus sin interferencias.
Cada dispositivo tiene una dirección única de 7 o 10 bits, lo que permite conectar hasta 128 (7 bits) o 1024 (10 bits) dispositivos en el mismo bus.
I2C soporta diferentes velocidades, como 100 kbps (modo estándar), 400 kbps (modo rápido) y hasta 3.4 Mbps (modo de alta velocidad).
Conectar dispositivos I2C
La Raspberry Pi tiene dos pines dedicados para I2C:
- GPIO 2 (SDA): Pin de datos
- GPIO 3 (SCL): Pin de reloj
Conecta los dispositivos I2C a estos pines, asegurándote de que todos los dispositivos compartan una conexión común a tierra (GND).
Por otro lado, el protocolo I2C requiere resistencias pull-up en las líneas SDA y SCL para garantizar un funcionamiento correcto.
La Raspberry Pi incluye resistencias pull-up internas, pero en algunos casos, especialmente con cables largos o muchos dispositivos, es posible que tengas que arreglar resistencias externas (generalmente de 4.7 kΩ).
Configuración de I2C en Raspberry Pi
Para utilizar I2C en una Raspberry Pi, primero debemos habilitar el protocolo y configurar los pines correspondientes. Vamos a ver cómo hacerlo paso a paso.
Habilitar I2C en Raspberry Pi
Abrimos la terminal en tu Raspberry Pi.
Ejecutamos el siguiente comando para abrir la configuración de Raspberry Pi:
sudo raspi-config
Vamos a Interfacing Options > I2C y seleccinamos Yes para habilitar I2C.
Reinicia la Raspberry Pi para aplicar los cambios:
sudo reboot
Instalar herramientas de I2C
Para interactuar con dispositivos I2C, también es muy conveniente instalar las herramientas i2c-tools
:
sudo apt update
sudo apt install i2c-tools
Estas herramientas nos permiten escanear dispositivos conectados al bus I2C y verificar su funcionamiento.
Por ejemplo, antes de comunicarnos con un dispositivo, es útil escanear el bus I2C para detectar las direcciones de los dispositivos conectados. Usa el siguiente comando en la terminal:
i2cdetect -y 1
Este comando mostrará una tabla con las direcciones de los dispositivos detectados. Algo así,
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: -- -- -- -- -- -- -- --
En este ejemplo, se ha detectado un dispositivo con la dirección 0x48
.
Comunicación con dispositivos I2C
Una vez configurado el bus I2C, podemos comenzar a comunicarnos con los dispositivos conectados. Hay varias librerías que nos pueden ayudar a usar I2C desde nuestros programas.
Por ejemplo, la librería smbus2 es una implementación de Python para interactuar con dispositivos I2C. La instalamos ejecutando:
pip install smbus2
Vamos a un ejemplo básico de cómo podemos usarla para leer y escribir datos en un dispositivo I2C utilizando Python.
from smbus2 import SMBus
# Dirección del dispositivo I2C
DEVICE_ADDRESS = 0x48
# Crear una instancia del bus I2C
bus = SMBus(1)
# Escribir un byte en el dispositivo
bus.write_byte(DEVICE_ADDRESS, 0x01)
# Leer un byte del dispositivo
data = bus.read_byte(DEVICE_ADDRESS)
print(f"Dato leído: {data}")
# Cerrar el bus
bus.close()
En este ejemplo:
write_byte
: Escribe un byte en el dispositivo.read_byte
: Lee un byte del dispositivo.
Ejemplos prácticos
Lectura de un sensor de temperatura I2C
Vamos a implementar un ejemplo práctico utilizando un sensor de temperatura I2C, como el LM75. Este sensor tiene una dirección I2C predeterminada de 0x48
y proporciona lecturas de temperatura en formato de 2 bytes.
from smbus2 import SMBus
import time
# Dirección del sensor LM75
LM75_ADDRESS = 0x48
# Crear una instancia del bus I2C
bus = SMBus(1)
try:
while True:
# Leer 2 bytes de datos del sensor
data = bus.read_i2c_block_data(LM75_ADDRESS, 0x00, 2)
# Convertir los datos a temperatura en grados Celsius
temperature = (data[0] << 8 | data[1]) >> 5
temperature = temperature * 0.125
print(f"Temperatura: {temperature:.2f} °C")
# Esperar 1 segundo antes de la siguiente lectura
time.sleep(1)
except KeyboardInterrupt:
print("Lectura detenida")
finally:
# Cerrar el bus I2C
bus.close()
- Lectura de datos: Utilizamos
read_i2c_block_data
para leer 2 bytes del sensor. - Conversión de temperatura: Los datos se convierten a temperatura en grados Celsius utilizando la fórmula proporcionada en la hoja de datos del sensor.
- Bucle infinito: El programa lee la temperatura cada segundo hasta que se interrumpe