Lesezeit: 8 Minuten

Inhalt
Ziele des Projekts
- Einführung in die Bibliothek U8g2_for_Adafruit_GFX
- Darstellung von Datum und Uhrzeit in großer Schrift
Verwendete Hardware
- TFT-Display mit 320×240 Pixeln
- ESP32-Wroom mit integriertem TFT-Display mit 320×170 Pixeln (IdeaSpark)
So sieht es aus:


Konfiguration der Mikrocontroller
Die Bibliothek U8g2_for_Adafruit_GFX
Die Bibliothek U8g2_for_Adafruit_GFX ist eine Ergänzung der von Adafruit entwickelten Grafikbibliothek. Sie stellt Funktionen für die Darstellung von Text zur Verfügung.
Außerdem stehen eine Vielzahl von 🔗Schriften bereit.
Schlüsselwort | Aktion |
---|---|
setFontDirection(Parameter); | 0: von links nach rechts (Standard) 1: von rechts nach links |
setForegroundColor(Farbe); | Vordergrundfarbe |
setBackgroundColor(Farbe) | Hintergrundfarbe |
setFont(Schritart); | Schftart festlegen |
setCursor(x, y); | Cursor setzen |
print(Text); | Text schreiben |
Benötigte Bibliothek installieren

Anmerkungen zum Programm
- im Kopf des Programms muss ein Objekt der Bibliothek erstellt werden
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften; - im setup-Teil wird das Objekt der Bibliothek (u8g2Schriften) der Grafikbibliothek (tft) zugeordnet
u8g2Schriften.begin(tft); - jeder Funktion zur Darstellung von Text muss der Name des Objektes (u8g2Schriften) vorangestellt werden:
Vordergrundfarbe: u8g2Schriften.setForegroundColor(Farbe);
Hintergrundfarbe: u8g2Schriften.setBackgroundColor(Farbe);
Schriftart: u8g2Schriften.setFont(Schriftart);
u8g2Schriften.setCursor(x, y); - Vorder- und Hintergrundfarbe können für das Programm individuell festgelegt werden
Das Programm
TFT 320×240 Pixel
#ifdef ESP8266
#include "ESP8266WiFi.h"
#else
#include "WiFi.h"
#endif
#include "time.h"
#include "Adafruit_ILI9341.h"
#include "U8g2_for_Adafruit_GFX.h"
// Farben
#define SCHWARZ 0x0000
#define WEISS 0xFFFF
#define BLAU 0x001F
#define ROT 0xF800
#define GRUEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define GELB 0xFFE0
#define BRAUN 0x9A60
#define GRAU 0x7BEF
#define GRUENGELB 0xB7E0
#define DUNKELCYAN 0x03EF
#define ORANGE 0xFDA0
#define PINK 0xFE19
#define BORDEAUX 0xA000
#define HELLBLAU 0x867D
#define VIOLETT 0x915C
#define SILBER 0xC618
#define GOLD 0xFEA0
int Vordergrundfarbe = GRUEN;
int Hintergrundfarbe = SILBER;
// Wemos D1 Mini
// #define TFT_CS D8
// #define TFT_RST D1
// #define TFT_DC D2
// XIAO
// #define TFT_CS D7
// #define TFT_RST D1
// #define TFT_DC D2
// Arduino Nano ESP 32
// #define TFT_CS 10
// #define TFT_RST 9
// #define TFT_DC 8
// SPI-Pins ESP32-C6
// #define TFT_CS 18
// #define TFT_RST 3
// #define TFT_DC 2
// ESP32-WROOM
// #define TFT_CS 5
// #define TFT_RST 4
// #define TFT_DC 2
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;
// WiFi-Daten
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";
// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"
/*
Liste der Zeitzonen
https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
CEST = Central European Summer Time von
M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"
// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;
/*
Struktur tm
tm_hour -> Stunde: 0 bis 23
tm_min -> Minuten: 0 bis 59
tm_sec -> Sekunden 0 bis 59
tm_mday -> Tag 1 bis 31
tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
tm_year -> Jahre seit 1900
tm_yday -> vergangene Tage seit 1. Januar des Jahres
tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;
// Variablen für die Zeit
int Stunden, Minuten, Sekunden;
// Start wird nur beim ersten Start für den Aufbau des TFTs benötigt
bool Start = true;
unsigned long Zeitmessung = 0;
void setup()
{
// Schriften von u8g2 tft zuordnen
u8g2Schriften.begin(tft);
// Zeitzone: Parameter für die zu ermittelnde Zeit
configTzTime(Zeitzone, Zeitserver);
WiFi.mode(WIFI_STA);
// WiFi starten
WiFi.begin(Router, Passwort);
Serial.println("------------------------");
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
Serial.print(".");
}
Serial.println();
Serial.print("Verbunden mit ");
Serial.println(Router);
Serial.print("IP über DHCP: ");
Serial.println(WiFi.localIP());
// Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
// beim Start entspricht das Datum der Unixtime: 1.1.1970
// Datum/Kalender sollen erst angezeigt werden, wenn das Datum korrekt ist
String Jahr = String(Zeit.tm_year + 1900);
int Zaehler = 0;
// String Jahr nach "1970" durchsuchen
int Suche = Jahr.indexOf("1970");
Serial.println("-------------------------");
Serial.println("Datum und Zeit holen (maximal 90 Sekunden)...");
// solange die Suche nicht erfolgreich ist
while (Suche != -1)
{
// aktuelle Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
Jahr = String(Zeit.tm_year + 1900);
// String Jahr nach "1970" durchsuchen
Suche = Jahr.indexOf("1970");
// Zeit in Stunden, Minuten und Sekunden
Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);
delay(1000);
Zaehler++;
if (Zaehler >= 90)
{
Serial.println();
Serial.println("Datum und Zeit konnte innerhalb von " + String(Zaehler) + " Sekunden nicht geholt werden");
Serial.println("Programm wird beendet");
// Programm beenden
while (1);
}
Serial.print(".");
}
Serial.println();
// Datum/Zeit erfolgreich synchronisiert
if (Suche == -1)
{
Serial.println("-------------------------");
Serial.println("Datum/Zeit erfolgreich synchronisiert ...");
if (Zeit.tm_mday < 10) Serial.print("0");
Serial.print(Zeit.tm_mday);
Serial.print(".");
// Monat: führende 0 ergänzen
if (Zeit.tm_mon < 9) Serial.print("0");
// Zählung beginnt mit 0 -> +1
Serial.print(Zeit.tm_mon + 1);
Serial.print(".");
// Anzahl Jahre seit 1900
Serial.println(Zeit.tm_year + 1900);
if (Zeit.tm_hour < 10) Serial.print("0");
Serial.print(Zeit.tm_hour);
Serial.print(":");
if (Zeit.tm_min < 10) Serial.print("0");
Serial.println(Zeit.tm_min);
Serial.print(":");
if (Zeit.tm_sec < 10) Serial.print("0");
Serial.println(Zeit.tm_sec);
Serial.println("-------------------------");
}
// Zeit in Stunden, Minuten und Sekunden
Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
// TFT starten Hintergrundfarbeer Hintergrund
tft.begin();
// Rotation anpassen Querformat
tft.setRotation(1);
tft.fillScreen(Hintergrundfarbe);
u8g2Schriften.setForegroundColor(Vordergrundfarbe);
u8g2Schriften.setBackgroundColor(Hintergrundfarbe);
ZeigeDatum();
Zeitmessung = millis() + 1000;
}
void loop()
{
// Start = true
// -> Zeit einmalig synchronisieren
if (Start)
{
Start = false;
// Zeit jede Minute mit Zeitserver synchronisieren
// aktuelle Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
// Zeit in Stunden, Minuten und Sekunden
Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);
ZeitAnzeigen();
}
// Sekunden weiter zählen
if (Zeitmessung < millis())
{
Zeitmessung += 1000;
Sekunden++;
if (Sekunden == 60)
{
// Zeit jede Minute mit Zeitserver synchronisieren
// aktuelle Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
// Zeit in Stunden, Minuten und Sekunden
Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);
// Mitternacht
// -> Wechsel des Datums anzeigen
if (Stunden == 0 && Minuten == 0)
{
Serial.println("neues Datum");
ZeigeDatum();
}
ZeitAnzeigen();
}
}
}
void ZeitAnzeigen()
{
// Bereich für die Uhrzeit löschen
tft.fillRect(1, 80, tft.width(), tft.height(), Hintergrundfarbe);
u8g2Schriften.setFont(u8g2_font_logisoso78_tn);
// Cursor setzen
u8g2Schriften.setCursor(2, 200);
// Stunde: wenn Stunde < 10 -> 0 davor setzen
if (Zeit.tm_hour < 10) u8g2Schriften.print("0");
u8g2Schriften.print(Zeit.tm_hour);
u8g2Schriften.print(":");
// Minuten
// wenn Minute < 10 -> 0 davor setzen
if (Zeit.tm_min < 10) u8g2Schriften.print("0");
u8g2Schriften.print(Zeit.tm_min);
}
void ZeigeDatum()
{
tft.fillScreen(Hintergrundfarbe);
u8g2Schriften.setFont(u8g2_font_fub42_tf);
// Cursor setzen
u8g2Schriften.setCursor(20, 50);
// Tag: führende 0 ergänzen
if (Zeit.tm_mday < 10)
{
Serial.print("0");
u8g2Schriften.print("0");
}
Serial.print(Zeit.tm_mday);
Serial.print(".");
u8g2Schriften.print(Zeit.tm_mday);
u8g2Schriften.print(".");
// Monat: führende 0 ergänzen
if (Zeit.tm_mon < 9)
{
Serial.print("0");
u8g2Schriften.print("0");
}
Serial.print(Zeit.tm_mon + 1);
Serial.print(".");
u8g2Schriften.print(Zeit.tm_mon + 1);
u8g2Schriften.print(".");
// Anzahl Jahre seit 1900
Serial.print(Zeit.tm_year + 1900);
Serial.print(" ");
u8g2Schriften.print(Zeit.tm_year + 1900);
tft.drawFastHLine(1, 65, tft.width(), Vordergrundfarbe);
tft.drawFastHLine(1, 66, tft.width(), Vordergrundfarbe);
}
TFT 320×170 Pixel (IdeaSpark)
#include "WiFi.h"
#include "time.h"
#include "Adafruit_ST7789.h"
#include "U8g2_for_Adafruit_GFX.h"
#define TFT_CS 15
#define TFT_RST 4
#define TFT_DC 2
// Farben
#define SCHWARZ 0x0000
#define WEISS 0xFFFF
#define BLAU 0x001F
#define ROT 0xF800
#define GRUEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define GELB 0xFFE0
#define BRAUN 0x9A60
#define GRAU 0x7BEF
#define GRUENGELB 0xB7E0
#define DUNKELCYAN 0x03EF
#define ORANGE 0xFDA0
#define PINK 0xFE19
#define BORDEAUX 0xA000
#define HELLBLAU 0x867D
#define VIOLETT 0x915C
#define SILBER 0xC618
#define GOLD 0xFEA0
int Vordergrundfarbe = WEISS;
int Hintergrundfarbe = SCHWARZ;
#define TFT_CS 15
#define TFT_RST 4
#define TFT_DC 2
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;
// WiFi-Daten
char Router[] = "Router_SSID";
char Passwort[] = "anea1246";
// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"
/*
Liste der Zeitzonen
https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
CEST = Central European Summer Time von
M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"
// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;
/*
Struktur tm
tm_hour -> Stunde: 0 bis 23
tm_min -> Minuten: 0 bis 59
tm_sec -> Sekunden 0 bis 59
tm_mday -> Tag 1 bis 31
tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
tm_year -> Jahre seit 1900
tm_yday -> vergangene Tage seit 1. Januar des Jahres
tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;
// Variablen für die Zeit
int Stunden, Minuten, Sekunden;
// Start wird nur beim ersten Start für den Aufbau des TFTs benötigt
bool Start = true;
unsigned long Zeitmessung = 0;
void setup()
{
// Schriften von u8g2 tft zuordnen
u8g2Schriften.begin(tft);
// Zeitzone: Parameter für die zu ermittelnde Zeit
configTzTime(Zeitzone, Zeitserver);
WiFi.mode(WIFI_STA);
// WiFi starten
WiFi.begin(Router, Passwort);
Serial.println("------------------------");
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
Serial.print(".");
}
Serial.println();
Serial.print("Verbunden mit ");
Serial.println(Router);
Serial.print("IP über DHCP: ");
Serial.println(WiFi.localIP());
// Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
// beim Start entspricht das Datum der Unixtime: 1.1.1970
// Datum/Kalender sollen erst angezeigt werden, wenn das Datum korrekt ist
String Jahr = String(Zeit.tm_year + 1900);
int Zaehler = 0;
// String Jahr nach "1970" durchsuchen
int Suche = Jahr.indexOf("1970");
Serial.println("-------------------------");
Serial.println("Datum und Zeit holen (maximal 90 Sekunden)...");
// solange die Suche nicht erfolgreich ist
while (Suche != -1)
{
// aktuelle Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
Jahr = String(Zeit.tm_year + 1900);
// String Jahr nach "1970" durchsuchen
Suche = Jahr.indexOf("1970");
// Zeit in Stunden, Minuten und Sekunden
Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);
delay(1000);
Zaehler++;
if (Zaehler >= 90) {
Serial.println();
Serial.println("Datum und Zeit konnte innerhalb von " + String(Zaehler) + " Sekunden nicht geholt werden");
Serial.println("Programm wird beendet");
// Programm beenden
while (1);
}
Serial.print(".");
}
Serial.println();
// Datum/Zeit erfolgreich synchronisiert
if (Suche == -1)
{
Serial.println("-------------------------");
Serial.println("Datum/Zeit erfolgreich synchronisiert ...");
if (Zeit.tm_mday < 10) Serial.print("0");
Serial.print(Zeit.tm_mday);
Serial.print(".");
// Monat: führende 0 ergänzen
if (Zeit.tm_mon < 9) Serial.print("0");
// Zählung beginnt mit 0 -> +1
Serial.print(Zeit.tm_mon + 1);
Serial.print(".");
// Anzahl Jahre seit 1900
Serial.println(Zeit.tm_year + 1900);
if (Zeit.tm_hour < 10) Serial.print("0");
Serial.print(Zeit.tm_hour);
Serial.print(":");
if (Zeit.tm_min < 10) Serial.print("0");
Serial.println(Zeit.tm_min);
Serial.print(":");
if (Zeit.tm_sec < 10) Serial.print("0");
Serial.println(Zeit.tm_sec);
Serial.println("-------------------------");
}
// Zeit in Stunden, Minuten und Sekunden
Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
// TFT starten
tft.init(170, 320);
// Rotation anpassen Querformat
tft.setRotation(1);
tft.fillScreen(Hintergrundfarbe);
u8g2Schriften.setForegroundColor(Vordergrundfarbe);
u8g2Schriften.setBackgroundColor(Hintergrundfarbe);
u8g2Schriften.setFont(u8g2_font_fub42_tf);
ZeigeDatum();
Zeitmessung = millis() + 1000;
}
void loop()
{
// Start = true
// -> Zeit einmalig synchronisieren
if (Start)
{
Start = false;
// Zeit jede Minute mit Zeitserver synchronisieren
// aktuelle Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
// Zeit in Stunden, Minuten und Sekunden
Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);
ZeitAnzeigen();
}
// Sekunden weiter zählen
if (Zeitmessung < millis())
{
Zeitmessung += 1000;
Sekunden++;
if (Sekunden == 60)
{
// Zeit jede Minute mit Zeitserver synchronisieren
// aktuelle Zeit holen
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
// Zeit in Stunden, Minuten und Sekunden
Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec);
// Mitternacht
// -> Wechsel des Datums anzeigen
if (Stunden == 0 && Minuten == 0)
{
Serial.println("neues Datum");
ZeigeDatum();
}
ZeitAnzeigen();
}
}
}
void ZeitAnzeigen()
{
// nur den Beriech der Zeit löschen
tft.fillRect(1, 75, tft.width(), tft.height(), Hintergrundfarbe);
u8g2Schriften.setFont(u8g2_font_logisoso78_tn);
// Cursor setzen
u8g2Schriften.setCursor(2, 160);
// Stunde: wenn Stunde < 10 -> 0 davor setzen
if (Zeit.tm_hour < 10) u8g2Schriften.print("0");
u8g2Schriften.print(Zeit.tm_hour);
u8g2Schriften.print(":");
// Minuten
// wenn Minute < 10 -> 0 davor setzen
if (Zeit.tm_min < 10) u8g2Schriften.print("0");
u8g2Schriften.print(Zeit.tm_min);
}
void ZeigeDatum()
{
tft.fillScreen(Hintergrundfarbe);
u8g2Schriften.setFont(u8g2_font_fub42_tf);
// Cursor setzen
u8g2Schriften.setCursor(10, 50);
// Tag: führende 0 ergänzen
if (Zeit.tm_mday < 10)
{
Serial.print("0");
u8g2Schriften.print("0");
}
Serial.print(Zeit.tm_mday);
Serial.print(".");
u8g2Schriften.print(Zeit.tm_mday);
u8g2Schriften.print(".");
// Monat: führende 0 ergänzen
if (Zeit.tm_mon < 9)
{
Serial.print("0");
u8g2Schriften.print("0");
}
Serial.print(Zeit.tm_mon + 1);
Serial.print(".");
u8g2Schriften.print(Zeit.tm_mon + 1);
u8g2Schriften.print(".");
// Anzahl Jahre seit 1900
Serial.print(Zeit.tm_year + 1900);
Serial.print(" ");
u8g2Schriften.print(Zeit.tm_year + 1900);
tft.drawFastHLine(1, 65, tft.width(), Vordergrundfarbe);
tft.drawFastHLine(1, 66, tft.width(), Vordergrundfarbe);
}
Quellen
Verwandte Anleitungen
- Datum und Zeit mit ESP und time.h anzeigen
- Datum und Zeit mit dem NTP-Protokoll anzeigen
- Stoppuhr
- Wecker mit einem RTC-Modul
- Zeit im Seriellen Monitor mit ESP-Mikrocontroller anzeigen
- Datum, Uhrzeit und Temperatur auf einem LCD mit einem RTC-Modul anzeigen
- Zeit mit time.h auf einer 4-stelligen 7-Segment-Anzeige darstellen
- Zeiterfassung mit RFID-Modul
Letzte Aktualisierung: