USB-LCD mit einem Raspberry Pi ansteuern und HTM-Inhalte anzeigen lassen

Warum?

RPI-MensaSo, auf Bitten von Facebook-Kommentaren, versuche ich mich heute an meinem ersten Tutorial.

Mein Raspberry Pi liegt seit einigen Monaten nur bei mir in einer Schublade rum, da ich bisher keinen wirkliche Verwendung für ihn hatte (Als Elektronik-Bastler musste ich ihn natürlich bei Markteinführung kaufen)

Da mir nun mein Mitbewohner netterweise ein USB-LCD zum rumspielen geliehen hat, dachte ich mir, dass das in Verbindung mit dem PI eine großartige Gelegenheit ist, die bevorzugte Programmiersprache des Pi’s, nämlich Python, auszuprobieren:

Meine Zielsetztung war: Auf dem 4×20 Zeichen großen LCD mittels des RPI den aktuellen Menüplan unserer Mensa anzeigen zu lassen.

Als Display verwende ich folgendes: http://www.sureelectronics.net/goods.php?id=937

Wer mein langweiliges Geschwafel überspringen möchte: am Ende der Seite befindet sich der fertige Code

1. Den Raspberry vorbereiten

Für dieses Tutorial benutzte ich einen komplett leer gemachten RPI, damit ich ja nicht vergesse irgend ein Package zu erwähnen, welches für unser Vorhaben nötig ist. Als Betriebssystem verwende ich die direkt bei Raspberry angebotene Raspian Distribution:

http://www.raspberrypi.org/downloads

Nach der Insatallation, aktiviere ich die „Expand Filesystem“ Option und passe die Kofiguration meines Tastaturlayouts an.  In meinem Fall musste ich unter den erweiterten Einstellungen noch „Overscan“ aktivieren, da mein 1080p display Schwarze Balken angezeigt hat.

Danach startet das System erstmal neu.

Nach dem Neustart logge ich mich ein und starte direkt mit „startx“ in die Grafische Benutzeroberfläche von Raspian.

startx

In der Grafischen Oberfläche kann man (wenn erwünscht) mittels dem „WiFi Config“ Programm auf dem Desktop sein WLAN einrichten;

Als nächstes sollten wir ein Update des Betriebssystems machen. Hierzu öffnen wir das LXTerminal und geben folgenden Befehl ein:

sudo apt-get update

Wenn das Update durchgelaufen ist können wir noch ein Upgrade hinterherschieben:

sudo apt-get upgrade

Jetzt brauchen wir noch ein Package um die Serielle Kommunikation zu dem LCD herstellen zu können. Einfach wieder folgendes in das Terminal eingeben:

sudo apt-get install python-serial

Wenn wir das alles gemacht haben, sind wir im Grunde bereit mit der Ansteuerung von dem LCD-File zu beginnen.

2. Kleiner Einstieg in Python

Nachdem jetzt unser Raspberry Pi läuft können wir einen Blick in die Programmiersprache Python werfen. Zum Einstig habe ich dieses Tolle Tutorial entdeckt, dass so ziemlich alles Grundlegende abdeckt:

http://www.afterhoursprogramming.com/tutorial/Python/Overview/

Einfach mal ein bisschen durchklicken und dich an der Einfachheit dieser Sprache zu erfreuen🙂

Als erstes erstellen wir einen neuen Ordner in unserem user-Verzeichnis („Rechtsklick“ -> „Create New“ -> „Folder“)

In dem Ordner legen wir eine leeres Dokument an („Rechtsklick“ -> „Create New“ -> „Blank File“) und nennen es „HelloWorld.py“. Ich würde übrigens davon abraten Leerzeichen in Ordner oder Dateinamen zu verwenden, das macht die Sache nur Komplizierter🙂

Mit einem Doppelklick öffen wir die soeben erstelle Datei um sie zu bearbeiten. Natürlich schreiben wir zunächst das berühmte HelloWolrd! Programm:

print "Hello World!"

