Wet­ter­da­ten mit Open­wea­ther-API 3.0

Seri­el­ler Monitor

#ifdef ESP32
  #include "WiFi.h"
  #include "HTTPClient.h"
#else
    #include "ESP8266WiFi.h"
    #include "ESP8266HTTPClient.h"
#endif

#include "Arduino_JSON.h"
#include "time.h"
#include "TimeLib.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;

// Daten für die API von Openweather -> muss angepasst werden
String APIKey = "4d26a936a4fe519ff3678dxxxxxxxxxx";

// lon = longitude = Breitengrad, lat = latitude = Längengrad
// mit Kartenprogramm oder Openweathermap bestimmen
String Koordinaten = "&lat=50.99111161485325&lon=7.129065378199176";
String Stadt ="Bergisch Gladbach";

/*
  Aktualisierungs-Intervall
  1000 Zugriffe pro Tag kostenlos
  86.400 Sekunden = 1 Tag -> Abruf alle 86,4 Sekunden möglich
  zu Testzwecken das Intervall kurz halten und später
  auf 10 Minuten (oder länger) setzen
*/
unsigned long Intervall = 600000;

// String für die vom Server gelieferten Daten
String JSONDaten;

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

  Serial.begin(9600);
  delay(1000);

  // WiFi starten und Verbindung aufbauen
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP anzeigen
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}

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

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

  // Tag: führende 0 ergänzen
  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 des Monats beginnt mit 0 -> 1 hinzufügen
  Serial.print(Zeit.tm_mon + 1);
  Serial.print(".");

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

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

  // Minuten
  // wenn Minute < 10 -> 0 davor setzen
  if (Zeit.tm_min < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_min);
  Serial.print(":");

  // Sekunden
  if (Zeit.tm_sec < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_sec);
  Serial.println();

  // Wetterdaten holen, wenn WiFi verbunden ist
  if (WiFi.status() == WL_CONNECTED) 
  {
    // Name des Servers und Daten übergeben
    String OpenweatherServer = "http://api.openweathermap.org/data/3.0//onecall?" + Koordinaten;
    OpenweatherServer = OpenweatherServer + "&APPID=" + APIKey + "&units=metric&exclude=daily,hourly,minutely";

    // Server anzeigen
    // Serial.println(OpenweatherServer);

    // Daten vom Server abrufen
    // c_str() liefert einen mit \0 beendeten String
    JSONDaten = ServerAntwortHolen(OpenweatherServer.c_str());

    /*
        parse: Zeichenkette im JSON-Format in ein JavaScript-Objekt umzuwandeln
        damit die Daten (Schlüssel-Wert-Paare)ausgewertet werden können 
        z.B. ["current"] ["temp"]
      */
    JSONVar Objekt = JSON.parse(JSONDaten);

    // Stadt
    Serial.println(Stadt);

    Serial.print("Geodaten: "); 
    Serial.print(Objekt["lat"]);
    Serial.print(".");
    Serial.println(Objekt["lon"]);
    Serial.print("Zeitzone: ");
    Serial.println(Objekt["timezone"]);

    // Temperatur
    Serial.print("Temperatur: ");
    double Temperatur = Objekt["current"]["temp"];
    String AnzeigeTemperatur = String(Temperatur);
    AnzeigeTemperatur.replace(".", ",");
    Serial.print(AnzeigeTemperatur);
    Serial.println("°C");

    // Luftdruck
    Serial.print("Luftdruck: ");
    Serial.print(Objekt["current"]["pressure"]);
    Serial.println(" hPa");

    // Luftfeuchtigkeit
    Serial.print("Luftfeuchtigkeit: ");
    Serial.print(Objekt["current"]["humidity"]);
    Serial.println("%");

    // Windgeschwindigkeit
    Serial.print("Windgeschwindigkeit: ");
    double Windgeschwindigkeit = Objekt["current"]["wind_speed"];
    String AnzeigeWindgeschwindigkeit = String(Windgeschwindigkeit);
    AnzeigeWindgeschwindigkeit.replace(".", ",");
    Serial.print(AnzeigeWindgeschwindigkeit);
    Serial.println(" m/s");

    // Windrichtung
    Serial.print("Windrichtung: ");
    Serial.print(Objekt["current"]["wind_deg"]);
    Serial.println("°");

    // Wetterlage
    Serial.print("Wetterlage: ");
    String Wetterlage = Objekt["current"]["weather"][0]["main"];
    if (Wetterlage == "Clear") 
    {
      Serial.println("klarer Himmel");
    }

    if (Wetterlage == "Mist") 
    {
      Serial.println("Nebel");
    }

    if (Wetterlage == "Clouds") 
    {
      Serial.println("wolkig");
    }

    if (Wetterlage == "Rain") 
    {
      Serial.println("Regen");
    }

    if (Wetterlage == "Snow") 
    {
      Serial.println("Schneefall");
    }

    if (Wetterlage == "Drizzle") 
    {
      Serial.println("Nieselregen");
    }

    if (Wetterlage == "Thunderstorm") 
    {
      Serial.println("Gewitter");
    }

    // Sonnenaufgang als UNIX-Time
    long Sonnenaufgang = Objekt["current"]["sunrise"];
    Serial.print("Sonnenaufgang: ");

    // Zeit des Sonnenaufgangs setzen
    setTime(Sonnenaufgang);
    String ZeitSonnenaufgang;

    // Uhrzeit bestimmen
    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenaufgang) + 2 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 2) + ":";
    }

    // Normalzeit
    else 
    {
      if (hour(Sonnenaufgang) + 1 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 1) + ":";
    }

    if (minute(Sonnenaufgang) < 10) ZeitSonnenaufgang = ZeitSonnenaufgang + "0";
    ZeitSonnenaufgang = ZeitSonnenaufgang + String(minute(Sonnenaufgang));
    Serial.println(ZeitSonnenaufgang);

    // Sonnenuntergang 
    long Sonnenuntergang = Objekt["current"]["sunset"];
    Serial.print("Sonnenuntergang: ");
    setTime(Sonnenuntergang);  
    String ZeitSonnenuntergang;

    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenuntergang) + 2 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 2) + ":";
    }

    // Normalzeit
    else
    {
      if (hour(Sonnenuntergang) + 1 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 1) + ":";
    }

    if (minute(Sonnenuntergang) < 10) ZeitSonnenuntergang = ZeitSonnenuntergang + "0";
    ZeitSonnenuntergang = ZeitSonnenuntergang + String(minute(Sonnenuntergang));
    Serial.println(ZeitSonnenuntergang);

   // letzte Messung entspricht der gerade ermittelten Zeit
    Serial.print("letzte Messung: ");

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

    Serial.print(Zeit.tm_hour);
    Serial.print(":");
    
    // Minuten
    if (Zeit.tm_min < 10) 
    {
      Serial.print("0");
    }

    Serial.println(Zeit.tm_min);
    Serial.println("-----------------------------");
  }

  delay(Intervall);
}

