Ratgeber · 12 Min. Lesezeit

ESP32 NTP Uhrzeit: Zeitzone, Sommerzeit, OLED-Uhr und RTC-Backup

ESP32 NTP Uhrzeit abrufen: configTzTime mit Zeitzone und Sommerzeit, getLocalTime, strftime, OLED-Uhr, DS3231-Backup, tägliche Aufgabe und ntptime am Pico W.

Die ESP32 NTP Uhrzeit abzurufen heißt, das Board mit Zeitservern im Internet zu verbinden und Datum und Uhrzeit ohne Uhrmodul auf wenige Dutzend Millisekunden genau zu kennen. Sobald der ESP32 im WLAN ist, holt ein einziger Aufruf von configTzTime() die Zeit, wendet deine Zeitzone samt Sommerzeit an, und danach zählt das Board selbstständig weiter. Für Tischuhren, zeitgesteuerte Bewässerung, Zeitstempel beim Datenloggen, einen Wecker am Morgen oder Licht, das zu einer festen Uhrzeit angeht, brauchst du kein separates RTC-Modul mehr.

In dieser Anleitung gehen wir Schritt für Schritt durch: wie NTP funktioniert, die richtige Zeitzone für Deutschland, Österreich und die Schweiz (MEZ/MESZ), das Datum mit getLocalTime und strftime beliebig formatieren, die Uhrzeit auf einem OLED-Display anzeigen, die Zeit mit einem DS3231-Modul halten, wenn WLAN oder Strom ausfällt, und eine Aufgabe jeden Tag zu einer festen Uhrzeit ausführen. Im letzten Abschnitt erledigen wir dasselbe auf dem Raspberry Pi Pico W mit dem MicroPython-Modul ntptime.

ESP32-Entwicklungsboard
ESP32 DevKit: Dank eingebautem WLAN holt es die Zeit von NTP-Servern und führt Datum und Uhrzeit ohne separates Uhrmodul.

Was ist NTP und wie bekommt der ESP32 die Uhrzeit?

NTP (Network Time Protocol) ist ein seit den 1980er-Jahren genutztes Protokoll, mit dem Computer und Geräte ihre Uhren über das Internet synchronisieren. Die Server sind in Schichten (Stratum) angeordnet: Stratum-1-Server hängen direkt an einer Atomuhr oder an GPS, Stratum-2-Server beziehen ihre Zeit von ihnen und so weiter. Der ESP32 fragt die Zeit mit einem kleinen Paket über UDP-Port 123 an; der Server antwortet mit einem Zeitstempel, der die Sekunden seit 1900 samt Sekundenbruchteil enthält. Der ESP32 berücksichtigt die Laufzeit des Pakets und stellt seine eigene Uhr. Über einen Heimanschluss erreichst du so meist eine Genauigkeit von 10 bis 50 Millisekunden, mehr als genug für ein Uhrenprojekt.

Der lwIP-Netzwerkstack im ESP32 verwendet SNTP, eine vereinfachte Variante von NTP. Nach dem ersten Empfang führt der ESP32 die Zeit als Systemzeit und zählt mit einem vom Quarz abgeleiteten Timer weiter; er fragt nicht jede Sekunde im Internet nach. Im Hintergrund fragt er in festen Abständen erneut beim Server an (im Arduino-ESP32-Core standardmäßig alle 3 Stunden) und korrigiert kleine Abweichungen. Die Systemzeit wird in UTC geführt; die Ortszeit, die du siehst, wird daraus mit der Zeitzonenregel berechnet.

BegriffWert / Erklärung
Protokoll und PortSNTP, UDP 123
ZeitstempelSekunden seit 1900 (der ESP32 rechnet sie in Unix-Zeit ab 1970 um)
Typische Genauigkeit10–50 ms über einen Heimanschluss
NeusynchronisationStandard 3 Stunden im Arduino-ESP32-Core, änderbar mit sntp_set_sync_interval() (mindestens 15 s)
Maximale Serverzahl3 (die an configTzTime übergebenen Servernamen)
DatenverkehrAnfrage und Antwort sind je 48 Byte große NTP-Pakete; nur wenige Kilobyte pro Tag
VoraussetzungenESP32, ein 2,4-GHz-WLAN und Internetzugang

configTime und configTzTime: Zeitzone und Sommerzeit einstellen

Im Arduino-ESP32-Core gibt es zwei Wege, NTP zu starten. configTime(gmtOffset_sec, daylightOffset_sec, server1, server2, server3) erwartet den UTC-Versatz und den Sommerzeit-Versatz in Sekunden, zum Beispiel configTime(3600, 3600, "pool.ntp.org") für MEZ. Diese Methode ist einfach, kennt aber die Umstellungstermine deiner Region nicht; in Deutschland würde die Umstellung am falschen Tag passieren. Für Länder ohne Sommerzeit, etwa die Türkei mit ganzjährig UTC+3 (configTime(10800, 0, ...)), reicht sie aus.

Der bessere Weg ist configTzTime(TZ, server1, server2, server3). Diese Funktion erwartet eine Zeitzonen-Zeichenkette im POSIX-Format, die auch die Sommerzeitregeln enthält; der ESP32 stellt jedes Jahr selbst um. Für Deutschland, Österreich und die Schweiz lautet sie "CET-1CEST,M3.5.0,M10.5.0/3": CET ist die Winterzeit-Abkürzung, -1 bedeutet, dass man von der Ortszeit eine Stunde abzieht, um UTC zu erhalten, CEST ist die Sommerzeit, M3.5.0 heißt „letzter Sonntag im März“ und M10.5.0/3 „letzter Sonntag im Oktober um 3 Uhr“. Die Beispielsketche unten verwenden die türkische Zeitzone "<+03>-3"; ersetze TZ_INFO einfach durch den Wert aus der Tabelle.

