Foto­schau mit ESP32 TFT und SD-Kartenleser

mit inter­nem Kartenleser

#include "SdFat.h"
#include "Adafruit_ST7796S_kbv.h"
#include "Adafruit_ImageReader.h"

// ESP32-WROOM
#define TFT_CS        5
#define TFT_RST       4 
#define TFT_DC        2

/* 
  SD VSPI Standard-Pins
  CLK    18
  MOSI   23
  MISO   19
  CS      5
*/

// Objekt tft der Bibliothek Adafruit_ST7796S_kbv erstellen
Adafruit_ST7796S_kbv tft = Adafruit_ST7796S_kbv(TFT_CS, TFT_DC, TFT_RST);

// Objekt SD der Bibliothek SdFat erstellen
SdFat SD;              

// Objekt des Kartenlesers wird an das Dateisystem der SD-Karte übertragen
Adafruit_ImageReader reader(SD);

Adafruit_Image Bild;  

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F

// 3 = FAT32
#define SD_FAT_TYPE 3

// SPI-Geschwindigkeit
#define SPI_SPEED SD_SCK_MHZ(10)

// CSPin der SD-Karte
int CSPin = 15;

// Anzeigedauer
int Intervall = 6000;

bool Beschreibung = true;

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);
 
  // TFT starten
  tft.begin();
  
  tft.invertDisplay(1);

  // Rotation anpassen
  tft.setRotation(3);

  // schwarzer Hintergrund
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(3);
  tft.setTextColor(WEISS);
  tft.setCursor(1, 20);

  /*
     SD-Karte mit Angabe des CSPins und  der SPI-Geschwindigkeit starten
     wenn die Intialisierung fehlschlägt
     - keine SD-Karte vorhanden
     - falsche Pinbelegung
     -> es wird eine Fehlermeldung angezeigt
  */
  if (!SD.begin(CSPin, SPI_SPEED)) 
  {
    tft.println("Start der SD-Karte");
    tft.print("fehlgeschlagen!");
    Serial.println("Start der SD-Karte fehlgeschlagen!");
  } 
  else 
  {
    Serial.println("SD-Karte gestartet");
    tft.print("SD-Karte gestartet!");
  }

  delay(5000);
}

void loop() 
{  
  reader.drawBMP("koeln.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.setCursor(10, 295);  
    tft.print("K");
    // ö = 0x94
    tft.write(0x94);
    tft.println("ln Blick vom Messeturm");
  }
  
  delay(Intervall);
 
  reader.drawBMP("duenen.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("D");
    // ü = 0x81
    tft.write(0x81);
    tft.print("nen Ibiza");
  }

  delay(Intervall);  
 
  reader.drawBMP("overath_bahnhof.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Overath Bahnhof");
  }

  delay(Intervall);
 
  reader.drawBMP("dresden_frauenkirche.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Dresden Frauenkirche");
  }

  delay(Intervall);
 
  reader.drawBMP("chartres.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Chartres Dom");
  }

  delay(Intervall);

  reader.drawBMP("bonn_uni.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Bonn Uni");
  }

  delay(Intervall);

  reader.drawBMP("braunwald.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Braunwald Schweiz");
  }

  delay(Intervall);
   
  reader.drawBMP("koeln_deutz.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("K");
    // ö = 0x94
    tft.write(0x94);
    tft.println("ln Deutz");
  }

  delay(Intervall);

  reader.drawBMP("st_michelle.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("St. Michelle Frankreich");
  }
  delay(Intervall);

  reader.drawBMP("lindos.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Lindos Rhodos");
  }

  delay(Intervall);
}

mit exter­nem SD-Kartenleser

#include "SdFat.h"
#include "Adafruit_ST7796S_kbv.h"
#include "Adafruit_ImageReader.h"

// TFT HSPI
#define TFT_CS        15
#define TFT_RST        4 
#define TFT_DC         2
#define TFT_CLK       14
#define TFT_MOSI      13 

/* 
  SD VSPI Standard-Pins
  CLK    18
  MOSI   23
  MISO   19
  CS      5
*/

// Objekt tft der Bibliothek Adafruit_ST7796S_kbv erstellen
Adafruit_ST7796S_kbv tft = Adafruit_ST7796S_kbv(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST);

// Objekt SD der Bibliothek SdFat erstellen
SdFat SD;              

// Objekt des Kartenlesers wird an das Dateisystem der SD-Karte übertragen
Adafruit_ImageReader reader(SD);

Adafruit_Image Bild;  

// Farben
#define SCHWARZ     0x0000
#define WEISS       0xFFFF
#define BLAU        0x001F

// 3 = FAT32
#define SD_FAT_TYPE 3

// SPI-Geschwindigkeit
#define SPI_SPEED SD_SCK_MHZ(4)

// CSPin der SD-Karte
int CSPin = 5;

// Anzeigedauer
int Intervall = 5000;

// true -> Beschreibung anzeigen
// false -> Bild ohne Beschriftung anzeigen
bool Beschreibung = true;

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);
 
  // TFT starten
  tft.begin();

  // Rotation anpassen
  tft.setRotation(1);

  // schwarzer Hintergrund
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(3);
  tft.setTextColor(WEISS);
  tft.setCursor(1, 20);

  /*
     SD-Karte mit Angabe des CSPins und  der SPI-Geschwindigkeit starten
     wenn die Intialisierung fehlschlägt
     - keine SD-Karte vorhanden
     - falsche Pinbelegung
     -> es wird eine Fehlermeldung angezeigt
  */
  if (!SD.begin(CSPin, SPI_SPEED)) 
  {
    tft.println("Start der SD-Karte");
    tft.print("fehlgeschlagen!");
    Serial.println("Start der SD-Karte fehlgeschlagen!");
  } 
  else 
  {
    Serial.println("SD-Karte gestartet");
    tft.print("SD-Karte gestartet!");
  }

  delay(5000);
}
void loop() 
{  
  reader.drawBMP("koeln.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.setCursor(10, 295);  
    tft.print("K");
    // ö = 0x94
    tft.write(0x94);
    tft.println("ln Blick vom Messeturm");
  }
  
  delay(Intervall);
 
  reader.drawBMP("duenen.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("D");
    // ü = 0x81
    tft.write(0x81);
    tft.print("nen Ibiza");
  }

  delay(Intervall);  
 
  reader.drawBMP("overath_bahnhof.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Overath Bahnhof");
  }

  delay(Intervall);
 
  reader.drawBMP("dresden_frauenkirche.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Dresden Frauenkirche");
  }

  delay(Intervall);
 
  reader.drawBMP("chartres.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Chartres Dom");
  }

  delay(Intervall);

  reader.drawBMP("bonn_uni.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Bonn Uni");
  }

  delay(Intervall);

  reader.drawBMP("braunwald.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Braunwald Schweiz");
  }

  delay(Intervall);
   
  reader.drawBMP("koeln_deutz.bmp", tft, 0, 0);

  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("K");
    // ö = 0x94
    tft.write(0x94);
    tft.println("ln Deutz");
  }

  delay(Intervall);

  delay(Intervall);

  reader.drawBMP("st_michelle.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("St. Michelle Frankreich");
  }
  delay(Intervall);

  reader.drawBMP("lindos.bmp", tft, 0, 0);
  
  if (Beschreibung)
  {
    tft.setCursor(10, 295);  
    tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120); 
    tft.print("Lindos Rhodos");
  }

  delay(Intervall);
}

Letzte Aktualisierung:

Foto­schau mit TFT-Shield

#include "Adafruit_ILI9341.h"
#include "SdFat.h"
#include "Adafruit_ImageReader.h"

// CS-Pin SD-Karte
#define SD_CS 4    

// Pins TFT
#define TFT_CS 10  
#define TFT_DC 9   

// Dateisystem SD-Karte
SdFat SD;              

// Objekt des Kartenlesers wird an das Dateisystem der SD-Karte übertragen
Adafruit_ImageReader reader(SD);

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
Adafruit_Image Bild;  

ImageReturnCode Status;

int Intervall = 2000;

void setup() 
{
  // TFT starten
  tft.begin();

  // SD-Karte starten
  SD.begin(SD_CS);

  tft.setRotation(3);  
  tft.fillScreen(0);
  tft.setTextSize(2);
  tft.setTextColor(ILI9341_WHITE);
}

