Skip to Content

Automatische Uhr mit Sommerzeitumstellung

Automatische Uhr mit Sommerzeitumstellung

Nervt es dich auch, zweimal im Jahr alle Uhren auf Sommer- und Winterzeit umzustellen? Dann ist dieser Artikel genau das Richtige für dich! Ich zeige dir, wie du eine digitale Uhr baust, die sich automatisch anpasst. Außerdem bekommst du eine Uhr, die immer die genaue Zeit anzeigt.

Indem wir die Uhr per WLAN mit einem Internet-Zeitserver synchronisieren, stellen wir sicher, dass unsere Uhr immer die richtige Zeit anzeigt – egal ob sich die Sommerzeit ändert oder wir in eine andere Zeitzone reisen. Zusätzlich lernst du, wie man JSON- und Datumszeit-Strings ausliest und die Zeit auf einem LCD-Display anzeigt.

Ich verwende für dieses Projekt ein ESP32-C3 SuperMini, aber jeder ESP32, ESP8266 oder ein Arduino mit WiFi-Shield funktioniert genauso.

Los geht’s!

Benötigte Teile

Hier sind die benötigten Teile für das Projekt. Anstelle des unten aufgeführten ESP32-C3 Mini Development Boards habe ich ein sehr ähnliches Board verwendet, das ESP32-C3 SuperMini von AliExpress heißt. Meins hatte nur eine einfarbige eingebaute LED, während das untenstehende Board eine RGB-LED besitzt. Abgesehen davon sollten sie fast identisch sein und beide funktionieren.

ESP32-C3 Mini

USB-C-Kabel

LCD 16×2

Dupont wire set

Dupont-Kabelset

Half_breadboard56a

Breadboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Sommerzeit (Daylight Savings Time)

Die Sommerzeit (DST) ist eine Praxis, bei der die Uhr während der Sommermonate um eine Stunde vorgestellt wird, um abends mehr Tageslicht zu haben. Das soll Energie sparen und das Tageslicht besser nutzen. Allerdings gilt die Sommerzeit nicht in allen Ländern oder Regionen, und die Start- und Enddaten variieren.

Die meisten Länder stellen die Zeit um 1 Uhr oder 2 Uhr um und verschieben sie dann um eine Stunde. Es gibt aber auch Sonderfälle, wie Lord Howe Island (Australien), das nur um 30 Minuten umstellt, Kuba stellt um Mitternacht um und manche Länder wechseln um 1 Uhr UTC statt 1 Uhr Ortszeit. Einen kompletten Überblick findest du im Wikipedia-Artikel: Daylight saving time by country.

Damit unsere digitale Uhr die Sommerzeit automatisch anpasst, müssen wir eine Mechanik einbauen, die die DST-Regeln der jeweiligen Zeitzone berücksichtigt. Da die Regeln aber von Land zu Land sehr unterschiedlich sind, ist es ziemlich aufwendig, die Sommerzeit-Anpassung selbst zu programmieren. Deshalb verlassen wir uns auf einen Internet-Zeitserver, der das alles für uns übernimmt.

Wenn wir unsere Uhr mit einem Internet-Zeitserver synchronisieren, bekommen wir die aktuelle Zeit zusammen mit Zusatzinfos wie Zeitzone und ob gerade Sommerzeit gilt. Diese Infos werden meist in einem JSON format geliefert, den wir auslesen müssen, um die relevanten Daten zu extrahieren.

Im nächsten Abschnitt schauen wir uns einige Internet-Zeitserver an, wie man sich mit ihnen verbindet und wie deren JSON-Format aussieht.

Internet-Zeitserver

In diesem Abschnitt besprechen wir kurz drei Internet-Zeitserver, wie man deren APIs nutzt und welche Infos im JSON-Output enthalten sind. Außerdem erzähle ich dir etwas über das Network Time Protocol (NTP), das eine gute Alternative ist.

WorldTimeAPI

WorldTimeAPI ist ein einfacher Webservice, der die aktuelle Zeit entweder als Plain-Text oder als JSON zurückgibt. Du kannst diese Website nutzen, um die Zeit für eine bestimmte Zeitzone oder basierend auf der IP-Adresse deines Computers zu bekommen. Wir nutzen Letzteres. Das ist einfacher und unsere Uhr passt sich dann nicht nur automatisch an die Sommerzeit an, sondern auch, wenn sie in eine andere Zeitzone gebracht wird.

