I²C tekst display met twee regels van 16, 20 of 24 tekens
De programma's beneden zijn gemaakt voor LCD tekst displays van twee regels van 16, 20 of 24 tekens. Dit soort displays kunnen het adres 0x27 of 0x3F gebruiken. Als je display met het ene adres niet werkt probeer dan het andere. Op foto's van deze displays kun je niet zien hoe mooi deze displays zijn. Displays met witte letters op een blauwe achtergrond zijn vaak veel helderder dan zwarte letters op een groene achtergrond. Je kunt de helderheid tussen bepaalde grenzen regelen met de stelknop achter op de interface van het display.
Er zijn diverse bibliotheken die je kunt gebruiken met dit display.
Ik gebruikte tot voor kort altijd de bibliotheek LiquidCrystal_I2C van Francisco Malpartida. Deze komt in de plaats van de standaard LiquidCrystal_I2C. Tegenwoordig wordt de bibliotheek van Frank de Brabander geadviseerd. Omdat deze ook LiquidCrystal_I2C heet kan er verwarring ontstaan. Je kunt deze bibliotheek heel gemakkelijk vinden in Bibliotheekbeheer en dan meteen installeren.
De bibliotheek LiquidCrystal_I2C_Hangul.h werkt ook erg eenvoudig en kan eveneens via het menu bibliotheek beheren geïnstalleerd worden. Deze bibliotheek ondersteunt, zoals de naam al aangeeft het Hangul (Koreaans) schrift, maar de resultaten zijn niet overtuigend. In beide methode zet je de achtergrond aan met de instructie background(), maar setBacklight(HIGH) werkt ook. De beste en meest stabiele bibliotheek is LiquidCrystal_PCF8574.h van Matthias Hertel. Deze werkt helaas nogal afwijkend. Toch kunnen animaties er beter uitzien als je de bibliotheek van Matthias Hertel gebruikt. Bij deze bibliotheek moet je de achtergrondverlichting aanzetten met setBacklight(1), waarbij 1 de intensiteit is (je mag een hoger getal invullen - maximum 255, maar ik zie bij mijn displays geen verschil).
Als je de oude, standaardbibliotheek LiquidCrystal_I2C gebruikt dan kan het zijn dat lcd.print maar één letter print.
Je moet dan in het bestand LiquidCrystal_I2C.cpp bij
de 0 veranderen in een 1.
Ik heb voor de duidelijkheid van alle bibliotheken voorbeelden opgenomen, zie onder "Een Valentijn surprise" of "Lichtkrant". Als je deze bibliotheek gebruikt met een ESP processor, dan krijg je in de Arduino IDE een waarschuwing dat de bibliotheek misschien niet werkt, maar ik ben geen enkel probleem tegengekomen. Ik hem dit getest met een ESP32 en een ESP8266, met verschillende displays.
Aansluiting op je Arduino
Dit is heel simpel: VCC op 5 volt en GND op GND; bij de meeste Arduino's SDA op A4 en SCL op A5.
Aansluiting op systemen met een ESP processor
Modules met een ESP processor hebben doorgaans alleen 3,3 volt uitgangen. Een enkele zoals de WeMos D1 mini en de LoLin nodeMCU v2 hebben ook een pin die 5 volt levert, mits je de USB poort gebruikt voor de voeding.
Step-up (of boost-up) converter
Als jouw module alleen 3,3 volt uitgangen heeft, dan kun je een aparte 5 volt voeding voor het display gebruiken. Het is echter handiger om een zogenaamde step-up converter te gebruiken. Koop er een die 5 volt als uitgang heeft. Sluit VIN (of Vi of V1) van de step-up converter aan op een 3,3 volt pin en GND op GND. VOUT (of Vo) gaat dan naar VCC van het display. Via step-up converter naar display. Links: WeMos ESP8266 nodeMCU; rechts ESP32 WROOM
Bij bijna alle nodeMCU's die de ESP2866 gebruiken is pin D1 de klok en pin D2 de datalijn. Sluit D1 aan op SCL van het display en D2 op SDA van het display. Bij nodeMCU's, devKits e.d. die de ESP-32 gebruiken is pin 21 SDA en pin 22 SCL. Ik testte meer dan tien van deze displays met een aantal verschillende borden, waaronder met ESP32, allemaal zonder problemen.
Als eerste laat ik zien hoe je je eigen symbolen kunt maken. Op deze pagina kun je gemakkelijk je eigen ontwerp maken. Meer dan 8 verschillende tegelijkertijd gaat niet, maar na elkaar wel. Verderop staat enige uitleg bij de code. LET OP: bij sommige displays moet je in de tweede regel 0x3F vervangen door 0x27.
#include <LiquidCrystal_I2C.h> // Installeer de versie van Frank de Brabander
// Pas indien nodig het i2c adres (0x27) aan. Mogelijke waarden: 0x27 en 0x3F
LiquidCrystal_I2C lcd(0x27, 24, 2); // initialiseer op 24 karakters en 2 regels.
// Definieer enkele eigen symbolen
byte lach[8] = {0x0E, 0x11, 0x1B, 0x11, 0x1B, 0x15, 0x11, 0x0E}; // Met hex getallen...
byte pop[8] = {0x04, 0x0E, 0x0E, 0x04, 0x0E, 0x1F, 0x1F, 0x0E};
byte pijl[8] = {0x04, 0x0E, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04};
byte raam[8] = {0x1F, 0x15, 0x15, 0x1F, 0x15, 0x15, 0x15, 0x1F};
byte hart[8] = {0, 10, 31, 31, 14, 4, 0, 0}; // of met decimale getallen...
byte euro[8] = {0, B111, B1000, B11110, B1000, B11110, B1000, B111}; // of met binaire getallen
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0); lcd.print("Dit display is 24 breed!");
// Ken een nummer (0 t/m 5) toe aan de eigen karakters:
lcd.createChar(0, lach); lcd.createChar(1, pop);
lcd.createChar(2, pijl); lcd.createChar(3, raam);
lcd.createChar(4, hart); lcd.createChar(5, euro);
lcd.setCursor(6, 1);
lcd.write((byte)0); lcd.print(" ");
lcd.write(1); lcd.print(" ");
lcd.write(2); lcd.print(" ");
lcd.write(3); lcd.print(" ");
lcd.write(4); lcd.print(" ");
lcd.write(5);
}
void loop() {
}
Uitleg bij de code
Voor meer informatie over LiquidCrystal_I2C kijk bij het vierregelig display.
In de vier regels die met byte beginnen worden de speciale symbolen gedefinieerd. Per pixel-regel wordt één byte gebruikt. Omdat dit display symbolen gebruikt van 5 pixels breed zijn alleen de laatste 5 bits van de byte van belang. Ik heb om de getallen te krijgen een programma gebruikt. Het is niet moeilijk om dat zonder programma te doen: stel dat je het raam wil maken (x = pixel AAN, spatie = pixel UIT)
xxxxx Vertaal dit in B11111 (B staat voor binair, dit moet een hoofdletter zijn!)
x x x Vertaal dit in B10101 (gebruik een 1 voor AAN en een 0 voor UIT)
x x x Vertaal dit in B10101
xxxxx Vertaal dit in B11111
x x x Vertaal dit in B10101
x x x Vertaal dit in B10101
x x x Vertaal dit in B10101
xxxxx Vertaal dit in B11111
De instructie wordt dan dus byte raam[8] = {B11111, B10101, B10101, B11111, B10101, B10101, B10101, B11111};
Je kunt de nieuwe symbolen op twee manieren schrijven: met write of met print. Als je write gebruikt dan kun je gewoon het nummer van het symbool invoeren (maar als dat nummer 0 is moet je in sommige bibliotheken char(0) zetten. Als je print gebruikt dan moet je aangeven dat je een char bedoelt. Voor de pijl (nummer 2): lcd.write(2); of lcd.print(char(2));. Theoretisch is het beter om de byte-waarde door te geven in plaats van een char en dat kan belangrijk zijn als je andere bibliotheken gebruikt dan hier: gebruik dan bijvoorbeeld lcd.print( (byte) 0). Het kan nog compacter door direct de hexadecimale waarde waarde door te geven. Dit geeft de mogelijkheid om in een print statement een aantal symbolen tegelijk te zetten: lcd.print("\x00\x01\x02");. Als je weet dat de hex waarde van de spatie 20 is dan kun je de regels
uit het 16 × 2 programma vervangen door:
lcd.print("\x01\x20\x02\x20\x03");. Dit is efficiënter, maar gaat wel te koste van de leesbaarheid. Bovendien mag je \x00 niet in de string hebben staan, omdat dit het einde van de string aanduidt.
Een Valentijn surprise
Hier hoef je alleen de naam van je geliefde in te zetten (in plaats van Lisa). Als de naam van je geliefde langer dan 7 letters is dan past dat niet op het standaard 1602 display en zul je de eerste regel moeten aanpassen of een 24 × 2 display gebruiken.
Deze lange displays hebben soms een "backpack" van buydisplay.com. Deze zijn bekend slecht. Na enige tijd functioneren krijg je ze wellicht niet meer aan de praat of alleen na resetten. Dit kun je oplossen door een weerstand van rond de 5 kΩ te schakelen lussen SDA en VCC en ook een tussen SCL en VCC. Als het display rare tekens gaat tonen verlaag dan de I2C frequentie. In de sketch voor het 24 × 2 display zie je hoe je dat kunt doen (haal de voorste commentaarstrepen weg).
Lichtkrant
In het voorbeeld neem ik van de lange string "Krant" steeds de juiste letters die op de 16 plaatsen passen. Door te beginnen met spaties wordt de regel automatisch schoongemaakt als de krant begint te lopen. Het voordeel is hiervan is dat dit met andere displays, met minimale aanpassingen, ook zal werken. De laatste tekst blijft even staan wegens delay(1000). Kies voor de delays de waardes die jij prettig vindt. Als je de spaties in Krant achter de tekst zet dan krijg je meteen de hele tekst te zien die vervolgens naar links loopt. Kies zelf wat je beter vindt. Voor een 24 × 2 display kun de overal 16 vervangen door 24 en bij een 20 × 2 display door 20.
#include <LiquidCrystal_I2C_Hangul.
#include <LiquidCrystal_I2C.h> // Versie van Frank de Brabander
// Pas indien nodig het I2C adres (0x27) aan! Kan ook 0x3F zijn
LiquidCrystal_I2C display(0x27, 16, 2);
void setup() {
display.init();
display.backlight();
display.print("Hallo allemaal !");
}
String Krant = " Dit is 'n mooie lichtkrant!";
void loop() {
for (int Teller = 0; Teller <= Krant.length() - 16; Teller++) {
display.setCursor(0, 1);
display.print(Krant.substring(Teller, Teller + 16));
delay(250);
}
delay(1000);
}
Hieronder staat een versie met de LiquidCrystal_I2C_Hangul bibliotheek. Ik heb deze getest met verschillende displays, waaronder een 20 × 2 en een 16 × 4 display.
#include <LiquidCrystal_I2C_Hangul.h>
#define L 16 // Dit is het aantal letters per regel dat het display kan weergeven
// Kies hieronder het I2C adres. Dit is 0x27 of 0x3F
LiquidCrystal_I2C_Hangul display(0x27, L, 2);
void setup() {
display.init();
display.backlight();
display.setCursor((L > 16) ? 2 : 0, 0);
display.print("Hallo allemaal !");
}
String Krant = " Dit is 'n mooie lichtkrant!";
void loop() {
for (int Teller = 0; Teller <= Krant.length() - L; Teller++) {
display.setCursor(0, 1);
display.print(Krant.substring(Teller, Teller + L));
delay(250);
}
delay(1000);
}
Het cryptische (L > 16) ? 2 : 0 betekent: als L groter is dan 16 vul dan 2 in en anders 0, met andere woorden als je een display gebruikt met 16 of minder karakters per regel start dan op positie 0 en anders op positie 2.
Nog een leuke animatie
Deze animatie is oorspronkelijk gemaakt voor de Raspberry Pi Pico door Hylke Blijker. Ik heb de animatie iets veranderd en geschikt gemaakt voor de Arduino.
In theorie geeft de bibliotheek van Matthias Hertel de rustigste animatie en die kan nog op verschillende manieren verbeterd worden. Het is echter mijn ervaring dat hoe mooi de animatie is vooral afhangt van de kwaliteit van het display. Optimalisaties hebben hooguit een marginaal effect.