void loop() 
{
  // Bild laden
  // alle Dateien befinden sich im root-Verzeichnis /
  Status = reader.loadBMP("/koeln.bmp", Bild);

  // Bild anzeigen
  // Parameter: Dateiname, tft, StartpositionX, StartpositionY
  reader.drawBMP("koeln.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.print("K");

  // ö = 0x94
  tft.write(0x94);
  tft.println("ln");
  delay(Intervall);  
  tft.fillScreen(0);

  Status = reader.loadBMP("/dresden_bruecke.bmp", Bild);
  reader.drawBMP("dresden_bruecke.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.println("Dresden 'Blaues Wunder'");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/overath_Bahnhof.bmp", Bild);
  reader.drawBMP("overath_Bahnhof.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.println("Overath Bahnhof");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/dresden_frauenkirche.bmp", Bild);
  reader.drawBMP("dresden_frauenkirche.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.println("Dresden Frauenkirche");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/braunwald.bmp", Bild);
  reader.drawBMP("braunwald.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.println("Braunwald/Schweiz");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/chartres.bmp", Bild);
  reader.drawBMP("chartres.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.println("Chartres Kathedrale");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/strand.bmp", Bild);
  reader.drawBMP("strand.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.println("Strand Algarve");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/duenen_ibiza.bmp", Bild);
  reader.drawBMP("duenen_ibiza.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.print("D");

  // ü = 0x81
  tft.write(0x81);
  tft.print("nen Ibiza");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/lindos.bmp", Bild);
  reader.drawBMP("lindos.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.print("Lindos/Rhodos");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/see.bmp", Bild);
  reader.drawBMP("see.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.print("See bei Innsbruck");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/uni_bonn.bmp", Bild);
  reader.drawBMP("uni_bonn.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.print("Bonn Uni");
  delay(Intervall);
  tft.fillScreen(0);

  Status = reader.loadBMP("/berlin_olympia.bmp", Bild);
  reader.drawBMP("berlin_olympia.bmp", tft, 0, 0);
  tft.setCursor(10, 220);
  tft.print("Berlin Olympiastatdion");
  delay(Intervall);
  tft.fillScreen(0);
}

Letzte Aktualisierung:

Ana­lo­ge Uhr mit TFT

240×240 Pixel

#ifdef ESP8266
  #include "ESP8266WiFi.h"

#else 
  #include "WiFi.h"
#endif

#include "time.h"
#include "Adafruit_GC9A01A.h"

// Adafruit-Schriftart einbinden
#include "Fonts/FreeSans12pt7b.h"

// 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_GC9A01A tft(TFT_CS, TFT_DC);

// WiFi-Daten
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

// Variablen des TFTs (Höhe, Breite, Radius)
const int MitteHoehe = tft.height() / 2;
const int MitteBreite = tft.width() / 2;
const int Radius = tft.width() / 2;

// Multiplikatoren für x- y-Positionen der Stunden, Minuten und Sekunden
float SekundePosX = 0, SekundePosY = 0, MinutePosX = 0, MinutePosY = 0, StundePosX = 0, StundePosY = 0;
float GradSekunden = 0, GradMinuten = 0, GradStunden = 0;

// x- y-Koordinaten für die Anzeige Stunden, Minuten und Sekunden
int SekundenZeigerX = MitteHoehe, SekundenZeigerY = MitteHoehe;
int MinutenZeigerX = MitteHoehe, MinutenZeigerY = MitteHoehe;
int StundenZeigerX = MitteHoehe, StundenZeigerY = MitteHoehe; 

// Start wird nur beim ersten Start für den Aufbau des TFTs benötigt
bool Start = true;

// Variablen für die Markierungen und Punkte und Striche des Ziffernblatts
float PosX, PosY;
int PunktX, PunktY, PunktX1, PunktX2, PunktY1, PunktY2;

// Variablen für die Zeit
int Stunden, Minuten, Sekunden;

// 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

// Farben innerer Kreis, Randfarbe und Zeigerfarbe
// die Farben der Zeiger können aber auch individuell gesetzt werden
const int Kreisfarbe = SCHWARZ;
const int Zeigerfarbe = WEISS;
const int Randfarbe = BORDEAUX;

// true -> Datum anzeigen
// false -> Datum nicht anzeigen
bool DatumAnzeigen = true;

// true -> Sekundenzeiger nur als Kreis
bool SekundenzeigerKreis = true;

// Ziffern 12 3 6 9 anzeigen/nicht anzeigen
bool Ziffernanzeigen = true;

// 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 SuMinutener 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 = SoMinutenerzeit (dst = daylight saving time)
*/
tm Zeit;

unsigned long Zeitmessung = 0; 

void setup() 
{
  Serial.begin(9600);

  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());

  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Zeit in Stunden, Minuten und Sekunden
  Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;
  
  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(Kreisfarbe);

  // 4 Pixel breiter äußerer Rand, Farbe au der Farbpalette wählen
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 1, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 2, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 3, Randfarbe);
  tft.drawCircle(MitteHoehe, MitteBreite, Radius - 4, Randfarbe);

  // innere Fläche bis auf den Rand von 4 Pixeln vollständig löschen
  // wenn andere Farbe als äußerer Rand gewählt wird ergibt sich ein schmaler Rand
  tft.fillCircle(MitteHoehe, MitteBreite, Radius - 4, Kreisfarbe);

 /*
    alle 30° Linie am Rand als Stundenmarkierung zeichnen
    DEG_TO_RAD (= PI/180 = 0.0174532925) -> Winkel in Bogenmaß umrechnen
    sin/cos berechnen die x-/y-Kordinaten des Punktes auf der Kreislinie
  */
  for (int i = 0; i < 360; i += 30) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // kurze Linien zeichnen, von 114 bis 100 vom äußeren Rand aus
    // Farbe individuell wählbar
    int PunktX1 = PosX * 110 + Radius;
    int PunktY1 = PosY * 110 + Radius;
    int PunktX2 = PosX * 100 + Radius;
    int PunktY2 = PosY * 100 + Radius;

    tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Zeigerfarbe);
    
    // keine Striche an der Position der Zahlen
    if (Ziffernanzeigen)
    {
      if (PunktX1 == 10 || PunktX1 == 120 || PunktX1 == 230)
      {
        tft.drawLine(PunktX1, PunktY1, PunktX2, PunktY2, Kreisfarbe);
      }  
    }  
  }

  // alle 6 Grad Punkte als Sekundenmarkierung zeichnen
  for (int i = 0; i < 360; i += 6) 
  {
    PosX = cos((i - 90) * DEG_TO_RAD);
    PosY = sin((i - 90) * DEG_TO_RAD);

    // Positionen der Punkte
    // 108 -> Abstand vom Mittelpunkt
    PunktX = PosX * 108 + Radius;
    PunktY = PosY * 108 + Radius;
    tft.drawPixel(PunktX, PunktY, Zeigerfarbe);  
  }

  // Markierung 12 3 6 9
  if (Ziffernanzeigen)
  {
    tft.setFont(&FreeSans12pt7b);
    tft.setTextColor(Zeigerfarbe);
    tft.setCursor(tft.height() / 2 - 15, 25);
    tft.print("12");
    
    tft.setCursor(10, tft.height() / 2 + 7);
    tft.print("9");
    
    tft.setCursor(220, tft.height() / 2 + 10);
    tft.print("3");
  
    tft.setCursor(tft.height() / 2 - 7, 230);
    tft.print("6");
  }

  if (DatumAnzeigen)
  {
    ZeigeDatum();
  }

  Zeitmessung = millis() + 1000; 
}

