HD44780 LCD Display per I2C mit dem Raspberry Pi ansteuern

LCD Zeichen Displays sind eine einfache und kostengünstige Art einen Text anzeigen zu lassen. Dank dem HD44780 Controller ist das Ansteuern der Module sehr einfach geworden. Allerdings muss man viele GPIOs dafür belegen. Eine Alternative stellt hier der I2C Datenbus dar, womit nur noch zwei GPIOs belegt werden.

In diesem Tutorial wird ein 20×04 HD44780 Zeichen Display mit Hilfe eines I2C Display Adapters angesteuert. Um den Spannungspegel für das Modul herzustellen, ohne dabei die GPIOs zu gefährden wird ein Logik Konverter benutzt.

 

Zubehör

Um ein HD47780 Display per I²C ansprechen zu können, habe ich folgendes Zubehör verwendet:

 

hd44780 i2c display

Die Pins des I2C LCD Adapters passen perfekt auf das Display und können aufgelötet werden. Manche Displays werden bereits mit aufgelötetem I²C Adapter geliefert.

 

Aufbau

Auf dem Raspberry Pi dürfen GPIOs nicht mehr als 3.3V Spannung abbekommen, allerdings gibt es einige Module (wie dieses Display), welche 5V Signale benötigen und senden. Dafür kann ein Logic Level Converter benutzt werden, welcher 2 Seiten hat. Auf einer Seite werden jene Anschlüsse, die auf 3.3V laufen angeschlossen und auf der anderen jene mit 5V. Erkennen kannst du das an verschiedenen Merkmalen (LV – HV), wie du im folgenden Bild siehst:

647241639_842

Angeschlossen werden die Pins dann folgendermaßen:

Raspberry Pi 3.3V Level Konverter 5V Level Konverter I2C LCD Adapter
3.3V (Pin 1) LV
5V (Pin 2) HV VCC
GND (Pin 6) GND GND GND
GPIO2 / SDA (Pin 3) TX1 (unten)
GPIO3 / SCL (Pin 5) TX1 (oben)
 — TX0 (unten) SDA
 — TX0 (oben) SCL

 

Hier noch als Zeichnung:

 

Raspberry Pi HD44780 I2C Display Controller

Dabei kann jeder beliebige Masse Pin genommen werden. Der Übersicht zuliebe habe ich Pin 20 statt Pin 6 auf der schematischen Abbildung gewählt.

Dieser Aufbau ist im Übrigen auch mit anderen Modulen, welche Signale mit einer höheren Spannung als 3.3V (in diesem Fall 5V) brauchen (Real Time Clock, etc.) verwendbar.

 

Software

Bevor wir starten können, werden zwei I²C Tools benötigt, welche wir installieren:

sudo apt-get install python-smbus i2c-tools

Danach schalten wir I2C frei (falls du es bereits aus vorherigen Tutorials freigeschaltet hast, kannst du dies überspringen):

sudo raspi-config

Unter „8. Advanced Options“ > „A7 I2C“ aktivieren wir es. Nun fügen wir der modules-Datei noch die entsprechenden Einträge hinzu:

sudo nano /etc/modules

Diese beiden Zeilen kommen ans Ende:

Anschließend muss noch neugestartet werden, damit alle Änderungen in Kraft treten.

sudo reboot

 

Hast du das Display bereits angeschlossen, kann nun getestet werden, ob es erkannt wurde (solltest du eines der aller ersten Raspberry Pi’s [Rev.1] haben, musst du eine 0 statt 1 übergeben):

sudo i2cdetect -y 1

Die Ausgabe sollte so aussehen:

pi@raspberrypi ~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Falls du hier eine andere Zahl als 27 angezeigt bekommst, musst du dies gleich in der lcddriver.py Datei ändern (ADDRESS = 0x27).

Laden wir aber erst einmal den Code:

mkdir hd44780 && cd hd44780
wget http://tutorials-raspberrypi.de/wp-content/uploads/scripts/hd44780_i2c.zip
unzip hd44780_i2c.zip

Mit Hilfe der beiden enthaltenen Skripts kann das Display nun angesprochen werden. Dazu öffnen wir die Python Konsole und geben folgenden Code ein:

sudo python

Der erste Parameter der lcd_display_string Funktion steht dabei für den Text und der zweite für die Zeile. Es müssen nicht alle Zeilen auf einmal geändert werden, allerdings können nicht ohne weiteres einzelne Zeichen ersetzt werden. Dafür müsste der gesamte Text (mit geändertem Zeichen an der gewünschten Position) erneut gesendet werden.

Bei meinem I2C Adapter war der Kontrast am Anfang sehr niedrig eingestellt. Falls nichts angezeigt werden sollte, teste das Rädchen auf der Rückseite und schaue schräg auf das Display.

20160115_212307

 

 

Code Referenz: https://github.com/CaptainStouf/raspberry_lcd4x20_I2C