// Wetterdaten holen
String ServerAntwortHolen(const char* OpenweatherServer) 
{
  WiFiClient Client;
  HTTPClient httpClient;

  httpClient.begin(Client, OpenweatherServer);

  // Anfrage senden
  int AntwortCode = httpClient.GET();

  String ServerAntwort = "";

  // Antwort erhalten: Code 200
  if (AntwortCode == 200) 
  {
    // Wetter als String holen, wird später in ein JSON-Objekt umgewandelt
    ServerAntwort = httpClient.getString();

    // Rohdaten anzeigen
    // Serial.println(Serverantwort);
  }

  else 
  {
    Serial.println("Der Server ist nicht erreichbar!");
  }

  httpClient.end();
  return ServerAntwort;
}

TFT 160×128

Du musst ab Zei­le 17 die ⇒SPI-Pins des TFT-Dis­plays an den ver­wen­de­ten Mikro­con­trol­ler anpassen.

#ifdef ESP32
  #include "WiFi.h"
  #include "HTTPClient.h"
#else
    #include "ESP8266WiFi.h"
    #include "ESP8266HTTPClient.h"
#endif

#include "Arduino_JSON.h"
#include "time.h"
#include "TimeLib.h"

#include "Adafruit_GFX.h"
#include "Adafruit_ST7735.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

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

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;

// Daten für die API von Openweather -> muss angepasst werden
String APIKey = "4d26a936a4fe519ff3678dxxxxxxxxxx";

// lon = longitude = Breitengrad, lat = latitude = Längengrad
// mit Kartenprogramm oder Openweathermap bestimmen
String Koordinaten = "&lat=50.9833&lon=7.133";
String Stadt ="Bergisch Gladbach";

/*
  Aktualisierungs-Intervall
  1000 Zugriffe pro Tag kostenlos
  86.400 Sekunden = 1 Tag -> Abruf alle 86,4 Sekunden möglich
  zu Testzwecken das Intervall kurz halten und später
  auf 10 Minuten (oder länger) setzen
*/
unsigned long Intervall = 600000;

// String für die vom Server gelieferten Rohdaten
String JSONDaten;

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

  Serial.begin(9600);

  // WiFi starten und Verbindung aufbauen
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP anzeigen
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());

   // TFT starten schwarzer Hintergrund
  tft.initR(INITR_BLACKTAB);

  // Rotation anpassen Querformat
  tft.setRotation(1);

  // Schriftgröße
  tft.setTextSize(1);
}