void loop() 
{
  // Sekunden weiter zählen
  if (Zeitmessung < millis()) 
  {
    Zeitmessung += 1000;
    Sekunden++;  

    if (Sekunden == 60) 
    { 
 
      // Sekunden = 0; 
      Minuten++; 

     if (DatumAnzeigen) ZeigeDatum();

      // aktuelle Zeit holen
      time(&aktuelleZeit);

      // localtime_r -> Zeit in die lokale Zeitzone setzen
      localtime_r(&aktuelleZeit, &Zeit);

      // Zeit in Stunden, Minuten und Sekunden
      Stunden = Zeit.tm_hour, Minuten = Zeit.tm_min, Sekunden = Zeit.tm_sec;

      if (Minuten > 59) 
      {
        Minuten = 0;
        Stunden++;  
        if (Stunden > 23) Stunden = 0;
      }
    }

    // Datum anzeigen/nicht anzeigen
    // Datumsanzeige nur erneuern, wenn der Sekundenzeiger
    // vollständig als Strich und Kreis angezeigt wird
    if (DatumAnzeigen && !SekundenzeigerKreis)
    {
      // Anzeige des Datums nur aktualisieren,
      // wenn sich der Sekundenzeiger darüber befindet
      if (Sekunden > 20 & Sekunden < 40)
      {
        ZeigeDatum();
      }
    }

    // Vorausberechnung der x- und y-Koordinaten
    // alle 6° eine Sekunde vorwärts
    GradSekunden = Sekunden * 6;    
  
    // alle 6° eine Minute vorwärts     
    GradMinuten = Minuten * 6; 

    // alle 30° eine Stunde vorwärts
    // 30 / 3600 = 0.0833333
    // sorgt dafür, dass der Stundenzeiger entsprechend 
    // der Anzahl der Minuten weiter "wandert"
    GradStunden = Stunden * 30 + GradMinuten * 0.0833333; 
    StundePosX = cos((GradStunden - 90) * DEG_TO_RAD);
    StundePosY = sin((GradStunden - 90) * DEG_TO_RAD);

    MinutePosX = cos((GradMinuten - 90) * DEG_TO_RAD) ;
    MinutePosY = sin((GradMinuten - 90) * DEG_TO_RAD);

    SekundePosX = cos((GradSekunden - 90) * DEG_TO_RAD);
    SekundePosY = sin((GradSekunden - 90) * DEG_TO_RAD);

    // nach jeder Minute Minuten-/Stundenzeiger löschen
    // oder einmalig beim Start der Anzeige
    if (Sekunden == 0 || Start) 
    {
      Start = false;
      tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);  

      // 62 Pixel -> Länge des Stundenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      StundenZeigerX = StundePosX * 62 + MitteHoehe + 1;
      StundenZeigerY = StundePosY * 62 + MitteHoehe + 1;
      tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

      // 84 Pixel -> Länge des Minutenzeigers
      // Mittelpunkt + 1 -> Mittelpunkt soll nicht gelöscht werden
      MinutenZeigerX = MinutePosX * 84 + MitteHoehe;
      MinutenZeigerY = MinutePosY * 84 + MitteHoehe + 1;
    }

    // Sekundenzeiger löschen
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, Kreisfarbe);

    // Kreis am Sekundenzeiger löschen, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, Kreisfarbe);

    // 85 Pixel -> Länge des Sekundenzeigers
    SekundenZeigerX = SekundePosX * 85 + MitteHoehe + 1;
    SekundenZeigerY = SekundePosY * 85 + MitteHoehe + 1;

    // Zeiger neu zeichnen
    // Sekunden Linie nur anzeigen wenn SekundenzeigerKreis false
    if (!SekundenzeigerKreis) tft.drawLine(SekundenZeigerX, SekundenZeigerY, MitteHoehe, MitteHoehe + 1, ROT);
    
    // Minuten
    tft.drawLine(MinutenZeigerX, MinutenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Stunden
    tft.drawLine(StundenZeigerX, StundenZeigerY, MitteHoehe, MitteHoehe + 1, Zeigerfarbe);

    // Kreis an der Spitze des Sekundenzeigers, Radius 5
    tft.fillCircle(SekundenZeigerX, SekundenZeigerY, 5, ROT);

    // Mittelpunkt zeichnen
    tft.fillCircle(MitteHoehe, MitteHoehe + 1, 3, Zeigerfarbe); 
  }
}

void ZeigeDatum()
{
  tft.setFont(&FreeSans12pt7b);  
  tft.setCursor(65, 170);
  tft.setTextColor(GRUEN);
      
  // Bildschirmbereich für das Datum löschen
  tft.fillRect(60, 150, 125, 25, Kreisfarbe);
  if (Zeit.tm_mday < 10) tft.print("0");
  tft.print(Zeit.tm_mday);
  tft.print(".");

  // Monat: führende 0 ergänzen
  if (Zeit.tm_mon < 9) tft.print("0");
    
  // Zählung beginnt mit 0 -> +1
  tft.print(Zeit.tm_mon + 1);
  tft.print(".");

  // Anzahl Jahre seit 1900
  tft.print(Zeit.tm_year + 1900);
}

320×240 Pixel

Benö­tig­te Bibliothek

Mess­wer­te eines Poten­tio­me­ters darstellen

TFT mit 320×240 Pixeln

#include "Adafruit_ILI9341.h"

// Schriftarten einbinden
#include "Fonts/FreeSans24pt7b.h"
#include "Fonts/FreeSans12pt7b.h"

// Wemos D1 Mini
// #define TFT_CS D8
// #define TFT_RST D1
// #define TFT_DC D2

// ESP32-WROOM
// #define TFT_CS 5
// #define TFT_RST 4 
// #define TFT_DC 2

// Farben
#define SCHWARZ    0x0000
#define WEISS      0xFFFF 

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

// GFXcanvas-Objekt erstellen: Höhe 170 Pixel, Breite 320 Pixel
GFXcanvas1 Bereich(170, 320);

// analogen Pin anpassen
int Poti = A0;

// maximalen Wert des ADC anpassen
// ESP32: 4096, ESP8266: 1024
int ADCMax = 1024;

/*
  Abstand der Markierung von der Mitte des TFTs
  der ADC liefert keine linear verlaufenden Werte
  der Abstand kann angepasst werden
*/
int AbstandMarkierung = 40;

void setup()
{
  // TFT starten
  tft.begin();

  // Rotation anpassen
  tft.setRotation(2);

  // schwarzer Hintergrund
  tft.fillScreen(SCHWARZ);
  Serial.begin(9600);
}

void loop()
{
  Bereich.fillScreen(SCHWARZ);

  // analogen Wert lesen
  int WertPoti = analogRead(Poti);

  Serial.println(WertPoti);

  // analogen Wert anzeigen
  Bereich.setFont(&FreeSans24pt7b); 
  Bereich.setCursor(10, 50);  
  Bereich.print(WertPoti);

  // analogen Wert auf die Höhe des TFTs übertragen
  int BalkenPoti = map(WertPoti, 0, ADCMax, 0, 320);

  /*
    bei gedrehtem Bildschirm wird der Balken von oben nach unten angezeigt
    zuerest maximalen Wert weiß füllen
    anschließend vom maximalen Wert den gemessenen Wert abziehen
    und schwarz füllen
  */
  Bereich.fillRect(130, 1, 50, 320, WEISS);
  Bereich.fillRect(130, 1, 50, 320 - BalkenPoti, SCHWARZ);

  Bereich.setCursor(70, tft.width() / 2 - AbstandMarkierung);
  Bereich.setFont(&FreeSans12pt7b); 

  // je nach Wert ADCMax Zahlen anzeigen
  if (ADCMax == 4096) Bereich.print("3000");
  else  Bereich.print("750");
  Bereich.drawLine(tft.height() / 2, tft.width() / 2 - AbstandMarkierung, 50, tft.width() / 2 - AbstandMarkierung, WEISS);

  Bereich.setCursor(70, tft.width() / 2 + 40);
  if (ADCMax == 4096) Bereich.print("2000");
  else Bereich.print("500");
  Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung, 50, tft.width() / 2 + AbstandMarkierung, WEISS);

  Bereich.setCursor(70, tft.width() / 2 + AbstandMarkierung * 3);
  if (ADCMax == 4096) Bereich.print("1000");
  else Bereich.print("250");
  Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung * 3, 50, tft.width() / 2 + AbstandMarkierung * 3, WEISS);

  // GFXcanvas anzeigen
  tft.drawBitmap(0, 0, Bereich.getBuffer(), Bereich.width(), Bereich.height(), WEISS, SCHWARZ);
}

TFT mit 160×128 Pixeln

#include "Adafruit_ST7735.h"

// Schriftarten einbinden
#include "Fonts/FreeSans9pt7b.h"
#include "Fonts/FreeSans12pt7b.h"

// Wemos D1 Mini
// #define TFT_CS D8
// #define TFT_RST D1
// #define TFT_DC D2

// ESP32-WROOM
// #define TFT_CS 5
// #define TFT_RST 4 
// #define TFT_DC 2

// Farben
#define SCHWARZ    0x0000
#define WEISS      0xFFFF 

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// GFXcanvas-Objekt erstellen: Höhe 128 Pixel, Breite 160 Pixel
GFXcanvas1 Bereich(128, 160);

// analogen Pin anpassen
int Poti = A0;

// maximalen Wert des ADC anpassen
// ESP32: 4096, ESP8266: 1024
int ADCMax = 4096;

/*
  Abstand der Markierung von der Mitte des TFTs
  der ADC liefert keine lienear verlaufenden Werte
  der Abstand kann angepasst werden
*/
int AbstandMarkierung = 20;

void setup()
{
  // TFT starten
  tft.initR(INITR_BLACKTAB);

  // Rotation anpassen
  tft.setRotation(0);

  // schwarzer Hintergrund
  tft.fillScreen(SCHWARZ);
}