Wir speichern das File mit CTRL+S (auf deutschen Tastaturen STRG+S). Dieser Einzeiler ist schon ein lauffähiges Python Programm. In unserem Terminal navigieren wir nun zu dem übergeordnetem Ordner von unserem neuen Programm (in meinem Fall heißt der Ordner „Tutorial“:

cd Tutorial/

Mit dem Terminal-Befehl „ls“ können wir uns anzeigen lassen, welche Dateien in diesem Ordner liegen:

ls

Um unser Programm auszuführen geben wir in das Terminal einfach „python“, ein Leerzeichen und dann den vollständigen Dateinamen unseres Programms ein. In unserem Fall:

python HelloWorld.py

Das wars schon; wir sehen die Ausgaben die wir generieren wollten:

Dieser kleine Einschub sollte in Verbindung mit dem obengenannten Tutorial reichen um einfache Programme zu schreiben. Ich denke eine weiterführendere Python  Anleitung würde den Rahmen dieses Blog-Posts sprengen. Von daher gehen wir direkt zu dem nächsten Kapitel über.

3. Das LCD mittles des RPI ansteuern

Wir starten erneut mit einer kleinen Datei in unserem Ordner und nennen sie lcd.py.  Wir geben am Anfang des Programms an, welche Packages wir verwenden wollen:

import serial #Ermöglicht die serielle Verbindung herzustellen
import time #noetig für den "time.sleep()" Befehl

Gefolgt von den Imports konfigurieren wir die serielle Schnittstelle zu dem USB Port, bzw. zu dem LCD:

lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)

Darauf hin können wir schon den ersten Befehl reinschreiben:

import serial
import time

lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)

# Diese Funktion schaltet die Hintergrundbeleuchtung aus
def Backlight_off():
    lcd.write("\xFE")
    lcd.write("\x46")
    time.sleep(0.025)

# Aufruf der Funktion
Backlight_off()

Jetzt können wir noch weitere Funktionen hinzufügen:

import serial
import time

lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)

# Turn the Backlight off //////////////////////////
def Backlight_off():
    lcd.write("\xFE")
    lcd.write("\x46")
    time.sleep(0.025)

# Turn the Backlight on ///////////////////////////
def Backlight_on():
    lcd.write("\xFE")
    lcd.write("\x42")
    lcd.write("\x00")
    time.sleep(0.025)

# Clear a single Row (Parameter: Rownumber) /////////
def Clearline(row):
    lcd.write("\xFE")
    lcd.write("\x47")
    lcd.write("\x01")
    lcd.write(chr(row))
    lcd.write("                    ")
    time.sleep(0.025)

# Clears the whole screen ////////////////////////////
def Clearscreen():
    for row in range(1, 5):
        Clearline(row)
# Hier drunter kommt das Hauptprogramms rein ++++++++++++++++++++++++++++++++++++++++++++

Gut, wenn alle Funktionen das tuen, was sie tun sollten, können wir uns um die Hauptfunktion des LCD kümmern: Text ausgeben; Theoretisch sollte es möglich sein dem Lcd einen Text und die Position des Texten anzugeben um den Text auf dem LCD anzuzeigen, leider Funktioniert das bei mir nicht so richtig; ich habe es nur hinbekommen, wenn ich dem LCD immer eine Zeichenfolge übergebe, die genau 20 Zeichen (das ist die breite des LCD) lang ist. Also muss man aus dem Text „Hallo Welt!“ zunächst „Hallo Welt!         “ machen, also im Grunde so viele Leerzeichen anfügen, damit man insgesamt auf 20 Zeichen kommt. Dies habe ich in der Funktion „Write(row, text)“ realisiert:

import serial
import time

lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)

# Turn the Backlight off //////////////////////////
def Backlight_off():
    lcd.write("\xFE")
    lcd.write("\x46")
    time.sleep(0.025)

# Turn the Backlight on ///////////////////////////
def Backlight_on():
    lcd.write("\xFE")
    lcd.write("\x42")
    lcd.write("\x00")
    time.sleep(0.025)

# Clear a single Row (Parameter: Rownumber) /////////
def Clearline(row):
    lcd.write("\xFE")
    lcd.write("\x47")
    lcd.write("\x01")
    lcd.write(chr(row))
    lcd.write("                    ")
    time.sleep(0.025)

# Clears the whole screen ////////////////////////////
def Clearscreen():
    for row in range(1, 5):
        Clearline(row)

