Arduino Mikrocontroller Tutorials - Module

LCD Display mit I2C Ansteuermodul (HW-061)

Bild LCD mit I2C Modul HW-061
LCD PIN Pin am I2C Modul HW-061
VSS (Voltage Source) GND
VDD (Voltage Drain) +5 V
VO (Contrast Control) analoge Spannung zwischen 0-5 V
RS (Register Select) Port 0 (0=GND, 1=VCC)
RW (Read/Write) Port 1 (0=GND, 1=VCC)
EN (Enable) Port 2 (0=GND, 1=VCC)
D0 - D3 dauerhaft +5V
D4 - D7 Port 4 - Port 7 (0=GND, 1=VCC)
A dauerhaft +5 V
K Port 3 auf GND (0=VCC, 1=GND,)

Das Modul HW-061 dient zum einfachen ansteuern eines standard LCD Displays mit 16 Anschlusspins. Statt den 16 Anschlussleitungen werden aufgrund der I2C Übertragung nur 4 Leitungen benötigt (VCC, GND, SDA, CLK). Mit dem eingebauten Poti kann man den Kontrast einstellen und mit dem Jumper die Hintergrundbeleuchtung an- und ausschalten. Kern des HW-061 Moduls ist ein 8-bit Port-Expander IC (PCF8574) welcher die I2C Signale in 8 parallel anliegende Ausgangspegel umwandelt. Das LCD Display selbst und die Ansteuerung eines I2C Port-Expanders sind bereits in vorhergegangenen Kapitel vorgestellt worden.

Hier eine Tabelle mit einer Übersicht welcher Ausgang des HW-061 welchem Eingang des LCD Displays entspricht. Die Ports P0-P7 werden über I2C Daten gesteuert.

I2C Port-Expander (PCF8574)

Bild I2C Modul HW-061

Der PCF8574 antwortet nicht auf die allgemeine I2C "Call Address". Die voreingestellte Adresse ist 0x27. Falls man eine andere Adresse benötigt kann diese über 3 Lötbrücken verändert werden. Nachfolgend nochmal eine Übersicht welches bit welchem LCD Eingang entspricht. Die Ports P4-P7 dienen zum Übertragen von Daten und die Ports P0-P4 zum schalten der Steuerleitungen. Die Pinbezeichnungen und die nachfolgenden Befehle sind im Kapitel LCD Display ausführlich erklärt.

P7 P6 P5 P4 P3 P2 P1 P0
D7 D6 D5 D4 LED EN RW RS

Programmcode ohne die Verwendung einer Bibliothek

Die Befehle für das IR oder die Anzeigedaten für das DR liegen immer als 8 bit vor (außer der erste Befehl zum Einstellen des 4-Bit-Modus). Im 4-Bit-Modus mussen die 8 bit daher auf 2x gesendet werden (P4-P7). In der datenSenden() Funktion werden die 8 Daten bit daher zunächst aufgeteilt und an die Stellen P4-P7 verschoben. An die Stellen P0-P3 werden Werte für die Steuerleitungen kopiert. LED=1 (Hintergrundbeleuchtung an), RW=0 (Schreibmodus), RS= 1/0 (abhängig ob in das Befehlsregister geschrieben werden soll RS=0, oder in das Datenregister RS=1).

Der EN Pin von den Steuerleitungen an P2 muss einmal seinen Pegel von 1 auf 0 ändern. Erst bei diesem Flankenwechsel werden die anliegenden Pegel von den vom LCD Display übernommen. Das ist auch der Grund, warum jedes Halbbyte 3x übertragen wird.