RegionTZ-Zeichenkette (configTzTime)Entsprechung mit configTime
Türkei (ganzjährig UTC+3)<+03>-3configTime(10800, 0, ...)
Deutschland, Österreich, SchweizCET-1CEST,M3.5.0,M10.5.0/3Ungeeignet, configTzTime verwenden
Großbritannien, PortugalGMT0BST,M3.5.0/1,M10.5.0Ungeeignet, configTzTime verwenden
USA Ostküste (New York)EST5EDT,M3.2.0,M11.1.0Ungeeignet, configTzTime verwenden
Aserbaidschan, Georgien (UTC+4)<+04>-4configTime(14400, 0, ...)
UTC (für Zeitstempel)UTC0configTime(0, 0, ...)
Das Vorzeichen in einer POSIX-Zeitzone ist umgekehrt: Schreibst du für Deutschland "CET+1" oder für die Türkei "UTC+3", liest der ESP32 das als „hinter UTC“, und die Uhr liegt um 2 bzw. 6 Stunden daneben. Richtig sind "CET-1..." und "<+03>-3". Weicht deine Uhr um genau das Doppelte des Versatzes ab, ist fast immer das Vorzeichen schuld.

Was du brauchst und Verdrahtung

Um die Uhrzeit im seriellen Monitor zu sehen, reichen ein ESP32 und ein WLAN. Später in der Anleitung nutzen wir ein 0,96-Zoll-OLED-Display mit SSD1306 für die Anzeige, ein DS3231-RTC-Modul gegen Stromausfälle und ein Relaismodul für das Beispiel mit der geplanten Aufgabe. OLED und DS3231 teilen sich denselben I2C-Bus, beide kommen also an dieselben zwei Pins. Die Pinbelegung des ESP32 findest du im Werkzeug Pinout.

Bauteil-PinESP32Raspberry Pi Pico WHinweis
OLED / DS3231 VCC3V33V3 (OUT)Beide laufen mit 3,3 V
OLED / DS3231 GNDGNDGNDGemeinsame Masse
OLED / DS3231 SDAGPIO 21GP4I2C-Datenleitung
OLED / DS3231 SCLGPIO 22GP5I2C-Taktleitung
Relaismodul INGPIO 26GP15Beispiel geplante Aufgabe
Relaismodul VCC5V (VIN)VBUSDie meisten Relaisspulen brauchen 5 V
Der ESP32 verbindet sich nur mit 2,4-GHz-WLANs. Nutzt dein Router für 5 GHz und 2,4 GHz denselben Namen oder enthält der Netzwerkname Umlaute oder Sonderzeichen, kann die Verbindung scheitern. Kommt nie eine Uhrzeit an, prüfe zuerst im seriellen Monitor, ob das WLAN verbunden ist; NTP funktioniert erst danach.

Schritt für Schritt: dein erster ESP32-NTP-Sketch

  1. Stelle sicher, dass das ESP32-Boardpaket in der Arduino IDE installiert ist, und wähle unter Werkzeuge ESP32 Dev Module. Wie das geht, steht im Beitrag Was ist der ESP32.
  2. Eine zusätzliche Bibliothek ist nicht nötig: WiFi.h und time.h gehören zum ESP32-Core.
  3. Ersetze WIFI_SSID und WIFI_PASS durch dein eigenes Netzwerk und TZ_INFO durch "CET-1CEST,M3.5.0,M10.5.0/3".
  4. Lade den Sketch hoch und öffne den seriellen Monitor mit 115200 Baud.
  5. Zuerst erscheinen WLAN-Punkte, nach ein paar Sekunden dann Datum und Uhrzeit, jede Sekunde aktualisiert.
C++ (Arduino IDE)
1#include <WiFi.h>
2#include <time.h>
3
4const char* WIFI_SSID = "AgAdi";       // Wi-Fi adı / Wi-Fi name
5const char* WIFI_PASS = "Sifre123";    // Wi-Fi şifresi / Wi-Fi password
6const char* TZ_INFO   = "<+03>-3";     // Türkiye: UTC+3, yaz saati yok / Turkey: UTC+3, no DST
7
8void setup() {
9  Serial.begin(115200);
10  WiFi.begin(WIFI_SSID, WIFI_PASS);
11  Serial.print("Wi-Fi");
12  while (WiFi.status() != WL_CONNECTED) {    // bağlanana kadar bekle / wait until connected
13    delay(500);
14    Serial.print(".");
15  }
16  Serial.println(" OK");
17
18  // NTP sunucuları + saat dilimi / NTP servers + time zone
19  configTzTime(TZ_INFO, "pool.ntp.org", "time.cloudflare.com");
20
21  struct tm t;
22  while (!getLocalTime(&t)) {                // ilk eşitlemeyi bekle (5 sn deneme) / wait for the first sync (5 s per try)
23    Serial.println("NTP bekleniyor / waiting for NTP");
24  }
25  Serial.println("Saat alindi / time received");
26}
27
28void loop() {
29  struct tm t;
30  if (getLocalTime(&t)) {
31    Serial.println(&t, "%d.%m.%Y %H:%M:%S");  // ör. 16.11.2026 14:05:09 / e.g. 16.11.2026 14:05:09
32  }
33  delay(1000);
34}
35
ZeileWas macht sie?
configTzTime(TZ_INFO, ...)Startet den SNTP-Client, setzt Server und Zeitzone; kehrt sofort zurück, die Zeit kommt im Hintergrund
getLocalTime(&t)Füllt eine struct tm mit der Ortszeit; ohne gültige Zeit wartet sie bis zu 5 Sekunden und gibt false zurück
Serial.println(&t, "...")Die Print-Klasse des ESP32 kann eine struct tm direkt mit strftime-Format ausgeben
time(nullptr)Liefert die Sekunden seit 1970 (Unix-Zeit, UTC)

Ein wichtiges Detail: getLocalTime() entscheidet anhand des Jahres, ob die Zeit „gültig“ ist. Beim Start steht die Systemzeit auf dem 1. Januar 1970, und die Funktion liefert false, bis das Jahr nach 2016 liegt. Code, der Daten loggt oder Aufgaben ausführt, bevor NTP da ist, erzeugt also keine Einträge mit Datum 1970, sofern du den Rückgabewert prüfst. Der zweite Parameter ist die Wartezeit in Millisekunden; willst du loop() nicht blockieren, schreib getLocalTime(&t, 0), dann wird nur einmal geprüft.

struct tm: die Bestandteile der Uhrzeit

getLocalTime() schreibt die Zeit zerlegt in eine struct tm. Mit diesen Feldern vergleichst du Stunden, Tage oder Monate, wenn du geplante Aufgaben baust. Zwei Felder verwirren Einsteiger oft: Der Monat zählt ab 0, das Jahr ab 1900.

FeldBereichBeispiel (Montag, 16. November 2026, 14:05:09)
tm_sec0–59 (60 bei Schaltsekunde)9
tm_min0–595
tm_hour0–2314
tm_mday1–3116
tm_mon0–11 (0 = Januar)10
tm_yearJahre seit 1900126 (1900 + 126 = 2026)
tm_wday0–6 (0 = Sonntag)1
tm_yday0–365 (Tag im Jahr, ab 0)319
Zeigt das Display „16.10.2026“, obwohl November ist, hast du vergessen, 1 zu tm_mon zu addieren. Siehst du das Jahr 126, brauchst du tm_year + 1900. Mit strftime passieren diese Umrechnungen automatisch.

Datum und Uhrzeit mit strftime formatieren

strftime() schreibt die Zeit aus einer struct tm nach einem Muster in ein Zeichen-Array. Die Prozent-Codes im Muster werden durch den passenden Wert ersetzt, alle anderen Zeichen bleiben stehen. Das Array muss so groß sein wie die längste Ausgabe plus eins (für die abschließende Null): „14:05:09“ hat 8 Zeichen, also mindestens 9 Byte. Die wichtigsten Codes:

CodeBedeutungBeispielausgabe
%H / %M / %SStunde (00–23) / Minute / Sekunde14 / 05 / 09
%I und %p12-Stunden-Format und AM/PM02 PM
%d / %m / %YTag / Monat (01–12) / vierstelliges Jahr16 / 11 / 2026
%yZweistelliges Jahr26
%A / %aWochentag lang / kurz (Englisch)Monday / Mon
%B / %bMonatsname lang / kurz (Englisch)November / Nov
%jTag im Jahr (001–366)320
%F / %TKurzformen für %Y-%m-%d / %H:%M:%S2026-11-16 / 14:05:09
%ZZeitzonen-Abkürzung+03 (bzw. CET / CEST)

Die C-Bibliothek des ESP32 kennt nur englische Wochentags- und Monatsnamen; %A liefert immer „Monday“. Für ein deutsches Datum legst du die Namen in eigenen Arrays ab und nutzt tm_wday und tm_mon als Index. Das Beispiel unten macht das mit türkischen Namen; tausche sie einfach gegen „Sonntag, Montag, …“ und „Januar, Februar, …“. Da der serielle Monitor UTF-8 unterstützt, erscheinen Umlaute dort korrekt. Der Sketch erzeugt ein gut lesbares Datum und das sortierbare ISO-Format (2026-11-16 14:05:09) zum Loggen.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <time.h>
3
4const char* WIFI_SSID = "AgAdi";
5const char* WIFI_PASS = "Sifre123";
6const char* TZ_INFO   = "<+03>-3";
7
8// tm_wday: 0 = Pazar ... 6 = Cumartesi / 0 = Sunday ... 6 = Saturday
9const char* GUNLER[] = {"Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"};
10const char* AYLAR[]  = {"Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran",
11                        "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"};
12
13void setup() {
14  Serial.begin(115200);
15  WiFi.begin(WIFI_SSID, WIFI_PASS);
16  while (WiFi.status() != WL_CONNECTED) delay(500);
17  configTzTime(TZ_INFO, "pool.ntp.org");
18}
19
20void loop() {
21  struct tm t;
22  if (!getLocalTime(&t)) return;             // saat henüz yok / time not set yet
23
24  char saat[9];                              // "HH:MM:SS" + '\0'
25  char iso[20];                              // "YYYY-MM-DD HH:MM:SS" + '\0'
26  strftime(saat, sizeof(saat), "%H:%M:%S", &t);
27  strftime(iso, sizeof(iso), "%Y-%m-%d %H:%M:%S", &t);
28
29  // Türkçe tarih: 16 Kasım 2026 Pazartesi / Turkish date
30  Serial.printf("%d %s %d %s  %s\n", t.tm_mday, AYLAR[t.tm_mon], t.tm_year + 1900, GUNLER[t.tm_wday], saat);
31  Serial.printf("Kayit / log: %s  epoch: %ld\n", iso, (long)time(nullptr));
32  delay(1000);
33}
34
Schreib beim Loggen (SD-Karte, Google Sheets, Server) das Datum immer als %Y-%m-%d %H:%M:%S oder direkt als Unix-Zeit. Dieses Format ist alphabetisch sortiert zugleich chronologisch sortiert, und Excel sowie Datenbanken erkennen es als Datum. Auf dem Display kannst du trotzdem das deutsche Format verwenden.

Uhrzeit und Datum auf einem OLED-Display anzeigen

Um aus der Ausgabe im seriellen Monitor eine echte Tischuhr zu machen, ist das 0,96-Zoll-OLED mit SSD1306 ideal: günstig, mit zwei Leitungen angeschlossen und mit gestochen scharfen großen Ziffern. Der Sketch unten zeigt oben Wochentag und Datum, in der Mitte groß die Uhrzeit und unten den WLAN-Status. Weil er nur neu zeichnet, wenn sich die Sekunde ändert, und nicht bei jedem Schleifendurchlauf, belastet er den I2C-Bus nicht unnötig. Installiere die Bibliotheken Adafruit SSD1306 und Adafruit GFX über den Bibliotheksverwalter; das Display selbst erklärt der Beitrag OLED-Display (SSD1306).

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <Wire.h>
3#include <Adafruit_GFX.h>
4#include <Adafruit_SSD1306.h>
5#include <time.h>
6
7const char* WIFI_SSID = "AgAdi";
8const char* WIFI_PASS = "Sifre123";
9const char* TZ_INFO   = "<+03>-3";
10// OLED yazı tipinde Türkçe harf yok / the OLED font has no Turkish letters
11const char* GUNLER[] = {"Pazar", "Pazartesi", "Sali", "Carsamba", "Persembe", "Cuma", "Cumartesi"};
12
13Adafruit_SSD1306 display(128, 64, &Wire, -1);
14int sonSaniye = -1;                          // son çizilen saniye / last drawn second
15
16void yaz(const char* mesaj) {                // ekrana tek satır / one line on screen
17  display.clearDisplay();
18  display.setTextSize(1);
19  display.setCursor(0, 0);
20  display.print(mesaj);
21  display.display();
22}
23
24void setup() {
25  Wire.begin(21, 22);                        // SDA = 21, SCL = 22
26  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
27  display.setTextColor(SSD1306_WHITE);
28  yaz("Wi-Fi baglaniyor...");
29
30  WiFi.begin(WIFI_SSID, WIFI_PASS);
31  while (WiFi.status() != WL_CONNECTED) delay(300);
32  configTzTime(TZ_INFO, "pool.ntp.org", "time.cloudflare.com");
33  yaz("NTP bekleniyor...");
34}
35
36void loop() {
37  struct tm t;
38  if (!getLocalTime(&t, 0)) {                // 0 = beklemeden dene / try without waiting
39    delay(200);
40    return;
41  }
42  if (t.tm_sec == sonSaniye) {               // saniye değişmediyse çizme / redraw only on a new second
43    delay(20);
44    return;
45  }
46  sonSaniye = t.tm_sec;
47
48  char saat[9], tarih[11];
49  strftime(saat, sizeof(saat), "%H:%M:%S", &t);
50  strftime(tarih, sizeof(tarih), "%d.%m.%Y", &t);
51
52  display.clearDisplay();
53  display.setTextSize(1);
54  display.setCursor(0, 0);
55  display.print(GUNLER[t.tm_wday]);          // gün adı / day name
56  display.setCursor(68, 0);
57  display.print(tarih);                      // 10 karakter = 60 piksel / 10 chars = 60 px
58  display.setTextSize(2);
59  display.setCursor(16, 26);
60  display.print(saat);                       // 8 x 12 = 96 piksel genişlik / 96 px wide
61  display.setTextSize(1);
62  display.setCursor(0, 56);
63  display.print(WiFi.status() == WL_CONNECTED ? "Wi-Fi: var" : "Wi-Fi: yok");
64  display.display();
65}
66

