16×2 LCD an Raspberry Pi betreiben

Etwas was ich schon länger mal ausprobieren wollte, aber bisher keine Verwendung für gefunden habe ist es ein LC Display an einem Raspberry Pi zu betreiben um diverse Informationen darauf auszugeben. Ich war eigentlich auf der Suche nach einem Set von Widerständen unterschiedlicher Größe und bin dabei über ein Sensor Set für Arduino und Raspberry gestolpert in dem praktischerweise auch Widerstände enthalten waren. Zudem war dort ein 16×2 LCD mit dabei, so das ich mal damit rumspielen konnte.

Nach ein wenig Recherche im Internet habe ich auch einige Anleitungen, Schaltpläne und Scripte gefunden die ich dann versucht habe umzusetzen. Problem dabei war das die entweder für einen alten Pi 1 oder für Arduino waren. Also habe ich gedacht ich schreibe mal eine eigenes Tutorial dazu basierend auf einem aktuellen RPi 3B.

Hardware

  • Raspberry Pi (im Grunde egal welche Version)
  • 16×2 LC Display
  • Widerstände (330 oder 470 und 2.2k Ohm)
  • Jumperkabel

Aufbau


Links befindet sich der 2.2k Ohm Widerstand der die Helligkeit der Hintergrundbeleuchtung der einzelnen Blöcke steuert.
Rechts kommt der 330 oder 470 Ohm Widerstand hin, der für die Helligkeit der Buchstaben da ist.
Mit beidem kann man etwas rumspielen. In meinen Tests hat sich herausgestellt das für die Hintergrundbeleuchtung min. 2.2k Ohm oder 2x 1k Ohm in Reihe am besten ist. Man kann auch etwas erhöhen.

Software

Als Betriebssystem kommt bei mir Raspbian Stretch zum Einsatz. Wie das konfiguriert wird erkläre ich hier nun nicht. Es sollte aber auch unter jedem anderen Linux System auf dem Pi funktionieren (Ubuntu Mate, Arch, DietPi etc.). Wichtig ist nur das Python installiert ist.

Anschließend kann man folgendes Script als Beispiel verwenden:

#!/usr/bin/python
# -*- coding: utf-8 -*-
#--------------------------------------
#    ___  ___  _ ____
#   / _ \/ _ \(_) __/__  __ __
#  / , _/ ___/ /\ \/ _ \/ // /
# /_/|_/_/  /_/___/ .__/\_, /
#                /_/   /___/
#
#  lcd_16x2.py
#  16x2 LCD Test Script with
#  backlight control and text justification
#
# Author : Matt Hawkins
# Date   : 06/04/2015
#
# http://www.raspberrypi-spy.co.uk/
#
# Copyright 2015 Matt Hawkins
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#--------------------------------------

# The wiring for the LCD is as follows:
# 1 : GND
# 2 : 5V
# 3 : Contrast (0-5V)*
# 4 : RS (Register Select)
# 5 : R/W (Read Write)       - GROUND THIS PIN
# 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: LCD Backlight +5V**
# 16: LCD Backlight GND

#import
import RPi.GPIO as GPIO
import time, os, datetime

# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18
LED_ON = 15

# Define some device constants
LCD_WIDTH = 16    # Maximum characters per line
LCD_CHR = True
LCD_CMD = False

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005


# get cpu speed
def get_cpu_speed():
  tempFile = open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq")
  cpu_speed = tempFile.read()
  tempFile.close()
  return int(cpu_speed)/1000

# special char degree
degree = chr(223)

