En esta guía completa, te enseñaremos a programar un LCD 16×2 I2C con la Raspberry Pi Pico utilizando MicroPython. Además, exploraremos cómo el mismo código y librería pueden ser aplicados en otras plataformas como NodeMCU ESP8266 o ESP32. Si estás trabajando con módulos I2C para pantallas LCD, este tutorial te proporcionará todas las herramientas y conocimientos necesarios para simplificar tus proyectos de electrónica.
Si estás familiarizado con otros microcontroladores como PIC o Arduino, y has trabajado con el protocolo I2C, este tutorial te resultará bastante sencillo. Si aún no has explorado el uso del I2C con PIC, te invitamos a revisar nuestra guía detallada sobre I2C con PIC, donde cubrimos la implementación de este protocolo en microcontroladores PIC como el PIC16F877A. También, si estás usando Arduino, no te pierdas nuestro tutorial sobre I2C con Arduino, donde exploramos cómo conectar y programar periféricos I2C como pantallas LCD en placas Arduino.
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:
Entendiendo el Protocolo I2C: Comunicación Simple y Eficiente
El protocolo I2C (Inter-Integrated Circuit) es una tecnología de comunicación serie ampliamente utilizada en proyectos electrónicos, desde sistemas embebidos hasta microcontroladores como el Raspberry Pi Pico. Su principal ventaja es que permite conectar múltiples dispositivos a un mismo bus utilizando solo dos cables: SDA (Serial Data Line) para la transmisión de datos y SCL (Serial Clock Line) para la sincronización de estos datos.
¿Cómo Funciona I2C?
A diferencia de otros protocolos como SPI, que requiere múltiples cables para cada dispositivo, I2C simplifica la comunicación permitiendo que todos los dispositivos compartan el mismo bus de datos. Esto es posible porque cada dispositivo conectado al bus tiene una dirección única, que se utiliza para identificarlo durante la comunicación.
Cuando un dispositivo maestro, como la Raspberry Pi Pico, desea comunicarse con un dispositivo esclavo, como un LCD 16×2 o un sensor de temperatura, primero envía un pulso de reloj a través de la línea SCL para sincronizar todos los dispositivos en el bus. Luego, el maestro envía la dirección del esclavo con el que quiere comunicarse a través de la línea SDA, seguida por los datos que quiere transferir. El dispositivo esclavo que tiene la dirección correspondiente responde y recibe o envía los datos según sea necesario.
Configuración de Dispositivos en I2C
Para usar el I2C en tus proyectos con Raspberry Pi Pico o cualquier otro microcontrolador, lo primero que debes hacer es configurar los pines SDA y SCL en tu código. Estos pines deben estar conectados correctamente a los dispositivos esclavos, como el LCD I2C, que estamos utilizando en este tutorial. Por ejemplo, en la Raspberry Pi Pico, los pines comunes para I2C son el Pin 0 para SDA y el Pin 1 para SCL.
Es importante mencionar que el protocolo I2C también requiere la adición de resistencias pull-up en las líneas SDA y SCL para garantizar que las líneas se mantengan en un estado alto cuando no se está transmitiendo datos. Esto es esencial para evitar errores de comunicación en el bus I2C.
Aplicaciones del Protocolo I2C
El protocolo I2C es increíblemente versátil y se utiliza en una variedad de aplicaciones más allá de la conexión de pantallas LCD. Por ejemplo, puedes conectar varios sensores (como acelerómetros, giroscopios, o sensores de temperatura), módulos de memoria EEPROM, relojes en tiempo real (RTC), y más. La capacidad de conectar múltiples dispositivos a través de un solo bus hace que I2C sea la opción preferida en muchos proyectos de sistemas embebidos y electrónica.
En este tutorial, hemos enfocado nuestro uso de I2C en la Raspberry Pi Pico, pero si estás trabajando con otros microcontroladores como el ESP8266, ESP32, o incluso PIC y Arduino, el proceso es muy similar. La clave está en configurar correctamente los pines y entender cómo identificar la dirección I2C de cada dispositivo para asegurar una comunicación eficiente.
I2C con MicroPython en Raspberry Pi Pico / ESP8266/32
Una de las maneras más efectivas de conectar un LCD 16×2 o LCD 20×4 a una Raspberry Pi Pico o a un ESP8266/ESP32 es mediante un módulo I2C. Este protocolo simplifica considerablemente la conexión al usar solo dos pines: SDA y SCL. Si quieres aprender más sobre cómo configurar I2C en PIC o I2C en Arduino, no dudes en visitar nuestras guías especializadas.
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
Cuando trabajas con un LCD 16×2 I2C en una Raspberry Pi Pico o un ESP8266 programado en MicroPython, es crucial identificar la dirección I2C del módulo para una correcta configuración. Este paso es similar al proceso que seguimos en otros microcontroladores, como los PIC o Arduino, donde también se requiere conocer la dirección I2C para establecer la comunicación adecuada. Puedes encontrar más información sobre cómo hacerlo en nuestros tutoriales dedicados a I2C en PIC y I2C en Arduino.
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 tres archivos con extensión .py. Para que la librería funcione correctamente en tu Raspberry Pi Pico, asegúrate de transferir los archivos lcd_api.py y pico_i2c_lcd.py a la memoria de la placa utilizando el IDE de Thonny. Si estás familiarizado con la configuración de I2C en otros microcontroladores, como los PIC o Arduino, este proceso te resultará sencillo y rápido.
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:
Display OLED Raspberry Pi Pico / ESP8266
Operadores Lógicos y Relacionales
Sensor de Presión MPX con PIC
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.
Mi nombre es Sergio Andres Castaño Giraldo, y en este sitio web voy a compartir una de las cosas que mas me gusta en la vida y es sobre la Ingeniería de Control y Automatización. El sitio web estará en constante crecimiento, voy a ir publicando material sobre el asunto desde temas básicos hasta temas un poco más complejos. Suscríbete al sitio web, dale me gusta a la página en Facebook y únete al canal de youtube. Espero de corazón que la información que comparto en este sitio, te pueda ser de utilidad. Y nuevamente te doy las gracias y la bienvenida a control automático educación.