Approved Reseller
Approved Reseller
Uno de los elementos más vistosos que se pueden usar con una Raspberry Pi Pico es la pantalla LCD Grove. Prácticamente es el elemento faltante para tener una “computadora” en miniatura. Entre algunos de los métodos para comunicarse con este tipo de dispositivos existe el llamado protocolo I2C, el cual veremos de forma rápida. En este tutorial estaremos usando los siguientes materiales:
Para manejar el módulo de LCD de Grove necesitarás utilizar una librería que contiene todas las funciones necesarias para controlar tu LCD. A grandes rasgos es un código que incluye como mover el cursor en la pantalla, borrarla y poner caracteres en ella. Para usarla solo copia el código en un archivo llamado grove_lcd_i2c.py y guárdalo en la carpeta donde tengas tu código o dentro de la Raspberry Pi Pico. Al final del post encontrarás el código.
El puerto I2C permite conectar una gran diversidad de módulos con solo dos cables a tu Pico. Para lograr esto manda datos digitales a una dirección que corresponde al módulo que quieres usar y un comando. Puedes conectar tantos módulos como direcciones haya disponibles. En nuestro caso conectaremos la LCD en el puerto I2C_0 que está en los pines 0 y 1 de tu Pico.
Este código es una prueba simple para desplegar mensajes en la Raspberry Pi Pico. Como puedes ver estamos asignando dos pines digitales, llamados LCD_SDA y LCD_SCL. Estos corresponden a los pines de datos del protocolo I2C. Además, definimos una variable LCD_ADDR, con un valor de 62. Esa es la dirección de nuestra pantalla LCD. Para iniciar la comunicación serial, usamos la función I2C() y para iniciar la pantalla LCD, usamos la función Grove_LCD_I2C(). Por último, la función home() manda el cursor de la pantalla al primer caracter y la función write() escribe el mensaje.
from machine import * import utime from grove_lcd_i2c import Grove_LCD_I2C utime.sleep(1) led = Pin(25, Pin.OUT) LCD_SDA = Pin(0) LCD_SCL = Pin(1) LCD_ADDR = 62 # 0x3E or 62 i2c = I2C(0, sda=LCD_SDA, scl=LCD_SCL) #print(i2c.scan()) lcd = Grove_LCD_I2C(i2c, LCD_ADDR) lcd.home() lcd.write("Raspberry Pi \nPico")
La pantalla puede actualizarse con datos que leamos desde la Pico, no necesariamente datos de texto que hayamos programado previamente. Para lograr esto, podemos configurar una lectura analógica y mostrarla en la pantalla cada segundo. Para ello, solo tenemos que asignar el pin analógico, y guardar la lectura en una variable de texto tipo string. En este caso, el valor lo convertimos a un porcentaje, que representa el ancho de pulso de una salida PWM. En este caso, usamos una nueva función llamada clear() que nos permite borrar la pantalla.
from machine import * import utime from grove_lcd_i2c import Grove_LCD_I2C utime.sleep(1) led = Pin(25, Pin.OUT) LCD_SDA = Pin(0) LCD_SCL = Pin(1) LCD_ADDR = 62 # 0x3E or 62 i2c = I2C(0, sda=LCD_SDA, scl=LCD_SCL) lcd = Grove_LCD_I2C(i2c, LCD_ADDR) adc = machine.ADC(26) conversion_factor = 100 / (65535) while True: porcentaje = adc.read_u16() * conversion_factor lcd.home() lcd.clear() out_string = "PWM %: " + str(porcentaje) lcd.write(out_string) utime.sleep(1)
Conclusiones:
Con estos comandos podrás mandar mensajes a tu pantalla LCD Grove, mientras quepan en la pantalla. Prueba a combinarlo con otros sensores, como un sensor de temperatura o de luz. Igual y si lo usas como una tarjeta de presentación en un negocio también está perfecto. ¡Te invitamos a que sigas los demás tutoriales de Raspberry Pi Pico que tenemos para ti!
Referencias:
Making A Lucky Draw Device Using Raspberry Pi Pico
# # Grove 16x2 I2C LCD (White on Blue) # - https://my.cytron.io/p-grove-16-x-2-lcd-white-on-blue?tracking=idris # # Update: # 10 Jan 2021: Tested with MicroPython ESP32 V1.13 # from machine import Pin, I2C import utime class Grove_LCD_I2C(object): # Commands LCD_CLEARDISPLAY = 0x01 LCD_RETURNHOME = 0x02 LCD_ENTRYMODESET = 0x04 LCD_DISPLAYCONTROL = 0x08 LCD_CURSORSHIFT = 0x10 LCD_FUNCTIONSET = 0x20 LCD_SETCGRAMADDR = 0x40 LCD_SETDDRAMADDR = 0x80 # Flags for display entry mode LCD_ENTRYRIGHT = 0x00 LCD_ENTRYLEFT = 0x02 LCD_ENTRYSHIFTINCREMENT = 0x01 LCD_ENTRYSHIFTDECREMENT = 0x00 # Flags for display on/off control LCD_DISPLAYON = 0x04 LCD_DISPLAYOFF = 0x00 LCD_CURSORON = 0x02 LCD_CURSOROFF = 0x00 LCD_BLINKON = 0x01 LCD_BLINKOFF = 0x00 # Flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 LCD_MOVERIGHT = 0x04 LCD_MOVELEFT = 0x00 # Flags for function set LCD_8BITMODE = 0x10 LCD_4BITMODE = 0x00 LCD_2LINE = 0x08 LCD_1LINE = 0x00 LCD_5x10DOTS = 0x04 LCD_5x8DOTS = 0x00 def __init__(self, i2c, address, oneline=False, charsize=LCD_5x8DOTS): self.i2c = i2c self.address = address self.disp_func = self.LCD_DISPLAYON # | 0x10 if not oneline: self.disp_func |= self.LCD_2LINE elif charsize != 0: # For 1-line displays you can choose another dotsize self.disp_func |= self.LCD_5x10DOTS # Wait for display init after power-on utime.sleep_ms(50) # 50ms # Send function set self.cmd(self.LCD_FUNCTIONSET | self.disp_func) utime.sleep_us(4500) ##time.sleep(0.0045) # 4.5ms self.cmd(self.LCD_FUNCTIONSET | self.disp_func) utime.sleep_us(150) ##time.sleep(0.000150) # 150µs = 0.15ms self.cmd(self.LCD_FUNCTIONSET | self.disp_func) self.cmd(self.LCD_FUNCTIONSET | self.disp_func) # Turn on the display self.disp_ctrl = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF self.display(True) # Clear it self.clear() # Set default text direction (left-to-right) self.disp_mode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT self.cmd(self.LCD_ENTRYMODESET | self.disp_mode) def cmd(self, command): assert command >= 0 and command < 256 command = bytearray([command]) self.i2c.writeto_mem(self.address, 0x80, bytearray([])) self.i2c.writeto_mem(self.address, 0x80, command) def write_char(self, c): assert c >= 0 and c < 256 c = bytearray([c]) self.i2c.writeto_mem(self.address, 0x40, c) def write(self, text): for char in text: if char == '\n': self.cursor_position(0, 1) else: self.write_char(ord(char)) def cursor(self, state): if state: self.disp_ctrl |= self.LCD_CURSORON self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) else: self.disp_ctrl &= ~self.LCD_CURSORON self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) def cursor_position(self, col, row): col = (col | 0x80) if row == 0 else (col | 0xc0) self.cmd(col) def autoscroll(self, state): if state: self.disp_ctrl |= self.LCD_ENTRYSHIFTINCREMENT self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) else: self.disp_ctrl &= ~self.LCD_ENTRYSHIFTINCREMENT self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) def blink(self, state): if state: self.disp_ctrl |= self.LCD_BLINKON self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) else: self.disp_ctrl &= ~self.LCD_BLINKON self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) def display(self, state): if state: self.disp_ctrl |= self.LCD_DISPLAYON self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) else: self.disp_ctrl &= ~self.LCD_DISPLAYON self.cmd(self.LCD_DISPLAYCONTROL | self.disp_ctrl) def clear(self): self.cmd(self.LCD_CLEARDISPLAY) utime.sleep_ms(2) # 2ms def home(self): self.cmd(self.LCD_RETURNHOME) utime.sleep_ms(2) # 2m