En esta entrada aprenderemos a programar un LCD I2C con la Raspberry Pi Pico usando MicroPython y adicionalmente veremos que el mismo código y la misma librería puede ser empleada en un NodeMCU ESP8266 o ESP32.
Antes de comenzar te invito a que visites nuestro CURSO GRATUITO DE MICROPYTHON en Raspberry Pi Pico o ESP.
Y que te suscríbas al canal, si te interesa los temas de programación en microcontroladores y principalmente la teoría de la ingeniería de control:
I2C con MicroPython en Raspberry Pi Pico / ESP8266/32
Una de las fomas más fáciles y prácticas de utilizar un display LCD con Raspberry Pi Pico, con NodeMCU ESP8266 o ESP32 es usando directamente un módulo I2C para la conexión de un LCD16x2, LCD20x4 o cualquier otro LCD.

Inicialmente, debemos conocer las funciones de i2c con micropython para poder determinar la dirección i2c del componente y posteriormente conectar la Raspberry Pi Pico lcd 16×2 i2c o el esp8266 micropython lcd i2c. A partir de la documentación oficial de MicroPython podemos determinar:
i2c = machine.I2C
( id = -1 , * , scl , sda , frecuencia = 400000 )
Se construye el objeto I2C usando los siguientes parámetros:
- id identifica un periférico I2C en particular. El valor predeterminado de -1 selecciona una implementación de software de I2C que puede funcionar (en la mayoría de los casos) con pines arbitrarios para SCL y SDA. Si id es -1, entonces se deben especificar los pines scl y sda . Otros valores permitidos para id dependen del puerto / placa en particular, dado que hay placas que poseen varios puertos I2C y la especificación de scl y sda puede o no ser requerida o permitida en este caso.
- scl debe ser un objeto pin que especifique el pin que se utilizará para SCL.
- sda debe ser un objeto pin que especifique el pin que se utilizará para SDA.
- freq debe ser un número entero que establezca la frecuencia máxima para SCL.
Dirección Modulo LCD I2C
Si estamos empleando en nuestro proyecyo un LCD con la Raspberry Pi Pico o si usamos un esp8266 empleando un lcd programado en micropython, necesitamos determinar la dirección del dispositivo.
Podemos usar el siguiente código estandar con MicroPython para ver cual es la dirección del Módulo I2C.
import machine import utime i2c = machine.I2C(0, scl=machine.Pin(9), sda=machine.Pin(8), freq=200000) direccion = hex(i2c.scan()[0]) print('La dirección I2C es ', direccion)
LCD I2C con MicroPython
En este tutorial de la Raspberry Pi Pico con Display LCD via I2c donde empleamos también el nodemcu esp8266 donde conectamos un lcd de los que venden en el mercado veremos como programarlo paso a paso en MicroPython.
Inicialmente, deberemos descargar alguna librería que sea capaz de controlar el LCD via I2C directamente con MicroPytho, esto la podremos encontrar directamente en el IDE de Thonny, pero para este caso usaremos la librería RPI-PICO-I2C-LCD (click para descargar)
Instalación de la Librería
Una vez descargada y descomprimida la librería, verás que tendrás tres archivos con extensión .py, y para que funcione la librería, debes pasar el archivo lcd_api.py y pico_i2c_lcd.py a la memoria de la Raspberry Pi Pico. Eso lo puedes hacer con el IDE de Thonny, dando click en VIEW/FILES
Se abrirá la ventana de archivos, donde en la parte superior te muestra los archivos que tiene tu computador y en la parte inferior los archivos de tu raspberry pi pico, debes dar click derecho sobre los archivos que deseas pasar a la memoria de la pico y dar click donde dice Upload to/
Finalmente verifica que los archivos se encuentren dentro de la Flash de la PICO