WorldTimeAPI auszuprobieren ist ganz einfach. Klicke einfach auf diesen Link: http://worldtimeapi.org/api/ip oder gib ihn in die Adresszeile deines Browsers ein. Du musst deine IP-Adresse nicht explizit angeben. Der Webservice erkennt sie automatisch anhand der Anfrage. Im Browser bekommst du dann eine Ausgabe ähnlich wie die folgende (ich habe sie etwas formatiert und meine IP-Adresse unkenntlich gemacht):

{
    "abbreviation": "AEDT",
    "client_ip": "122.150.000.000",
    "datetime": "2023-11-16T12:09:46.409360+11:00",
    "day_of_week": 4,
    "day_of_year": 320,
    "dst": true,
    "dst_from": "2023-09-30T16:00:00+00:00",
    "dst_offset": 3600,
    "dst_until": "2024-04-06T16:00:00+00:00",
    "raw_offset": 36000,
    "timezone": "Australia/Melbourne",
    "unixtime": 1700096986,
    "utc_datetime": "2023-11-16T01:09:46.409360+00:00",
    "utc_offset": "+11:00",
    "week_number": 46
}

Diese Ausgabe ist im JSON-Format. Sie enthält noch weitere Informationen außer der aktuellen Zeit. Uns interessiert aber vor allem das datetime -Feld, das uns die aktuelle Ortszeit liefert. In diesem Beispiel ist es "2023-11-16T12:09:46.409360+11:00".

Jedes Mal, wenn du diesen Link aufrufst, bekommst du die aktuelle Zeit. Achte aber darauf, den Link nicht zu oft aufzurufen, sonst könntest du gesperrt werden!

WorldTimeAPI ist der Internet-Zeitserver, den wir für unsere Uhr verwenden. Ich stelle dir aber auch zwei Alternativen vor, die etwas andere Informationen liefern und vielleicht besser zu deinem Anwendungsfall passen.

timezonedb

Timezonedb bietet mehrere APIs, mit denen du Zeitzoneninformationen abrufen kannst. Es gibt aber auch einen Service, der die aktuelle Zeit liefert. Dafür musst du dich allerdings registrieren, um einen API_KEY zu bekommen, mit dem du den Service nutzen kannst. Es gibt einen kostenlosen Plan und sobald du deinen API_KEY hast, kannst du folgenden Link nutzen, um Zeitinformationen im JSON-Format zu erhalten:

http://api.timezonedb.com/v2/get-time-zone?key=API_KEY&format=json&by=zone&zone=Australia/Melbourne

Leider musst du eine Zeitzone angeben. Um nach IP-Adresse abzufragen, brauchst du den kostenpflichtigen Premium-Plan.

{
    "status": "OK",
    "message": "",
    "countryCode": "AU",
    "countryName": "Australia",
    "regionName": "",
    "cityName": "",
    "zoneName": "Australia\/Melbourne",
    "abbreviation": "AEDT",
    "gmtOffset": 39600,
    "dst": "1",
    "zoneStart": 1696089600,
    "zoneEnd": 1712419199,
    "nextAbbreviation": "AEST",
    "timestamp": 1700145739,
    "formatted": "2023-11-16 14:42:19"
}

Der Vorteil dieses Services ist aber, dass er eine schön formatierte Zeit-String zurückgibt, die leicht zu verwenden ist. Siehe das formatted -Feld oben.

ipgeolocation

Als dritte Option gibt es ipgeolocation. Auch hier musst du dich registrieren, um einen API_KEY zu bekommen. Aber der kostenlose Entwickler-Plan ist sehr großzügig mit 1.000 täglichen und 30.000 monatlichen Anfragen – das reicht locker. Hier ist der Link, um Zeitinfos basierend auf deiner IP-Adresse zu bekommen: https://api.ipgeolocation.io/timezone?apiKey=API_KEY. Natürlich musst du deinen eigenen API_KEY eintragen.

Die zurückgegebenen Informationen sind sehr umfangreich und enthalten nicht nur die Zeit, sondern auch die Geolokation des Anfragenden. Wie du siehst, wohne ich aktuell in Melbourne, Australien.