void loop() 
{
  tft.fillScreen(ST7735_BLACK);
  tft.setTextColor(ST7735_GREEN);
  tft.setCursor(1, 5);

  // aktuelle Zeit holen
  time(&aktuelleZeit);

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

  // Tag: führende 0 ergänzen
  if (Zeit.tm_mday < 10) 
  {
    Serial.print("0");
    tft.print("0");
  }

  Serial.print(Zeit.tm_mday);
  Serial.print(".");
  tft.print(Zeit.tm_mday);
  tft.print(".");

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

  // Zählung des Monats beginnt mit 0 -> 1 hinzufügen
  Serial.print(Zeit.tm_mon + 1);
  Serial.print(".");
  tft.print(Zeit.tm_mon + 1);
  tft.print(".");

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

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

  // Minuten
  // wenn Minute < 10 -> 0 davor setzen
  if (Zeit.tm_min < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_min);
  Serial.print(":");

  // Sekunden
  if (Zeit.tm_sec < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_sec);
  Serial.println();

  // Wetterdaten holen, wenn WiFi verbunden ist
  if (WiFi.status() == WL_CONNECTED) 
  {
    // Name des Servers und Daten übergeben
    String OpenweatherServer = "http://api.openweathermap.org/data/3.0//onecall?" + Koordinaten;
    OpenweatherServer = OpenweatherServer + "&APPID=" + APIKey + "&units=metric&exclude=daily,hourly,minutely";

    // Server anzeigen
    Serial.println(OpenweatherServer);
    
    // Daten vom Server abrufen
    // c_str() liefert einen mit \0 beendeten String
    JSONDaten = ServerAntwortHolen(OpenweatherServer.c_str());

    /*
        parse: Zeichenkette im JSON-Format in ein JavaScript-Objekt umzuwandeln
        damit die Daten (Schlüssel-Wert-Paare)ausgewertet werden können 
        z.B. ["current"] ["temp"]
      */
    JSONVar Objekt = JSON.parse(JSONDaten);

    // Stadt
    Serial.println(Stadt);
    tft.setCursor(1, 15);
    tft.println(Stadt);
    tft.drawFastHLine(1, 25, tft.width(), ST7735_GREEN);
    tft.setTextColor(ST7735_WHITE);

    // Temperatur
    Serial.print("Temperatur: ");
    double Temperatur = Objekt["current"]["temp"];
    String AnzeigeTemperatur = String(Temperatur);
    AnzeigeTemperatur.replace(".", ",");
    Serial.print(AnzeigeTemperatur);
    Serial.println("°C");
    tft.setCursor(1, 33);
    tft.print("Temperatur: " + AnzeigeTemperatur + char(247) + "C");

    // Luftdruck
    Serial.print("Luftdruck: ");
    Serial.print(Objekt["current"]["pressure"]);
    Serial.println(" hPa");
    tft.setCursor(1, 46);
    tft.print("Luftdruck: ");
    tft.print(Objekt["current"]["pressure"]);
    tft.println(" hPa");

    // Luftfeuchtigkeit
    Serial.print("Luftfeuchtigkeit: ");
    Serial.print(Objekt["current"]["humidity"]);
    Serial.println("%");
    tft.setCursor(1, 59);
    tft.print("Luftfeuchtigkeit: ");
    tft.print(Objekt["current"]["humidity"]);
    tft.println("%");

    // Windgeschwindigkeit
    Serial.print("Windgeschwindigkeit: ");
    double Windgeschwindigkeit = Objekt["current"]["wind_speed"];
    String AnzeigeWindgeschwindigkeit = String(Windgeschwindigkeit);
    AnzeigeWindgeschwindigkeit.replace(".", ",");
    Serial.print(AnzeigeWindgeschwindigkeit);
    Serial.println(" m/s");
    tft.setCursor(1, 72);
    tft.print("Wind: " + AnzeigeWindgeschwindigkeit);
    tft.println(" m/s");

    // Windrichtung
    Serial.print("Windrichtung: ");
    Serial.print(Objekt["current"]["wind_deg"]);
    Serial.println("°");

    // Wetterlage
    Serial.print("Wetterlage: ");
    String Wetterlage = Objekt["current"]["weather"][0]["main"];
    tft.setCursor(1, 85);
    tft.print("Wetterlage: ");
    if (Wetterlage == "Clear") 
    {
      Serial.println("klarer Himmel");
      tft.print("klarer Himmel");
    }

    if (Wetterlage == "Mist") 
    {
      Serial.println("Nebel");
      tft.print("Nebel");
    }

    if (Wetterlage == "Clouds") 
    {
      Serial.println("wolkig");
      tft.println("wolkig");
    }

    if (Wetterlage == "Rain") 
    {
      Serial.println("Regen");
      tft.println("Regen");
    }

    if (Wetterlage == "Snow") 
    {
      Serial.println("Schneefall");
      tft.println("Schneefall");
    }

    if (Wetterlage == "Drizzle") 
    {
      Serial.println("Nieselregen");
      tft.println("Nieselregen");
    }

    if (Wetterlage == "Thunderstorm") 
    {
      Serial.println("Gewitter");
      tft.println("Gewitter");
    }

    // letzte Messung entspricht der gerade ermittelten Zeit
    Serial.print("letzte Messung: ");

    tft.setCursor(1, 180);
    tft.print("letzte Messung: ");

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

    Serial.print(Zeit.tm_hour);
    Serial.print(":");

    tft.print(Zeit.tm_hour);
    tft.print(":");
    
    // Minuten
    if (Zeit.tm_min < 10) 
    {
      tft.print("0");
      Serial.print("0");
    }

    Serial.println(Zeit.tm_min);
    tft.print(Zeit.tm_min);

    // Sonnenaufgang als UNIX-Time
    long Sonnenaufgang = Objekt["current"]["sunrise"];
    Serial.print("Sonnenaufgang: ");

    // Zeit des Sonnenaufgangs setzen
    setTime(Sonnenaufgang);
    String ZeitSonnenaufgang;

    // Uhrzeit bestimmen
    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenaufgang) + 2 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 2) + ":";
    }

    // Normalzeit
    else 
    {
      if (hour(Sonnenaufgang) + 1 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 1) + ":";
    }

    if (minute(Sonnenaufgang) < 10) ZeitSonnenaufgang = ZeitSonnenaufgang + "0";
    ZeitSonnenaufgang = ZeitSonnenaufgang + String(minute(Sonnenaufgang));
    Serial.println(ZeitSonnenaufgang);

    // Sonnenuntergang 
    long Sonnenuntergang = Objekt["current"]["sunset"];
    Serial.print("Sonnenuntergang: ");
    setTime(Sonnenuntergang);  
    String ZeitSonnenuntergang;

    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenuntergang) + 2 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 2) + ":";
    }

    // Normalzeit
    else
    {
      if (hour(Sonnenuntergang) + 1 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 1) + ":";
    }

    if (minute(Sonnenuntergang) < 10) ZeitSonnenuntergang = ZeitSonnenuntergang + "0";
    ZeitSonnenuntergang = ZeitSonnenuntergang + String(minute(Sonnenuntergang));
    Serial.println(ZeitSonnenuntergang);
    Serial.println("-----------------------------");

    tft.setCursor(1, 111);

    // zwischen 0 und 11 Uhr -> Sonnenaufgang anzeigen
    // zwischen 12 und 23 Uhr Sonnenuntergang anzeigen
    switch (Zeit.tm_hour)
    {
      case 0 ... 11:
        tft.print("Sonnenaufgang: " + ZeitSonnenaufgang);
        break;
      case 12 ... 23:
        tft.print("Sonnenuntergang: " + ZeitSonnenuntergang);
        break;
    }
  }

  delay(Intervall);
}

// Wetterdaten holen
String ServerAntwortHolen(const char* OpenweatherServer) 
{
  WiFiClient Client;
  HTTPClient httpClient;

  httpClient.begin(Client, OpenweatherServer);

  // Anfrage senden
  int AntwortCode = httpClient.GET();

  String ServerAntwort = "";

  // Antwort erhalten: Code 200
  if (AntwortCode == 200) 
  {
    // Wetter als String holen, wird später in ein JSON-Objekt umgewandelt
    ServerAntwort = httpClient.getString();

    // Rohdaten anzeigen
    // Serial.println(Serverantwort);
  }

  else 
  {
    Serial.println("Der Server ist nicht erreichbar!");
  }

  httpClient.end();
  return ServerAntwort;
}