171 Kommentare

  1. guter Beitrag
    als Alternative für den Pegelwandler würde natürlich auch ein von der Anschlussbelegung besser verständliches Modul funktionieren
    nur als Beispiel !!!
    http://www.amazon.de/dp/B00JQ0DITU/ref=pe_386171_38075861_TE_item

    aber ich finde es gut das ein Beitrag sich mit i2c befasst was es bei der reichlichen Auswahl von i2c (smb) Bausteine lögisch ist und sich diese ohne umständliche Umprogrammierung von GPIOS anschliessen lassen und damit einen einheitlichen Bus haben und viel Möglichkeiten des Programmieren lassen (bash, Python usw)

    Antworten
  2. Hallo Felix,

    ich hätte ein paar Fragen.

    * Kann dein „Driver“mehr als nur Text ausgeben? (blinken oder sowas ähnliches)
    * Wie kann man variablen ausgeben? Wenn ja, so (lcd.lcd_display_string(„%s-„, 1) %Text)
    * Braucht man einen Potenziometer um den Kontrast einstellen zu können?
    * Kann man Symbole wiedergeben z. B. ein Termometer? (Wenn ja, wie?)

    ich denke das reicht fürs erste. 🙂

    Mach weiter so.

    Antworten
    • Hallo Stefan,
      kurz und knackig:
      1. Nein, ist nur für Zeichen gedacht. Blinken ist aber ziemlich einfach zu erstellen (Schleife: halbe Sekunde Text anzeigen, Text speichern und Display leeren, halbe Sekunde später wieder vorherigen Text anzeigen lassen).
      2. Fast Richtig: lcd.lcd_display_string("String: %s" % string_var, 1)
      3. Wenn du es einstellen und justieren willst – ja. Du kannst aber auch einfach verschiedene Widerstände ausprobieren und die Größe nehmen, bei der der Kontrast dir gefällt.
      4. Was meinst du mit Symbolen? Du kannst ASCII Zeichen anzeigen lassen, aber keine Bilder. Ist ja auch keine Graphik- sondern ein Zeichendisplay 🙂
      LG Felix

      Antworten
  3. Hallo Felix,

    ich habe mich leider missverständlich ausgedrückt. Ich dachte mit meinem Beispiel“ blinken“ daran, ob es noch andere Methoden in dem von dir zur Verfügung gestellten Treiber gibt.

    Mir würde da jetzt spontan einfallen, dass der Cursor angezeigt wird, der Cursor blinkt, die Hintergrundbeleuchtung ausgeschaltet werden kann, der Text im Display von rechts nach links gescrollt werden kann usw.

    Ich hatte es in einem YouTube Video gesehen. Dieser verwendet einen Treiber von Adafruit. Der ist aber so viel ich gesehen habe nicht per I2C-Verbindung gedacht und wird deshalb wahrscheinlich nicht funktionieren. (Link: https://www.youtube.com/watch?v=cVdSc8VYVBM)

    Mal eine andere doofe Frage. Für was ist denn das Rädchen hinten auf dem I2C-Controller gedacht, ist das nicht für den Kontrast?

    Mit Symbolen hatte ich gemeint, ich könnte mir ein Temperatursymbol wie es die meisten 3D-Drucker verwenden anzeigen lassen. (Link: http://nicklievendag.com/wp-content/uploads/cyrus_3d_printer_review_display-1024×530.jpg)

    Antworten
    • Was du beschreibst ist zwar bei meiner Lösung nicht dabei, aber es sollte sehr einfach sein das zu erstellen.
      Beispiel Text von rechts nach links scrollen:
      Du kopierst den String mehrfach hintereinander („StringStrinString…“) und startest eine Schleife. Bei jedem Durchlauf wird der erste Buchstabe entfernt und die nächsten 16. bzw. 20 Zeichen ausgegeben (per Befehl wie im Tutorial gezeigt). Danach wird eine halbe Sekunde/o.ä. gewartet, bis die Schleife erneut ausgeführt wird.
      Einen Cursor kannst du genauso bauen: Einfach die Position X des String im Sekunden/o.ä. Takt einmal mit einem anderen Zeichen (Unterstrich z.B.) ersetzen. Warten und dann die normale Zeichenkette anzeigen und das ganze eben wiederholen.

      Antworten
    • Hallo Felix,

      auch wenn ich vielleicht nerve und vom Programmieren wenig verstehe, habe ich mir die Treiber-Datei nochmal angesehen. Am Anfang stehen meine sogar einige Funktionen, die ich auch im Video gesehen hatte….

      Allerdings denke ich, dass in der Treiberdatei dafür keine Funktionen definiert sind. Sehe ich das soweit richtig? Wenn ja, könnte man doch auch über den Treiber eine Definition entwickeln, die man in seinem Programm dann nur noch aufrufen müsste oder? Verdammt ich habe doch das falsche studiert….
      Dennoch könnte ich mir sowas vorstellen. Was meinst du dazu?

      def lcd_blinkon (self):
            self.lcd_write(LCD_BLINKON)
      Antworten