Beachte, dass die Wochentage ohne Sonderzeichen geschrieben sind: Die Standardschrift von Adafruit GFX enthält keine Zeichen wie ä, ö, ü oder ß und zeigt stattdessen sinnlose Symbole. Bei Textgröße 2 ist jedes Zeichen 12 Pixel breit; „14:05:09“ mit 8 Zeichen belegt 96 Pixel und steht ab Pixel 16 genau mittig auf dem 128 Pixel breiten Display. Willst du lieber ein 16x2-Zeichen-LCD, gib dieselben strftime-Ausgaben mit lcd.print() aus; die Verdrahtung erklärt der Beitrag I2C-LCD-Display.

Was passiert bei WLAN-Ausfall? DS3231 als RTC-Backup

Die häufigste Frage: Ist mit dem WLAN auch die Uhrzeit weg? Nein. Hat der ESP32 die Zeit einmal per NTP bekommen, zählt er mit seinem eigenen Timer weiter; ein WLAN-Abbruch hält die Uhr nicht an. Da dieser Timer vom 40-MHz-Quarz kommt, driftet er etwa ein bis zwei Sekunden pro Tag, und die nächste Synchronisation korrigiert das, sobald das WLAN zurück ist. Das eigentliche Problem ist ein Stromausfall oder ein Neustart über die EN-Taste: Dann springt die Systemzeit auf 1970 zurück, und ohne WLAN kann der ESP32 die Uhrzeit nicht kennen.

SituationBleibt die Zeit erhalten?Was tun?
WLAN fällt eine Weile ausJa, der ESP32 zählt weiterNichts; NTP korrigiert, sobald WLAN zurück ist
Deep Sleep (Tiefschlaf)Ja, der RTC-Timer zählt weiterBei langem Schlaf ab und zu nach dem Aufwachen per NTP abgleichen
Stromausfall oder EN-TasteNein, die Uhr springt auf 1970Ein batteriegepuffertes RTC-Modul wie den DS3231 ergänzen
Gar kein Internet (Feld, Lager)NTP kommt nie anDie Zeit nur aus einem RTC-Modul holen

Im Tiefschlaf wird die Zeit nicht vom Hauptquarz, sondern von einem ungenaueren RC-Oszillator im Chip gezählt. Dieser ist temperaturabhängig, sodass die Uhr bei langem Schlaf um einige Sekunden oder mehr abweichen kann; bei batteriebetriebenen Projekten, die stundenlang schlafen, ist ein NTP-Abgleich alle paar Aufwachvorgänge eine gute Gewohnheit. Einzelheiten stehen im Beitrag ESP32 Deep Sleep.

RTC-Uhrmodul
Batteriegepuffertes RTC-Modul: Es zählt weiter, auch wenn der ESP32 keinen Strom hat; bis das WLAN zurück ist, holst du die Zeit von hier.

Die beste Lösung für eine ausfallsichere Uhr kombiniert beides: Beim Start sofort die Zeit aus dem DS3231 holen, sie per NTP korrigieren, sobald WLAN da ist, und den DS3231 bei jeder NTP-Synchronisation aktualisieren. Im Sketch unten speichert der DS3231 UTC statt Ortszeit; so steckt die Zeitzonenregel an einer Stelle (der TZ-Zeichenkette), und die Sommerzeitumstellung bringt die RTC nie durcheinander. Um die NTP-Synchronisation mitzubekommen, wird mit sntp_set_time_sync_notification_cb() eine Callback-Funktion registriert. Weil sie im Netzwerk-Task läuft, passiert dort keine I2C-Arbeit; sie setzt nur ein Flag, und loop() schreibt in den DS3231. Der Sketch nutzt die Bibliothek RTClib.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <Wire.h>
3#include <RTClib.h>
4#include <sys/time.h>
5#include "esp_sntp.h"
6
7const char* WIFI_SSID = "AgAdi";
8const char* WIFI_PASS = "Sifre123";
9const char* TZ_INFO   = "<+03>-3";
10
11RTC_DS3231 rtc;
12volatile bool ntpGeldi = false;              // NTP eşitlemesi oldu mu? / did an NTP sync happen?
13
14void ntpCallback(struct timeval* tv) {       // her NTP eşitlemesinde çağrılır / called on every NTP sync
15  ntpGeldi = true;                           // I2C işini loop() yapsın / let loop() do the I2C work
16}
17
18void setup() {
19  Serial.begin(115200);
20  Wire.begin(21, 22);
21  setenv("TZ", TZ_INFO, 1);                  // NTP gelmese de saat dilimi geçerli / TZ valid even without NTP
22  tzset();
23
24  // 1) Sistem saatini önce DS3231'den kur (DS3231'de UTC saklanır) / set system time from the DS3231 (stores UTC)
25  if (rtc.begin() && !rtc.lostPower()) {
26    struct timeval tv = { (time_t)rtc.now().unixtime(), 0 };
27    settimeofday(&tv, nullptr);
28    Serial.println("Saat DS3231'den / time from DS3231");
29  }
30
31  // 2) Wi-Fi gelince NTP saati düzeltir; bağlantı sonra gelse de SNTP yeniden dener
32  //    NTP corrects the clock once Wi-Fi is up; SNTP keeps retrying if the link comes later
33  sntp_set_time_sync_notification_cb(ntpCallback);
34  WiFi.begin(WIFI_SSID, WIFI_PASS);
35  configTzTime(TZ_INFO, "pool.ntp.org", "time.cloudflare.com");
36}
37
38void loop() {
39  if (ntpGeldi) {
40    ntpGeldi = false;
41    rtc.adjust(DateTime((uint32_t)time(nullptr)));   // DS3231'e UTC yaz / write UTC to the DS3231
42    Serial.println("DS3231 NTP ile guncellendi / DS3231 updated from NTP");
43  }
44
45  struct tm t;
46  if (getLocalTime(&t, 0)) {
47    Serial.println(&t, "%d.%m.%Y %H:%M:%S");
48  } else {
49    Serial.println("Saat yok: NTP ve DS3231 bekleniyor / no time yet");
50  }
51  delay(1000);
52}
53
Der DS1307 funktioniert mit demselben Code (RTC_DS1307 schreiben und isrunning statt lostPower verwenden), kann aber ein bis zwei Minuten pro Monat abweichen. Dank seines temperaturkompensierten Quarzes bleibt der DS3231 bei etwa einer Minute pro Jahr. Unterschiede der Module und die Falle mit der Ladeschaltung für die Knopfzelle findest du im Beitrag Arduino RTC-Modul.