TFT 320×240 Pixel

Du musst ab Zei­le 17 die ⇒SPI-Pins des TFT-Dis­plays an den ver­wen­de­ten Mikro­con­trol­ler anpassen.

#ifdef ESP32
  #include "WiFi.h"
  #include "HTTPClient.h"
#else
    #include "ESP8266WiFi.h"
    #include "ESP8266HTTPClient.h"
#endif

#include "Arduino_JSON.h"
#include "time.h"
#include "TimeLib.h"
#include "Adafruit_ILI9341.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

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

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

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;

// Daten für die API von Openweather -> muss angepasst werden
String APIKey = "4d26a936a4fe519ff3678dxxxxxxxxxx";

// lon = longitude = Breitengrad, lat = latitude = Längengrad
// mit Kartenprogramm oder Openweathermap bestimmen
String Koordinaten = "&lat=50.9833&lon=7.133";
String Stadt ="Bergisch Gladbach";

/*
  Aktualisierungs-Intervall
  1000 Zugriffe pro Tag kostenlos
  86.400 Sekunden = 1 Tag -> Abruf alle 86,4 Sekunden möglich
  zu Testzwecken das Intervall kurz halten und später
  auf 10 Minuten (oder länger) setzen
*/
unsigned long Intervall = 600000;

// String für die vom Server gelieferten Daten
String JSONDaten;

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

  Serial.begin(9600);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP anzeigen
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());

  // TFT starten
  tft.begin();

  // Rotation anpassen
  tft.setRotation(1);

  // schwarzer Hintergrund
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);

  tft.setTextSize(2);
}

void loop() 
{
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_GREEN);

  tft.setCursor(1, 5);

  // aktuelle Zeit holen
  time(&aktuelleZeit);

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

  // Tag: führende 0 ergänzen
  if (Zeit.tm_mday < 10) 
  {
    Serial.print("0");
    tft.print("0");
  }
  Serial.print(Zeit.tm_mday);
  Serial.print(".");
  tft.print(Zeit.tm_mday);
  tft.print(".");

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

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

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

  // Minuten
  if (Zeit.tm_min < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_min);
  Serial.print(":");

  // Sekunden
  if (Zeit.tm_sec < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_sec);
  Serial.println();

  // Wetterdaten holen, wenn WiFi verbunden ist
  if (WiFi.status() == WL_CONNECTED) 
  {
     // Name des Servers und Daten übergeben
    String OpenweatherServer = "http://api.openweathermap.org/data/3.0//onecall?" + Koordinaten;
    OpenweatherServer = OpenweatherServer + "&APPID=" + APIKey + "&units=metric&exclude=daily,hourly,minutely";

    // Daten vom Server abrufen
    JSONDaten = ServerAntwortHolen(OpenweatherServer.c_str());

    /*
        parse: Zeichenkette im JSON-Format in ein JavaScript-Objekt umzuwandeln
        damit die Daten (Schlüssel-Wert-Paare)ausgewertet werden können 
        z.B. ["current"] ["temp"]
      */
    JSONVar Objekt = JSON.parse(JSONDaten);

    // Stadt
    Serial.println(Stadt);
    tft.setCursor(1, 30);
    tft.println(Stadt);
    tft.drawFastHLine(1, 47, tft.width(), ILI9341_GREEN);
    tft.setTextColor(ILI9341_WHITE);

    // Temperatur
    Serial.print("Temperatur: ");
    double Temperatur = Objekt["current"]["temp"];
    String AnzeigeTemperatur = String(Temperatur);
    AnzeigeTemperatur.replace(".", ",");
    Serial.print(AnzeigeTemperatur);
    Serial.println("°C");
    tft.setCursor(1, 55);
    tft.print("Temperatur: " + AnzeigeTemperatur + char(247) + "C");

    // Luftdruck
    Serial.print("Luftdruck: ");
    Serial.print(Objekt["current"]["pressure"]);
    Serial.println(" hPa");
    tft.setCursor(1, 80);
    tft.print("Luftdruck: ");
    tft.print(Objekt["current"]["pressure"]);
    tft.println(" hPa");

    // Luftfeuchtigkeit
    Serial.print("Luftfeuchtigkeit: ");
    Serial.print(Objekt["current"]["humidity"]);
    Serial.println("%");
    tft.setCursor(1, 105);
    tft.print("Luftfeuchtigkeit: ");
    tft.print(Objekt["current"]["humidity"]);
    tft.println("%");

    // Windgeschwindigkeit
    Serial.print("Windgeschwindigkeit: ");
    double Windgeschwindigkeit = Objekt["current"]["wind_speed"];
    String AnzeigeWindgeschwindigkeit = String(Windgeschwindigkeit);
    AnzeigeWindgeschwindigkeit.replace(".", ",");
    Serial.print(AnzeigeWindgeschwindigkeit);
    Serial.println(" m/s");
    tft.setCursor(1, 130);

    tft.print("Wind: " + AnzeigeWindgeschwindigkeit);
    tft.println(" m/s");

    // Windrichtung
    Serial.print("Windrichtung: ");
    Serial.print(Objekt["current"]["wind_deg"]);
    Serial.println("°");

    // Wetterlage
    Serial.print("Wetterlage: ");
    String Wetterlage = Objekt["current"]["weather"][0]["main"];
    tft.setCursor(1, 155);
    tft.print("Wetterlage: ");

    if (Wetterlage == "Clear") 
    {
      Serial.println("klarer Himmel");
      tft.print("klarer Himmel");
    }

    if (Wetterlage == "Mist") 
    {
      Serial.println("Nebel");
      tft.print("Nebel");
    }

    if (Wetterlage == "Clouds") 
    {
      Serial.println("wolkig");
      tft.println("wolkig");
    }

    if (Wetterlage == "Rain") 
    {
      Serial.println("Regen");
      tft.println("Regen");
    }

    if (Wetterlage == "Snow") 
    {
      Serial.println("Schneefall");
      tft.println("Schneefall");
    }

    if (Wetterlage == "Drizzle") 
    {
      Serial.println("Nieselregen");
      tft.println("Nieselregen");
    }

    if (Wetterlage == "Thunderstorm") 
    {
      Serial.println("Gewitter");
      tft.println("Gewitter");
    }
    
    // letzte Messung entspricht der gerade ermittelten Zeit
    Serial.print("letzte Messung: ");

    tft.setCursor(1, 180);
    tft.print("letzte Messung: ");

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

    Serial.print(Zeit.tm_hour);
    Serial.print(":");

    tft.print(Zeit.tm_hour);
    tft.print(":");
    
    // Minuten
    if (Zeit.tm_min < 10) 
    {
      tft.print("0");
      Serial.print("0");
    }

    Serial.println(Zeit.tm_min);
    tft.print(Zeit.tm_min);

    // Sonnenaufgang als UNIX-Time
    long Sonnenaufgang = Objekt["current"]["sunrise"];
    Serial.print("Sonnenaufgang: ");

    // Zeit des Sonnenaufgangs setzen
    setTime(Sonnenaufgang);
    String ZeitSonnenaufgang;

    // Uhrzeit bestimmen
    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenaufgang) + 2 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 2) + ":";
    }

    // Normalzeit
    else 
    {
      if (hour(Sonnenaufgang) + 1 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 1) + ":";
    }

    if (minute(Sonnenaufgang) < 10) ZeitSonnenaufgang = ZeitSonnenaufgang + "0";
    ZeitSonnenaufgang = ZeitSonnenaufgang + String(minute(Sonnenaufgang));
    Serial.println(ZeitSonnenaufgang);

    // Sonnenuntergang 
    long Sonnenuntergang = Objekt["current"]["sunset"];
    Serial.print("Sonnenuntergang: ");
    setTime(Sonnenuntergang);  
    String ZeitSonnenuntergang;

    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenuntergang) + 2 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 2) + ":";
    }

    // Normalzeit
    else
    {
      if (hour(Sonnenuntergang) + 1 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 1) + ":";
    }

    if (minute(Sonnenuntergang) < 10) ZeitSonnenuntergang = ZeitSonnenuntergang + "0";
    ZeitSonnenuntergang = ZeitSonnenuntergang + String(minute(Sonnenuntergang));
    Serial.println(ZeitSonnenuntergang);

    Serial.println("-----------------------------");
    
    tft.setCursor(1, 205);

    // zwischen 0 und 11 Uhr -> Sonnenaufgang anzeigen
    // zwischen 12 und 23 Uhr Sonnenuntergang anzeigen
    switch (Zeit.tm_hour)
    {
      case 0 ... 11:
        tft.print("Sonnenaufgang: " + ZeitSonnenaufgang);
        break;
      case 12 ... 23:
        tft.print("Sonnenuntergang: " + ZeitSonnenuntergang);
        break;
    }
  }

  delay(Intervall);
}