# Passt den uebergebenen Text-String >text< auf 20 Zeichen an und schreibt das
# ganze in Zeile >row<
def Write(row, text):
    size = text.__len__()
    # die Variabel >textdata< enthaelt spaeter den zu uebergebenden Text 
    textdata = " "
    # 1. Fall: der angebend Text ist zu lange, also schneiden wir ihn zurecht
    if size > 20:
        textdata = text[0:20]
    # 2.Fall der uebergebene Text ist genau 20 Zeichen lang, somit muessen wir
    # ihn nicht veraendern und speichern ihn direkt in >textdata<
    elif size == 20:
        textdata = text
    # 3.Fall der Text ist zu lang, somit muessen wir
    # ausreichend Leerzeichen anfuegen
    # um auf 20 Zeichen zu kommen
    elif size < 20:
        textdata = text
        numToAppend = 20 - size
        for i in range(0,numToAppend):
            textdata = textdata + " "
    # Jetzt haben wir ein 20 Zeichen langen String >textdata<, welchen wir
    # auf dem LCDin der Zeile >row< ausgeben koennen
    lcd.write("\xFE")
    lcd.write("\x47")
    lcd.write("\x01")
    lcd.write(chr(row))
    lcd.write(textdata)
    time.sleep(0.025)

Diese Funktion sieht zwar etwas unhandlich aus, aber wir mussten sie ja nur einmal schreiben🙂

Wenn wir später in unserem Hauptprogramm „Hallo Welt!“ in der Zeile 3 ausgeben wollen, müssen wir einfach nur schreiben:

Write(3, "Hallo Welt!")

..und unsere eben erstellte Funktion erledigt den Rest🙂

Wenn wir eine Bestimmte Zeile löschen wollen, geben wir einfach folgendes ein (hier löschen wir die dritte Zeile):

Clearline(3)

Um alle Zeilen zu löschen geben wir diesen Befehl ein:

Clearscreen()

4. Den HTML-Code der Mensa auslesen, bearbeiten und auf dem Display ausgeben

Da vermutlich die meisten Leute die das hier Lesen eher an dem LCD-Part interessiert sind und mir solangsam die Finger blute, kürze ich diesen Teil etwas ab:

Für das Anzeigen des aktuellen menüs meiner Mensa habe ich mir volgendes Konzept überlegt:

1. Ich schau mir den HTML Code meiner Mensa-Webseite an und suche nach den Zeilen, in welchem das aktuelle Menü drinne steht. Falls ihr euch den HTML-Code anschauen wollt hier ist die Adresse zu meiner Mensa: http://www.swfr.de/essen-trinken/speiseplaene/mensa-flugplatz/

Die gewünschte HTML-Zeile:

	<div id="Z2" ###VISIBLEZEILE1###><b><a href=#; ONMOUSEOVER="return overlib.ov('<img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/de.gif><br>kleine gebratene Fleischbällchen aus Schweine- und Rindfleisch (Schwedische Spezialität)<br><br><img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/gb.gif><br>little Swedish-style meatballs made from pork and beef',AUTOSTATUSCAP,HAUTO,VAUTO);" ONMOUSEOUT="return overlib.nd();" ONCLICK="lexFenster('<img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/de.gif><br>kleine gebratene Fleischbällchen aus Schweine- und Rindfleisch (Schwedische Spezialität)<br><br><img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/gb.gif><br>little Swedish-style meatballs made from pork and beef')">Köttbullar</a> (1,15)</b><br>Preiselbeer-Rahm-Sauce<br><a href=#; ONMOUSEOVER="return overlib.ov('<img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/de.gif><br>badisch-schwäbische Spezialität aus Spätzleteig, ähnllich dem Nudelteig aus Mehl, Eiern und Salz<br><br><img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/gb.gif><br>are similar to noodles and much used in southern Germany,they are fabricated by grating or scraping dough into boiling water and continuously sieving out the batches that are cooked. The dough is a simple affair, consisting of eggs, flour, and salt.',AUTOSTATUSCAP,HAUTO,VAUTO);" ONMOUSEOUT="return overlib.nd();" ONCLICK="lexFenster('<img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/de.gif><br>badisch-schwäbische Spezialität aus Spätzleteig, ähnllich dem Nudelteig aus Mehl, Eiern und Salz<br><br><img border=0 src=../typo3conf/ext/ts_speiseplan/pi1/gb.gif><br>are similar to noodles and much used in southern Germany,they are fabricated by grating or scraping dough into boiling water and continuously sieving out the batches that are cooked. The dough is a simple affair, consisting of eggs, flour, and salt.')">Bauernspätzle</a><br>Rohkostsalat </div>