void loop()
{
  Bereich.fillScreen(SCHWARZ);

  // analogen Wert lesen
  int WertPoti = analogRead(Poti);

  // analogen Wert anzeigen
  Bereich.setFont(&FreeSans12pt7b); 
  Bereich.setCursor(10, 20);  
  Bereich.print(WertPoti);

  // analogen Wert auf die Höhe des TFTs übertragen
  int BalkenPoti = map(WertPoti, 0, ADCMax, 0, 160);

  /*
    bei gedrehtem Bildschirm wird der Balken von oben nach unten angezeigt
    zuerest maximalen Wert weiß füllen
    anschließend vom maximalen Wert den gemessenen Wert abziehen
    und schwarz füllen
  */
  Bereich.fillRect(80, 1, 30, 160, WEISS);
  Bereich.fillRect(80, 1, 30, 160 - BalkenPoti, SCHWARZ);

  Bereich.setCursor(30, tft.width() / 2 - AbstandMarkierung);
  Bereich.setFont(&FreeSans9pt7b); 

  // je nach Wert ADCMax Zahlen anzeigen
  if (ADCMax == 4096) Bereich.print("3000");
  else Bereich.print("750");
  Bereich.drawLine(tft.height() / 2, tft.width() / 2 - AbstandMarkierung, 50, tft.width() / 2 - AbstandMarkierung, WEISS);

  Bereich.setCursor(30, tft.width() / 2 + AbstandMarkierung);

  if (ADCMax == 4096) Bereich.print("2000");
  else Bereich.print("500");
  Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung, 50, tft.width() / 2 + AbstandMarkierung, WEISS);

  Bereich.setCursor(30, tft.width() / 2 + AbstandMarkierung * 3);

  if (ADCMax == 4096) Bereich.print("1000");
  else Bereich.print("250");
  Bereich.drawLine(tft.height() / 2, tft.width() / 2 + AbstandMarkierung * 3, 50, tft.width() / 2 + AbstandMarkierung * 3, WEISS);

  // GFXcanvas anzeigen
  tft.drawBitmap(0, 0, Bereich.getBuffer(), Bereich.width(), Bereich.height(), WEISS, SCHWARZ);
}

Letzte Aktualisierung:

DHT11/DHT22 - Mess­da­ten und Zeit auf TFT anzeigen

TFT 160×128

#ifdef ESP8266
  #include "ESP8266WiFi.h"

#else 
  #include "WiFi.h"
#endif

#include "time.h"
#include "Adafruit_ST7735.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "DHT.h"

// freier digitaler Pin für DHT
int SENSOR_DHT = 11;

// Sensortyp festlegen
// DHT22
#define SensorTyp DHT22

// DHT11
// #define SensorTyp DHT11

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// 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

// 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_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

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;
WiFiServer Server(80);
WiFiClient Client;

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

// Bitmaps
const unsigned char Kalender [] PROGMEM = {
	// 'Kalender_30x35, 30x35px
	0x7f, 0xff, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 
	0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 
	0xff, 0xff, 0xff, 0xfc, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x8e, 0x00, 0x01, 0xc4, 
	0x8e, 0x00, 0x01, 0xc4, 0x8e, 0x00, 0x01, 0xc4, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 
	0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 
	0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 
	0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 
	0x8e, 0x00, 0x01, 0xc4, 0x8e, 0x00, 0x01, 0xc4, 0x8e, 0x00, 0x01, 0xc4, 0x80, 0x00, 0x00, 0x04, 
	0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xfc
};

const unsigned char Uhr [] PROGMEM = {
	// 'Uhr_30x30, 30x30px
	0x00, 0x1f, 0xe0, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x01, 0xf0, 0x3e, 0x00, 0x07, 0x80, 0x07, 0x80, 
	0x0f, 0x03, 0x03, 0xc0, 0x1c, 0x60, 0x18, 0xe0, 0x18, 0x00, 0x00, 0x60, 0x38, 0x01, 0x00, 0x70, 
	0x30, 0x01, 0x00, 0x30, 0x63, 0x01, 0x01, 0x98, 0x60, 0x01, 0x00, 0x18, 0xe0, 0x01, 0x00, 0x1c, 
	0xc0, 0x01, 0x00, 0x0c, 0xc0, 0x01, 0x00, 0x0c, 0xcc, 0x01, 0x00, 0xcc, 0xc0, 0x02, 0x00, 0x0c, 
	0xc0, 0x0c, 0x00, 0x0c, 0xc0, 0x30, 0x00, 0x0c, 0xe0, 0xc0, 0x00, 0x1c, 0x66, 0x00, 0x01, 0x98, 
	0x60, 0x00, 0x00, 0x18, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x18, 0x60, 0x10, 0x60, 
	0x1c, 0x00, 0x00, 0xe0, 0x0f, 0x03, 0x03, 0xc0, 0x07, 0x80, 0x07, 0x80, 0x01, 0xf0, 0x3e, 0x00, 
	0x00, 0x7f, 0xfc, 0x00, 0x00, 0x1f, 0xe0, 0x00
};

const unsigned char Thermometer [] PROGMEM = {
	// 'Thermometer_19x40, 19x40px
	0x01, 0xe0, 0x00, 0x03, 0xf8, 0x00, 0x06, 0x0c, 0x00, 0x04, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 
	0x04, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x18, 0x04, 
	0x00, 0x08, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 
	0x00, 0xe4, 0x00, 0x00, 0xe4, 0x00, 0x38, 0xe4, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe4, 0x00, 0x00, 
	0xe4, 0x00, 0x00, 0xe4, 0x00, 0x18, 0xe7, 0x00, 0x30, 0xe3, 0x80, 0x21, 0xe1, 0x80, 0x63, 0xf8, 
	0xc0, 0x47, 0xf8, 0xc0, 0x47, 0xfc, 0x40, 0xc7, 0xfc, 0x60, 0xc7, 0xfc, 0x60, 0xc7, 0xfc, 0x60, 
	0x47, 0xfc, 0x40, 0x63, 0xf8, 0xc0, 0x61, 0xf0, 0xc0, 0x30, 0x01, 0x80, 0x10, 0x03, 0x00, 0x0e, 
	0x0e, 0x00, 0x07, 0xfc, 0x00, 0x00, 0xe0, 0x00
};

const unsigned char Regen [] PROGMEM = {
	// 'Regen_43x35, 43x35px
	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x22, 0x22, 0x21, 0x00, 0x00, 0x00, 0x66, 0x22, 0x23, 0x20, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
	0x03, 0x11, 0x11, 0x19, 0x10, 0x00, 0x02, 0x00, 0x01, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x08, 0x08, 0x88, 0x80, 0x31, 0x11, 
	0x19, 0x18, 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x88, 0x8c, 0x88, 0xc4, 0xcc, 0xc0, 0x08, 0x88, 0x88, 0x04, 
	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
	0x00, 0x00, 0x80, 0x00, 0x23, 0x33, 0x11, 0x11, 0x99, 0x00, 0x20, 0x20, 0x11, 0x10, 0x11, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x88, 0x88, 0x88, 
	0x88, 0x00, 0x01, 0x08, 0x98, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x46, 0x00, 0x00, 
	0x00, 0x04, 0x44, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00
};

void setup()
{
    // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());

  // Schriften von u8g2 tft zuordnen
  u8g2Schriften.begin(tft); 

  // Zufallsgenerator starten
  randomSeed(analogRead(A0));
  Serial.begin(9600);
  delay(500);
  Serial.println("Bildschirm: " + String(tft.height()) + " x " + String(tft.width()));

  // TFT starten
  tft.initR(INITR_BLACKTAB);

  // Rotation anpassen
  tft.setRotation(2);

  // Bitmaps anzeigen
  tft.fillScreen(ST77XX_BLACK);
  tft.drawBitmap(1, 1, Kalender, 30, 35, ST77XX_WHITE);  
  tft.drawBitmap(1, 40, Uhr, 30, 30, ST77XX_WHITE);
  tft.drawBitmap(10, 75, Thermometer, 19, 40, ST77XX_WHITE);
  tft.drawBitmap(1, 121, Regen, 43, 35, ST77XX_WHITE);

  // Sensor starten
  dht.begin();
}

void loop()
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Temperatur lesen
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // nur den Bereich der Daten schwärzen 
  tft.fillRect(45, 1, tft.width(), tft.height(), ST77XX_BLACK);

  u8g2Schriften.setForegroundColor(ST77XX_WHITE);   
  u8g2Schriften.setBackgroundColor(ST77XX_BLACK);
  u8g2Schriften.setFont(u8g2_font_helvB12_te); 
  u8g2Schriften.setCursor(48, 20); 
    
    // Tag: führende 0 ergänzen
  if (Zeit.tm_mday < 10) 
  {
    u8g2Schriften.print("0");
  }

  u8g2Schriften.print(Zeit.tm_mday);
  u8g2Schriften.print(".");

  // Monat: führende 0 ergänzen
  if (Zeit.tm_mon < 9) 
  {
    u8g2Schriften.print("0");
  }
  u8g2Schriften.print(Zeit.tm_mon + 1);
  u8g2Schriften.print(".");

  // Anzahl Jahre seit 1900
  u8g2Schriften.print(Zeit.tm_year + 1900);
  u8g2Schriften.print(" ");

  u8g2Schriften.setCursor(48, 60);

  // Stunde: wenn Stunde < 10 -> 0 davor setzen
  if (Zeit.tm_hour < 10) u8g2Schriften.print("0");
  u8g2Schriften.print(Zeit.tm_hour);
  u8g2Schriften.print(":");

  // Minuten
  if (Zeit.tm_min < 10) u8g2Schriften.print("0");
  u8g2Schriften.print(Zeit.tm_min);

  // Messdaten anzeigen
  u8g2Schriften.setCursor(48, 100);
  u8g2Schriften.print(Temperatur + " °C");
  u8g2Schriften.setCursor(48, 140);
  u8g2Schriften.print(Luftfeuchtigkeit + " %");

  delay(10000);
}

