Saltar al contenido principal

Sensores por I2C

Muchos sensores avanzados se conectan por I2C: IMUs, sensores de distancia láser, de temperatura, pantallas... La Raspberry tiene un bus I2C en los pines 3 (SDA) y 5 (SCL). Como ejemplo, conectamos la misma IMU de la guía de Arduino.

1. Activar I2C​

En Raspberry Pi OS:

sudo raspi-config

Interface Options → I2C → Yes y reinicia. En Ubuntu viene activado. Instala después las herramientas y la librería de Python:

sudo apt install i2c-tools python3-smbus2

2. Conectar la IMU​

MPU6050 conectado a la Raspberry: VCC a 3,3 V, GND, SDA al pin 3 y SCL al pin 5
MPU6050Raspberry Pi
VCC3,3 V (pin 17)
GNDGND (pin 9)
SDASDA, GPIO2 (pin 3)
SCLSCL, GPIO3 (pin 5)
tip

Aliméntalo con 3,3 V. Así todo el bus I2C trabaja a la tensión de la Raspberry y sus pines quedan protegidos.

3. Comprobar que aparece​

i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
...
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

El 68 es la dirección del MPU6050, igual que en el escáner I2C de Arduino. Si no aparece, revisa SDA y SCL.

4. Leer la inclinación​

Los registros son los mismos que en Arduino: se despierta el sensor escribiendo un 0 en el registro 0x6B y se leen 14 bytes a partir del 0x3B.

import math
import time
from smbus2 import SMBus

MPU = 0x68
bus = SMBus(1) # el bus I2C de los pines 3 y 5
bus.write_byte_data(MPU, 0x6B, 0) # despierta el sensor


def con_signo(alto, bajo):
valor = (alto << 8) | bajo
return valor - 65536 if valor >= 32768 else valor


while True:
d = bus.read_i2c_block_data(MPU, 0x3B, 14) # 14 bytes desde el registro 0x3B
ax = con_signo(d[0], d[1]) / 16384.0 # en g
ay = con_signo(d[2], d[3]) / 16384.0
az = con_signo(d[4], d[5]) / 16384.0
gz = con_signo(d[12], d[13]) / 131.0 # en °/s

roll = math.degrees(math.atan2(ay, az))
pitch = math.degrees(math.atan2(-ax, math.sqrt(ay * ay + az * az)))
print(f'roll {roll:6.1f}° pitch {pitch:6.1f}° giro Z {gz:6.1f} °/s')
time.sleep(0.1)
roll 30.0° pitch 0.4° giro Z 0.3 °/s
  • SMBus(1) abre el bus I2C número 1, el de la cabecera
  • read_i2c_block_data(dirección, registro, n) lee n bytes seguidos
  • con_signo() junta los dos bytes de cada medida en un número con signo, lo que en Arduino hacía el tipo int16_t

Para un ángulo estable, añade el filtro complementario: funciona exactamente igual en Python.

Otros sensores I2C​

La forma de trabajar es siempre la misma: comprobar la dirección con i2cdetect y leer sus registros, o usar la librería que ofrece el fabricante. Muchos módulos tienen librería de Python en el proyecto Adafruit Blinka / CircuitPython, que funciona en la Raspberry:

SensorMide
VL53L0Xdistancia con láser, hasta 2 m
BME280temperatura, humedad y presión
ADS11154 entradas analógicas: lo que le falta a la Raspberry
SSD1306pantalla OLED pequeña