2. Eine einzigartige Markierung dieser Zeile finden: in unserem Fall kommt der Abschnitt

###VISIBLEZEILE1###><b>

nur in dieser Zeile vor.

3. Die Betreffende Zeilen aus dem gesamten HTML-File rauskopieren in die Variabel >menu1html<, bzw. >menu2html<

import urllib2
import string

# Here comes the HTML part ////////////////////////////////
url = 'http://www.swfr.de/essen-trinken/speiseplaene/mensa-flugplatz/'

menu1pattern = "###VISIBLEZEILE1###><b>"
menu2pattern = "###VISIBLEZEILE2###><b>"

temp = " "
menu1html = ""
menu2html = ""

# Get the HTML lines containing the food menues
usock = urllib2.urlopen(url)
while temp != "":
        temp = usock.readline()
        if string.find(temp, menu1pattern) != -1:
                menu1html = temp
        elif string.find(temp, menu2pattern) != -1:
                menu2html = temp
usock.close()

Diese Funktion speichert die beiden Menüs in den beiden erwähnten Variablen

4. Die Zeile Reduzieren; wie euch vielleicht aufgefallen ist ist der größte Teil dieser Zeile href-Elemente (Links); ich habe eine kleine Python Funktion geschrieben, die diesen Teil rausfiltert:

#now we have to delete the Links in the html-lines
def deleteLinks(htmlLine):
    linkBegin = string.find(htmlLine,"<a href", 0)
    if linkBegin != -1:
        linkEnd = string.find(htmlLine, "</a>", linkBegin)
        # Because the menueline is a part of the link, we have to exclude this part
        realLinkEnd = string.rfind(htmlLine, ">", linkBegin, linkEnd-1)+1
        newHtmlLine = htmlLine[0:linkBegin] + htmlLine[(realLinkEnd):(linkEnd)] + htmlLine[(linkEnd + 4):(htmlLine.__len__())]
        return newHtmlLine
    else:
        return htmlLine

Das heißt, wenn wir diese mehrmals (für Jeden Link einmal, also einfach 4 mal, da höchstens vier Links enthalten sind) Funktion auf unsere HTML-Zeile Anwenden, sollte folgendes rauskommen:

	<div id="Z2" ###VISIBLEZEILE1###><b>Köttbullar (1,15)</b><br>Preiselbeer-Rahm-Sauce<br>Bauernspätzle<br>Rohkostsalat </div>

beziehungsweise

	<div id="Z2" ###VISIBLEZEILE2###><b>Ravioli mit Käse-Spinat-Füllung</b><br>Oliven-Pilz-Sauce (2,10)<br>Geriebener Käse<br>Beilagensalat</div>

Damit können wir doch schon eher was anfangen🙂

Folgender Code filtert die gewünschten Essens-Zeilen raus und speichert sie in die Variablen menu1line1, menu1line2, menu1line3, menu1line4:

# get the HTML markers for menu1
b1 = string.find(menu1html, "<b>")
e1 = string.find(menu1html, "</b>", b1)

b2 = string.find(menu1html, "<br>", e1)
e2 = string.find(menu1html, "<br>", b2+1)
b3 = string.find(menu1html, "<br>", e2)
e3 = string.find(menu1html, "<br>", b3+1)
b4 = string.find(menu1html, "<br>", e3)
e4 = string.find(menu1html, "<", b4+1)

menu1line1 = menu1html[(b1+3):e1].strip()
menu1line2 = menu1html[(b2+4):e2].strip()
menu1line3 = menu1html[(b3+4):e3].strip()
menu1line4 = menu1html[(b4+4):e4].strip()

mit

print menu1line1
print menu1line2
print menu1line3
print menu1line4

erhalten wir nun die Ausgabe

Köttbullar (1,15)
Preiselbeer-Rahm-Sauce
Bauernspaätzle
Rohkostsalat