TFT 320×240

#ifdef ESP8266
  #include "ESP8266WiFi.h"

#else 
  #include "WiFi.h"
#endif

#include "Adafruit_ILI9341.h"
#include "time.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "DHT.h"

// freier digitaler Pin für DHT
int SENSOR_DHT = D3;

// Sensortyp festlegen
// DHT22
#define SensorTyp DHT22

// DHT11
// #define SensorTyp DHT11

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// 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

// 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);

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;
WiFiServer Server(80);
WiFiClient Client;

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

// Bitmaps
const unsigned char Uhr [] PROGMEM = {
	// 'Uhr, 50x50px
	0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 
	0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x01, 
	0xfe, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x1f, 0xc0, 
	0x00, 0x01, 0xf8, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf0, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0x07, 
	0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x07, 0x80, 0xc0, 0x00, 0x40, 0x78, 0x00, 0x0f, 0x80, 0x00, 
	0x00, 0x00, 0x7c, 0x00, 0x1f, 0x00, 0x00, 0x80, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0x00, 0xc0, 0x00, 
	0x1e, 0x00, 0x3e, 0x00, 0x00, 0xc0, 0x00, 0x1f, 0x00, 0x3c, 0x00, 0x00, 0xc0, 0x00, 0x0f, 0x00, 
	0x38, 0x30, 0x00, 0xc0, 0x01, 0x07, 0x00, 0x78, 0x00, 0x00, 0xc0, 0x00, 0x07, 0x80, 0x78, 0x00, 
	0x00, 0xc0, 0x00, 0x07, 0x80, 0x70, 0x00, 0x00, 0xc0, 0x00, 0x03, 0x80, 0xf0, 0x00, 0x00, 0xc0, 
	0x00, 0x03, 0xc0, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x03, 
	0xc0, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xc0, 0xf1, 0x80, 0x00, 0xc0, 0x00, 0x63, 0xc0, 0xf1, 
	0x80, 0x01, 0x80, 0x00, 0x63, 0xc0, 0xf0, 0x00, 0x07, 0x00, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0x1c, 
	0x00, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0x78, 0x00, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0xe0, 0x00, 0x00, 
	0x03, 0xc0, 0x70, 0x03, 0x80, 0x00, 0x00, 0x03, 0x80, 0x78, 0x07, 0x00, 0x00, 0x00, 0x07, 0x80, 
	0x78, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x78, 0x20, 0x00, 0x00, 0x01, 0x07, 0x80, 0x3c, 0x00, 
	0x00, 0x00, 0x00, 0x0f, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1e, 0x00, 0x00, 0x00, 
	0x00, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x7c, 
	0x00, 0x07, 0x80, 0x80, 0x00, 0xc0, 0x78, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x03, 
	0xf0, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0x01, 0xf8, 0x00, 0xc0, 0x07, 0xe0, 0x00, 0x00, 0xfe, 0x00, 
	0x00, 0x1f, 0xc0, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x1f, 0xe0, 0x01, 0xfe, 
	0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 
	0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00
};

const unsigned char Thermometer [] PROGMEM = {
	// 'Thermometer, 34x70px
	0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 
	0x7c, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x07, 0x80, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0x00, 0x00, 0xe0, 
	0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 
	0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 
	0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 
	0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 
	0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 
	0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 
	0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc3, 0xe1, 0xc0, 
	0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x0f, 0xc3, 0xf1, 0xc0, 0x00, 
	0x0f, 0xc3, 0xf1, 0xc0, 0x00, 0x0f, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 
	0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 
	0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x03, 0xc3, 0xf1, 0xf0, 0x00, 0x07, 0xc3, 0xf0, 
	0xf8, 0x00, 0x0f, 0x03, 0xf0, 0x7c, 0x00, 0x0e, 0x03, 0xe0, 0x3c, 0x00, 0x1c, 0x07, 0xf0, 0x1e, 
	0x00, 0x3c, 0x1f, 0xfc, 0x0f, 0x00, 0x38, 0x3f, 0xfe, 0x0f, 0x00, 0x78, 0x7f, 0xff, 0x07, 0x80, 
	0x70, 0x7f, 0xff, 0x87, 0x80, 0x70, 0x7f, 0xff, 0x83, 0x80, 0xf0, 0xff, 0xff, 0x83, 0xc0, 0xf0, 
	0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 
	0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0x83, 0xc0, 0x70, 0x7f, 0xff, 0x83, 0x80, 0x70, 0x7f, 0xff, 
	0x87, 0x80, 0x78, 0x3f, 0xff, 0x07, 0x80, 0x38, 0x3f, 0xfe, 0x0f, 0x00, 0x3c, 0x0f, 0xfc, 0x0f, 
	0x00, 0x1e, 0x03, 0xe0, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x3e, 0x00, 0x0f, 0x00, 0x00, 0x7c, 0x00, 
	0x07, 0xe0, 0x01, 0xf8, 0x00, 0x03, 0xf8, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 
	0x7f, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00
};