Funciones de la librería
- lcd.putstr (“¡El texto va aquí!”) – Envía una cadena de caracteres a la pantalla. IMPORTANTE: para imprimir una variable puedes usar la siguiente instrucción: lcd.putstr (str (Variable)) [Convierte la variable en una cadena]
- lcd.show_cursor() / lcd.hide_cursor() – Mostrar / Ocultar el cursor de la pantalla lcd (barra blanca)
- lcd.blink_cursor_on() / lcd.blink_cursor_off() – Enciende / apaga el cursor parpadeante al imprimir
- lcd.backlight_on() / lcd.backlight_off() – Enciende / apaga la luz de fondo de la pantalla LCD (controlada por un pequeño transistor en la biblioteca)
- lcd.display_on() / lcd.display_off() – Enciende / apaga la pantalla (no la retroiluminación sino todo el chip)
- lcd.clear(): borra todos los caracteres o cualquier cosa escrita en la pantalla
- lcd.move_to(Col, Row) – Mover a la posición según los valores de fila y col (Y, X)
- lcd.custom_char(Num, bytearray ([caracteres HEX]))) – Num puede ser cualquier número entero 0 – 8 (escribiendo en ubicaciones CGRAM) simplemente utilizado para numerar. Los caracteres HEX se crean simplemente usando este enlace: https://maxpromer.github.io/LCD-Character-Creator/ . Proporcionará una cadena de caracteres hexadecimales que pueden reemplazar los “caracteres HEX” en el comando de ejemplo
Raspberry Pi Pico LCD I2C
El circuito empleado en micropython con la Raspberry Pi Pico usando el módulo I2C y un LCD16x2 será el siguiente, donde alimentaremos el display con el pin VBUS de la placa (Pin 40)

ESP8266 LCD display
El circuito con el esp8266 empleando un lcd 16×2 será el siguiente:

Código en MicroPython Display LCD – I2C
El siguiente código puede ser usado tanto con la Raspberry Pi Pico como en un ESP, a modo de ejemplo el NodeMCU ESP8266, basta solo configurar los pines empleados para la comunicación i2c.
import utime from machine import I2C,Pin from lcd_api import LcdApi from pico_i2c_lcd import I2cLcd #Dirección del I2C y tamaño del LCD I2C_ADDR = 0x27 I2C_NUM_ROWS = 2 I2C_NUM_COLS = 16 # Raspberry Pi Pico i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000) #Esp8266 #i2c = I2C(sda=Pin(4), scl=Pin(5), freq=100000) #Configuración LCD lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) battery_0 = [0x0E, 0x1B, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F] battery_15 = [0x0E, 0x1B, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x1F] battery_30 = [ 0x0E, 0x1B, 0x11, 0x11, 0x11, 0x1F, 0x1F, 0x1F] battery_45 = [0x0E, 0x1B, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F] battery_60 = [0x0E, 0x1B, 0x11, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F] battery_75 = [0x0E, 0x1B, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F] battery_100 = [0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F] def lcd_str(message, col, row): lcd.move_to(col, row) lcd.putstr(message) def main(): lcd.custom_char(0, bytearray(battery_0)) lcd.custom_char(1, bytearray(battery_15)) lcd.custom_char(2, bytearray(battery_30)) lcd.custom_char(3, bytearray(battery_45)) lcd.custom_char(4, bytearray(battery_60)) lcd.custom_char(5, bytearray(battery_75)) lcd.custom_char(6, bytearray(battery_100)) while True: lcd.clear() lcd_str("Battery:", 0, 0) lcd.move_to(0,1) for i in range(0,7): lcd.putchar(chr(i)) utime.sleep(3) lcd.clear() lcd.move_to(0,0) lcd.putstr("Suscribete a ") utime.sleep(1) lcd.move_to(0,1) lcd.putstr("Control ") utime.sleep(1) lcd_str("Automatico ", 0, 0) utime.sleep(1) lcd_str("Educacion ", 0, 1) utime.sleep(1) lcd.clear() lcd_str("Numeros en", 3,0) lcd_str("Esquinas", 4,1) utime.sleep(1) lcd_str("1", 0,0) utime.sleep(1) lcd_str("2", 15,0) utime.sleep(1) lcd_str("3", 0,1) utime.sleep(1) lcd_str("4", 15,1) utime.sleep(1) lcd.clear() lcd_str("Suscribete", 0, 0) lcd_str("Activa: CAMPANA", 0, 1) lcd.blink_cursor_on() utime.sleep(2) #Backspace for j in range(1, -1, -1): for i in range(15, -1, -1): lcd.move_to(i, j) lcd.putstr(' ') utime.sleep_ms(100) utime.sleep(1) lcd.hide_cursor() #BackLight lcd.clear() lcd.backlight_off() lcd_str("BackLight OFF", 0, 0) utime.sleep(3) lcd.clear() lcd.backlight_on() lcd_str("BackLight ON", 0, 0) utime.sleep(3) if __name__ == '__main__': main()
Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:
👉 Invitar a Sergio a un Café ☕️
Que esten muy bien, nos vemos en la siguiente entrada.