Texto dinámico en LCD HD44780
En este proyecto voy a controlar una pantallita LCD HD44780 para mostrar un texto scrolleando.
Necesitaremos, a parte de la Raspberry Pi, lo siguiente:
- LCD HD44780 o similar (habría que adaptar el pinout si usáis otro)
- Placa board para sostener los componentes
- 8 cables con pines hembra-macho de colores
- Varios trozos de cable para puentear
- Potenciómetro 10k Ohm (103) o resistencia de 470 Ohm (opcional)
El LCD HD44780 tiene 16 pines (Vss, Vdd, V0, RS, RW, E, D0, D1, D2, D3, D4, D5, D6, D7, A, K) y usaremos la siguiente asignación de pines:
- Vss hacia GND
- Vdd hacia +5V
- V0 hacia GND o hacia la patilla negativa del potenciómetro si lo usamos (la otra patilla del potenciómetro iría a +5V)
- RS hacia pin GPIO2 para conmutar entre enviar comando o enviar dato
- RW hacia GND porque solo vamos a escribir en el LCD, nunca a leer
- E hacia pin GPIO3 para habilitar/deshabilitar el LCD
- D4..D7 para datos en modo 4 bits (los conectaremos, por orden, a GPIO25, GPIO8, GPIO9, GPIO11)
- A a +5V (es el ánodo)
- K a GND (es el cátodo)
Para organizar mejor los cables he utilizado unos adaptadores de placa base para USB/Firewire que he cortado y adaptado, así que nos quedarán 2 grupos: el rojo para los datos y el azul para alimentación, RS y E.
La numeración que seguiremos será la GPIO, para ello estableceremos el modo BCM con GPIO.setmode(BCM). Por ejemplo, en modo BCM el pin E sería 3 (GPIO3), en modo BOARD el pin E sería el 5 como se puede observar en la siguiente imagen.