const unsigned char Regen [] PROGMEM = {
	// 'Regen, 60x49px
	0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x02, 0x08, 0x21, 0x04, 0x10, 0x00, 0x00, 0x00, 0x06, 0x18, 0x63, 0x0c, 0x30, 0x80, 0x00, 
	0x00, 0x06, 0x10, 0x63, 0x0c, 0x31, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x20, 0x84, 0x10, 0x41, 0x08, 0x20, 0x00, 0x00, 0x61, 0x8c, 0x30, 0xc3, 0x18, 0x60, 0x00, 
	0x08, 0xc1, 0x8c, 0x30, 0xc3, 0x18, 0x61, 0x00, 0x00, 0x41, 0x04, 0x20, 0x82, 0x08, 0x40, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 0x86, 0x18, 0x43, 0x04, 0x30, 0x80, 
	0x18, 0x71, 0x86, 0x18, 0xc3, 0x0c, 0x31, 0x80, 0x18, 0x21, 0x84, 0x10, 0xc3, 0x0c, 0x21, 0x80, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x18, 0x21, 0x04, 0x10, 0x42, 0x18, 0x40, 
	0x86, 0x18, 0x63, 0x0c, 0x30, 0xc6, 0x18, 0xc0, 0x86, 0x10, 0x63, 0x0c, 0x30, 0xc6, 0x18, 0xc0, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x18, 0x21, 0x04, 0x10, 0xc2, 0x0c, 0x21, 0x00, 0x30, 0x63, 0x0c, 0x31, 0xc6, 0x0c, 0x63, 0x00, 
	0x30, 0x63, 0x0c, 0x31, 0x86, 0x18, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x06, 0x10, 0x43, 0x08, 0x20, 0x86, 0x10, 0x00, 0x06, 0x30, 0xc3, 0x18, 0x61, 0x86, 0x30, 0x00, 
	0x04, 0x30, 0xc2, 0x18, 0x61, 0x8c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x0c, 0x30, 0xc6, 0x18, 0x61, 0x00, 0x00, 
	0x00, 0x00, 0x61, 0xc6, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x86, 0x10, 0x60, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const unsigned char Kalender [] PROGMEM = {
	// 'Kalender, 51x60px
	0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xe0, 0xff, 0xff, 
	0xff, 0x1f, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 
	0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
	0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 
	0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 
	0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 
	0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 
	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0xf0, 
	0x00, 0x00, 0x01, 0xe0, 0x60, 0x81, 0xf8, 0x00, 0x00, 0x03, 0xf0, 0x60, 0x81, 0xf8, 0x00, 0x00, 
	0x03, 0xf0, 0x60, 0x81, 0xf8, 0x00, 0x00, 0x03, 0xf0, 0x60, 0x81, 0xf8, 0x00, 0x00, 0x03, 0xf0, 
	0x60, 0x80, 0xf0, 0x00, 0x00, 0x01, 0xe0, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
	0x80, 0xf0, 0x00, 0x00, 0x01, 0xe0, 0x60, 0x81, 0xf8, 0x00, 0x00, 0x03, 0xf0, 0x60, 0x81, 0xf8, 
	0x00, 0x00, 0x03, 0xf0, 0x60, 0xc1, 0xf8, 0x00, 0x00, 0x03, 0xf0, 0x60, 0xc1, 0xf8, 0x00, 0x00, 
	0x03, 0xf0, 0x60, 0xc0, 0xf0, 0x00, 0x00, 0x01, 0xe0, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 
	0xff, 0xff, 0xff, 0xc0
};

void setup()
{
    // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());

  // Schriften von u8g2 tft zuordnen
  u8g2Schriften.begin(tft); 

  // Zufallsgenerator starten
  randomSeed(analogRead(A0));
  Serial.begin(9600);
  delay(500);
  Serial.println("Bildschirm: " + String(tft.height()) + " x " + String(tft.width()));

  // TFT starten
  tft.begin();

  // Rotation anpassen
  tft.setRotation(2);

  // Bitmaps anzeigen
  tft.fillScreen(ILI9341_BLACK);
  tft.drawBitmap(1, 1, Kalender, 51, 60, ILI9341_WHITE);  
  tft.drawBitmap(1, 90, Uhr, 50, 50, ILI9341_WHITE);
  tft.drawBitmap(10, 170, Thermometer, 34, 70, ILI9341_WHITE);
  tft.drawBitmap(1, 270, Regen, 60, 49, ILI9341_WHITE);

  // Sensor starten
  dht.begin();
}

void loop()
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Temperatur lesen
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // nur den Bereich der Daten schwärzen 
  tft.fillRect(60, 1, tft.width(), tft.height(), ILI9341_BLACK);

  u8g2Schriften.setForegroundColor(ILI9341_WHITE);   
  u8g2Schriften.setBackgroundColor(ILI9341_BLACK);
  u8g2Schriften.setFont(u8g2_font_helvB24_tf); 
  u8g2Schriften.setCursor(70, 45); 
    
    // Tag: führende 0 ergänzen
  if (Zeit.tm_mday < 10) 
  {
    u8g2Schriften.print("0");
  }

  u8g2Schriften.print(Zeit.tm_mday);
  u8g2Schriften.print(".");

  // Monat: führende 0 ergänzen
  if (Zeit.tm_mon < 9) 
  {
    u8g2Schriften.print("0");
  }
  u8g2Schriften.print(Zeit.tm_mon + 1);
  u8g2Schriften.print(".");

  // Anzahl Jahre seit 1900
  u8g2Schriften.print(Zeit.tm_year + 1900);
  u8g2Schriften.print(" ");

  u8g2Schriften.setCursor(70, 120);

    // Stunde: wenn Stunde < 10 -> 0 davor setzen
    if (Zeit.tm_hour < 10) u8g2Schriften.print("0");
    u8g2Schriften.print(Zeit.tm_hour);
    u8g2Schriften.print(":");

    // Minuten
    if (Zeit.tm_min < 10) u8g2Schriften.print("0");
    u8g2Schriften.print(Zeit.tm_min);

     // Messdaten anzeigen
    u8g2Schriften.setCursor(70, 210);
    u8g2Schriften.print(Temperatur + " °C");
    u8g2Schriften.setCursor(70, 300);
    u8g2Schriften.print(Luftfeuchtigkeit + " %");

    delay(10000);
}

Letzte Aktualisierung:

DHT11/DHT22 Mess­da­ten auf Wavesha­re 1,54 E-Ink anzeigen

Anzei­ge nur Text

#include "GxEPD2_3C.h"
#include "DHT.h"
#include "U8g2_for_Adafruit_GFX.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

// freien Pin auf dem Board wählen
int SENSOR_DHT = 9;

// Sensortyp festlegen
// DHT22
#define SensorTyp DHT22

// DHT11
// #define SensorTyp DHT11

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// Display-Parameter
// GxEPD2_154_Z90c: Chip SSD1681 Bildschirm: 200x200
#define GxEPD2_DISPLAY_CLASS GxEPD2_3C
#define GxEPD2_DRIVER_CLASS GxEPD2_154_Z90c  

// Board wählen:
// ESP32-Wroom
// Anschlüsse: CLK -> 18, DIN -> 23, CS -> 5, DC -> 2, RST -> 22, BUSY -> 4
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ 5, /*DC=*/ 2, /*RST=*/ 22, /*BUSY=*/ 4));

// NodeMCU
// CLK - D5, DIN -> D7, CS -> D8, DC -> D6, RST -> D2, BUSY -> D1
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/D4, /*DC=*/ D6, /*RST=*/ D2, /*BUSY=*/ D1));

// ESP32-C6
// Anschlüsse: CLK -> 21, DIN -> 19, CS -> 18, DC -> 3, RST -> 10, BUSY -> 11
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ 18, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 11));

// Nano ESP32
// Anschlüsse: CLK -> D13, DIN -> D11, CS -> D10, DC-> D6, RST -> D8, BUSY -> D9
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ D10, /*DC=*/ D6, /*RST=*/ D7, /*BUSY=*/ D9));

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // Sensor starten
  dht.begin();

  // Bildschirm starten
  display.init(115200, true, 2, false); 

  // Bildschirm um 90° drehen
  display.setRotation(1);

  // vollständigen Bildschirm nutzen
  display.setFullWindow();

  // weißer Hintergrund
  display.fillScreen(GxEPD_WHITE);

  // Schriften von u8g2 display zuordnen
  u8g2Schriften.begin(display); 
}

void loop() 
{
  // Temperatur lesen
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // Anzeige aufbauen
  display.firstPage();
  do 
  {
    display.fillScreen(GxEPD_WHITE);

    u8g2Schriften.setForegroundColor(GxEPD_BLACK);   
    u8g2Schriften.setBackgroundColor(GxEPD_WHITE);
    u8g2Schriften.setFont(u8g2_font_fub35_tf);  

    u8g2Schriften.setCursor(1, 80);
    u8g2Schriften.print(Temperatur + " °C");
    u8g2Schriften.setCursor(1, 180);
    u8g2Schriften.print(Luftfeuchtigkeit + " %");
  } 
  while (display.nextPage());

  // alle 5 Minuten aktualisieren
  delay(300000);
}

Anzei­ge nur Text mit Uhrzeit

#ifdef ESP8266
  #include "ESP8266WiFi.h"
#else 
  #include "WiFi.h"
#endif

#include "time.h"
#include "GxEPD2_3C.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "DHT.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

// freien Pin auf dem Board wählen
int SENSOR_DHT = 9;

// Sensortyp festlegen
// DHT22
#define SensorTyp DHT22

// DHT11
// #define SensorTyp DHT11

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// Schriftart
#include "Fonts/FreeMonoBold24pt7b.h"

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;
WiFiServer Server(80);
WiFiClient Client;

// Display-Parameter
// GxEPD2_154_Z90c: Chip SSD1681 Bildschirm: 200x200
#define GxEPD2_DISPLAY_CLASS GxEPD2_3C
#define GxEPD2_DRIVER_CLASS GxEPD2_154_Z90c  

// Board wählen:
// ESP32-Wroom
// Anschlüsse: CLK -> 18, DIN -> 23, CS -> 5, DC -> 2, RST -> 22, BUSY -> 4
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ 5, /*DC=*/ 2, /*RST=*/ 22, /*BUSY=*/ 4));

// NodeMCU
// CLK - D5, DIN -> D7, CS -> D8, DC -> D6, RST -> D2, BUSY -> D1
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/D4, /*DC=*/ D6, /*RST=*/ D2, /*BUSY=*/ D1));

// ESP32-C6
// Anschlüsse: CLK -> 21, DIN -> 19, CS -> 18, DC -> 3, RST -> 10, BUSY -> 11
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ 18, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 11));

// Nano ESP32
// Anschlüsse: CLK -> D13, DIN -> D11, CS -> D10, DC-> D6, RST -> D8, BUSY -> D9
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ D10, /*DC=*/ D6, /*RST=*/ D7, /*BUSY=*/ D9));

void setup() 
{
  // Schriften von u8g2 display zuordnen
  u8g2Schriften.begin(display); 
  
  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // 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());

  // Sensor starten
  dht.begin();

  // Bildschirm starten
  display.init(115200, true, 2, false); 

  // Bildschirm um 90° drehen
  display.setRotation(1);

  // vollständigen Bildschirm nutzen
  display.setFullWindow();

  // weißer Hintergrund
  display.fillScreen(GxEPD_WHITE);
}