#include "Wire.h" // Anschluss-Pins I2C: SDA=A4, CLK=A5 #define IR 0 // Instruction Register #define DR 1 // Data Register void setup() { Wire.begin(); datenSenden(IR, B00000010); // 4-Bit Übertragungsmodus datenSenden(IR, B00101000); // Function Set datenSenden(IR, B00001110); // Display Control datenSenden(IR, B00000001); // Clear Display } void loop() { datenSenden(DR, 'H'); datenSenden(DR, 'a'); datenSenden(DR, 'l'); datenSenden(DR, 'l'); datenSenden(DR, 'o'); while(true); }
Funktion datenSenden() #define adresse 0x27 void datenSenden(bool rs, byte daten) { //daten aufteilen in zwei Halbbytes byte oberesHalbByte = daten & B11110000; byte unteresHalbByte = (daten & B00001111) << 4; //Steuerleitungen dazu schalten X|X|X|X|LED=1|EN=1|RW=0|RS=1 byte erstesSendeByte = oberesHalbByte | B00001101; byte zweitesSendeByte = unteresHalbByte | B00001101; // wenn ins Instruction Register geschrieben werden soll: RS=0 if (rs == 0) { erstesSendeByte &= B11111110; zweitesSendeByte &= B11111110; } // Daten auf I2C übertragen 3x erstesSendeByte und 3x zweitesSendebyte // ... jeweils mit einem Enable (EN=0) Puls dazwischen Wire.beginTransmission(adresse); Wire.write(erstesSendeByte); Wire.endTransmission(); Wire.beginTransmission(adresse); Wire.write(erstesSendeByte & B11111011); // EN = LOW Wire.endTransmission(); Wire.beginTransmission(adresse); Wire.write(erstesSendeByte); Wire.endTransmission(); delayMicroseconds(100); Wire.beginTransmission(adresse); Wire.write(zweitesSendeByte); Wire.endTransmission(); Wire.beginTransmission(adresse); Wire.write(zweitesSendeByte & B11111011); // EN = LOW Wire.endTransmission(); Wire.beginTransmission(adresse); Wire.write(zweitesSendeByte); Wire.endTransmission(); delay(20); }

Programmcode mit der Bibliothek LiquidCrystal_I2C.h

LiquidCrystal_I2C myLCD (I2C Adresse, Anzahl Stellen, Anzahl Zeilen)

Erstellt eine Instanz von von LiquidCrystal_I2C und übernimmt die Modul-Adresse und die Displaymaße.

myLCD.init()

Initialisiert das Display mit den Grundeinstellungen

myLCD.backlight() und myLCD.noBacklight()

Schaltetet die Hintergrundbeleuchtung an oder aus. Die Displayanzeige wird dadurch nicht gelöscht.

myLCD.clear()

Löscht das Display und setzt den Cursor links in die erste Reihe.

myLCD.home()

Setzt den Cursor ganz links in die ersten Reihe. Ohne den Displayinhalt zu löschen.

myLCD.setCursor(Stelle, Zeile)

Setzt den Cursor an die entsprechende Stelle (0= vorderste Stelle) in der entsprechenden Zeile (0= oberste Zeile). Je Zeile kann der Cursor an 40 Stellen (0-39) gesetzt werden. Wenn der Displayinhalt mit scrollDisplayLeft() oder scrollDisplayRight() noch nicht bewegt wurde werden standardmäßig die ersten 16 Stellen angezeigt.

myLCD.cursor() und myLCD.noCursor()

Mit diesen Befehlen wird der Cursor als Unterstrich an der Stelle an der als nächste geschrieben werden soll angezeigt. Mit noCursor() wird der Unterstrich wieder ausgeblendet.

myLCD.blink() und myLCD.noBlink()

Mit diesem Befehl wird der Cursor als blinkendes Rechteck an der Stelle angezeigt, an der als nächstes geschrieben wird. Mit noBlink() wird das blinkende Rechteck wieder ausgeschalten.

myLCD.display() und myLCD.noDisplay()

Mt diesen Befehlen kann der Displayinhalt aus und wieder eingeschaltet werden. Im ausgeschalteten Zustand bleibt der Inhalt gespeichert. Die Hintergrundbeleuchtung bleibt auch im ausgeschalteten Modus an.

myLCD.scrollDisplayLEFT() und myLCD.scrollDisplayRight()

Durch diese Befehle kann der sichtbare Ausschnitt (die 16 derzeit angezeigten Stellen) nach links oder rechts bewegt werden.

myLCD.autoscroll() und noAutoscroll()

Mit autoscroll()kann auf einer Displaystelle geschrieben werden. Anstatt dass sich der Cursor weiterbewegt bewegt sich mit diesen Befehlen der ganze Displayinhalt. Mit noAutoscroll() wird wieder auf die Cursor Bewegung geschalten.

leftToRight() und rightToLeft()

Legt die schreibrichtung fest. Also die Bewegung des Cursors nach dem ein Buchstabe geschrieben wurde.

myLCD.write() und myLCD.print()

Mit diesen Befehlen können einzelne Zeichen (character) oder ganze Strings auf das display übertragen werden.

#include "LiquidCrystal_I2C.h" LiquidCrystal_I2C myLCD(0x27,16,2); // Slave Adresse, Zeichen pro Zeile, Anzahl Zeilen void setup() { myLCD.init(); myLCD.backlight(); } void loop() { myLCD.print("Hallo!!!"); delay(1000); myLCD.noBacklight(); delay(1000); myLCD.backlight(); delay(1000); myLCD.setCursor(0,1); myLCD.print("alles wird gut!"); delay(1000); myLCD.clear(); delay(1000); }