LCD Displays am Arduino sind eine praktische Möglichkeit, damit man Daten nicht immer nur über die serielle Schnittstelle ausgeben muss und lassen auch kleine Projekte gleich professioneller aussehen.

Besonders das 1602 Display mit 2 Zeilen à 16 Zeichen ist in fast jedem Arduino Starter Kit zu finden. Diese Displays sind praktisch und kostengünstig, haben jedoch einen Nachteil: Sie werden standardmäßig parallel angesteuert und benötigen dadurch mindestens 6 Digitalpins am Arduino und eventuell auch noch eine Potentiometer am Breadboard.

Das kann problematisch werden, wenn weitere Sensoren oder Module angeschlossen werden sollen. Hinzu kommt der Kabelsalat auf dem Breadboard, der bei komplexeren Projekten schnell unübersichtlich wird.

Die Lösung: Die I²C-Schnittstelle für LCD Displays

Die I²C-Schnittstelle (Inter Integrated Circuit) bietet eine einfache Lösung für dieses Problem. I²C ist ein Protokoll zur seriellen Kommunikation zwischen elektronischen Bauteilen. Es benötigt nur zwei Leitungen und damit nur 2 Digitalpins am Arduino:

  • SDA (Serial Data Line) für die Datenübertragung
  • SCL (Serial Clock Line) für den Takt

Jedes I²C-Gerät hat eine eindeutige Adresse. Dadurch können über dieselben zwei Pins mehrere Module wie Sensoren oder Displays angesprochen werden.

Für Standard-LCDs gibt es kleine I²C-Adapterplatinen, die einfach an die 16 Anschlusspins des Displays gelötet werden. Diese verwenden meist den PCF8574, einen I/O Expander, der serielle Daten in parallele Signale für das LCD umwandelt. Diese Adapter stellen dann die 4 I²C-Anschlüsse (VCC, GND, SDA, SCL) zur Verfügung. Ein Potentiometer zur Helligkeitssteuerung der Anzeige ist oft noch zusätzlich auf der Platine integriert.

Diese Erweiterungen sind praktisch, machen das Modul jedoch etwas unhandlicher. Aus diesem Grund gibt es inzwischen auch LCD Displays mit integrierter I²C-Schnittstelle, die direkt auf dem Modul verbaut ist und so den gewohnten Formfaktor beibehält.

Anschluss eines I²C-LCD Displays an den Arduino

Der Anschluss eines I²C-LCD Displays an den Arduino UNO ist denkbar einfach:

  1. VCC an 5V
  2. GND an GND
  3. SDA an A4 (Arduino UNO)
  4. SCL an A5 (Arduino UNO)

Hinweis: Bei anderen Mikrocontrollern können die I²C-Pins variieren.

  • Arduino UNO/Nano: SDA an A4, SCL an A5.
  • Arduino Micro: SDA an D2, SCL an D3.
  • Arduino Mega 2560: SDA an D20, SCL an D21.
  • ESP8266 (NodeMCU): SDA an GPIO4 (D2), SCL an GPIO5 (D1).
  • ESP32: SDA an GPIO21, SCL an GPIO22.
  • Raspberry Pi (Model 3 & 4): SDA an GPIO2 (Pin 3), SCL an GPIO3 (Pin 5).
  • STM32 (Blue Pill): SDA an PB7, SCL an PB6.
  • Teensy 4.x: SDA an Pin 18, SCL an Pin 19.

LCD Display, Zeichensatz und Sonderzeichen

LCD-Displays wie das 1602 oder 2004 verwenden oft einen HD44780-kompatiblen Controller, der einen festgelegten Zeichensatz (Character Generator ROM, CGROM) integriert hat. Dieser Zeichensatz basiert auf dem erweiterten ASCII-Code und enthält neben den englischen Buchstaben, Zahlen und Symbolen auch einige Sonderzeichen wie Pfeile oder mathematische Symbole. Allerdings fehlen häufig länderspezifische Sonderzeichen, etwa deutsche Umlaute (ä, ö, ü) oder das „ß“.

Für individuelle Anpassungen bietet der Controller einen benutzerdefinierten Zeichensatz (CGRAM), in dem bis zu acht eigene Zeichen definiert werden können. Diese Zeichen werden als 8×5-Pixel-Matrix erstellt und können zur Darstellung von Sonderzeichen oder Symbolen genutzt werden. Wenn jedoch mehr als acht Sonderzeichen benötigt werden, müssen diese dynamisch neu definiert werden, was bei häufiger Nutzung den Code komplexer macht.

Eine sehr gute Library zur Anzeige deutscher Umlaute samt umfangreicher Erklärung:
https://werner.rothschopf.net/202003_arduino_liquid_crystal_umlaute.htm

Einfacher Sekundenzähler auf einem LCD Display

#include <LCDI2C_Multilingual_MCD.h>

LCDI2C_Latin lcd(0x27, 16, 2); // I2C Adresse: 0x27; Display: 16x2

void setup() {
  lcd.init(); // Display initialisieren
  lcd.backlight(); // Hintergrundbeleuchtung einschalten
  lcd.setCursor(0, 0); // Cursor auf erstes Zeichen in erster Zeile
  lcd.print("Sekunden:"); // Text in erster Zeile ausgeben
}