Jeden Tag zu einer festen Uhrzeit eine Aufgabe ausführen

Am häufigsten wird die NTP-Zeit für geplante Aufgaben genutzt: um 07:30 die Bewässerungspumpe 10 Minuten laufen lassen, um 19:00 die Gartenbeleuchtung einschalten, jede volle Stunde einen Messwert senden. Das Prinzip ist einfach: In loop() die Zeit lesen und die Aufgabe starten, wenn Stunde und Minute dem Ziel entsprechen. Die eigentliche Feinheit ist, zu verhindern, dass die Aufgabe innerhalb derselben Minute hunderte Male auslöst. Dazu speicherst du den Tag, an dem sie lief (tm_yday), in einer Variablen; am selben Tag läuft sie dann kein zweites Mal. Der Sketch unten schaltet an Werktagen jeden Morgen um 07:30 das Relais an GPIO 26 für 10 Minuten ein; weil er die Dauer mit millis() misst, blockiert der Code nirgends.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <time.h>
3
4const char* WIFI_SSID = "AgAdi";
5const char* WIFI_PASS = "Sifre123";
6const char* TZ_INFO   = "<+03>-3";
7
8const int ROLE_PIN = 26;                     // röle modülü IN / relay module IN
9const int GOREV_SAAT = 7;                    // her gün 07:30 / every day at 07:30
10const int GOREV_DAKIKA = 30;
11const unsigned long SURE_MS = 10UL * 60 * 1000;   // 10 dakika çalış / run for 10 minutes
12
13int sonGun = -1;                             // görevin çalıştığı son gün (tm_yday) / last day the task ran
14bool roleAcik = false;
15unsigned long acilisMs = 0;
16
17void setup() {
18  Serial.begin(115200);
19  pinMode(ROLE_PIN, OUTPUT);
20  digitalWrite(ROLE_PIN, LOW);
21  WiFi.begin(WIFI_SSID, WIFI_PASS);
22  while (WiFi.status() != WL_CONNECTED) delay(500);
23  configTzTime(TZ_INFO, "pool.ntp.org");
24}
25
26void loop() {
27  struct tm t;
28  if (getLocalTime(&t, 0)) {                 // saat geçerliyse / only when the time is valid
29    bool haftaici = (t.tm_wday >= 1 && t.tm_wday <= 5);   // Pzt-Cuma / Mon-Fri
30    if (haftaici && t.tm_hour == GOREV_SAAT && t.tm_min == GOREV_DAKIKA && t.tm_yday != sonGun) {
31      sonGun = t.tm_yday;                    // bugün bir kez / once per day
32      digitalWrite(ROLE_PIN, HIGH);
33      roleAcik = true;
34      acilisMs = millis();
35      Serial.println(&t, "%H:%M gorev basladi / task started");
36    }
37  }
38  if (roleAcik && millis() - acilisMs >= SURE_MS) {   // süre dolunca kapat / switch off after the period
39    digitalWrite(ROLE_PIN, LOW);
40    roleAcik = false;
41    Serial.println("Gorev bitti / task finished");
42  }
43  delay(200);
44}
45
  • Auf Sekunden prüfen: Eine Bedingung wie t.tm_sec == 0 überspringt die Aufgabe, wenn die Schleife genau diese Sekunde verpasst (beim WLAN-Neuverbinden oder während eines langen delay). Minute und Tag zu prüfen ist sicherer.
  • Gültige Zeit prüfen: Keine Aufgaben ausführen, solange getLocalTime() false liefert, sonst triffst du direkt nach dem Start falsche Entscheidungen auf Basis von 1970.
  • Verpasste Aufgabe: Fällt der Strom um 07:29 aus und kommt um 07:35 zurück, läuft die Aufgabe an diesem Tag nicht. Ist das wichtig, formuliere die Bedingung als „nach 07:30 und heute noch nicht gelaufen“ und speichere sonGun mit Preferences dauerhaft.
  • Mehrere Aufgaben: Stunde, Minute und Dauer in einem Array halten und für jede Aufgabe eine eigene Variable für den letzten Lauftag verwenden.
  • Lasten mit hohem Strom: Pumpe oder Lampe über ein Relaismodul oder einen MOSFET schalten, nie direkt am Pin.
Die GPIO-Pins des ESP32 liefern 3,3 V und nur einige zehn Milliampere. Der IN-Eingang eines Relaismoduls schaltet meist schon mit 3,3 V, manche 5-V-Relaisplatinen aber nicht zuverlässig; nimm dann eine Platine mit 3,3-V-Ansteuerung oder einen Transistortreiber. Arbeitest du auf der 230-V-Seite, fass die Verdrahtung nie an, solange der Stecker steckt.

