Raspberry Pi + LCD + Python (Clock)

By isendev.

 Posted on 2014/01/01 18:56.

 Tagged as: hardware, programming, diy, python.

I've been playing a bit with my Raspberry PI - LCD combo, and I've come with this code. It shows a simple clock that refreshes every second. Nothing really fancy here, just a proof of concept. What I really want is to show some Raspberry Pi system information on the display. Something relatively easy using the psutil python library.

#!/usr/bin/python
# 20x4 LCD Clock Script for Raspberry Pi.
# Original code by: Matt Hawkins
# Site: http://www.raspberrypi-spy.co.uk
# Modified by: Antonio Perdices.
# Site: https://www.isendev.com
# 01/01/2014

# LCD Wiring.
# 1 : GND                    - TO GROUND
# 2 : 5V                     - TO +5V
# 3 : Contrast (0-5V)        - TO 10K POT OUTPUT
# 4 : RS (Register Select)
# 5 : R/W (Read Write)       - TO GROUND
# 6 : Enable or Strobe
# 7 : Data Bit 0             - NOT USED
# 8 : Data Bit 1             - NOT USED
# 9 : Data Bit 2             - NOT USED
# 10: Data Bit 3             - NOT USED
# 11: Data Bit 4
# 12: Data Bit 5
# 13: Data Bit 6
# 14: Data Bit 7
# 15: Backlight 5V           - NOT USED
# 16: Backlight GND          - NOT USED

# Imports.
import RPi.GPIO as GPIO
import time
import datetime

# GPIO to LCD Mapping.
# Using Broadcom GPIO numbers
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18

# Constants.

# Max chars per line.
LCD_WIDTH = 20

# LCD Byte Mode. 'Character' or 'Command'.
LCD_CHR = True
LCD_CMD = False

# 1st Line LCD RAM address.
LCD_LINE_1 = 0x80
# 2nd Line LCD RAM address.
LCD_LINE_2 = 0xC0
# 3rd Line LCD RAM address.
LCD_LINE_3 = 0x94
# 4th Line LCD RAM address.
LCD_LINE_4 = 0xD4

# Timing constants.
E_PULSE = 0.00005
E_DELAY = 0.00005

# Main program.
def main():

    # Disable warnings.
    GPIO.setwarnings(False)

    # Use Broadcom GPIO numbers.
    GPIO.setmode(GPIO.BCM)

    # Enable GPIO outputs.
    GPIO.setup(LCD_E, GPIO.OUT)  # E
    GPIO.setup(LCD_RS, GPIO.OUT) # RS
    GPIO.setup(LCD_D4, GPIO.OUT) # DB4
    GPIO.setup(LCD_D5, GPIO.OUT) # DB5
    GPIO.setup(LCD_D6, GPIO.OUT) # DB6
    GPIO.setup(LCD_D7, GPIO.OUT) # DB7

    # Init display.
    lcd_init()

    # Write blank lines.
    lcd_byte(LCD_LINE_1, LCD_CMD)
    lcd_string("",2)
    lcd_byte(LCD_LINE_4, LCD_CMD)
    lcd_string("",2)

    # Write message to console.
    print("Press Ctrl+C to exit...")

    # Main loop.
    while True:
        lcd_byte(LCD_LINE_2, LCD_CMD)
        lcd_string(datetime.datetime.now().strftime('%d/%B/%Y'),2)
        lcd_byte(LCD_LINE_3, LCD_CMD)
        lcd_string(datetime.datetime.now().strftime('%H:%M:%S'),2)
        time.sleep(1)

    # Cleaning Up.
    # GPIO.cleanup()

# Init display function.
def lcd_init():

    # Init commands.
    lcd_byte(0x33,LCD_CMD)
    lcd_byte(0x32,LCD_CMD)
    lcd_byte(0x28,LCD_CMD)
    lcd_byte(0x0C,LCD_CMD)
    lcd_byte(0x06,LCD_CMD)
    lcd_byte(0x01,LCD_CMD)

# Send byte data to display.
# bits = data.
# mode = 'True' for character or 'False' for command.
def lcd_byte(bits, mode):

    # Register Select.
    GPIO.output(LCD_RS, mode)

    # Send High bits.
    GPIO.output(LCD_D4, False)
    GPIO.output(LCD_D5, False)
    GPIO.output(LCD_D6, False)
    GPIO.output(LCD_D7, False)
    if bits&0x10==0x10:
        GPIO.output(LCD_D4, True)
    if bits&0x20==0x20:
        GPIO.output(LCD_D5, True)
    if bits&0x40==0x40:
        GPIO.output(LCD_D6, True)
    if bits&0x80==0x80:
        GPIO.output(LCD_D7, True)

    # Toggle 'Enable' pin.
    time.sleep(E_DELAY)
    GPIO.output(LCD_E, True)
    time.sleep(E_PULSE)
    GPIO.output(LCD_E, False)
    time.sleep(E_DELAY)

    # Low bits.
    GPIO.output(LCD_D4, False)
    GPIO.output(LCD_D5, False)
    GPIO.output(LCD_D6, False)
    GPIO.output(LCD_D7, False)
    if bits&0x01==0x01:
        GPIO.output(LCD_D4, True)
    if bits&0x02==0x02:
        GPIO.output(LCD_D5, True)
    if bits&0x04==0x04:
        GPIO.output(LCD_D6, True)
    if bits&0x08==0x08:
        GPIO.output(LCD_D7, True)

    # Toggle 'Enable' pin
    time.sleep(E_DELAY)
    GPIO.output(LCD_E, True)
    time.sleep(E_PULSE)
    GPIO.output(LCD_E, False)
    time.sleep(E_DELAY)

# Send string to display.
# Style parameter:
# 1 = Left justified.
# 2 = Centred.
# 3 = Right justified.
def lcd_string(message,style):

    if style==1:
        message = message.ljust(LCD_WIDTH," ")
    elif style==2:
        message = message.center(LCD_WIDTH," ")
    elif style==3:
        message = message.rjust(LCD_WIDTH," ")

    for i in range(LCD_WIDTH):
        lcd_byte(ord(message[i]),LCD_CHR)

# Execute main program.
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print("\nKeyboard interrupt detected... Bye!")
        lcd_byte(LCD_LINE_2, LCD_CMD)
        lcd_string("",2)
        lcd_byte(LCD_LINE_3, LCD_CMD)
        lcd_string("",2)
        pass


Tags
Archives