fügen wir nun alle Programmteile Zusammen und geben am Ende die in dem LCD-Abschnitt programmierten Write Befehle ein, erhalten wir nun unser gesamt Programm (ich habe noch eine Funktion hinzugefügt, mit der die Zusatzstoffe nicht angezeigt werden [die Zahlen in den runden klammern]):

import serial
import time
import urllib2
import string

lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)

# Turn the Backlight off //////////////////////////
def Backlight_off():
    lcd.write("\xFE")
    lcd.write("\x46")
    time.sleep(0.025)

# Turn the Backlight on ///////////////////////////
def Backlight_on():
    lcd.write("\xFE")
    lcd.write("\x42")
    lcd.write("\x00")
    time.sleep(0.025)

# Clear a single Row (Parameter: Rownumber) /////////
def Clearline(row):
    lcd.write("\xFE")
    lcd.write("\x47")
    lcd.write("\x01")
    lcd.write(chr(row))
    lcd.write("                    ")
    time.sleep(0.025)

# Clears the whole screen ////////////////////////////
def Clearscreen():
    for row in range(1, 5):
        Clearline(row)

# Passt den uebergebenen Text-String >text< auf 20 Zeichen an und schreibt das ganze
# in Zeile >row<
def Write(row, text):
    size = text.__len__()
    # die Variabel >textdata< enthaelt spaeter den zu uebergebenden Text 
    textdata = " "
    # 1. Fall: der angebend Text ist zu lange, also schneiden wir ihn zurecht
    if size > 20:
        textdata = text[0:20]
    # 2.Fall der uebergebene Text ist genau 20 Zeichen lang, somit muessen wir
    # ihn nicht veraendern und speichern ihn direkt in >textdata<
    elif size == 20:
        textdata = text
    # 3.Fall der Text ist zu lang, somit muessen wir ausreichend Leerzeichen
    # anfuegen um auf 20 Zeichen zu kommen
    elif size < 20:
        textdata = text
        numToAppend = 20 - size
        for i in range(0,numToAppend):
            textdata = textdata + " "
    # Jetzt haben wir ein 20 Zeichen langen String >textdata<, welchen wir auf dem
    # LCD in der Zeile >row< ausgeben koennen
    lcd.write("\xFE")
    lcd.write("\x47")
    lcd.write("\x01")
    lcd.write(chr(row))
    lcd.write(textdata)
    time.sleep(0.025)

# Here comes the HTML part ////////////////////////////////
url = 'http://www.swfr.de/essen-trinken/speiseplaene/mensa-flugplatz/'
menu1pattern = "###VISIBLEZEILE1###><b>"
menu2pattern = "###VISIBLEZEILE2###><b>"

temp = " "
menu1html = ""
menu1line1 = " "
menu1line2 = " "
menu1line3 = " "
menu1line4 = " "

menu2html = ""
menu2line1 = " "
menu2line2 = " "
menu2line3 = " "
menu2line4 = " "
b1 = 0
b2 = 0
b3 = 0
b4 = 0
e1 = 0
e2 = 0
e3 = 0
e4 = 0

# Get the HTML lines containing the food menues
usock = urllib2.urlopen(url)
while temp != "":
        temp = usock.readline()
        if string.find(temp, menu1pattern) != -1:
                menu1html = temp
        elif string.find(temp, menu2pattern) != -1:
                menu2html = temp
usock.close()

#now we have to delete the Links in the html-lines
def deleteLinks(htmlLine):
    linkBegin = string.find(htmlLine,"<a href", 0)
    if linkBegin != -1:
        linkEnd = string.find(htmlLine, "</a>", linkBegin)
        # Because the menueline is a part of the link, we have to exclude this part
        realLinkEnd = string.rfind(htmlLine, ">", linkBegin, linkEnd-1)+1
        newHtmlLine = htmlLine[0:linkBegin] + htmlLine[(realLinkEnd):(linkEnd)] + htmlLine[(linkEnd + 4):(htmlLine.__len__())]
        return newHtmlLine
    else:
        return htmlLine
#delete this ugly "()" in the lines
def deleteBrackets(foodLine):
    if string.find(foodLine, "(", 0) != -1:
        return foodLine[0:(string.find(foodLine, "(", 0)-1)]
    else:
        return foodLine

# Delete the Links
for i in range(0,5):
    menu1html = deleteLinks(menu1html)
    menu2html = deleteLinks(menu2html)