void loop() 
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Temperatur lesen
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // Anzeige aufbauen
  display.firstPage();
  do 
  {
    display.fillScreen(GxEPD_WHITE);
    
    u8g2Schriften.setForegroundColor(GxEPD_BLACK);   
    u8g2Schriften.setBackgroundColor(GxEPD_WHITE);
    u8g2Schriften.setFont(u8g2_font_fub35_tf); 
    
    u8g2Schriften.setCursor(1, 50);

    // Stunde: wenn Stunde < 10 -> 0 davor setzen
    if (Zeit.tm_hour < 10) u8g2Schriften.print("0");
    u8g2Schriften.print(Zeit.tm_hour);
    u8g2Schriften.print(":");

    // Minuten
    if (Zeit.tm_min < 10) u8g2Schriften.print("0");
    u8g2Schriften.print(Zeit.tm_min);

    // horizontale Linie
    display.fillRect(1, 62, display.width(), 4, GxEPD_BLACK);

    u8g2Schriften.setCursor(1, 110);

    u8g2Schriften.print(Temperatur + " °C");
    u8g2Schriften.setCursor(1, 170);
    u8g2Schriften.print(Luftfeuchtigkeit + " %");
  } 
  while (display.nextPage());

  // alle 5 Minuten aktualisieren
  delay(300000);
}

Anzei­ge mit Sym­bo­len und Text

#ifdef ESP8266
  #include "ESP8266WiFi.h"
#else 
  #include "WiFi.h"
#endif

#include "time.h"
#include "GxEPD2_3C.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "DHT.h"

// Objekt u8g2Schriften
U8G2_FOR_ADAFRUIT_GFX u8g2Schriften;

// Pin DHT
int SENSOR_DHT = 9;

// Sensortyp festlegen
// DHT22
#define SensorTyp DHT22

// DHT11
// #define SensorTyp DHT11

// Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

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;
WiFiServer Server(80);
WiFiClient Client;

// Display-Parameter
// GxEPD2_154_Z90c: Chip SSD1681 Bildschirm: 200x200
#define GxEPD2_DISPLAY_CLASS GxEPD2_3C
#define GxEPD2_DRIVER_CLASS GxEPD2_154_Z90c

// ESP32-Wroom
// Anschlüsse: CLK -> 18, DIN -> 23, CS -> 5, DC-> 2, RST -> 22, BUSY -> 4
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/5, /*DC=*/2, /*RST=*/22, /*BUSY=*/4));

// NodeMCU
// CLK - D5, DIN -> D7, CS -> D8, DC -> D6, RST -> D2, BUSY -> D1
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/D4, /*DC=*/D6, /*RST=*/D2, /*BUSY=*/D1));

// ESP32-C6
// Anschlüsse: CLK -> 21, DIN -> 19, CS -> 18, DC-> 3, RST -> 10, BUSY -> 11
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
//  display(GxEPD2_DRIVER_CLASS(/*CS=*/ 18, /*DC=*/ 3, /*RST=*/2, /*BUSY=*/11));

// Nano ESP32
// Anschlüsse: CLK -> D13, DIN -> D11, CS -> D10, DC-> D6, RST -> D8, BUSY -> D9
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, 200>
// display(GxEPD2_DRIVER_CLASS(/*CS=*/ D10, /*DC=*/ D6, /*RST=*/ D7, /*BUSY=*/ D9));


const unsigned char Thermometer [] PROGMEM = {
	// 'Thermometer, 34x70px
	0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 
	0x7c, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x07, 0x80, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0x00, 0x00, 0xe0, 
	0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 
	0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 
	0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 
	0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 
	0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 
	0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x00, 0x0f, 0xc0, 0x01, 
	0xc0, 0x00, 0x0f, 0xc0, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0xc3, 0xe1, 0xc0, 
	0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x0f, 0xc3, 0xf1, 0xc0, 0x00, 
	0x0f, 0xc3, 0xf1, 0xc0, 0x00, 0x0f, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 
	0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x00, 0xc3, 
	0xf1, 0xc0, 0x00, 0x00, 0xc3, 0xf1, 0xc0, 0x00, 0x03, 0xc3, 0xf1, 0xf0, 0x00, 0x07, 0xc3, 0xf0, 
	0xf8, 0x00, 0x0f, 0x03, 0xf0, 0x7c, 0x00, 0x0e, 0x03, 0xe0, 0x3c, 0x00, 0x1c, 0x07, 0xf0, 0x1e, 
	0x00, 0x3c, 0x1f, 0xfc, 0x0f, 0x00, 0x38, 0x3f, 0xfe, 0x0f, 0x00, 0x78, 0x7f, 0xff, 0x07, 0x80, 
	0x70, 0x7f, 0xff, 0x87, 0x80, 0x70, 0x7f, 0xff, 0x83, 0x80, 0xf0, 0xff, 0xff, 0x83, 0xc0, 0xf0, 
	0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0xc3, 0xc0, 0xf0, 0xff, 
	0xff, 0xc3, 0xc0, 0xf0, 0xff, 0xff, 0x83, 0xc0, 0x70, 0x7f, 0xff, 0x83, 0x80, 0x70, 0x7f, 0xff, 
	0x87, 0x80, 0x78, 0x3f, 0xff, 0x07, 0x80, 0x38, 0x3f, 0xfe, 0x0f, 0x00, 0x3c, 0x0f, 0xfc, 0x0f, 
	0x00, 0x1e, 0x03, 0xe0, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x3e, 0x00, 0x0f, 0x00, 0x00, 0x7c, 0x00, 
	0x07, 0xe0, 0x01, 0xf8, 0x00, 0x03, 0xf8, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 
	0x7f, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00
};

const unsigned char Regen [] PROGMEM = {
	// 'Regen, 60x49px
	0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x02, 0x08, 0x21, 0x04, 0x10, 0x00, 0x00, 0x00, 0x06, 0x18, 0x63, 0x0c, 0x30, 0x80, 0x00, 
	0x00, 0x06, 0x10, 0x63, 0x0c, 0x31, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x20, 0x84, 0x10, 0x41, 0x08, 0x20, 0x00, 0x00, 0x61, 0x8c, 0x30, 0xc3, 0x18, 0x60, 0x00, 
	0x08, 0xc1, 0x8c, 0x30, 0xc3, 0x18, 0x61, 0x00, 0x00, 0x41, 0x04, 0x20, 0x82, 0x08, 0x40, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 0x86, 0x18, 0x43, 0x04, 0x30, 0x80, 
	0x18, 0x71, 0x86, 0x18, 0xc3, 0x0c, 0x31, 0x80, 0x18, 0x21, 0x84, 0x10, 0xc3, 0x0c, 0x21, 0x80, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x18, 0x21, 0x04, 0x10, 0x42, 0x18, 0x40, 
	0x86, 0x18, 0x63, 0x0c, 0x30, 0xc6, 0x18, 0xc0, 0x86, 0x10, 0x63, 0x0c, 0x30, 0xc6, 0x18, 0xc0, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x18, 0x21, 0x04, 0x10, 0xc2, 0x0c, 0x21, 0x00, 0x30, 0x63, 0x0c, 0x31, 0xc6, 0x0c, 0x63, 0x00, 
	0x30, 0x63, 0x0c, 0x31, 0x86, 0x18, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x06, 0x10, 0x43, 0x08, 0x20, 0x86, 0x10, 0x00, 0x06, 0x30, 0xc3, 0x18, 0x61, 0x86, 0x30, 0x00, 
	0x04, 0x30, 0xc2, 0x18, 0x61, 0x8c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x0c, 0x30, 0xc6, 0x18, 0x61, 0x00, 0x00, 
	0x00, 0x00, 0x61, 0xc6, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x60, 0x86, 0x10, 0x60, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const unsigned char Uhr [] PROGMEM = {
	// Uhr, 50x50px
	0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 
	0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x01, 
	0xfe, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x1f, 0xc0, 
	0x00, 0x01, 0xf8, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf0, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0x07, 
	0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x07, 0x80, 0xc0, 0x00, 0x40, 0x78, 0x00, 0x0f, 0x80, 0x00, 
	0x00, 0x00, 0x7c, 0x00, 0x1f, 0x00, 0x00, 0x80, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0x00, 0xc0, 0x00, 
	0x1e, 0x00, 0x3e, 0x00, 0x00, 0xc0, 0x00, 0x1f, 0x00, 0x3c, 0x00, 0x00, 0xc0, 0x00, 0x0f, 0x00, 
	0x38, 0x30, 0x00, 0xc0, 0x01, 0x07, 0x00, 0x78, 0x00, 0x00, 0xc0, 0x00, 0x07, 0x80, 0x78, 0x00, 
	0x00, 0xc0, 0x00, 0x07, 0x80, 0x70, 0x00, 0x00, 0xc0, 0x00, 0x03, 0x80, 0xf0, 0x00, 0x00, 0xc0, 
	0x00, 0x03, 0xc0, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x03, 
	0xc0, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xc0, 0xf1, 0x80, 0x00, 0xc0, 0x00, 0x63, 0xc0, 0xf1, 
	0x80, 0x01, 0x80, 0x00, 0x63, 0xc0, 0xf0, 0x00, 0x07, 0x00, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0x1c, 
	0x00, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0x78, 0x00, 0x00, 0x03, 0xc0, 0xf0, 0x00, 0xe0, 0x00, 0x00, 
	0x03, 0xc0, 0x70, 0x03, 0x80, 0x00, 0x00, 0x03, 0x80, 0x78, 0x07, 0x00, 0x00, 0x00, 0x07, 0x80, 
	0x78, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x78, 0x20, 0x00, 0x00, 0x01, 0x07, 0x80, 0x3c, 0x00, 
	0x00, 0x00, 0x00, 0x0f, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1e, 0x00, 0x00, 0x00, 
	0x00, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x7c, 
	0x00, 0x07, 0x80, 0x80, 0x00, 0xc0, 0x78, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x03, 
	0xf0, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0x01, 0xf8, 0x00, 0xc0, 0x07, 0xe0, 0x00, 0x00, 0xfe, 0x00, 
	0x00, 0x1f, 0xc0, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x1f, 0xe0, 0x01, 0xfe, 
	0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 
	0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00
};

void setup() 
{
  // Schriften von u8g2 display zuordnen
  u8g2Schriften.begin(display); 

  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // 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());

  // Bildschirm starten
  display.init(115200, true, 2, false);

  // Bildschirm um 90° drehen
  display.setRotation(1);

  // vollständigen Bildschirm nutzen
  display.setFullWindow();
  display.fillScreen(GxEPD_WHITE);

  // Sensor starten
  dht.begin();
}

void loop()
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // Temperatur lesen
  String Temperatur = String(dht.readTemperature());

  // replace -> . durch , ersetzen
  Temperatur.replace(".", ",");

  // Luftfeuchtigkeit lesen
  String Luftfeuchtigkeit = String(dht.readHumidity());

  // replace -> . durch , ersetzen
  Luftfeuchtigkeit.replace(".", ",");

  // Anzeige aufbauen
  display.firstPage();
  do 
  {
    u8g2Schriften.setForegroundColor(GxEPD_BLACK);   
    u8g2Schriften.setBackgroundColor(GxEPD_WHITE);
    u8g2Schriften.setFont(u8g2_font_helvB24_tf);   

    u8g2Schriften.setCursor(70, 40);

    // Stunde: wenn Stunde < 10 -> 0 davor setzen
    if (Zeit.tm_hour < 10) u8g2Schriften.print("0");
    u8g2Schriften.print(Zeit.tm_hour);
    u8g2Schriften.print(":");

    // Minuten
    if (Zeit.tm_min < 10) u8g2Schriften.print("0");
    u8g2Schriften.print(Zeit.tm_min);

    // x, y, Bild-Array, Breite, Höhe, Farbe
    display.drawBitmap(5, 5, Uhr, 50, 50, GxEPD_BLACK);
    display.drawBitmap(15, 70, Thermometer, 34, 70, GxEPD_BLACK);
    display.drawBitmap(5, 150, Regen, 60, 49, GxEPD_BLACK);  

    // Messdaten anzeigen
    u8g2Schriften.setCursor(70, 110);
    u8g2Schriften.print(Temperatur + " °C");
    u8g2Schriften.setCursor(70, 180);
    u8g2Schriften.print(Luftfeuchtigkeit + " %");
  } 
  while (display.nextPage());

  // alle 5 Minuten aktualisieren
  delay(300000);
}

