Texto dinámico en LCD HD44780

octubre 13th, 2019 Categories: GPIO

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

Tags: , , ,
No comments yet.

Leave a Comment

Solve this *