Dispositivos I2C con ESP32 y MicroPython

Anterior: Parpadeo de un led con ESP32 y MicroPython

Siguiente: Dispositivos I2C con ESP32 y MicroPython (código)

Ahora que ya nos hemos atrevido a conectar nuestro ESP32 a un dispositivo externo y hacerlo funcionar, vamos a dar un paso más, pero un paso de gigante, porque esta vez vamos a conectar nuestro primer dispositivo I2C, en este caso, un display de 16×2, dieciséis columnas por dos filas. El esquema es como el de la siguiente imagen:

Y no estoy bromeando. Existen dos opciones para realizar este montaje: adquirir un display con el módulo adaptador I2C ya soldado, o adquirirlos por separado y luego soldar los pines de uno y otro. No es difícil de soldar, pero si no estás acostumbrado al soldador, mejor la primera opción.

En estas imágenes podemos ver los dos montajes. El de arriba con el módulo adaptador I2C ya montado, y el de abajo sin el susodicho módulo.

Pero ahora te estarás preguntando: «¿Qué narices es todo esto del I2C?» Pues vale, vamos a suponer que ninguno de los dos tenemos ni idea de electrónica, lo cual es muy posible que sea cierto =), y lo dejaremos en que I2C es un protocolo de comunicaciones por puerto serie que permite conectar una gran variedad y cantidad de dispositivos a nuestro microcontrolador utilizando tan solo dos pines para ello. De este modo podemos conectar no sólo displays, sino sensores de todo tipo, entradas analógicas, pantallas OLED, servomotores,… Y todo a la vez y con sólo dos pines.

Seguro que ahora mismo estás mirando el esquema y diciendo: «Oiga, que ahí hay cuatro hilos, no dos». Pues tienes toda la razón, pero dos de esos hilos son para la alimentación (VCC y GND), mientras los otros dos son el SDA (por donde viajan los datos entre dispositivos) y SDL (que transporta la señal de reloj que sincroniza los dispositivos).

Como se puede ver, el montaje no es especialmente complicado: conectamos el pin VCC del display a la salida de 5V del ESP32, el pin GND al GND del ESP32, el pin SDA al pin 21 y el SCL al pin 22 de la ESP32. Si tienes dudas sobre la ubicación de los pines, te recomiendo que veas este esquema de pines del ESP32, aunque teniendo en cuenta que diferentes modelos de ESP32 podrian tener un esquema de pines distinto.

Una de las características de los dispositivos I2C es que cada uno de ellos debe conectarse con una dirección binaria de siete bits, lo que en teoría nos permite conectar a nuestro microcontrolador un total de 112 dispositivos (teniendo en cuenta que 16 de las 128 posibles están reservadas). Para más información sobre el protocolo I2C, recomiendo esta página del blog de Luis Llamas.

Y es por eso que cuando vamos a conectar un dispositivo I2C a nuestro microcontrolador, lo primero que debemos hacer es identificar la dirección desde la que se conecta el susodicho dispositivo. Algunos dispositivos pueden configurarse para cambiar su dirección, y otros no. Estos displays LCD son de los que no. :-( Para saber cuál es la dirección I2C de los dispositivos que tenemos conectados, podemos utilizar este script:

| scan_i2c.py
from machine import Pin, SoftI2C
 
sdaPIN=Pin(21)
sclPIN=Pin(22)
 
i2c=SoftI2C(sda=sdaPIN, scl=sclPIN, freq=10000)
 
devices = i2c.scan()
if len(devices) == 0:
    print("Sin dispositivos I2C")
else:
    print('Dispositivos I2C encontrados:',len(devices))
for device in devices:
    print("Dirección: ",hex(device))

Si copiamos este código en Thonny y lo guardamos en nuestro ESP32, al ejecutarlo nos dará una salida como ésta:

Por lo tanto, el display tiene la dirección 0x27 (en hexadecimal, que en binario es 0100111, aunque eso a nosotros ahora mismo poco nos interesa). Utilizaremos 0x27 en nuestro programa para configurar el display.

Y bueno, si ya tenemos conectado nuestro display, es la hora de ver cómo lo vamos a hacer funcionar desde Thonny y MicroPython. Esta vez tampoco será tan simple como en ejemplos anteriores, ya que necesitamos instalar en la ESP32 un par de librerías necesarias para utilizar el display.

¿Que qué es una librería? No te asustes: una librería es sólo un conjunto de utilidades que utilizaremos llamándolas desde nuestro programa. Existen librerías en Python casi para cualquier cosa que se te pueda ocurrir, lo cual facilita muchísimo la elaboración de programas con un esfuerzo mínimo.

En este caso, las librerías que vamos a utilizar son específicas para utilizar el protocolo I2C y para utilizar displays. Es un trabajo que ya nos dan hecho, y lo único que tendremos que conocer (o consultar a medida que lo necesitemos) son las funciones, los parámetros a suministrarles y los resultados que nos ofrecerán. Para asegurarnos de que tendremos las librerías más actualizadas y sin «cosas raras», lo mejor es que nos vayamos directamente a la página de sus desarrolladores. Nosotros usaremos las librerías RPI-PICO-I2C-LCD, que puedes descargar en este enlace.

Como has podido observar, al pulsar sobre el enlace has descargado un archivo zip que contiene la última versión de estas librerías. Dentro hay dos archivos: lcd_api.py y pico_i2c_lcd.py, que tenemos que instalar en nuestra ESP32. Esto lo haremos con Thonny, abriendo estos archivos desde nuestro ordenador y guardando en el dispositivo MicroPython con el mismo nombre.

Una vez que tengamos estas dos librerías en nuestro ESP32, es el momento de crear el programa que hará funcionar el display, en este caso sólo una pequeña demostración, pero que servirá para ilustrar sus capacidades. El código es el siguiente:

| boot.py
from machine import Pin, SoftI2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
from time import sleep
from random import randint
 
I2C_ADDR = 0x27
filas = 2
columnas = 16
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)
lcd = I2cLcd(i2c, I2C_ADDR, filas, columnas)
 
while True:
    f = randint(0,1)
    c = randint(0,6)
    lcd.move_to(c,f)
    lcd.putstr('Hola Pep! ')
    sleep(1)
    lcd.clear()

Y el resultado al ejecutarlo es el que se puede ver en el siguiente vídeo:

Anterior: Parpadeo de un led con ESP32 y MicroPython

Siguiente: Dispositivos I2C con ESP32 y MicroPython (código)