{
    "geo": {
        "country_code2": "AU",
        "country_code3": "AUS",
        "country_name": "Australia",
        "country_name_official": "Commonwealth of Australia",
        "state_prov": "Victoria",
        "state_code": "AU-VIC",
        "district": "",
        "city": "Melbourne",
        "zipcode": "3004",
        "latitude": "-37.8",
        "longitude": "144.9"
    },
    "timezone": "Australia/Melbourne",
    "timezone_offset": 10,
    "timezone_offset_with_dst": 11,
    "date": "2023-11-16",
    "date_time": "2023-11-16 14:57:36",
    "date_time_txt": "Thursday, November 16, 2023 14:57:36",
    "date_time_wti": "Thu, 16 Nov 2023 14:57:36 +1100",
    "date_time_ymd": "2023-11-16T14:57:36+1100",
    "date_time_unix": 1700107056.275,
    "time_24": "14:57:36",
    "time_12": "02:57:36 PM",
    "week": 46,
    "month": 11,
    "year": 2023,
    "year_abbr": "23",
    "is_dst": true,
    "dst_savings": 1
}

ipgeolocation ist mein bevorzugter Zeitserver, weil die Datums- und Zeitangaben sehr praktisch formatiert sind (siehe die Felder date_time, date_time_txt und date_time_wti) und es viele Zusatzdaten gibt.

Um es aber so einfach wie möglich zu halten, verwende ich im Beispiel WorldTimeAPI, da du dich dort nicht registrieren musst.

Network Time Protocol

Abschließend noch ein Wort zum Network Time Protocol (NTP): „Das Network Time Protocol (NTP) ist ein networking protocol zur clock synchronization zwischen Computersystemen über packet-switched, variable latency Datennetze.“ (Quelle: Wikipedia).

Es ist speziell dafür entwickelt, Uhren sehr genau zu synchronisieren, ist aber recht komplex und schwierig zu verwenden. Schau dir dazu die TimeNTP library und die example code an.

Es gibt aber auch das SNTP (Simple Network Time Protocol), eine vereinfachte Version von NTP. Sie ist zwar weniger präzise, liefert aber immer noch Zeiten mit einer Genauigkeit von etwa 100 Millisekunden. Die Nutzung ist viel einfacher und wenn du mehr darüber wissen willst, schau dir unser How to synchronize ESP32 clock with SNTP server -Tutorial an.

Im nächsten Abschnitt zeige ich dir, wie du ein LCD-Display an den ESP32 anschließt, damit wir Zeit und Datum schön anzeigen können.

Anschließen der Bauteile

Wir brauchen ein Display, um die Zeit unserer Uhr anzuzeigen. Im Prinzip geht jedes Display, aber der Einfachheit halber nehmen wir ein 16×2 LCD-Display, das per I2C angeschlossen wird. Für mehr Infos zu LCD-Displays schau dir unsere Tutorials zu How to use a 16×2 character LCD with Arduino und Character I2C LCD with Arduino Tutorial (8 Examples) an.

Das LCD-Display an den ESP32 anzuschließen ist ganz einfach. Verbinde zuerst 5V mit VCC und G mit Ground. Dann verbinde SDA mit Pin 8 (gelbes Kabel) und SCL mit Pin 9 (oranges Kabel) am ESP32.

Connecting LCD display via I2C to ESP32
LCD-Display per I2C an ESP32 anschließen

Achte darauf, SDA und SCL richtig zu verbinden. Wenn du ein anderes Board verwendest, solltest du die Pins wählen, die auf deinem Board I2C unterstützen. Suche einfach nach den Pins, die mit SDA und SCL im Pinout markiert sind. Hier ist das Pinout für das ESP32-C3 Supermini, das ich in diesem Projekt verwende:

Pinout for the ESP32-C3 Supermini
Pinout für das ESP32-C3 Supermini

Obwohl GPIO8 und GPIO9 eigentlich die Standardpins für I2C sind, musste ich sie im Code unten explizit setzen, damit es funktioniert.

Hier ein Bild, wie unsere automatische Sommerzeit-Uhr in echt aussieht, wenn alles verkabelt ist und der Code läuft.

The Automatic Daylight Savings Time Clock
Die automatische Sommerzeit-Uhr

Falls du mehr Infos zum SuperMini-Board brauchst, das ich hier verwende, schau dir das ESP32-C3 SuperMini Board -Tutorial an.

Code für die Uhr

In diesem Abschnitt schreiben wir den Code für unsere automatische Sommerzeit-Uhr. Es sind 5 Schritte nötig.

Zuerst müssen wir die Zeit prüfen und entscheiden, ob wir synchronisieren wollen, zum Beispiel einmal pro Stunde. Falls ja, laden wir die Zeitinfos vom Internet-Zeitserver herunter. Diese Daten kommen im JSON-Format. Wir müssen sie also parsen und die Zeit extrahieren.

Sobald wir die Zeit haben, stellen wir die interne Uhr des ESP32 und zeigen die Zeit auf dem LCD an. Der folgende Code macht all das. Schau ihn dir kurz an, ich erkläre die Details im Text darunter.

// makerguides.com: Automatic Daylight Savings Time Clock

#include "WiFi.h"
#include "stdarg.h"
#include "HTTPClient.h"
#include "ArduinoJson.h"
#include "TimeLib.h"
#include "LiquidCrystal_I2C.h"
#include "Wire.h"

#define SDA 8
#define SCL 9
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASSPHRASE "YOUR_WIFI_PASSWORD"
#define URL "http://worldtimeapi.org/api/ip"

StaticJsonDocument<2048> doc;
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x3F, 16, 2);  

void lcd_print_time() {
  time_t t = now();
  char buff[24];
  sprintf(buff, "%d:%02d:%02d ", hour(t), minute(t), second(t));
  lcd.setCursor(3, 0);
  lcd.print(buff);
  sprintf(buff, "%02d-%02d-%04d ", day(t), month(t), year(t));
  lcd.setCursor(3, 1);
  lcd.print(buff);
}

bool should_sync_time() {
  time_t t = now();
  bool wifi_on = WiFi.status() == WL_CONNECTED;
  bool should_sync = (minute(t) == 0 && second(t) == 3) || (year(t) == 1970);
  return wifi_on && should_sync;
}

void sync_time() {
  delay(1000);
  HTTPClient http;
  http.begin(URL);
  if (http.GET() > 0) {
    String json = http.getString();
    auto error = deserializeJson(doc, json);
    if (!error) {
      int Y, M, D, h, m, s, ms, tzh, tzm;
      sscanf(doc["datetime"], "%d-%d-%dT%d:%d:%d.%d+%d:%d",
             &Y, &M, &D, &h, &m, &s, &ms, &tzh, &tzm);   
      setTime(h, m, s, D, M, Y);
    }
  }
  http.end();
}

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA, SCL);  // I2C for ESP32-C3 Supermini
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSPHRASE);
  while (WiFi.status() != WL_CONNECTED) 
    delay(500);
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void loop() {
  if (should_sync_time())
    sync_time();
  lcd_print_time();
  delay(100);
}

Jetzt schauen wir uns die einzelnen Teile des Codes genauer an und verstehen, wie alles funktioniert.

Konstanten und Bibliotheken

Wir beginnen damit, die nötigen Bibliotheken für dieses Projekt einzubinden, wie „ WiFi.h “, „ HTTPClient.h “, „ ArduinoJson.h “, „ TimeLib.h “ und „ LiquidCrystal_I2C.h “. Diese Bibliotheken stellen die benötigten Funktionen für WLAN, HTTP-Anfragen, JSON-Parsing, Zeitverwaltung und LCD-Steuerung bereit.

Du musst die Bibliotheken install ArduinoJson, TimeLib und LiquidCrystal_I2C installieren. Die anderen sind Teil der ESP32/Arduino-Standardbibliothek.

#include "WiFi.h"
#include "stdarg.h"
#include "HTTPClient.h"
#include "ArduinoJson.h"
#include "TimeLib.h"
#include "LiquidCrystal_I2C.h"
#include "Wire.h"

Als Nächstes definieren wir die Pins (SDA, SCL) für das I2C-Interface sowie WLAN-SSID und Passwort für die Verbindung zum Netzwerk. Ersetze „YOUR_WIFI_SSID“ und „YOUR_WIFI_PASSWORD“ durch deine echten Zugangsdaten.

#define SDA 8
#define SCL 9
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASSPHRASE "YOUR_WIFI_PASSWORD"

Wir definieren außerdem die URL der Internet-Zeitserver-API, die wir zur Synchronisierung der Uhr verwenden. In diesem Beispiel nutzen wir „ http://worldtimeapi.org/api/ip “, aber du kannst sie durch einen der anderen oben genannten Zeitserver ersetzen. Da das Datenformat unterschiedlich ist, musst du dann aber auch den Parsing-Code anpassen.

#define URL "http://worldtimeapi.org/api/ip"