# get the HTML markers for menu1
b1 = string.find(menu1html, "<b>")
e1 = string.find(menu1html, "</b>", b1)

b2 = string.find(menu1html, "<br>", e1)
e2 = string.find(menu1html, "<br>", b2+1)
b3 = string.find(menu1html, "<br>", e2)
e3 = string.find(menu1html, "<br>", b3+1)
b4 = string.find(menu1html, "<br>", e3)
e4 = string.find(menu1html, "<", b4+1)

menu1line1 = deleteBrackets(menu1html[(b1+3):e1]).strip()
menu1line2 = deleteBrackets(menu1html[(b2+4):e2]).strip()
menu1line3 = deleteBrackets(menu1html[(b3+4):e3]).strip()
menu1line4 = deleteBrackets(menu1html[(b4+4):e4]).strip()

# get the HTML markers for menu2
b1 = string.find(menu2html, "<b>")
e1 = string.find(menu2html, "</b>", b1)
b2 = string.find(menu2html, "<br>", e1)
e2 = string.find(menu2html, "<br>", b2+1)
b3 = string.find(menu2html, "<br>", e2)
e3 = string.find(menu2html, "<br>", b3+1)
b4 = string.find(menu2html, "<br>", e3)
e4 = string.find(menu2html, "<", b4+1)

menu2line1 = deleteBrackets(menu2html[(b1+3):e1]).strip()
menu2line2 = deleteBrackets(menu2html[(b2+4):e2]).strip()
menu2line3 = deleteBrackets(menu2html[(b3+4):e3]).strip()
menu2line4 = deleteBrackets(menu2html[(b4+4):e4]).strip()

# Hier beginnt das Hauptprogramm ++++++++++++++++++++++++++++++++++++++++++++++
Clearscreen() #Loescht den gesamten aktuellen Inhalt des LCD

# Schreibt das Menue1 auf das LCD-Display
Write(1, menu1line1)
Write(2, menu1line2)
Write(3, menu1line3)
Write(4, menu1line4)

# warte 5 Sekunden
time.sleep(5)

Clearscreen() #Loescht den gesamten aktuellen Inhalt des LCD# Schreibt das Menue2 auf das LCD-Display
Write(1, menu2line1)
Write(2, menu2line2)
Write(3, menu2line3)
Write(4, menu2line4)

Schlusslicht

Ich hoffe ich konnte irgendjemand mit diesem Tutorial helfen, oder gar für die Programmierung der Pi’s interessieren.

Ich hoffe Ihr vergebt mir sämtliche Rechtschreibfehler und vor allem die gemischt deutsch und englischen Kommentare (die Teile die ich für das Tutorial erneut geschrieben habe ich deutsch Kommentiert, die Teile die ich einfach aus meinem schon fertigem Programmcode kopiert habe sind noch auf englisch [so wie es sich gehört :-> ]). Auch die Formatierung des Codes in WordPress ist eine Qual! Ich hoffe aber ich konnte mich halbwegs verständlich ausdrücken.

Bei Fragen, Anregungen, Korrekturvorschlägen etc. am besten (falls vorhanden) die Kommentarfunktion nutzen.

Gruß, Marius