Synchronisationsintervall ändern und NTP überwachen

Das Standardintervall von 3 Stunden passt für die meisten Projekte. Um häufiger abzugleichen (etwa draußen bei starken Temperaturschwankungen) oder Datenverkehr zu sparen, übergibst du sntp_set_sync_interval() das neue Intervall in Millisekunden. Rufe die Funktion vor configTzTime() auf, denn das neue Intervall gilt erst beim nächsten Start oder wenn das laufende Intervall abläuft. Laut Protokoll darf es nicht kürzer als 15 Sekunden sein. sntp_get_sync_status() liefert nach einer abgeschlossenen Synchronisation einmal SNTP_SYNC_STATUS_COMPLETED und setzt sich dann zurück, so erkennst du jeden neuen Abgleich.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <time.h>
3#include "esp_sntp.h"
4
5const char* TZ_INFO = "<+03>-3";
6
7void setup() {
8  Serial.begin(115200);
9  WiFi.begin("AgAdi", "Sifre123");
10  while (WiFi.status() != WL_CONNECTED) delay(500);
11
12  sntp_set_sync_interval(6UL * 60 * 60 * 1000);   // 6 saatte bir eşitle (en az 15 sn) / sync every 6 hours (min 15 s)
13  configTzTime(TZ_INFO, "pool.ntp.org");          // ayar sntp_init() öncesi verilir / set before sntp_init()
14}
15
16void loop() {
17  if (sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) {
18    Serial.println("Yeni NTP esitlemesi / new NTP sync");
19  }
20  delay(1000);
21}
22

Welchen NTP-Server solltest du nehmen?

Die gängigste Wahl ist pool.ntp.org: ein Pool aus tausenden Servern, die Freiwillige weltweit betreiben, und der dir bei jeder Anfrage einen Server in deiner Nähe nennt. Länder-Subdomains (de.pool.ntp.org, at.pool.ntp.org, ch.pool.ntp.org) holen den Server noch näher heran. configTzTime() nimmt bis zu drei Servernamen; antwortet der erste nicht, geht es mit dem nächsten weiter.

ServerEigenschaftHinweis
pool.ntp.orgFreiwilligen-Pool, nächster ServerErste Wahl für den allgemeinen Einsatz
de.pool.ntp.org / europe.pool.ntp.orgLänder- oder Kontinent-PoolEtwas geringere Latenz
time.cloudflare.comInfrastruktur eines großen AnbietersGut als Ersatzserver
time.google.comVerschmiert Schaltsekunden (Leap Smear)Nicht mit anderen Servern mischen
IP-Adresse deines RoutersManche Router (z. B. FRITZ!Box) bieten lokales NTPNützlich im lokalen Netz ohne Internet
Willst du ein eigenes Produkt an hunderte Geräte ausliefern, ist es guter Stil, statt pool.ntp.org einen eigenen Pool (Vendor Zone) zu beantragen oder die Startzeit der Geräte zufällig zu streuen. Tausende Geräte, die in derselben Sekunde anfragen, belasten die Server der Freiwilligen.

NTP am Raspberry Pi Pico W: ntptime

Auf dem Raspberry Pi Pico W (und dem Pico 2 W) übernimmt das MicroPython-Modul ntptime diese Aufgabe. ntptime.settime() fragt den NTP-Server und stellt die interne RTC des Pico auf UTC. MicroPython kennt keine Zeitzonen-Zeichenkette wie der ESP32; für die Ortszeit addierst du den Versatz in Sekunden zu UTC (im Beispiel 3 × 3600 für die Türkei, für MEZ 3600 und im Sommer 7200). ntptime holt die Zeit nur einmal und gleicht nicht automatisch neu ab; bei langlaufenden Projekten beseitigt ein- bis zweimal täglich settime() die Drift. Auch die RTC des Pico W wird bei Stromausfall zurückgesetzt, das DS3231-Backup gilt also auch hier. Wie sich der Pico W mit dem WLAN verbindet, erklärt der Beitrag Pico W WLAN und Webserver.

Python
1import network
2import ntptime
3import time
4
5SSID = "AgAdi"
6PASS = "Sifre123"
7UTC_OFFSET = 3 * 3600          # Türkiye UTC+3 / Turkey UTC+3
8# localtime(): 0 = Pazartesi / 0 = Monday
9GUNLER = ("Pazartesi", "Sali", "Carsamba", "Persembe", "Cuma", "Cumartesi", "Pazar")
10
11wlan = network.WLAN(network.STA_IF)
12wlan.active(True)
13wlan.connect(SSID, PASS)
14while not wlan.isconnected():  # bağlanana kadar bekle / wait until connected
15    time.sleep(0.5)
16
17ntptime.host = "pool.ntp.org"
18for deneme in range(5):        # NTP bazen zaman aşımına uğrar / NTP may time out
19    try:
20        ntptime.settime()      # dahili RTC'yi UTC'ye ayarlar / sets the internal RTC to UTC
21        break
22    except OSError:
23        time.sleep(2)
24
25def yerel_saat():              # UTC + 3 saat / UTC + 3 hours
26    return time.localtime(time.time() + UTC_OFFSET)
27
28son_gun = -1
29while True:
30    yil, ay, gun, saat, dk, sn, hgun, ygun = yerel_saat()
31    print("{:02d}.{:02d}.{} {} {:02d}:{:02d}:{:02d}".format(gun, ay, yil, GUNLER[hgun], saat, dk, sn))
32    if saat == 7 and dk == 30 and ygun != son_gun:   # her gün 07:30'da bir kez / once a day at 07:30
33        son_gun = ygun
34        print("Gorev calisti / task ran")
35    time.sleep(1)
36

time.localtime() liefert in MicroPython ein Tupel mit acht Elementen: Jahr, Monat (1–12), Tag, Stunde, Minute, Sekunde, Wochentag und Tag im Jahr. Zwei Unterschiede zur struct tm des ESP32: Der Monat beginnt bei 1, und der Wochentag zählt 0 = Montag. ntptime.settime() wirft bei einer Zeitüberschreitung im Netzwerk einen OSError; deshalb hat der Code eine Schleife mit fünf Versuchen.

