HD44780

GPIO, Projekte

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 Pi3.3V Level Konverter5V Level KonverterI2C LCD Adapter
3.3V (Pin 1)LV
5V (Pin 2)HVVCC
GND (Pin 6)GNDGNDGND
GPIO / SDA (Pin 3)TX1 (unten)
GPIO / SCL (Pin 5)TX1 (oben)
 —TX0 (unten)SDA
 —TX0 (oben)SCL

 

Hier noch als Zeichnung:

 

i2c display_Steckplatine

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


, , , , , , , , ,


39 Kommentare

  1. Teetrinker sagt:

    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)

    • Felix sagt:

      Da hast du recht, der ist natürlich auch geeignet. Ich hatte den von mir verwendeten noch rumliegen und daher diesen benutzt.

  2. Stefan sagt:

    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.

    • Felix sagt:

      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

  3. Stefan sagt:

    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)

    • Felix sagt:

      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.

    • Stefan sagt:

      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)
    • Felix sagt:

      Hallo Stefan,
      klar, das ist möglich. Das meinte ich auch damit, dass man es sehr einfach erstellen kann. Was du mit self.lcd_write(LCD_BLINKON) meinst, verstehe ich allerdings nicht (ist LCD_BLINKON ein String?).

    • Stefan sagt:

      Hallo Felix,

      ich weiß eben nicht ob ich richtig liege. Wenn ich mir die Treiber-Datei ansehe z. B. die Funktion LCD_CLEAR, dann ist die Funktion genauso aufgebaut. Im Prinzip ruft er auch in der Funktion (Definition) auch nur einen Befehl auf, der vorher auch einem HEX-Wert versehen wurde. Ich dachte mir deshalb, dass es mit den anderen Befehlen die oben einen HEX-Wert bekommen haben genauso laufen würde. Was meinst du dazu?

    • Felix sagt:

      Hallo Stefan,
      die Hex Werte die am Anfang der Datei definiert wurden, sind alle aus dem Datenblatt. Das sind bestimmte Bytekombinationen, die bestimmte Funktionen (wie z.B: CLEAR) auf dem Display ausführen. Da das Display aber keine Blink Funktion hat, gibt es dafür auch keinen Code, den du senden könntest.
      Allerdings ist das auch nicht nötig, da alle benötigten Funktionen (welche Bytes senden) bereits definiert sind. Du kannst also diese Funktionen verwenden und in gewisser Weise aufrufen (zum Blinken wie ich beschrieben hatte).
      LG Felix

    • Blackbox sagt:

      Hallo zusammen,

      ich habe ein wenig an den Libarys herumgebastelt. Ich kann jetzt mit oder ohne Hintergrundbeleuchtung schreiben. Weiterhin gibt es die Möglichkeit eigene Zeichen zu bauen und auf das Display zu schreiben. Würde Sie posten, aber ich habe keine Möglichkeit hier „Code“ zu posten.

      Gruß
      Blackbox

    • Felix sagt:

      Hallo Blackbox,
      du kannst deinen Code gerne auf http://pastebin.com/ posten und hier verlinken. Danke für deine Mühe!
      LG Felix

    • Stefan Wollner sagt:

      Hat zwar etwas gedauert, aber hier ist mein lcd_driver.py:

      http://pastebin.com/c6VHZx7i

      Funktion:

      lcd.lcd_display_string0(„string“, 1) -> schreibt ohne Hintergrundbeleuchtung
      lcd.lcd_display_string1(„string“, 1) -> schreibt mit Hintergrundbeleuchtung

  4. heiko sagt:

    hallo, habe den code mal instaliert auf meinem raspi mit jessie, bekomme aber beim start immer die meldung
    Traceback (most recent call last):
    File „/home/pi/i2c lcd.py“, line 1, in
    import lcddriver
    ImportError: No module named lcddriver

    woran kann das liegen ?

    danke im voraus

  5. Vincent sagt:

    Hallo,

    bei mir leuchtet zwar der Display, aber er wird nicht in der i2cdetect-Tabelle angezeigt. Ich habe auch mehrmals die Lötkontakte und die Kontakte untereinander kontrolliert.
    Woran kann das liegen, dass bei mir nichts angezeigt wird.
    Danke im vorraus

    • Felix sagt:

      Hallo Vincent,
      wenn über die I2C Suche nichts angezeigt wird, so wurde das Display nicht gefunden. Es leuchtet nur, weil VCC und GND richtig angeschlossen sind und es Strom bekommt.
      LG Felix

    • Martin sagt:

      Hallo Vincent,
      vertausch mal SDL und SCL am Pi. Hatte das gleiche Problem danach ging es.
      Grüße Martin

  6. Martin sagt:

    Hallo Felix,
    dein script läuft super. Allerdings kann ich mir Uhrzeit und Datum über „time.strftime“ nicht anzeigen lassen bekomme dann immer eine Fehlermeldung wie kann ich das anzeigen lassen?
    Vielen Dank im Vorraus

  7. rene sagt:

    hallo
    super anleitung, hat auf anhieb geklappt.
    hab aber noch 2 fragen.
    ich möchte 2 oder mehr variablen in einer zeile darstellen, wie mache ich das?
    lcd.lcd_display_string("%s" % var1 % var2, 1) funktioniert leider nicht.
    2 frage was bedeutet das %s in der klammer.

    vielen dank im voraus

  8. Martin sagt:

    hallo
    kann ich mit dem script auch die hintergrundbeleuchtug steuern?
    wenn ja wie mache ich das?
    über den jumper auf der i2c platiene funktioniert es nicht
    danke im voraus

    • Felix sagt:

      Nein, die Hintergrundbeleichtung kannst du mit einem Poti einstellen.

    • Martin sagt:

      Hallo Felix
      war wohl missverständlich ich meinte ob man über ein script die hintergrundbeleuchtung ein bzw aus schalten kann durch drücken eines tasters
      Danke im vorraus Martin

    • Felix sagt:

      Hi Martin,
      die Bibliothek hat doch eine Funktion zum ein bzw. ausschalten der Hintergrundbeleuchtung: lcd.lcd_backlight("ON")

    • Martin sagt:

      Hallo Felix,
      kann sein das ich blind bin aber finde keinen eintrag
      lcd.lcd_backlight(„ON“)
      weder in der i2c_lib noch in der lcddriver
      muss ich das vieleicht noch ergänzen?
      habs schon versucht mit lcd.lcd_backlight(„ON“)
      aber bekomme immer eine fehlermeldung das es den eintrag nicht gibt.
      danke schonmal im vorraus
      Martin

    • Felix sagt:

      In der Datei lcddriver.py ab Zeile 89 findest du die Funktion.

    • Martin sagt:

      nachtrag
      habs auch mit
      LCD_BACKLIGHT = 0x08
      LCD_NOBACKLIGHT = 0x00
      aber auch das hilft nicht
      Martin

    • Martin sagt:

      hi felix
      ich will ja nicht den klugscheißer raushängen lassen aber in der lcddriver.py die ich habe ist ab zeile 86 die definition für die text zeilen also der
      def lcd display string
      und der geht bis zeile 94
      hast du vielleicht eine neuere lcddriver.py?

      grüße Martin

    • Felix sagt:

      Hey Martin,
      sorry – du hast natürlich recht: Ich habe eben gesehen, dass ich die neuste Version nicht hochgeladen hatte (nun schon – danke für den Hinweis). Hier die Funktion, die du einfügen kannst:

         #turn on/off the lcd backlight
         def lcd_backlight(self, state):
            if state in ("on","On","ON"):
               self.lcd_device.write_cmd(LCD_BACKLIGHT)
            elif state in ("off","Off","OFF"):
               self.lcd_device.write_cmd(LCD_NOBACKLIGHT)
            else:
               print "Unknown State!"

      LG, Felix

    • Martin sagt:

      hallo felix

      feedback jetzt funtzt es 😉

      LG Martin

  9. Micha sagt:

    Hallo,

    vielen Dank für das tutorial, hat wunderbar funktioniert, text etc. funst auch alles wunderbar, was ich jetzt noch gerne wüsste ist wie ich das Grad Zeichen (°) ausgeben kann. Hat da Jemand ne Idee?

    • Martin sagt:

      Hallo Micha
      das ° Zeichen bekommt du indem du +chr(233)+ vor dem Index eingibst
      Grüße Martin

    • Marcus sagt:

      Hallo das Problem habe ich auch. Was für einen Index meinst du?

      Grüße Marcus

  10. Nils Margotti sagt:

    Ich erhalte beim ausführen von „i2cdetect -y 1″ als resultat:
    “ 0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — — — — — — — — — — — — —
    10: — — — — — — — — — — — — — — — —
    20: — — — — — — — — — — — — — — — —
    30: — — — — — — — — — — — — — — — —
    40: — — — — — — — — — — — — — — — —
    50: — — — — — — — — — — — — — — — —
    60: — — — — — — — — — — — — — — — —
    70: — — — — — — — –“

    Das Display ist an und zeigt weiße und schwarze Rechtecke. Und wenn ich deinen Test-Code ausführe kriege ich einen IO-Fehler.

  11. Dave sagt:

    Moin,
    Wenn ich „sudo i2cdetect -y 1“ eingebe, wird zwar die Tabelle angezeigt, jedoch leider keine einzige Adresse.
    Kann mir jemand sagen was ich ggf. Falsch gemacht haben könnte?

    • Dave sagt:

      ehm… jo… ist nun wieder obsolet… habe gestern bei n paar bier SDA und SCL am Raspi vertauscht… *glorreich*

Schreibe einen Kommentar

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

Blog abonnieren

Abonniere Tutorials-RaspberryPi, um kein Tutorial mehr zu verpassen!