6 Gedanken zu “USB-LCD mit einem Raspberry Pi ansteuern und HTM-Inhalte anzeigen lassen

  1. Hallo Marius,

    sehr schönes Tutorial hast du da geschrieben. Dies hat mich direkt veranlasst das ganze nachzubauen.

    Aktuell hab ich nur das Problem das dass Display außer den Demo Mode (also den Text „LCDSmartie by Sure ……) nix von sich gibt. Hast du vorher noch irgendwelche Treiber installiert oder so etwas.

    Kenne mich noch nicht so gut aus in der Linux Welt ggf fehlt auch etwas ganz simples

    • Hallo Martin,

      nein, alle Packete, die ich verwendet habe, habe ich in dem Tutorial erwähnt.

      Im günstigstem Fall funktioniert dein Programm nicht, weil sich vielleicht ein kleiner Fehler eingeschlichen hat. Um zumindest diesen Fehler auszuschließen, habe ich mein Programm verkleinert und somit das beinahe kleinstmögliche LCD-Programm geschrieben:

      import serial
      import time
      
      lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)
      
      # Hier kommen die Funktionsdefinitionen Rein +++++++++++++++++
      # Turn the Backlight off //////////////////////////
      def Backlight_off():
          lcd.write("\xFE")
          lcd.write("\x46")
          time.sleep(0.025)
      
      # Turn the Backlight on ///////////////////////////
      def Backlight_on():
          lcd.write("\xFE")
          lcd.write("\x42")
          lcd.write("\x00")
          time.sleep(0.025)
      # Ende der Funktionsdefinitionen +++++++++++++++++++++++++++++
      
      
      
      # Hier Kommt das Hauptprogramm +++++++++++++++++++++++++++++++
      
      for row in range(1, 5):
          Backlight_off()
          time.sleep(1)
          Backlight_on()
          time.sleep(1)
      
      # Ende des Hauptprogramms ++++++++++++++++++++++++++++++++++++
      

      Dieses Programm sollte dafür sorgen, dass die Hintergrundbeleuchtung des LCD ein paar mal an und aus geht. Sollte dieses Programm laufen, sollte auch alles andere gehen (text schreiben, display löschen, etc.).
      Sollte es danach immer noch nicht gehen, melde dich hier einfach wieder.

      Gruß, Marius

      PS: sorry dass mein Eintrag nicht ganz so ordentlich formatiert ist wie sonst, aber mein Notebook ist grad in Reparatur, somit musste ich den Kommentar hier mit dem iPad schreiben, und dieses Webinterface ist auf so einem kleinen Screen einfach die Hölle…

      • Hallo Marius,

        ich habs gedreht und gewendet finde aber trotzdem keinen Fehler. Das Display bleibt einfach im Demomode.

        mfg Martin

  2. Also unter Windows funktioniert das Display ohne Probleme. Ich hab aber festgestellt das ich ein anderes Display geliefert bekommen habe als im Link angeben und zwar das DE-LP14113 20*4LCD Display Board with UART Based USB(Edition III) statt Edition I scheint mir demnach ein Treiberproblem zu sein

    • Hallo Martin,
      da ich grad ein paar Minuten Zeit hatte, habe ich mich mal mit Deinem Problem näher befasst.
      Zu aller erst, Du brauchst bei der seriellen ansteuerung (diese Hexadezimal codes) keinerlei Treiber, weil Du ja direkt mit der Hardware sprichst.
      Ich glaube aber, ich habe das Problem nach Studium des Datenblattes gefunden. Die Version 2 und Version 3 unterscheiden sich von der Version 1 unter anderen dadurch, dass sie zu Beginn der Kommunikation einen „establish communication“-Befehl brauchen. Ich hab Dir mal das Programm aus meinem letzten Post um diesen extra Befehl erweitert. Es wäre toll, wenn Du den ausprobieren würdest und dann hier reinschreibst, ob es geklappt hat (wäre ja wirklich schade wenn nicht, IMHO sollte es niemand zugemutet werden, diese lausige PC-Software dazu zu benutzen)

      import serial
      import time
      
      lcd = serial.Serial("/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0", 9600)
      
      # Hier kommen die Funktionsdefinitionen Rein +++++++++++++++++
      # Serielle Kommunikation etablieren ///////////////
      def establishCommunication():
          lcd.write("\xFE")
          lcd.write("\x53")
          lcd.write("\x75")
          lcd.write("\x72")
          lcd.write("\x65")
          time.sleep(0.025)
      
      # Turn the Backlight off //////////////////////////
      def Backlight_off():
          lcd.write("\xFE")
          lcd.write("\x46")
          time.sleep(0.025)
      
      # Turn the Backlight on ///////////////////////////
      def Backlight_on():
          lcd.write("\xFE")
          lcd.write("\x42")
          lcd.write("\x00")
          time.sleep(0.025)
      # Ende der Funktionsdefinitionen +++++++++++++++++++++++++++++
      
      
      
      # Hier Kommt das Hauptprogramm +++++++++++++++++++++++++++++++
      
      // zuerst die Kommunikation starten
      establishCommunication()
      
      // dann der Rest
      for row in range(1, 5):
          Backlight_off()
          time.sleep(1)
          Backlight_on()
          time.sleep(1)
      
      # Ende des Hauptprogramms ++++++++++++++++++++++++++++++++++++
      

      Gruss, Marius

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s