Projektideen mit der ESP32-NTP-Uhr

  • WLAN-Tischuhr: Uhrzeit, Datum und Raumtemperatur auf einem OLED-Display zeigen und nachts die Helligkeit senken.
  • Große LED-Uhr: Die NTP-Zeit als Lauftext auf einer MAX7219-LED-Matrix anzeigen.
  • Zeitgesteuerte Pflanzenbewässerung: Jeden Morgen die Bodenfeuchte prüfen und bei Bedarf eine Mini-Wasserpumpe für eine feste Zeit laufen lassen.
  • Datenlogger mit Zeitstempel: Sensormesswerte mit ISO-Datum auf eine SD-Karte schreiben.
  • Uhr mit Wetter: Neben der Uhrzeit das Wetter aus dem Internet zeigen; der Beitrag ESP32 Wetter setzt hier an.
  • Morgenbericht: Jeden Tag um 08:00 die Raumtemperatur und die nachts erkannten Bewegungen per Telegram aufs Handy schicken.

Häufige Fehler und Lösungen

SymptomMögliche UrsacheLösung
Zeit steht auf 1970 oder kommt nieWLAN nicht verbunden oder NTP-Port (UDP 123) gesperrtZuerst WiFi.status() prüfen; in Schul- und Firmennetzen ein anderes Netz oder einen Handy-Hotspot testen
Uhr geht genau 1 bzw. 2 Stunden nachKeine Zeitzone gesetzt, es wird UTC angezeigtconfigTzTime("CET-1CEST,M3.5.0,M10.5.0/3", ...)
Uhr liegt um den doppelten Versatz danebenUmgekehrtes Vorzeichen in der TZ-Zeichenkette ("CET+1")"CET-1CEST,..." bzw. "<+03>-3" schreiben
Monat einen zu wenig, Jahr 126tm_mon zählt ab 0, tm_year ab 1900tm_mon + 1, tm_year + 1900 oder strftime verwenden
Aufgabe löst in derselben Minute mehrfach ausKein WiederholungsschutzDen Lauftag (tm_yday) speichern und prüfen
Schleife hängt bei jedem Durchlauf 5 SekundenOhne gültige Zeit wartet getLocalTime() standardmäßig 5000 msIn loop() getLocalTime(&t, 0) verwenden
Seltsame Symbole im Wochentag auf dem OLEDDie Schrift hat keine UmlauteWochentage in ASCII schreiben oder zur Bibliothek U8g2 wechseln
Um einen Fehler einzugrenzen, lass zuerst den ersten Sketch laufen, der die Zeit nur im seriellen Monitor ausgibt. Stimmt sie dort, liegt das Problem bei Display, RTC oder Aufgabenlogik; ist sie auch dort falsch, schau dir WLAN und Zeitzoneneinstellung an.

ESP32 NTP ist der günstigste und bequemste Weg, einem Projekt eine genaue Uhrzeit zu geben: Mit wenigen Codezeilen holt er die Zeit auf die Sekunde genau, verwaltet Zeitzone und Sommerzeit selbst und übersteht mit einem zusätzlichen DS3231 auch Stromausfälle. In der BlueGrays-App findest du Projekte zu Echtzeit per ESP32 NTP, einer Digitaluhr mit DS1307-RTC, einer Wetteranzeige auf dem OLED und einem Temperaturlogger mit Zeitstempel, jeweils Schritt für Schritt mit Schaltplan und Code.

Häufige Fragen

Kann der ESP32 die Uhrzeit ohne Internet halten?

Ja, sobald er die Zeit einmal per NTP erhalten hat: Der ESP32 zählt die Systemzeit mit seinem eigenen Timer weiter, und ein WLAN-Ausfall hält die Uhr nicht an. Fällt aber der Strom aus oder startet das Board neu, springt die Zeit auf 1970. Für Orte ohne Internet oder eine ausfallsichere Uhr ergänzt du ein batteriegepuffertes RTC-Modul wie den DS3231.

Warum geht meine ESP32-NTP-Uhr eine Stunde falsch?

Ohne Zeitzone zeigt der ESP32 UTC an, im Winter also eine Stunde und im Sommer zwei Stunden hinter der deutschen Zeit. Verwende configTzTime("CET-1CEST,M3.5.0,M10.5.0/3", "pool.ntp.org"). Liegt sie um den doppelten Versatz daneben, ist das Vorzeichen in der TZ-Zeichenkette vertauscht.

Wie stelle ich beim ESP32 die Sommerzeit ein?

Am einfachsten mit configTzTime und einer POSIX-Zeitzone, die die Umstellungsregeln enthält. Für Deutschland, Österreich und die Schweiz lautet sie "CET-1CEST,M3.5.0,M10.5.0/3"; der ESP32 stellt dann am letzten Sonntag im März und im Oktober automatisch um. configTime mit festem Sommerzeit-Versatz kennt die Termine nicht.

Wie oft synchronisiert der ESP32 mit NTP?

Im Arduino-ESP32-Core fragt SNTP standardmäßig alle 3 Stunden erneut beim Server an und hält die Zeit dazwischen mit seinem eigenen Timer. Das Intervall änderst du mit sntp_set_sync_interval() in Millisekunden, laut Protokoll aber nicht unter 15 Sekunden.

Brauche ich beim ESP32 ein RTC-Modul?

Nicht, wenn das Gerät dauerhaft Strom hat und ins WLAN kommt; NTP ist genauer. Brauchst du nach einem Stromausfall sofort die richtige Zeit, bevor das Internet wieder da ist, oder läuft das Gerät ohne Internet, ergänzt du ein batteriegepuffertes RTC-Modul wie den DS3231.

Wie bekomme ich am Raspberry Pi Pico W die NTP-Zeit?

In MicroPython reicht nach der WLAN-Verbindung import ntptime und ntptime.settime(); damit wird die interne RTC des Pico auf UTC gestellt. Für die deutsche Zeit rechnest du time.localtime(time.time() + 3600) im Winter und + 7200 im Sommer. Da ntptime nicht automatisch neu abgleicht, solltest du settime() ein- bis zweimal am Tag wiederholen.

Alle Projekte ansehen
ESP32: Echtzeit aus dem Internet per NTP
#128Fortgeschritten
Premium

ESP32: Echtzeit aus dem Internet per NTP