String ServerAntwortHolen(const char* OpenweatherServer) 
{
  WiFiClient Client;
  HTTPClient httpClient;

  httpClient.begin(Client, OpenweatherServer);

  // Anfrage senden
  int AntwortCode = httpClient.GET();

  String ServerAntwort = "";

  // Antwort erhalten: Code 200
  if (AntwortCode == 200) 
  {
    // Wetter als String holen, wird später in ein JSON-Objekt umgewandelt
    ServerAntwort = httpClient.getString();

    // Rohdaten anzeigen
    // Serial.println(Serverantwort);
  }

  else 
  {
    Serial.println("Der Server ist nicht erreichbar!");
  }

  httpClient.end();
  return ServerAntwort;
}

ESP32-Wroom/E­SP32-C6 LCD

#include "WiFi.h"
#include "HTTPClient.h"
#include "Arduino_JSON.h"
#include "time.h"
#include "TimeLib.h"
#include "LCDIC2.h"

// 4-zeiliges LCD
LCDIC2 lcd(0x27, 20, 4);

char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxx";

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

// Daten für die API von Openweather -> muss angepasst werden
String APIKey = "4d26a936a4fe519ff3678dxxxxxxxxxx";

// lon = longitude = Breitengrad, lat = latitude = Längengrad
// mit Kartenprogramm oder Openweathermap bestimmen
// Daten für Bergisch Gladbach
String Koordinaten = "&lat=50.9833&lon=7.133";

// nicht länger als 20 Zeichen
String Stadt ="Bergisch Gladbach";

/*
  Aktualisierungs-Intervall
  1000 Zugriffe pro Tag kostenlos
  86.400 Sekunden = 1 Tag -> Abruf alle 86,4 Sekunden möglich
  zu Testzwecken das Intervall kurz halten und später
  auf 10 Minuten (oder länger) setzen
*/
unsigned long Intervall = 600000;

// String für die vom Server gelieferten Rohdaten
String JSONDaten;

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

  Serial.begin(9600);

  // WiFi starten und Verbindung aufbauen
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP anzeigen
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());

   // LCD starten
  lcd.begin();

  // Cursor "verstecken"
  lcd.setCursor(false);
}