void loop() {
    unsigned long seconds = millis() / 1000;
 
    lcd.setCursor(0, 1); // Cursor auf erstes Zeichen in zweiter Zeile
    lcd.print(seconds); // Zeit seit Start in Sekunden ausgeben
    lcd.print("s   "); // s für Sekunden und ein paar Leerzeichen zum Überschreiben alter Werte
    delay(500); // Leichte Verzögerung, damit nicht dauernd geschrieben wird
}Code-Sprache: PHP (php)

I²C-Adressen verstehen und ändern

Da alle über I²C angesteuerten Geräte über einen gemeinsamen Datenbus angesprochen werden, benötigt jedes Gerät eine eindeutige Adresse. Die Standardadresse für viele LCD-I²C-Module ist 0x27 (hexadezimal).

Wenn mehrere Displays verwendet werden sollen oder es einen Adresskonflikt mit anderen Geräten gibt, dann müssen unterschiedliche Adressen vergeben werden. Auf der Rückseite des I²C-Moduls befinden sich dazu drei Pins: A0, A1 und A2. Diese Pins steuern die letzten 3 Bits der I²C-Adresse.

  • Offen (HIGH): Das Bit ist auf 1 gesetzt.
  • Kurzgeschlossen (LOW): Das Bit wird auf 0 gesetzt.

Beispiel (I²C Adressen in 7 Bit)

  • A0 geschlossen: Ändert die Adresse von 0x27 (0b0100111) auf 0x26 (0b0100110).
  • A1 geschlossen: Ändert die Adresse von 0x27 (0b0100111) auf 0x25 (0b0100101).
  • Alle geschlossen: Adresse ändert sich von 0x27 (0b0100111) auf 0x20 (0b0100000).

So lassen sich mehrere Displays mit unterschiedlichen Adressen am selben I²C-Bus betreiben.

Drei Displays gleichzeitig ansteuern

In diesem Beispiel werden drei Displays über den I²C-Bus gleichzeitig angesteuert. Die Displays zeigen unterschiedliche Informationen an.

#include <LCDI2C_Multilingual_MCD.h>

LCDI2C_Latin lcd1(0x25, 16, 2); // I2C Adresse: 0x25; Display: 16x2
LCDI2C_Latin lcd2(0x26, 16, 2); // I2C Adresse: 0x26; Display: 16x2
LCDI2C_Latin lcd3(0x27, 20, 4); // I2C Adresse: 0x27; Display: 20x4

unsigned long lastSecond = 0; // Zwischenspeicher für Fortschrittsbalken
int progressBar = 0; // Aktuelle Länge des Fortschrittbalkens

void setup() {
  lcd1.init(); // Display1 initialisieren
  lcd1.backlight(); // Hintergrundbeleuchtung einschalten
  lcd1.setCursor(0, 0); // Cursor auf erstes Zeichen in erster Zeile
  lcd1.print("Sekunden:"); // Text in erster Zeile ausgeben

  lcd2.init(); // Display 2 initialisieren
  lcd2.backlight(); 
  lcd2.setCursor(0, 0); 
  lcd2.print("Millisekunden:"); 

  lcd3.init(); // Display 3 initialisieren
  lcd3.backlight(); 
  lcd3.setCursor(0, 0); 
  lcd3.print("Fortschrittsbalken:"); 
}

void loop() {

    unsigned long currentMillis = millis();
    unsigned long currentSeconds = currentMillis / 1000;

    // Display 1 - aktuelle Zeit in Sekunden
    lcd1.setCursor(0, 1); // Cursor auf erstes Zeichen in zweiter Zeile
    lcd1.print(currentSeconds); // Zeit seit Start in Sekunden ausgeben
    lcd1.print("s"); // sec für Sekunden

    // Display 2 - Zeit in Millisekunden
    lcd2.setCursor(0, 1);
    lcd2.print(currentMillis); // Zeit seit Start in Millisekunden ausgeben
    lcd2.print("ms");


    // Display 3: Fortschrittsbalken aktualisieren (60 Zeichen pro Minute)
    if (lastSecond != currentSeconds) { // Nur aktualisieren, wenn sich der Inhalt geändert hat
        progressBar = currentSeconds % 60; // Fortschritt von 0 bis 59
        lastSecond = currentSeconds;
        
        // Fortschrittsbalken leeren bei Neuanfang
        if (progressBar == 0) {
          for (int row = 1; row <= 3; row++) {
            lcd3.setCursor(0, row);
            lcd3.print("                    ");
          }
        }

        // Fortschrittsbalken zeichnen
        int row = 1;
        int col = 0;
        for (int i = 0; i < progressBar; i++) {
            lcd3.setCursor(col, row);
            lcd3.print("#");
            col++;
            if (col >= 20) { // Nächste Zeile nach 20 Zeichen
                col = 0;
                row++;
            }
        }
    }

}Code-Sprache: PHP (php)

Mit einer I²C-Schnittstelle kann man LCD Displays einfach ansteuern und in jedes Projekt integrieren. Anstatt für jedes Display mehrere Pins zu belegen, genügen zwei Pins (SDA und SCL), um mehrere Displays oder Sensoren zu betreiben. Das ermöglicht komplexe Projekte, ohne sich Gedanken über fehlende GPIO-Pins machen zu müssen.

Dank der verfügbaren Libraries und einfacher Adressänderungen ist die Einrichtung von I²C-LCDs schnell erledigt. Ob ein einzelnes Display oder mehrere Module gleichzeitig – mit I²C sind die Möglichkeiten nahezu unbegrenzt.


Tagged on:             

Schreibe einen Kommentar

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

Time limit is exhausted. Please reload the CAPTCHA.

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..