Der ESP32 verbindet sich mit dem WLAN und ruft die Echtzeit mit Millisekunden-Genauigkeit von NTP-Servern (Network Time Protocol) ab. Dank configTzTime() wird die türkische Zeitzone (TRT, UTC+3) automatisch angewendet, und der DST-Wechsel wird per POSIX-TZ-String verwaltet. Die Uhrzeit wird auf dem Serial Monitor und einem optionalen I2C-LCD ausgegeben. configTzTime() startet den SNTP-Dienst; bei verfügbarem Netzwerkzugang erfolgt regelmäßig eine erneute Synchronisierung, und zwischen den Sy

4.5(13)
21
Digitale Uhr mit ESP32 und RTC DS1307 (I2C + LCD)
#120Mittel
Premium

Digitale Uhr mit ESP32 und RTC DS1307 (I2C + LCD)

In diesem Projekt zeigen wir Uhrzeit und Datum auf einem 16x2-I2C-LCD-Display mithilfe des DS1307-Echtzeituhrmoduls (RTC) an. Das DS1307 ist ein batteriegestütztes RTC, das die Uhrzeit auch dann beibehält, wenn das ESP32 ausgeschaltet ist. Beide Module teilen sich denselben I2C-Bus (SDA/SCL), sodass wir mit nur zwei Signalkabeln die Steuerung mehrerer Geräte erlernen. So lernen Sie das I2C-Protokoll und die Funktionsweise von RTC-Modulen in der Praxis kennen.

4.6(26)
40
ESP32-WLAN-STA-Verbindung (mit LCD-Display)
#127Fortgeschritten

ESP32-WLAN-STA-Verbindung (mit LCD-Display)

In diesem Projekt verbinden wir den ESP32 im Station-Modus (STA) sicher und fehlertolerant mit dem heimischen WLAN. Wir lagern SSID und Passwort in eine separate secrets.h-Datei aus, um Leaks zu Git zu verhindern, richten einen Auto-Reconnect-Mechanismus ein und zeigen RSSI-Signalpegel und IP-Adresse auf einem I2C-LCD-Display an. Die interne LED dient als Statusanzeige. Ein Verbindungsmanager auf Produktionsniveau.

4.4(21)
34
ESP32 HTTPClient + Wetter-API (mit SSD1306-OLED-Display)
#134Fortgeschritten
Premium

ESP32 HTTPClient + Wetter-API (mit SSD1306-OLED-Display)

In diesem Projekt führen wir mit dem ESP32 über das Internet mithilfe von HTTPClient.h einen REST-API-Aufruf an die Wetter-API (wttr.in) durch. Im Gegensatz zur vorherigen I2C-LCD-Version verwenden wir hier ein SSD1306-OLED-Display (128×64) – dies ermöglicht große Schriftarten, Vektor-Symbole und eine reichhaltige visuelle Darstellung auf einem einzigen Bildschirm. Für die Wetteranzeige werden 7 verschiedene Vektor-Symbole (sonnig, teilweise bewölkt, bewölkt, regnerisch, schneereich, stürmisch

4.3(10)
19
ESP32 HTTPClient + Wetter-API (mit LCD-Display)
#133Fortgeschritten
Premium

ESP32 HTTPClient + Wetter-API (mit LCD-Display)

In diesem Projekt führen wir mit dem ESP32 über das Internet mithilfe von HTTPClient.h einen REST-API-Aufruf an die Wetter-API (wttr.in) durch. Mit ArduinoJson v7 analysieren wir die zurückgegebenen JSON-Daten und zeigen Informationen zu Stadt, Temperatur, Luftfeuchtigkeit, Wetter und Wind sowohl auf Türkisch als auch auf Englisch auf einem I2C-LCD-Display an. wttr.in ist kostenlos und erfordert keinen API-Schlüssel – Sie können den aktuellen Wetterbericht einer beliebigen Stadt abrufen, indem

4.7(13)
20
ESP32 Deep Sleep – Batteriesparmodus (OLED + RTC-RAM-Zähler)
#135Fortgeschritten
Premium

ESP32 Deep Sleep – Batteriesparmodus (OLED + RTC-RAM-Zähler)

Der Deep-Sleep-Modus des ESP32 senkt den Stromverbrauch auf etwa 10 µA, indem er die CPU und die meisten Peripheriegeräte abschaltet, und ist für batteriebetriebene IoT-Geräte von entscheidender Bedeutung. In diesem Projekt verwenden wir drei verschiedene Weckquellen: den Timer (15 s), einen externen Pin (EXT0 – Taste GPIO 33) und die Berührungserkennung (T0/GPIO 4). Mit RTC_DATA_ATTR markierte Variablen bleiben während des Deep-Sleep-Modus erhalten – der Boot-Zähler, der Timer-Wake-Zähler und

4.3(10)
16
ESP32 Temperatur-Datenlogger (DHT22 + DS1307 RTC + microSD + OLED)
#144Fortgeschritten
Premium

ESP32 Temperatur-Datenlogger (DHT22 + DS1307 RTC + microSD + OLED)

Baue einen zeitgestempelten Temperaturlogger mit ESP32! Lese Temperatur/Feuchtigkeit vom DHT22 jede Minute, hole die aktuelle Zeit vom DS1307 RTC und protokolliere auf microSD-Karte als CSV. Das OLED zeigt live Temperatur (große Schrift), Luftfeuchtigkeit, Zeitstempel und Logzähler. Die /temp_log.csv-Datei auf der SD-Karte öffnet sich in Excel, Google Sheets oder Python pandas zur Analyse — perfekt für Gewächshausüberwachung, Raumtemperaturverfolgung, Laboraufzeichnung, Lebensmittellageru

4.7(7)
12
ESP32 I2C-LCD-Display (16×2)
#119Mittel
Premium

ESP32 I2C-LCD-Display (16×2)

In diesem Projekt zeigen wir Text an, indem wir ein 16x2-Zeichen-LCD-Display über das I2C-Protokoll an den ESP32 anschließen. Dank I2C können wir das Display mit nur zwei Datenpins (SDA und SCL) steuern; die Verschwendung von 6+ Pins bei einer klassischen parallelen Verbindung entfällt. Der Code schreibt in die erste Zeile eine feste Meldung und in die zweite Zeile einen Zähler, der sich jede Sekunde erhöht. Außerdem lassen wir zu Beginn den I2C-Scanner laufen und geben die Adresse des Displays

4.9(23)
40