String ServerAntwortHolen(const char* OpenweatherServer) 
{
  WiFiClient Client;
  HTTPClient httpClient;

  httpClient.begin(Client, OpenweatherServer);

  // Anfrage senden
  int AntwortCode = httpClient.GET();

  String ServerAntwort = "";

  // Antwort erhalten: Code 200
  if (AntwortCode == 200) 
  {
    // Wetter als String holen, wird später in ein JSON-Objekt umgewandelt
    ServerAntwort = httpClient.getString();

    // Rohdaten anzeigen
    // Serial.println(Serverantwort);
  }

  else 
  {
    Serial.println("Der Server ist nicht erreichbar!");
  }

  httpClient.end();
  return ServerAntwort;
}

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

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

  // Tag: führende 0 ergänzen
  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 des Monats beginnt mit 0 -> 1 hinzufügen
  Serial.print(Zeit.tm_mon + 1);
  Serial.print(".");

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

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

  // Minuten
  // wenn Minute < 10 -> 0 davor setzen
  if (Zeit.tm_min < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_min);
  Serial.print(":");

  // Sekunden
  if (Zeit.tm_sec < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_sec);
  Serial.println();

  // Wetterdaten holen, wenn WiFi verbunden ist
  if (WiFi.status() == WL_CONNECTED) 
  {
    // Name des Servers und Daten übergeben
    String OpenweatherServer = "http://api.openweathermap.org/data/3.0//onecall?" + Koordinaten;
    OpenweatherServer = OpenweatherServer + "&APPID=" + APIKey + "&units=metric&exclude=daily,hourly,minutely";

    // Server anzeigen
    // Serial.println(OpenweatherServer);
    
    // Daten vom Server abrufen
    // c_str() liefert einen mit \0 beendeten String
    JSONDaten = ServerAntwortHolen(OpenweatherServer.c_str());

    /*
        parse: Zeichenkette im JSON-Format in ein JavaScript-Objekt umzuwandeln
        damit die Daten (Schlüssel-Wert-Paare)ausgewertet werden können 
        z.B. ["current"] ["temp"]
      */
    JSONVar Objekt = JSON.parse(JSONDaten);

    // Stadt
    Serial.println(Stadt);
    lcd.setCursor(0, 0);
    lcd.print(Stadt);

    // Temperatur
    Serial.print("Temperatur: ");
    double Temperatur = Objekt["current"]["temp"];
    String AnzeigeTemperatur = String(Temperatur);
    AnzeigeTemperatur.replace(".", ",");
    Serial.print(AnzeigeTemperatur);
    Serial.println("°C");
    lcd.setCursor(0, 1);
    lcd.print(AnzeigeTemperatur + "\337C");

    // Luftdruck
    int Luftdruck = Objekt["current"]["pressure"];
    Serial.print("Luftdruck: ");
    Serial.println(String(Luftdruck) + " hPa");
    lcd.setCursor(10, 1);
    lcd.print(String(Luftdruck) + " hPa");

    // Luftfeuchtigkeit
    int Luftfeuchtigkeit = Objekt["current"]["humidity"];
    Serial.print("Luftfeuchtigkeit: ");
    Serial.println(String(Luftfeuchtigkeit) + "%");
    lcd.setCursor(0, 2);
    lcd.print(String(Luftfeuchtigkeit) + "%");

    // Windgeschwindigkeit
    Serial.print("Windgeschwindigkeit: ");
    double Windgeschwindigkeit = Objekt["current"]["wind_speed"];
    String AnzeigeWindgeschwindigkeit = String(Windgeschwindigkeit);
    AnzeigeWindgeschwindigkeit.replace(".", ",");
    Serial.print(AnzeigeWindgeschwindigkeit);
    Serial.println(" m/s");

    // Windrichtung
    Serial.print("Windrichtung: ");
    Serial.print(Objekt["current"]["wind_deg"]);
    Serial.println("°");

    // Wetterlage
    Serial.print("Wetterlage: ");
    String Wetterlage = Objekt["current"]["weather"][0]["main"];
    lcd.setCursor(5, 2);
    if (Wetterlage == "Clear") 
    {
      Serial.println("klarer Himmel");
      lcd.print("klarer Himmel");
    }

    if (Wetterlage == "Mist") 
    {
      Serial.println("Nebel");
      lcd.print("Nebel");
    }

    if (Wetterlage == "Clouds") 
    {
      Serial.println("wolkig");
      lcd.print("wolkig");
    }

    if (Wetterlage == "Rain") 
    {
      Serial.println("Regen");
      lcd.print("Regen");
    }

    if (Wetterlage == "Snow") 
    {
      Serial.println("Schneefall");
      lcd.print("Schneefall");
    }

    if (Wetterlage == "Drizzle") 
    {
      Serial.println("Nieselregen");
      lcd.print("Nieselregen");
    }

    if (Wetterlage == "Thunderstorm") 
    {
      Serial.println("Gewitter");
      lcd.print("Gewitter");
    }

    // Sonnenaufgang als UNIX-Time
    long Sonnenaufgang = Objekt["current"]["sunrise"];
    Serial.print("Sonnenaufgang: ");

    // Zeit des Sonnenaufgangs setzen
    setTime(Sonnenaufgang);
    String ZeitSonnenaufgang;

    // Uhrzeit bestimmen
    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenaufgang) + 2 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 2) + ":";
    }

    // Normalzeit
    else 
    {
      if (hour(Sonnenaufgang) + 1 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 1) + ":";
    }

    if (minute(Sonnenaufgang) < 10) ZeitSonnenaufgang = ZeitSonnenaufgang + "0";
    ZeitSonnenaufgang = ZeitSonnenaufgang + String(minute(Sonnenaufgang));
    Serial.println(ZeitSonnenaufgang);

    // Sonnenuntergang 
    long Sonnenuntergang = Objekt["current"]["sunset"];
    Serial.print("Sonnenuntergang: ");
    setTime(Sonnenuntergang);  
    String ZeitSonnenuntergang;

    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenuntergang) + 2 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 2) + ":";
    }

    // Normalzeit
    else
    {
      if (hour(Sonnenuntergang) + 1 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 1) + ":";
    }
    ZeitSonnenuntergang = ZeitSonnenuntergang + String(minute(Sonnenuntergang));
    Serial.println(ZeitSonnenuntergang);

    // letzte Messung 
    long letzteMessung = Objekt["current"]["dt"];
    Serial.print("letzte Messung: ");
    setTime(letzteMessung);  
    String ZeitLetzteMessung;
    
    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(letzteMessung) + 2 < 10) ZeitLetzteMessung = "0";
      ZeitLetzteMessung = ZeitLetzteMessung + String(hour(letzteMessung) + 2) + ":";
    }

    // Normalzeit
    else 
    {
      if (hour(letzteMessung) + 1 < 10) ZeitLetzteMessung = "0";
      ZeitLetzteMessung = ZeitLetzteMessung + String(hour(letzteMessung) + 1) + ":";
    }
    
    if (minute(letzteMessung) < 10) ZeitLetzteMessung = ZeitLetzteMessung + "0";
    ZeitLetzteMessung = ZeitLetzteMessung + String(minute(letzteMessung));
    Serial.println(ZeitLetzteMessung);
    Serial.println("-----------------------------");
    lcd.setCursor(0, 3);
    lcd.print("aktualisiert: " + ZeitLetzteMessung);
  }

  delay(Intervall);
}

