Home > general > A minimal LCD (HD44780) library for MicroPython

A minimal LCD (HD44780) library for MicroPython

This post demonstrates a minimal LCD library for MicroPython, used on an ESP8266. This is a small collection of commands that I put together (mostly ported) to have simple control over an HD44780 compatible LCD. There are a couple of existing LCD libraries for MicroPython so make sure to check them out first, since this is a minimalistic approach and may be limiting for you project. The post is merely a reference to the code rather than full explanation on how HD44780 LCD works. There are plenty of sources about that as well as the post of the code’s original author.

I am using the NodeMCU board so make sure to adjust the connections according to the board you are using. The LCD uses an 8-bit data bus but it also supports 4-bit mode. That means we can break a byte to two nibbles (4 bits) and save up 4 wired connections.

Let’s take a look at the code. Credit goes to Matt Hawkins over raspberrypi-spy.co.uk who is the original author of the code. I just ported it over to MicroPython and made a couple of simple changes.

import machine
import time
 
LCD_RS = 16
LCD_E = 5
LCD_D4 = 4
LCD_D5 = 0
LCD_D6 = 2
LCD_D7 = 14
 
LCD_WIDTH = 16
LCD_CHR = True
LCD_CMD = False
 
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
 
E_PULSE = 0.0005
E_DELAY = 0.0005
 
pin_lcd_e = machine.Pin(LCD_E, machine.Pin.OUT)
pin_lcd_rs = machine.Pin(LCD_RS, machine.Pin.OUT)
pin_lcd_d4 = machine.Pin(LCD_D4, machine.Pin.OUT)
pin_lcd_d5 = machine.Pin(LCD_D5, machine.Pin.OUT)
pin_lcd_d6 = machine.Pin(LCD_D6, machine.Pin.OUT)
pin_lcd_d7 = machine.Pin(LCD_D7, machine.Pin.OUT)
 
def main():
    lcd_init()
    lcd_string("HD44780 LCD", LCD_LINE_1)
    lcd_string("with MicroPython", LCD_LINE_2)
 
def lcd_init():
    lcd_byte(0x33, LCD_CMD)
    lcd_byte(0x32, LCD_CMD)
    lcd_byte(0x0C, LCD_CMD)
    lcd_byte(0x01, LCD_CMD)
    lcd_byte(0x28,LCD_CMD)
    lcd_byte(0x06,LCD_CMD)
    time.sleep(E_DELAY)
 
def lcd_byte(bits, mode):
    pin_lcd_rs.value(mode)
    pin_lcd_d4.low()
    pin_lcd_d5.low()
    pin_lcd_d6.low()
    pin_lcd_d7.low()
    if bits & 0x10 == 0x10:
        pin_lcd_d4.high()
    if bits & 0x20 == 0x20:
        pin_lcd_d5.high()
    if bits & 0x40 == 0x40:
        pin_lcd_d6.high()
    if bits & 0x80 == 0x80:
        pin_lcd_d7.high()
    lcd_toggle_enable()
    pin_lcd_d4.low()
    pin_lcd_d5.low()
    pin_lcd_d6.low()
    pin_lcd_d7.low()
    if bits & 0x01 == 0x01:
        pin_lcd_d4.high()
    if bits & 0x02 == 0x02:
        pin_lcd_d5.high()
    if bits & 0x04 == 0x04:
        pin_lcd_d6.high()
    if bits & 0x08 == 0x08:
        pin_lcd_d7.high()
    lcd_toggle_enable()
 
def lcd_toggle_enable():
    time.sleep(E_DELAY)
    pin_lcd_e.high()
    time.sleep(E_PULSE)
    pin_lcd_e.low()
    time.sleep(E_DELAY)
 
def lcd_string(message, line):
    lcd_byte(line, LCD_CMD)
    for c in message: # Print out the message
        lcd_byte(ord(c), LCD_CHR)
    for i in range(LCD_WIDTH - len(message)): # Fill the rest of the line with empty characters
        lcd_byte(32, LCD_CHR)
 
main()

Copy the above code in a file, for example lcd.py and then use the following command to give it a test run (assuming your port is /dev/ttyUSB0)

ampy --port /dev/ttyUSB0 run lcd.py

Here is how it should look like šŸ™‚

hd44780-lcd-with-micropython

I did some changes in the lcd_string function in order to support multi length strings. So what it does, it first prints the contents of the message and then fills the rest of the line with empty characters in order to delete any remains from the previous refresh.

Hope this helps you out. Let me know in the comments.


Related Posts:



Categories: general Tags:
  1. No comments yet.
  1. No trackbacks yet.