Letzte Aktualisierung:

Zeit mit time.h auf einem 4-stel­li­gen 7-Segment-Anzeige

ESP32-Wroom

#include "WiFi.h"
#include "time.h"
#include "TM1637.h"

TM1637 Anzeige(5, 17);

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_wday -> Wochentag (0 = Sonntag, 6 = Samstag)
  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;
WiFiServer Server(80);

// String für die Anzeige der Zeit
String ZeitAnzeige;

void setup() 
{
  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());
  
  // Anzeige starten
  Anzeige.begin();  

  // Helligkeit
  Anzeige.setBrightness(10);

  Anzeige.clearScreen();
}

void loop() 
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // : einschalten
  Anzeige.colonOn();

  /*
    es kann bis zu 30 Sekunden dauern
    bis die Zeit ermittelt wird  
    String ZeitAnzeige zusammenbauen
    wenn Stunden/Minuten < 10 → führende 0 ergänzen
  */
  if (Zeit.tm_hour < 10) ZeitAnzeige = "0" + String(Zeit.tm_hour);
  else ZeitAnzeige = String(Zeit.tm_hour);

  if (Zeit.tm_min < 10) ZeitAnzeige += "0" + String(Zeit.tm_min);
  else ZeitAnzeige += String(Zeit.tm_min);

  Anzeige.display(ZeitAnzeige);
  delay(5000);
}

ESP32-C6

#include "WiFi.h"
#include "time.h"
#include "TM1637.h"

TM1637 Anzeige(15, 23);

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_wday -> Wochentag (0 = Sonntag, 6 = Samstag)
  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;
WiFiServer Server(80);

// String für die Anzeige der Zeit
String ZeitAnzeige;

void setup() 
{
  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());
  
  // Anzeige starten
  Anzeige.begin();  

  // Helligkeit
  Anzeige.setBrightness(10);

  Anzeige.clearScreen();
}

void loop() 
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // : einschalten
  Anzeige.colonOn();

  /*
    es kann bis zu 30 Sekunden dauern
    bis die Zeit ermittelt wird  
    String ZeitAnzeige zusammenbauen
    wenn Stunden/Minuten < 10 → führende 0 ergänzen
  */ 
  if (Zeit.tm_hour < 10) ZeitAnzeige = "0" + String(Zeit.tm_hour);
  else ZeitAnzeige = String(Zeit.tm_hour);

  if (Zeit.tm_min < 10) ZeitAnzeige += "0" + String(Zeit.tm_min);
  else ZeitAnzeige += String(Zeit.tm_min);

  Anzeige.display(ZeitAnzeige);
  delay(5000);
}

XIAO-ESP32-C3

#include "WiFi.h"

#include "time.h"
#include "TM1637.h"

TM1637 Anzeige(D3, D4);

// Router/Passwort
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_wday -> Wochentag (0 = Sonntag, 6 = Samstag)
  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;
WiFiServer Server(80);

// String für die Anzeige der Zeit
String ZeitAnzeige;

void setup() 
{
  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());
  
  // Anzeige starten
  Anzeige.begin();  

  // Helligkeit
  Anzeige.setBrightness(10);

  Anzeige.clearScreen();
}

void loop() 
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // : einschalten
  Anzeige.colonOn();

  /*
    es kann bis zu 30 Sekunden dauern
    bis die Zeit ermittelt wird  
    String ZeitAnzeige zusammenbauen
    wenn Stunden/Minuten < 10 → führende 0 ergänzen
  */
  if (Zeit.tm_hour < 10) ZeitAnzeige = "0" + String(Zeit.tm_hour);
  else ZeitAnzeige = String(Zeit.tm_hour);

  if (Zeit.tm_min < 10) ZeitAnzeige += "0" + String(Zeit.tm_min);
  else ZeitAnzeige += String(Zeit.tm_min);

  Anzeige.display(ZeitAnzeige);
  delay(5000);
}

Wemos D1 Mini

#include "ESP8266WiFi.h"

#include "time.h"
#include "TM1637.h"

TM1637 Anzeige(D3, D4);

// Router/Passwort
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_wday -> Wochentag (0 = Sonntag, 6 = Samstag)
  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;
WiFiServer Server(80);

// String für die Anzeige der Zeit
String ZeitAnzeige;

void setup() 
{
  // Zeitzone: Parameter für die zu ermittelnde Zeit
  configTzTime(Zeitzone, Zeitserver);

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  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());
  
  // Anzeige starten
  Anzeige.begin();  

  // Helligkeit
  Anzeige.setBrightness(10);

  Anzeige.clearScreen();
}

void loop() 
{
  // aktuelle Zeit holen
  time(&aktuelleZeit);

  // localtime_r -> Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  // : einschalten
  Anzeige.colonOn();

  /*
    es kann bis zu 30 Sekunden dauern
    bis die Zeit ermittelt wird  
    String ZeitAnzeige zusammenbauen
    wenn Stunden/Minuten < 10 → führende 0 ergänzen
  */
  if (Zeit.tm_hour < 10) ZeitAnzeige = "0" + String(Zeit.tm_hour);
  else ZeitAnzeige = String(Zeit.tm_hour);

  if (Zeit.tm_min < 10) ZeitAnzeige += "0" + String(Zeit.tm_min);
  else ZeitAnzeige += String(Zeit.tm_min);

  Anzeige.display(ZeitAnzeige);
  delay(5000);
}

Ardui­no UNO R4 WiFi

Zusätz­li­che Biblio­thek installieren