Ide­aS­park ESP32-Wroom mit TFT 1,9 Zoll

Zusätz­lich benö­tig­te Bibliothek

#include "WiFi.h"
#include "HTTPClient.h"
#include "Arduino_JSON.h"
#include "time.h"
#include "TimeLib.h"
#include "Adafruit_ST7789.h"
#include "U8g2_for_Adafruit_GFX.h"

#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;

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;

// Daten für die API von Openweather -> muss angepasst werden
String APIKey = "4d26a936a4fe519ff3678dxxxxxxxxxx";

// lon = longitude = Breitengrad, lat = latitude = Längengrad
// mit Kartenprogramm oder Openweathermap bestimmen
String Koordinaten = "&lat=50.99111161485325&lon=7.129065378199176";
String Stadt ="Bergisch Gladbach";

/*
  Aktualisierungs-Intervall
  1000 Zugriffe pro Tag kostenlos
  86.400 Sekunden = 1 Tag -> Abruf alle 86,4 Sekunden möglich
  zu Testzwecken das Intervall kurz halten und später
  auf 10 Minuten (oder länger) setzen
*/
unsigned long Intervall = 600000;

// String für die vom Server gelieferten Rohdaten
String JSONDaten;

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

  Serial.begin(9600);

  // WiFi starten und Verbindung aufbauen
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP anzeigen
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());

   // TFT starten schwarzer Hintergrund
  tft.init(170, 320);

  // Rotation anpassen Querformat
  tft.setRotation(1);
}

void loop() 
{
  tft.fillScreen(ST77XX_BLACK);
  u8g2Schriften.setForegroundColor(ST77XX_GREEN);   
  u8g2Schriften.setBackgroundColor(ST77XX_BLACK);
  u8g2Schriften.setFont(u8g2_font_t0_17b_tf);   
  u8g2Schriften.setCursor(1, 15);

  // aktuelle Zeit holen
  time(&aktuelleZeit);

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

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

  // Zählung des Monats beginnt mit 0 -> 1 hinzufügen
  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);
  u8g2Schriften.print(" ");

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

  // Minuten
  // wenn Minute < 10 -> 0 davor setzen
  if (Zeit.tm_min < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_min);
  Serial.print(":");

  // Sekunden
  if (Zeit.tm_sec < 10) 
  {
    Serial.print("0");
  }
  Serial.print(Zeit.tm_sec);
  Serial.println();

  // Wetterdaten holen, wenn WiFi verbunden ist
  if (WiFi.status() == WL_CONNECTED) 
  {
    // Name des Servers und Daten übergeben
    String OpenweatherServer = "http://api.openweathermap.org/data/3.0//onecall?" + Koordinaten;
    OpenweatherServer = OpenweatherServer + "&APPID=" + APIKey + "&units=metric&exclude=daily,hourly,minutely";

    // Server anzeigen
    // Serial.println(OpenweatherServer);
    
    // Daten vom Server abrufen
    // c_str() liefert einen mit \0 beendeten String
    JSONDaten = ServerAntwortHolen(OpenweatherServer.c_str());

    /*
        parse: Zeichenkette im JSON-Format in ein JavaScript-Objekt umzuwandeln
        damit die Daten (Schlüssel-Wert-Paare)ausgewertet werden können 
        z.B. ["current"] ["temp"]
      */
    JSONVar Objekt = JSON.parse(JSONDaten);

    // Stadt
    Serial.println(Stadt);
    u8g2Schriften.setCursor(1, 33);
    u8g2Schriften.println(Stadt);
    tft.drawFastHLine(1, 38, tft.width(), ST77XX_GREEN);
    u8g2Schriften.setForegroundColor(ST77XX_WHITE);   

    // Temperatur
    Serial.print("Temperatur: ");
    double Temperatur = Objekt["current"]["temp"];
    String AnzeigeTemperatur = String(Temperatur);
    AnzeigeTemperatur.replace(".", ",");
    Serial.print(AnzeigeTemperatur);
    Serial.println("°C");
    u8g2Schriften.setCursor(1, 53);
    u8g2Schriften.print("Temperatur: " + AnzeigeTemperatur + "°C");

    // Luftdruck
    Serial.print("Luftdruck: ");
    Serial.print(Objekt["current"]["pressure"]);
    Serial.println(" hPa");
    u8g2Schriften.setCursor(1, 71);
    u8g2Schriften.print("Luftdruck: ");
    u8g2Schriften.print(Objekt["current"]["pressure"]);
    u8g2Schriften.println(" hPa");

    // Luftfeuchtigkeit
    Serial.print("Luftfeuchtigkeit: ");
    Serial.print(Objekt["current"]["humidity"]);
    Serial.println("%");
    u8g2Schriften.setCursor(1, 89);
    u8g2Schriften.print("Luftfeuchtigkeit: ");
    u8g2Schriften.print(Objekt["current"]["humidity"]);
    u8g2Schriften.println("%");

    // Windgeschwindigkeit
    Serial.print("Windgeschwindigkeit: ");
    double Windgeschwindigkeit = Objekt["current"]["wind_speed"];
    String AnzeigeWindgeschwindigkeit = String(Windgeschwindigkeit);
    AnzeigeWindgeschwindigkeit.replace(".", ",");
    Serial.print(AnzeigeWindgeschwindigkeit);
    Serial.println(" m/s");
    u8g2Schriften.setCursor(1, 107);
    u8g2Schriften.print("Wind: " + AnzeigeWindgeschwindigkeit);
    u8g2Schriften.println(" m/s");

    // Windrichtung
    Serial.print("Windrichtung: ");
    Serial.print(Objekt["current"]["wind_deg"]);
    Serial.println("°");

    // Wetterlage
    Serial.print("Wetterlage: ");
    String Wetterlage = Objekt["current"]["weather"][0]["main"];
    u8g2Schriften.setCursor(1, 125);
    u8g2Schriften.print("Wetterlage: ");
    if (Wetterlage == "Clear") 
    {
      Serial.println("klarer Himmel");
      u8g2Schriften.print("klarer Himmel");
    }

    if (Wetterlage == "Mist") 
    {
      Serial.println("Nebel");
      u8g2Schriften.print("Nebel");
    }

    if (Wetterlage == "Clouds") 
    {
      Serial.println("wolkig");
      u8g2Schriften.println("wolkig");
    }

    if (Wetterlage == "Rain") 
    {
      Serial.println("Regen");
      u8g2Schriften.println("Regen");
    }

    if (Wetterlage == "Snow") 
    {
      Serial.println("Schneefall");
      u8g2Schriften.println("Schneefall");
    }

    if (Wetterlage == "Drizzle") 
    {
      Serial.println("Nieselregen");
      u8g2Schriften.println("Nieselregen");
    }

    if (Wetterlage == "Thunderstorm") 
    {
      Serial.println("Gewitter");
      u8g2Schriften.println("Gewitter");
    }

    // letzte Messung entspricht der gerade ermittelten Zeit
    Serial.print("letzte Messung: ");

    u8g2Schriften.setCursor(1, 143);
    u8g2Schriften.print("letzte Messung: ");

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

    Serial.print(Zeit.tm_hour);
    Serial.print(":");

    u8g2Schriften.print(Zeit.tm_hour);
    u8g2Schriften.print(":");
    
    // Minuten
    if (Zeit.tm_min < 10) 
    {
      u8g2Schriften.print("0");
      Serial.print("0");
    }

    Serial.println(Zeit.tm_min);
    u8g2Schriften.print(Zeit.tm_min);

    // Sonnenaufgang als UNIX-Time
    long Sonnenaufgang = Objekt["current"]["sunrise"];
    Serial.print("Sonnenaufgang: ");

    // Zeit des Sonnenaufgangs setzen
    setTime(Sonnenaufgang);
    String ZeitSonnenaufgang;

    // Uhrzeit bestimmen
    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenaufgang) + 2 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 2) + ":";
    }

    // Normalzeit
    else 
    {
      if (hour(Sonnenaufgang) + 1 < 10) ZeitSonnenaufgang = "0";
      ZeitSonnenaufgang = ZeitSonnenaufgang + String(hour(Sonnenaufgang) + 1) + ":";
    }

    if (minute(Sonnenaufgang) < 10) ZeitSonnenaufgang = ZeitSonnenaufgang + "0";
    ZeitSonnenaufgang = ZeitSonnenaufgang + String(minute(Sonnenaufgang));
    Serial.println(ZeitSonnenaufgang);

    // Sonnenuntergang 
    long Sonnenuntergang = Objekt["current"]["sunset"];
    Serial.print("Sonnenuntergang: ");
    setTime(Sonnenuntergang);  
    String ZeitSonnenuntergang;

    // Sommerzeit
    if(Zeit.tm_isdst > 0)
    {
      if (hour(Sonnenuntergang) + 2 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 2) + ":";
    }

    // Normalzeit
    else
    {
      if (hour(Sonnenuntergang) + 1 < 10) ZeitSonnenuntergang = "0";
      ZeitSonnenuntergang = ZeitSonnenuntergang + String(hour(Sonnenuntergang) + 1) + ":";
    }

    if (minute(Sonnenuntergang) < 10) ZeitSonnenuntergang = ZeitSonnenuntergang + "0";
    ZeitSonnenuntergang = ZeitSonnenuntergang + String(minute(Sonnenuntergang));
    Serial.println(ZeitSonnenuntergang);
    Serial.println("-----------------------------");

    u8g2Schriften.setCursor(1, 161);

    // zwischen 0 und 11 Uhr -> Sonnenaufgang anzeigen
    // zwischen 12 und 23 Uhr Sonnenuntergang anzeigen
    switch (Zeit.tm_hour)
    {
      case 0 ... 11:
        u8g2Schriften.print("Sonnenaufgang: " + ZeitSonnenaufgang);
        break;
      case 12 ... 23:
        u8g2Schriften.print("Sonnenuntergang: " + ZeitSonnenuntergang);
        break;
    }
  }

  delay(Intervall);
}

// Wetterdaten holen
String ServerAntwortHolen(const char* OpenweatherServer) 
{
  WiFiClient Client;
  HTTPClient httpClient;

  httpClient.begin(Client, OpenweatherServer);

  // Anfrage senden
  int AntwortCode = httpClient.GET();

  String ServerAntwort = "";

  // Antwort erhalten: Code 200
  if (AntwortCode == 200) 
  {
    // Wetter als String holen, wird später in ein JSON-Objekt umgewandelt
    ServerAntwort = httpClient.getString();

    // Rohdaten anzeigen
    // Serial.println(Serverantwort);
  }

  else 
  {
    Serial.println("Der Server ist nicht erreichbar!");
  }

  httpClient.end();
  return ServerAntwort;
}

Letzte Aktualisierung: Apr. 7, 2025 @ 14:29