Wir erstellen dann ein statisches JSON-Dokument mit einer Kapazität von 2048 Bytes, um die Antwort des Zeitservers zu speichern. Ist die Antwort größer, gibt es einen Fehler. Wenn du also eine andere API verwendest, die mehr Daten liefert, erhöhe diesen Wert entsprechend.

StaticJsonDocument<2048> doc;

Wir initialisieren das LCD-Display mit LiquidCrystal_I2C library. Die Parameter im LiquidCrystal_I2C-Konstruktor geben die I2C-Adresse des Displays (0x3F) sowie die Anzahl der Spalten und Zeilen (16 und 2) an. Wenn du ein 20×4-LCD verwendest, musst du das anpassen. Manche Displays haben auch die I2C-Adresse 0x27 statt 0x3F.

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x3F, 16, 2);

Hilfsfunktionen

Es ist immer gut, komplexen Code in kleinere, besser handhabbare Funktionen zu unterteilen. Ich habe drei Hilfsfunktionen implementiert: um die Zeit auf dem LCD anzuzeigen, zu prüfen, ob synchronisiert werden muss, und um die aktuelle Zeit herunterzuladen.

lcd_print_time

Die Hilfsfunktion lcd_print_time() zeigt die aktuelle Zeit auf dem LCD-Display an. Sie holt sich die aktuelle Zeit mit der now() -Funktion aus der TimeLib library und formatiert sie mit der sprintf() -Funktion als String. Der formatierte Zeit-String wird dann mit der lcd.print() -Funktion auf dem LCD angezeigt. Wir schreiben in Spalte 3 und die Zeilen 0 und 1, damit der Text schön zentriert ist.

void lcd_print_time() {
  time_t t = now();
  char buff[24];
  sprintf(buff, "%d:%02d:%02d ", hour(t), minute(t), second(t));
  lcd.setCursor(3, 0);
  lcd.print(buff);
  sprintf(buff, "%02d-%02d-%04d ", day(t), month(t), year(t));
  lcd.setCursor(3, 1);
  lcd.print(buff);
}

should_sync_time

Wir definieren eine weitere Hilfsfunktion namens should_sync_time(), die prüft, ob die Uhr mit dem Internet-Zeitserver synchronisiert werden soll.

Sie prüft, ob die aktuelle Minute null und die Sekunde drei ist oder ob das aktuelle Jahr 1970 ist. Das heißt, wir synchronisieren jede Stunde und zwar 3 Sekunden nach der vollen Stunde, um eventuelle Sommerzeit-Umstellungen zu erwischen, die zur vollen Stunde passieren. Im schlimmsten Fall geht unsere Uhr dann 3 Sekunden nach.

bool should_sync_time() {
  time_t t = now();
  bool wifi_on = WiFi.status() == WL_CONNECTED;
  bool should_sync = (minute(t) == 0 && second(t) == 3) || (year(t) == 1970);
  return wifi_on && should_sync;
}

Du kannst auch öfter synchronisieren, aber übertreib es nicht! Der Internet-Zeitserver wird dich sperren , wenn du jede Sekunde die Zeit abfragst! Alle zehn Minuten wäre wahrscheinlich auch okay.

Wir prüfen außerdem, ob das aktuelle Jahr 1970 ist. Das ist das Jahr, das die ESP32-Uhr nach dem Start meldet (Beginn der Unix time). Das heißt, wenn der ESP32 eingeschaltet wird, synchronisieren wir sofort, auch wenn es nicht zur vollen Stunde ist. Sonst könnte die Zeit bis zu einer Stunde falsch sein!

sync_time

Als Nächstes definieren wir die sync_time() -Funktion, die für die Synchronisierung der Uhr mit dem Internet-Zeitserver zuständig ist. Sie erstellt eine Instanz der HTTPClient -Klasse und macht eine GET request zur angegebenen URL. Wenn die Anfrage erfolgreich ist (HTTP-Statuscode > 0), holt sie sich die Antwort als String und parst sie als JSON mit der ArduinoJson library.

Wenn das JSON-Parsing erfolgreich ist, werden Jahr, Monat, Tag, Stunde, Minute, Sekunde und Zeitzoneninfos aus dem JSON-Objekt mit der sscanf() -Funktion extrahiert. Am Ende wird die Zeit mit der setTime() -Funktion aus der TimeLib library gesetzt.