Y ahora el código! hay que instalar los siguientes paquetes para poder ejecutar el script python:
sudo apt-get install python-setuptools
sudo apt-get install python-pip
sudo pip install rpi.gpio
Mostrando el Lorem Ipsum con scroll (dinámico) o mensaje estático (comentado)
#!/usr/bin/python
import RPi.GPIO as GPIO
from time import sleep
class HD44780:
'''
Inicializador
'''
def __init__(self):
#Establecer pines GPIO de la Raspberry Pi para los pines RS, E y datos
self.pin_rs = 2
self.pin_e = 3
self.pins_db = [25, 8, 9, 11]
self.dinamico = False #Modo estático activado (el texto aparece escrito instantáneamente)
#Establecer los pines como salida
GPIO.setmode(GPIO.BCM) #Numeración BCM (numeración GPIO en lugar de numeración física de la placa)
GPIO.setup(self.pin_e, GPIO.OUT) #Establecer pin Enable como salida
GPIO.setup(self.pin_rs, GPIO.OUT) #Establecer pin Commando/Dato como salida
for pin in self.pins_db: #Establecer pines de datos como salida
GPIO.setup(pin, GPIO.OUT)
self.clear() #Llamar a función local para vaciar la pantalla y setearla
'''
Vaciar pantalla y configurarla
'''
def clear(self):
self.cmd(0x28) # Function set: Modo 4 bits, 2 líneas, 5x7 pixels (DL = 0: 4 bits, N = 1: 2 lines, F = 0: 5x7 dots, # = 0: Not 24x4 module)
self.cmd(0x0C) # Display ON/OFF Control: Display activado, cursor y parpadeo desactivado (D = 1: Display On, C = 0: Cursor Off, B: Cursor blink off)
self.cmd(0x06) # Entry Mode Set: Dirección del cursor (I/D = 1: Increment, S = 0: Do not accompany display shift)
self.cmd(0x01) # Clear Display: Vaciar pantalla
'''
Enviar comando
bits: comando a enviar
char_mode: modo comando/dato. Por defecto en false (comando)
'''
def cmd(self, bits, char_mode=False):
sleep(0.001) #Esperar 1ms
bits = bin(bits) #Castear a binario
bits = bits[2:] #Descartar los primeros 2 bits (0b)
zeros = (8 - len(bits)) * "0" #Generar "00"
bits = zeros + bits #Insertar los dos "00" a la izquierda de bits
GPIO.output(self.pin_rs, char_mode) #Establecer pin RS = modo comando / modo dato
#Primer paquete
self.inicializarDatos() #Inicializar datos a 0
for i in range(4): #Se envian los datos, de 0 a 3
if bits[i] == "1":
GPIO.output(self.pins_db[::-1][i], True) #Enviar solo los 1, los demás son 0 por defecto
self.refrescarEnable() #Refrescar enable
#Segundo paquete
self.inicializarDatos() #Inicializar datos a 0
for i in range(4, 8): #Se envian los datos, de 4 a 7
if bits[i] == "1":
GPIO.output(self.pins_db[::-1][i-4], True) #Enviar solo los 1, los demás son 0 por defecto
self.refrescarEnable() #Refrescar enable
'''
Mensaje a enviar (Soporte para cadenas con y sin salto de linea \n incluido)
text: texto a enviar en string
dinamico: modo dinámico. Por defecto en false (estático)
'''
def message(self, text, dinamico=False):
self.dinamico = dinamico
caracter = 0 #Contador de caracter (0 a 31)
for i in range(len(text)):
if text[i] == '\n': #Salto de línea explícito
self.cmd(0xC0) #Segunda línea (Mover cursor a posición 0x40)
if self.dinamico:
if caracter == 16: #Salto de linea implícito
self.cmd(0xC0) #Segunda línea (Mover cursor a posición 0x40)
elif caracter == 31: #Fin de la segunda línea
self.cmd(0x0F) #Poner cursor parpadeando
sleep(3) #Esperar 3 segundos
self.cmd(0x0C) #Segunda linea y quitar cursor parpadeando
self.cmd(0x01) #Borrar display y cursor a home
caracter = 0 #Resetear contador de caracter
if text[i] != '\n': #Enviar caracter si no es un salto de línea
self.cmd(ord(text[i]), True)
caracter += 1 #Incrementar contador de caracter
'''
Inicializar datos
'''
def inicializarDatos(self):
for pin in self.pins_db:
GPIO.output(pin, False) #Inicializar todos los pines de datos a 0
'''
Refrescar enable
'''
def refrescarEnable(self):
if(self.dinamico):
sleep(0.01) #Esperar 10ms solo en modo dinamico
GPIO.output(self.pin_e, True) #Enable = 1
if(self.dinamico):
sleep(0.01) #Esperar 10ms solo en modo dinamico
GPIO.output(self.pin_e, False) #Enable = 0
if(self.dinamico):
sleep(0.01) #Esperar 10ms solo en modo dinamico
'''
Función principal
'''
if __name__ == '__main__':
lcd = HD44780() #Cargar clase principal
#lcd.clear()
#lcd.message(" Welcome to\nUltimateRaspbian") #Mensaje estático
lcd.message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam metus justo, eleifend et quam eget, congue consectetur lacus", True) #Mensaje dinámico
GPIO.cleanup()
He necesitado leer el datasheet del LCD HD44780 https://www.sparkfun.com/datasheets/LCD/HD44780.pdf para asegurarme del voltaje, lo que hace cada pin, qué comandos enviar para configurarlo a mi manera, etc.

Aquí el instruction set para las configuraciones:

Proyecto basado en las siguientes referencias:
Mostrar un mensaje con HD44780 -> http://www.rpiblog.com/2012/11/interfacing-16×2-lcd-with-raspberry-pi.html
Otro proyecto más completo -> https://cdn-learn.adafruit.com/downloads/pdf/drive-a-16×2-lcd-directly-with-a-raspberry-pi.pdf
Otro proyecto con texto scrolleando -> https://github.com/zzeromin/RetroPie-Clcd
Comandos e instrucciones para configurar -> http://www.dinceraydin.com/lcd/commands.htm
Datasheet LCD HD44780 -> https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
Y así es como queda



Null Games