def main():
  # Main program block
  
  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
  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
  GPIO.setup(LED_ON, GPIO.OUT) # Backlight enable

  # Initialise display
  lcd_init()

  # Toggle backlight on-off-on
  lcd_backlight(True)
  time.sleep(0.5)
  lcd_backlight(False)
  time.sleep(0.5)
  lcd_backlight(True)
  time.sleep(0.5)

  while True:
  
    # Return current date and time
    from datetime import datetime
    now = datetime.now()
    
    # Return CPU temperature as a character string                                      
    def getCPUtemperature():
        res = os.popen('vcgencmd measure_temp').readline()
        return(res.replace("temp=","").replace("'C\n",""))

    # Return RAM information (unit=kb) in a list                                        
    # Index 0: total RAM                                                                
    # Index 1: used RAM                                                                 
    # Index 2: free RAM                                                                 
    def getRAMinfo():
        p = os.popen('free')
        i = 0
        while 1:
            i = i + 1
            line = p.readline()
            if i==2:
                return(line.split()[1:4])

    # Return % of CPU used by user as a character string                                
    def getCPUuse():
        return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip(\
    )))

    # Return information about disk space as a list (unit included)                     
    # Index 0: total disk space                                                         
    # Index 1: used disk space                                                          
    # Index 2: remaining disk space                                                     
    # Index 3: percentage of disk used                                                  
    def getDiskSpace():
        p = os.popen("df -h /")
        i = 0
        while 1:
            i = i +1
            line = p.readline()
            if i==2:
                return(line.split()[1:5])
      
    # CPU informatiom
    CPU_temp = getCPUtemperature()
    CPU_usage = getCPUuse()

    # RAM information
    # Output is in kb, here I convert it in Mb for readability
    RAM_stats = getRAMinfo()
    RAM_total = round(int(RAM_stats[0]) / 1000,1)
    RAM_used = round(int(RAM_stats[1]) / 1000,1)
    RAM_free = round(int(RAM_stats[2]) / 1000,1)

    # Disk information
    DISK_stats = getDiskSpace()
    DISK_total = DISK_stats[0]
    DISK_free = DISK_stats[1]
    DISK_perc = DISK_stats[3]

    # system hardware and os
    lcd_string("Rasbperry Pi 3B+",LCD_LINE_1,2)
    lcd_string("Raspbian Stretch",LCD_LINE_2,2)

    time.sleep(3) # 3 second delay

    # current date and time
    lcd_string(now.strftime("%d. %b %Y"),LCD_LINE_1,2)
    lcd_string(now.strftime("%H:%M") + " Uhr",LCD_LINE_2,2)

    time.sleep(3) # 3 second delay

    # CPU Info
    lcd_string("Speed: " + str(get_cpu_speed()) + " Mhz",LCD_LINE_1,1)
    lcd_string("Temp: " + CPU_temp + degree + "C",LCD_LINE_2,1)

    time.sleep(3) # 1 second delay
    
    lcd_string("RAM Total",LCD_LINE_1,2)
    lcd_string(str(RAM_total) + " MB",LCD_LINE_2,2)

    time.sleep(3) # 1 second delay

    lcd_string("RAM Used",LCD_LINE_1,2)
    lcd_string(str(RAM_used) + " MB",LCD_LINE_2,2)

    time.sleep(3) # 1 second delay

    lcd_string("RAM Free",LCD_LINE_1,2)
    lcd_string(str(RAM_free) + " MB",LCD_LINE_2,2)

    time.sleep(3) # 1 second delay
  
    lcd_string("Disk Space Total",LCD_LINE_1,2)
    lcd_string(str(DISK_total),LCD_LINE_2,2)

    time.sleep(3) # 1 second delay

    lcd_string("Disk Space Used",LCD_LINE_1,2)
    lcd_string(str(DISK_free) + " (" + str(DISK_perc) + ")",LCD_LINE_2,2)

    time.sleep(3) # 1 second delay

  
def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = data
  # mode = True  for character
  #        False for command

  GPIO.output(LCD_RS, mode) # RS

  # 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
  lcd_toggle_enable()

  # 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
  lcd_toggle_enable()

def lcd_toggle_enable():
  # Toggle enable
  time.sleep(E_DELAY)
  GPIO.output(LCD_E, True)
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False)
  time.sleep(E_DELAY)

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

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

  lcd_byte(line, LCD_CMD)

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

def lcd_backlight(flag):
  # Toggle backlight on-off-on
  GPIO.output(LED_ON, flag)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)
    lcd_string("Goodbye!",LCD_LINE_1,2)
    GPIO.cleanup()

Das Script ist im Original von Matt Hawkins. Ich habe dies nur um einige wenige Zeile erweitert.

Script Download:

cd ~
wget https://download.christian-brauweiler.de/RaspberryPi/Python/lcd.py

Starten des Scripts:

python lcd.py

Ergebnis

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.