void sync_time() {
  delay(1000);
  HTTPClient http;
  http.begin(URL);
  if (http.GET() > 0) {
    String json = http.getString();
    auto error = deserializeJson(doc, json);
    if (!error) {
      int Y, M, D, h, m, s, ms, tzh, tzm;
      sscanf(doc["datetime"], "%d-%d-%dT%d:%d:%d.%d+%d:%d",
             &Y, &M, &D, &h, &m, &s, &ms, &tzh, &tzm);            
      setTime(h, m, s, D, M, Y);
    }
  }
  http.end();
}

Zum Debuggen kannst du nach scanf folgende Zeile einfügen, um die geparste Zeit auszugeben:

Serial.printf("sync: %2d:%02d:%02d  %4d-%02d-%02d\n", h, m, s, Y, M, D); 

Beachte, dass ich am Anfang von sync_time eine Sekunde Verzögerung eingebaut habe. Das verhindert, dass wir mehrmals pro Sekunde synchronisieren. Später siehst du, dass die Anzeige im loop()-Funktion alle 100ms aktualisiert wird. Das heißt, die second(t) == 3 -Bedingung wäre 10-mal pro Sekunde wahr und wir würden mehrfach synchronisieren.

Es gibt bessere Wege, das zu lösen. Um den Code einfach zu halten, habe ich aber einfach ein delay verwendet. Das bedeutet aber auch, dass die Anzeige jede Stunde für eine Sekunde nicht aktualisiert wird. Du kannst das natürlich gerne verbessern.

Setup-Funktion

In der setup() -Funktion initialisieren wir die serielle Kommunikation mit 115200 Baud. Außerdem initialisieren wir das I2C-Interface mit der Wire.begin() -Funktion.

Dann setzen wir den WLAN-Modus auf Station mit WiFi.mode() und verbinden uns mit dem WLAN mit WiFi.begin(). Wir warten, bis die Verbindung steht, indem wir den WLAN-Status mit WiFi.status() prüfen.

Zum Schluss initialisieren wir das LCD-Display, schalten die Hintergrundbeleuchtung ein und löschen das Display mit den Funktionen lcd.init(), lcd.backlight() und lcd.clear().

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA, SCL); // I2C for ESP32-C3 Supermini
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSPHRASE);
  while (WiFi.status() != WL_CONNECTED) 
    delay(500);
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

Beachte, dass ich die SDA- und SCL-Pins für das I2C-Interface explizit mit Wire.begin(8,9) gesetzt habe. Ohne das hat I2C auf dem ESP32-C3 Supermini bei mir nicht funktioniert. Falls jemand eine bessere Lösung kennt, schreibt es gerne in die Kommentare.

Loop-Funktion

In der loop() -Funktion prüfen wir ständig, ob die Uhr mit dem Internet-Zeitserver synchronisiert werden soll, indem wir die should_sync_time() -Funktion aufrufen. Falls eine Synchronisierung nötig ist, rufen wir die sync_time() -Funktion auf, um die Uhr zu aktualisieren. Dann rufen wir die lcd_print_time() -Funktion auf, um die aktuelle Zeit auf dem LCD anzuzeigen. Mit der delay() -Funktion fügen wir eine kleine Verzögerung von 100 Millisekunden ein, um zu häufige Updates zu vermeiden.

void loop() {
  if (should_sync_time())
    sync_time();
  lcd_print_time();
  delay(100);
}

Das war’s! Mit diesem Code hast du eine digitale Uhr, die sich automatisch an Sommerzeit und verschiedene Zeitzonen anpasst, indem sie sich per WLAN mit einem Internet-Zeitserver synchronisiert. Die aktuelle Zeit wird auf einem LCD angezeigt und die Uhr wird regelmäßig synchronisiert.

Erweiterungen

Es gibt viele Möglichkeiten, dieses Projekt zu erweitern. Zusätzlich zu Zeit und Datum könnten wir die Zeitzone, den Zeitzonen-Offset und ob gerade Sommerzeit aktiv ist anzeigen. Ein stündlicher Piepton oder eine Weckfunktion wären natürlich auch praktisch.

Je nach Land möchtest du die Zeit vielleicht lieber im 12-Stunden-Format mit AM/PM anzeigen oder mehrere Zeitzonen darstellen. Auch die Anzeige des Wochentags und Monatsnamens wäre leicht hinzuzufügen.

Wir sind nicht auf Internet-Zeitserver beschränkt. Jede Information, die im Internet verfügbar ist – wie Wettervorhersagen, Börsenticker oder Nachrichten – könnte zusätzlich zur Zeit angezeigt werden. Es ist nur eine weitere HTTP-Anfrage mit Daten, die geparst werden können.

