1.1l 🚧 LCD Anzeige
Für kleines Geld gibt es LCD-Displays auf Basis des HD44780 Treiberchips. Um sie bequem an einem µC betreiben zu können werden sie mit einem Portexpander-Chip HLF8574 über I2C angeschlossen. Eine Library macht die Ansteuerung zum Kinderspiel.

LiquidCrystal_PCF8574 Library
Arduino Library for LiquidCrystal displays with I2C PCF8574 adapter🔗
ToDo: Wie kann der Insert-Modus des Displays eingeschaltet werden?

Testprogramm
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd (0x27); // LCD-Adresse auf 0x27 für 16 Zeichen und 2 Zeilen ein
byte herz[] = {0b00000,0b01010,0b11011,0b11111,0b01110,0b00100,0b00000,0b00000};
byte dotOff[] = {0b00000,0b01110,0b10001,0b10001,0b10001,0b01110,0b00000,0b00000};
byte dotOn[] = {0b00000,0b01110,0b11111,0b11111,0b11111,0b01110,0b00000,0b00000};
void setup() {
lcd.begin(16, 2); // LCD initialisieren
lcd.clear(); // Displaypuffer löschen
lcd.setBacklight(255); // Hintergrundbeleuchtung einschalten
lcd.setCursor(0,0); // Cursor auf erstes Zeichen, erste Zeile setzen
lcd.print("MezMedia.de"); // Text ausgeben
lcd.setCursor(0,1); // erstes Zeichen, zweite Zeile
lcd.print("Viel Erfolg!");
delay(2000);
lcd.createChar(0, herz); // eigene Zeichen definieren
lcd.createChar(2, dotOff);
lcd.createChar(7, dotOn);
}
int show = -1;
void loop() {
int i;
switch(show){
case 0: // Raus rein scrollen
for(i=0;i<16;i++){
lcd.scrollDisplayRight();
delay(200);
}
for(i=0;i<16;i++){
lcd.scrollDisplayLeft();
delay(70);
}
delay(1000);
break;
case 1: // Cursor
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cursor On");
lcd.cursor();
delay(1000);
for(i=8;i>0;i--){
lcd.setCursor(i, 0);
delay(200);
}
delay(1000);
lcd.blink();
for(i=1;i<9;i++){
lcd.setCursor(i, 0);
delay(300);
}
delay(1000);
lcd.noBlink();
lcd.noCursor();
delay(1000);
break;
case 2: // eigene Zeichen
lcd.clear();
//lcd.print("Herz:<\00>"); // funktioniert nicht
lcd.write(0); // RAM-Position 0 für Herz funktioniert
lcd.setCursor(0, 1);
lcd.print("Punkt:<\02><\07>");
delay(2000);
break;
case 3: // verschiedene Zeichen ausgeben
lcd.clear();
for(i=0xe0;i<0xe0+16;i++){
lcd.write(i);
delay(50);
}
lcd.setCursor(0, 1);
for(i=0xf0;i<0xf0+16;i++){
lcd.write(i);
delay(50);
}
delay(4000);
break;
case 4: // Autoscroll
lcd.clear();
lcd.print("Autoscroll-Test:");
delay(1000);
lcd.autoscroll(); // einschalten
for(i=1;i<=9;i++){
lcd.print(i);
delay(400);
}
lcd.noAutoscroll(); // ausschalten
delay(2000);
break;
default:
show=-1;
}
show++;
}
Funktionen
| Befehl / Beispiel | Erklärung |
|---|---|
LiquidCrystal_PCF8574 lcd (0x27); | Initialisierung für LCD auf Adresse 0x27 |
lcd.begin(16, 2); | LCD hat 2 Zeilen mit 16 Zeichen |
lcd.clear(); | Den Pufferspeicher löschen und Cursor auf 0,0 |
lcd.home(); | Cursor auf 0,0 |
lcd.setBacklight(255); | Die Hintergrundbeleuchtung einschalten. Faktisch ist 0 aus und alle anderen Werte an |
lcd.setCursor(0,0);lcd.setCursor(0,1); | Cursor auf erstes Zeichen, erste Zeile setzen Cursor auf erstes Zeichen, zweite Zeile setzen |
lcd.print("MezMedia.de"); | Text auf LCD ausgeben |
lcd.write(0xe1); | Byte zu LCD schicken, hier Code Buchstabe ‘ä’ |
lcd.cursor(); | Den Cursor einschalten |
lcd.noCursor(); | Den Cursor ausschalten |
lcd.blink(); | Am Cursor blinken lassen |
lcd.noBlink(); | Blinken ausschalten |
lcd.display(); | Display wieder einschalten |
lcd.noDisplay(); | Display ausschalten |
lcd.scrollDisplayLeft(); | Anzeige nach Links scrollen |
lcd.scrollDisplayRight(); | Anzeige nach Rechts scrollen |
lcd.autoscroll(); | Anzeige scrollt automatisch nach links bei Eingabe nach Zeilenende |
lcd.noAutoscroll(); | Autoscroll wieder ausschalten |
lcd.leftToRight(); | Anzeige von Links nach Rechts |
lcd.rightToLeft(); | Anzeige von Rechts nach Links |
lcd.createChar(1, dotOff); | Ein eigenes Zeichen im RAM-Speicher auf Adresse 1 ablegen |
LCD-Chip HD44780
Synopsis: HD44780📖 Sonderzeichen LCD HD44780 kompatibel🔗 Dot-Matrix LCD-Displays🔗
- Ein Zeichen ist 5×8 (Breite x Höhe) Pixel groß
- Hat einen 80 Zeichen langen Textpuffer (wird beim Scrollen interessant)
- Kann 8 “Kundenzeichen” im RAM ablegen, Zeichen 0..7
HD44780 Displaycode Tabelle
Für ASCII funktioniert es noch gut, aber bei Umlauten und Sonderzeichen muss man sich die Code-Tabelle📖 anschauen und den entsprechenden Displaycode senden Beispiele:
| Zeichen | Unicode | LCD-Code |
|---|---|---|
| € | U+20AC | \xd3 |
| ° | U+0080 | \xdf |
| 𝛼 | U+03B1 | \xe0 |
| ä | U+00E4 | \xe1 |
| ß | U+00DF | \xe2 |
| ε | U+03B5 | \xe3 |
| µ | U+00B5 | \xe4 |
| 𝜎 | U+03C3 | \xe5 |
| ö | U+00F6 | \xef |
| Ω | U+03A9 | \xf4 |
| ü | U+00FC | \xf5 |
| Σ | U+03A3 | \xf6 |
| π | U+03C0 | \xf7 |

💊 Umlaute und Sonderzeichen ersetzen
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd (0x27);
String text="Für 20° -> 30µV";
void setup() {
lcd.begin(16, 2); // LCD initialisieren
lcd.clear(); // Displaypuffer löschen
lcd.setBacklight(255); // Hintergrundbeleuchtung ein
Serial.begin(9600);
Serial.println(text);
lcd.print(text); // Text direkt ausgeben
lcd.setCursor(0,1);
lcd.print("F\xf5r 20\xdf \x7e 30\xe4V"); // Codiert
}
void loop() {}
Die Ausgabe von UTF-8 auf dem seriellen Monitor klappt problemlos. Die LCD-Anzeige gibt aber Unsinn aus. Erst durch händisches Ersetzten mit den richtigen LCD-Codes wird die Anzeige sinnvoll.

🚧 Aufgabenidee: Erstellen Sie eine Funktion void ausgebenLCD(String s), die sinnvolle Ersetzungen für diese Zeichen vornimmt: \~°µßäöü-><-
Vergleichen Sie die Zeichen in den Listen: Unicodeblock Basis-Lateinisch📖 Unicodeblock Lateinisch-1, Ergänzung📖 mit der Tabelle der LCD-Codes und erstellen Sie eine Tabelle mit den zu ersetzenden Zeichen. Gegebenenfalls müssen eigene Zeichen im RAM hinterlegt werden.
😵💫 Noch keine Lösung, bin über UTF-8 und Strings gestolpert. Scheint kompliziert zu werden. Z.B. String utf=”\\~°µßäöü”; utf.length() ergibt 14 🤷…
| UTF | \ 0x5c | ~ 0x7e | ° 0xb0 | µ 0xb5 | ß 0xdf | ä 0xe4 | ö 0xf6 | ü 0xfc |
| LCD | RAM 0x00 | RAM 0x01 | 0xdf | 0xe4 | 0xe2 | 0xe1 | 0xef | 0xf5 |
LCD an SturmBoard anschließen mit Drahtbrücken
Das I2C-LCD-Display ist an PA11 (SCL) und PA12 (SDA) angeschlossen. Beim Assembler und bei MBED hat Herr Sturm eine Software I2C-Lösung zur Anbindung verwendet, d.h. es wird nicht die I2C-Hardware des Controllers genutzt, sondern die Schnittstelle ist per Software realisiert.
Die Arduino I2C-Library Wire benutzt standardmässig D15 = PB8 (SCL) und D14 = PB9 (SDA). Meine einfache Lösung sind zwei Drahtbrücken:
- Serial Clock SCL: D15 = PB8 -> PA11
- Serial Data SDA: D14 = PB9 -> PA12
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd (0x27); // LCD-Adresse auf 0x27 für 16 Zeichen und 2 Zeilen ein
void setup() {
lcd.begin(16, 2); // initialize the lcd
lcd.clear();
lcd.setBacklight(255);
lcd.setCursor(0,0); // erstes Zeichen, erste Zeile
lcd.print("MezMedia.de");
}
void loop() {
delay(1000);
lcd.setBacklight(255);
lcd.setCursor(0,1); // erstes Zeichen, zweite Zeile
lcd.print("Viel Erfolg!");
delay(1000);
for (int i= 255;i>=0;i--){
lcd.setBacklight(i);
lcd.setCursor(0, 1);
lcd.printf("Backlight: %d ",i);
delay(50);
}
}
Mit dem Testprogramm erkannt: Die Hintergrundbeleuchtung geht nur an und aus. 😕
Beim STM32L152RE gibt es zwei I2C Schnittstellen, die über eine interne Verdrahtungsmatrix auf unterschiedliche Ports geschaltet werden können. Im Datenblatt ab Seite 47 sind die möglichen Anschluss-Pins für I2C zu finden.
PA11 und PA12 sind leider nicht dabei. 😭
Nach der API-Beschreibung kann die zweite Schnittstelle recht leicht eingerichtet werden, auch dort könnte das LCD-Display mit Drahtbrücken von PB10 und PB11 angeschlossen werden. Leider wird dies mit der BlueTooth Schnittstelle kollidieren.


| Pin | I2C |
|---|---|
| PB5 (D4) | I2C1_SMBA |
| PB6 (D10) | I2C1_SCL |
| PB7 | I2C1_SDC |
| PB8 (D15) | I2C1_SCL |
| PB9 (D14) | I2C1_SDA |
| PB10 (D6) | I2C2_SCL |
| PB11 | I2C2_SDA |
| PB12 | I2C2_SMBA |

LCD an SturmBoard anschließen mit Software Lösung
Ein Kollege hat eine Softwarelösung entwickelt, die ohne Drahtbrücken auskommt: https://github.com/schreger/LiquidCrystal_PCF8574_SoftWire/tree/main
Dazu muss eine Bibliothek eingefügt werden, Perplexity:
Arduino Bibliothek hinzufügen: Schritt-für-Schritt-Anleitung
Es gibt zwei Hauptmethoden, um eine Bibliothek zur Arduino IDE hinzuzufügen:
1. Über den Bibliotheksmanager (empfohlen)
- Öffne die Arduino IDE.
- Gehe zu Sketch > Bibliothek einbinden > Bibliotheken verwalten….
- Im Bibliotheksmanager kannst du nach dem Namen der gewünschten Bibliothek suchen.
- Wähle die gewünschte Bibliothek aus und klicke auf Installieren.
- Die IDE lädt die Bibliothek automatisch herunter und installiert sie.
😔 Geht nicht, weil Bibliothek nicht auftaucht.
2. Manuelle Installation einer ZIP-Bibliothek
- Lade die gewünschte Bibliothek als ZIP-Datei (z.B. von GitHub) herunter.
- Öffne die Arduino IDE.
- Gehe zu Sketch > Bibliothek einbinden > .ZIP-Bibliothek hinzufügen….
- Wähle die heruntergeladene ZIP-Datei aus und bestätige mit Öffnen.
- Die Bibliothek wird installiert und steht anschließend zur Verfügung.
😉 Geht nicht, weil die JSON-Dateien fehlen.


👋 Manuelles Hinzufügen zum Sketch
1. Sketch erstellen:
#include <Arduino.h>
#include <SoftWire.h>
#include <LiquidCrystal_PCF8574_SoftWire.h>
SoftWire wire(PA12, PA11);
LiquidCrystal_PCF8574_SoftWire lcd(0x27); // set the LCD address to 0x27
void setup() {
wire.begin();
wire.setClock(100000); // I2C speed 100kHz
lcd.begin(16, 2,wire); // initialize the lcd for a 16 chars and 2 line
lcd.clear();
lcd.setBacklight(255);
lcd.setCursor(0,0); // erstes Zeichen, erste Zeile
lcd.print("MezMedia.de");
}
void loop() {
delay(1000);
lcd.setBacklight(255);
lcd.setCursor(0,1); // erstes Zeichen, zweite Zeile
lcd.print("Viel Erfolg!");
delay(1000);
for (int i= 255;i>=0;i--){
lcd.setBacklight(i);
lcd.setCursor(0, 1);
lcd.printf("Backlight: %d ",i);
delay(50);
}
}
2. Library laden und entpacken
https://github.com/schreger/LiquidCrystal_PCF8574_SoftWire/tree/main
3. Mit Copy & Paste zum Sketch hinzufügen
Taucht dann im Sketch auf und wird mit kompiliert.