Da wir regelmäßig ins Internet gehen, könnten wir das auch nutzen, um die Internetgeschwindigkeit zu überwachen oder Verbindungsabbrüche zu erkennen.

Fazit

In diesem Tutorial hast du gelernt, wie man eine digitale Uhr baut, die sich automatisch an Sommerzeit und verschiedene Zeitzonen anpasst. Durch die Synchronisierung per WLAN mit einem Internet-Zeitserver zeigt die Uhr immer die genaue Zeit an.

Wir haben mit den benötigten Teilen für das Projekt angefangen – dazu gehören ein WLAN-fähiges ESP32-Board und ein LCD-Display. Danach haben wir erklärt, wie man die Teile verbindet, um die Uhr zu bauen.

Anschließend haben wir das Konzept der Sommerzeit besprochen und warum es wichtig ist, die Uhr für saisonale Zeitumstellungen anzupassen. Wir haben gezeigt, wie man die Sommerzeit im Code berücksichtigt, damit die Uhr immer korrekt aktualisiert wird.

Um unsere Uhr mit einem Internet-Zeitserver zu synchronisieren, haben wir JSON-Parsing-Techniken genutzt, um die Zeitdaten aus der API des Anbieters zu extrahieren. Außerdem haben wir gelernt, wie man mit Datumszeit-Strings arbeitet, um die Zeit auf dem LCD-Display anzuzeigen.

Wenn du ein schöneres, größeres Display mit Touchscreen für deine Uhr möchtest, schau dir das Digital Clock with CrowPanel 3.5″ ESP32 Display -Tutorial an. Und wenn du die Zeit mal auf eine ungewöhnliche Art anzeigen willst, kannst du mit diesem Code auch eine LED-Ring-Uhr bauen, wie in diesem Tutorial beschrieben: LED Ring Clock with WS2812.

Wenn du noch Fragen hast oder weitere Hilfe brauchst, schau in den FAQ-Bereich oder besuche die angegebenen Links für mehr Infos und Ressourcen.

Häufig gestellte Fragen

Hier findest du häufig gestellte Fragen zum Bau einer digitalen Uhr, die sich automatisch an Sommerzeit und verschiedene Zeitzonen anpasst:

F: Kann ich für dieses Projekt jedes Board mit WLAN verwenden?

A: Ja, du kannst jedes Mikrocontroller-Board verwenden, das WLAN hat oder mit einem WLAN-Shield ausgestattet werden kann. Beliebte Optionen sind ESP8266 und ESP32, die WLAN schon eingebaut haben.

F: Wie stellt die Uhr auf Sommerzeit um?

A: Die Uhr stellt auf Sommerzeit um, indem sie sich mit einem Internet-Zeitserver synchronisiert. Diese Zeitserver liefern genaue Zeitinfos, inklusive aktueller Zeitzone und ob gerade Sommerzeit gilt. Indem du diese Infos ausliest und die Uhr entsprechend anpasst, zeigt sie immer die richtige Zeit an.

F: Brauche ich für dieses Projekt unbedingt ein LCD-Display?

A: Ein LCD-Display ist nicht zwingend nötig, aber für dieses Projekt empfehlenswert, da du so die Zeit direkt sehen kannst. Du kannst die Zeit aber auch auf einen seriellen Monitor oder ein anderes Ausgabegerät deiner Wahl ausgeben.

F: Kann ich den Code anpassen und weitere Funktionen hinzufügen?

A: Auf jeden Fall! Der bereitgestellte Code ist ein Ausgangspunkt und du kannst ihn nach Belieben erweitern oder anpassen. Zum Beispiel könntest du mehrere Zeitzonen unterstützen, zusätzliche Infos anzeigen oder andere Sensoren und Module einbinden.

F: Gibt es Einschränkungen bei der Nutzung eines Internet-Zeitservers?

A: Die Nutzung eines Internet-Zeitservers ist praktisch, um deine Uhr zu synchronisieren, setzt aber eine Internetverbindung voraus. Wenn deine Uhr keine Verbindung bekommt, kann sie die Zeit nicht aktualisieren. Außerdem kann es sein, dass der Zeitserver mal nicht erreichbar ist, was die Genauigkeit deiner Uhr beeinflussen kann.

Links

Hier ein paar nützliche Links zu ähnlichen Projekten: