In diesem Tutorial lernst du, wie du ein DS3231 Real Time Clock (RTC) Modul mit einem ESP32 verwendest.
Ein RTC-Modul ist eine externe Uhr, die die aktuelle Zeit und das Datum verfolgt. Es arbeitet unabhängig von der Hauptstromversorgung, sodass es die genaue Zeit auch bei ausgeschaltetem Strom beibehält.
Ich zeige dir, wie du ein RTC in Kombination mit dem ESP32 im Deep-Sleep verwendest, wie du die RTC für die Sommerzeit anpasst und wie du die RTC mit einem Internet-Zeitserver synchronisierst.
Benötigte Teile
Für dieses Projekt benötigst du ein DS3231 RTC Modul und einen ESP32. Ich verwende den ESP32 lite als Mikroprozessor, da er eine Batterieschnittstelle zum Laden hat, mit der du den ESP32 und die RTC mit einer LiPo-Batterie betreiben kannst. Allerdings funktionieren auch andere ESP32 oder ESP8266. Zur Anzeige der Zeit habe ich ein OLED gewählt, du könntest aber auch ein LCD Display.

ESP32 lite

USB-Datenkabel

DS3231 RTC Modul

Dupont-Kabelset

Breadboard

OLED-Display
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.
Grundlagen des DS3231 Chips
Der DS3231 ist ein kleiner Chip (38 x 22 x 14 mm) mit einer hochpräzisen Echtzeituhr (RTC) und einem integrierten temperaturkompensierten Quarzoszillator und Quarz. Dieser Chip enthält einen Batteriefachhalter, sodass er auch bei abgeschalteter Hauptstromversorgung weiterläuft.

Die RTC verfolgt Sekunden, Minuten, Stunden, Wochentag, Datum, Monat und Jahr. Für Monate mit weniger als 31 Tagen wird das Datum automatisch angepasst, inklusive Schaltjahreskorrekturen. Die Uhr arbeitet im 24-Stunden- oder 12-Stunden-Format. Sie bietet zwei programmierbare Kalenderalarme und einen programmierbaren Rechteckwellenausgang. Die Kommunikation erfolgt über einen I2C-Bus.
Eine präzise, temperaturkompensierte Spannungsreferenz und ein Komparator überwachen den VCC-Status, erkennen Stromausfälle, liefern einen Reset-Ausgang und schalten bei Bedarf automatisch auf die Backup-Stromversorgung um. Das Gerät integriert einen digitalen Temperatursensor, der über die I2C-Schnittstelle zugänglich ist.
Im Folgenden sind die Hauptmerkmale des DS3231 aufgeführt (source):
Technische Spezifikationen
- Betriebsspannung: 3,3–5,5 V
- Uhrchip: Hochpräziser Uhrchip DS3231
- Uhrgenauigkeit: 2 ppm im Bereich von 0-40 °C, jährlicher Fehler ca. 1 Minute
- Zwei Kalenderalarme
- Programmierbarer Rechteckwellenausgang
- Echtzeituhr generiert Sekunden, Minuten, Stunden, Wochentag, Datum, Monat und Jahr mit Schaltjahrkompensation bis 2100
- Integrierter Temperatursensor mit ±3 °C Genauigkeit
- Speicherchip: AT24C32 (32K Speicherkapazität)
- IIC-Busschnittstelle, maximale Übertragungsgeschwindigkeit 400 kHz (bei 5 V Betriebsspannung)
- Kann mit anderen IIC-Geräten kaskadiert werden, 24C32-Adresse kann durch Kurzschließen von A0/A1/A2 geändert werden, Standardadresse ist 0x57
- Verwendet CR2032-Batterie, um den Betrieb der Uhr bei Stromausfall sicherzustellen
Blockdiagramm des DS3231
Das folgende Blockdiagramm zeigt die internen Komponenten des DS3231. Du siehst den Quarzoszillator, den Temperatursensor, die Stromversorgungskontrolle und die I2C-Schnittstelle.

Die Pins des DS3231 sind wie folgt: VCC und GND für die allgemeine Stromversorgung und VBAT für die Batteriepufferung. SCL und SDA sind für die I2C-Schnittstelle.
Der Pin mit der Bezeichnung „33kHz“ gibt das 32kHz Taktsignal aus. INT/SQW ist ein Interrupt-Pin, der zur Signalisierung von Alarmen oder als programmierbarer Rechteckwellenausgang verwendet werden kann.
RST ist der Reset-Pin, der dem angeschlossenen Mikroprozessor signalisiert, dass die Stromversorgung verloren ging oder wiederhergestellt wurde. Die Pins „33kHz“, INT/SQW und RST haben weitere Funktionen. Für Details siehe das unten verlinkte Datenblatt:
Grundlagen des DS3231 RTC Moduls
Der DS3231 Chip selbst ist zu klein, um direkt an einen ESP32 angeschlossen zu werden, und es fehlen einige erforderliche Bauteile. Deshalb verwendet man typischerweise ein DS3231 RTC Modul. Das Modul enthält die fehlenden Komponenten und hat auch einen Halter für eine CR2032 Batterie, die die Backup-Stromversorgung liefert. Das Bild unten zeigt Vorder- und Rückseite eines typischen DS3231 RTC Moduls:

Anstelle einer CR2032 Batterie kannst du auch eine wiederaufladbare LIR2032 Batterie verwenden, musst aber auf die Versorgungsspannung achten. Mehr dazu später.
Pinbelegung des DS3231 RTC Moduls
Die Pinbelegung eines DS3231 RTC Moduls entspricht im Wesentlichen der des DS3231 Chips.

VCC und GND sind für die Stromversorgung mit 3,3–5,5 V. SCL und SDA sind die Pins für die I2C-Schnittstelle (mit integrierten 4,7k Pullup-Widerständen). Die Pins 32K und SQW sind Ausgänge für das 32kHz Taktsignal und das programmierbare Rechteckwellensignal, die hier nicht benötigt werden.
Die I2C-Adresse des DS3231 RTC Moduls ist über drei Lötpads (A0, A1, A2) konfigurierbar, die überbrückt werden können. Siehe den hervorgehobenen Bereich unten rechts auf dem Modul im Bild oben. Die Standard-I2C-Adresse ist 0x57, wenn keine Brücken gesetzt sind. Das Bild unten zeigt alle möglichen Konfigurationen und die entsprechenden I2C-Adressen.

Batterieladung mit DS3231 RTC Modul
Das DS3231 RTC Modul ermöglicht das Laden der Backup-Batterie über die Hauptstromversorgung (VCC). Das Bild unten zeigt den Schaltplan des DS3231 RTC Moduls. Im gelb markierten Bereich siehst du einen 200Ω Widerstand und eine 1N4148 Diode, die als sehr einfache Ladeschaltung fungieren.

Du musst diese Ladeschaltung jedoch deaktivieren, wenn eine nicht wiederaufladbare CR2032-Batterie mit einer Versorgungsspannung von 5 V verwendet wird. Und wenn du eine wiederaufladbare LIR2032-Batterie nutzt, sollte VCC für sicheres Laden niemals höher als 4,7 Volt sein.
Der Battery charging circuit of DS3231 module Artikel beschreibt die Probleme der Ladeschaltung ausführlicher und zeigt auch, wie man sie deaktiviert. Die folgende Tabelle aus dem Artikel listet die verschiedenen Szenarien mit unterschiedlichen Versorgungsspannungen und Batterietypen sowie die erforderlichen Maßnahmen auf:
| Batterietyp | 3,3 V Versorgung | 5 V Versorgung |
|---|---|---|
| CR2032 | Batterie nicht betroffen | Ladeschaltung deaktivieren |
| LIR2032 | Batterie nicht betroffen Laden funktioniert nicht | Ladeschaltung deaktivieren oder Sicherstellen, dass 5 V tatsächlich 4,7 V sind |
Anschluss des DS3231 RTC Moduls an ESP32 lite
Das Anschließen des DS3231 RTC Moduls an einen ESP32 ist einfach. Verbinde zuerst SCL des DS3231 mit Pin 23 des ESP32. Dann verbinde SDA mit Pin 19 des ESP32. Schließlich verbinde GND mit Masse und 3,3 V mit VCC, wie unten gezeigt:

Da wir das DS3231 RTC Modul mit 3,3 V betreiben, kann eine CR2032-Batterie eingesetzt sein, während es an die Stromversorgung angeschlossen ist.
Einfacher Testcode für DS3231 RTC Modul
Du benötigst eine Softwarebibliothek, um mit dem DS3231 RTC Modul zu kommunizieren. Es gibt mehrere, aber ich mag die Arduino-DS3231 Bibliothek von Korneliusz Jarzębski am liebsten. Um sie zu installieren, gehe zum github repo und klicke auf den grünen „Code“-Button. Wähle dann „Download Zip“ aus dem Menü, wie unten gezeigt:

Dies lädt eine Datei namens „Arduino-DS3231-dev.zip“ auf deinen Computer. Um diese ZIP-Bibliothek zu installieren, folge den üblichen Schritten. Klicke auf Sketch -> Add .ZIP Library und wähle dann die Datei Arduino-DS3231-dev.zip aus, die du gerade heruntergeladen hast.

Mit der installierten Bibliothek können wir die Funktion des DS3231 RTC Moduls testen. Der folgende einfache Code setzt die Zeit und das Datum im RTC Modul auf die Kompilierzeit des Sketches und gibt dann Zeit und Datum in einer Schleife aus:
#include "Wire.h"
#include "DS3231.h"
DS3231 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(__DATE__, __TIME__);
}
void loop() {
RTCDateTime dt = rtc.getDateTime();
Serial.printf("%4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
delay(1000);
}
Der Code beginnt mit dem Einbinden der Wire.h Bibliothek für I2C-Kommunikation und der DS3231.h Bibliothek für die Kommunikation mit dem DS3231 RTC.
Als nächstes erstellen wir eine Instanz der DS3231 Klasse. In der setup() Funktion initialisieren wir die RTC und setzen das aktuelle Datum und die Uhrzeit mit rtc.setDateTime(). Die Makros __DATE__ und __TIME__ fügen automatisch das Datum und die Uhrzeit ein, zu der der Sketch kompiliert wurde. Beachte, dass die Zeit nicht aktuell ist, wenn der ESP32 nach dem Kompilieren und Hochladen neu gestartet wird, aber das behandeln wir später.
In der loop-Funktion holen wir die aktuelle Zeit und das Datum von der RTC mit RTCDateTime dt = rtc.getDateTime() und verwenden printf, um Datum und Zeit im Serial Monitor auszugeben.
Beispielausgabe
Wenn du den Code hochlädst und den Serial Monitor öffnest, solltest du Datum und Zeit wie folgt sehen:

Sommerzeit mit DS3231 RTC Modul
Während der DS3231 Datum und Zeit genau verfolgt, passt er die Sommerzeit (DST) nicht automatisch an. Das bedeutet, dass der DS3231 falsche Zeit (und Datum) anzeigt, wenn dein Land auf Sommerzeit oder zurück auf Normalzeit (ST) umstellt.
Es gibt im Wesentlichen zwei Möglichkeiten, damit umzugehen. 1) Du könntest einen Knopf hinzufügen, der manuell zwischen DST und ST wechselt. Das ist natürlich nicht optimal. 2) Du fügst Code hinzu, der den Wechsel automatisch für deine Zeitzone durchführt.
In diesem Abschnitt zeige ich dir, wie du die Sommerzeit automatisch handhabst, während du das DS3231 RTC Modul nutzt. Wir verwenden dafür die ezTime Library Bibliothek. Du kannst sie wie gewohnt über den Library Manager installieren:

Nach der Installation kannst du sie verwenden, um die DS3231 RTC auf Sommerzeit mit folgendem Code einzustellen:
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
Timezone loc;
DS3231 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(2024,12,4,3,16,30); // UTC
loc.setPosix(TIMEZONE);
}
void loop() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
delay(5000);
}
Im obigen Code verbinden wir einen ESP32 mit einem DS3231 Real-Time Clock (RTC) Modul, um die aktuelle Zeit zu verfolgen, inklusive Anpassungen für die Sommerzeit. Das Programm initialisiert die RTC, setzt ein bestimmtes Datum und eine Uhrzeit und ruft dann alle 5 Sekunden die aktuelle UTC- und Ortszeit ab und zeigt sie an.
Lass uns den Code in seine Komponenten aufschlüsseln, um ihn besser zu verstehen.
Eingebundene Bibliotheken
Wir beginnen mit dem Einbinden der notwendigen Bibliotheken für unser Projekt. Die Wire.h Bibliothek wird für die I2C-Kommunikation verwendet, über die der ESP32 mit dem DS3231 RTC kommuniziert. Die DS3231.h Bibliothek bietet Funktionen speziell für die Interaktion mit dem DS3231 Modul, und ezTime.h wird für die Handhabung von Zeitzonen und Sommerzeitanpassungen genutzt.
#include "Wire.h" #include "DS3231.h" #include "ezTime.h"
Konstanten und Variablen
Als nächstes definieren wir eine Konstante für die Zeitzone. In diesem Fall verwenden wir AEST-10AEDT,M10.1.0,M4.1.0/3, was Melbourne, Australien entspricht. Dieser String gibt die Standardzeitverschiebung und die Regeln für die Sommerzeit an.
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
Die Teile dieser Zeitzonendefinition sind wie folgt
- AEST: Australian Eastern Standard Time
- -10: UTC-Versatz von 10 Stunden vor der koordinierten Weltzeit (UTC)
- AEDT: Australian Eastern Daylight Time
- M10.1.0: Übergang zur Sommerzeit am ersten Sonntag im Oktober
- M4.1.0/3: Rückkehr zur Normalzeit am ersten Sonntag im April, mit 3 Stunden Unterschied zur UTC.
Für andere Zeitzonendefinitionen schau dir die Posix Timezones Database an. Kopiere einfach den dort gefundenen String und ändere die TIMEZONE Konstante entsprechend.
Wir erstellen auch Instanzen der Timezone und DS3231 Klassen. Die loc Variable hält unsere Ortszeitinformationen, während rtc die RTC verwaltet.
Timezone loc; DS3231 rtc;
Setup-Funktion
In der setup() Funktion initialisieren wir die serielle Kommunikation mit 9600 Baud für Debugging. Dann initialisieren wir die RTC und setzen sie auf ein bestimmtes Datum und eine Uhrzeit (4. Dezember 2024, 03:16:30 UTC). Schließlich setzen wir die Zeitzone mit der zuvor definierten Konstante.
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(2024,12,4,3,16,30); // UTC
loc.setPosix(TIMEZONE);
}
Loop-Funktion
Die loop() Funktion läuft kontinuierlich. Zuerst holen wir die aktuelle Zeit und das Datum von der RTC mit rtc.getDateTime(). Dann setzen wir die UTC-Zeit mit den abgerufenen Werten.
RTCDateTime dt = rtc.getDateTime(); UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Als nächstes geben wir die aktuelle UTC-Zeit formatiert im Serial Monitor aus. Das umfasst Jahr, Monat, Tag, Stunde, Minute und Sekunde.
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Wir geben auch die Ortszeit mit der loc Variable aus, die für Zeitzone und Sommerzeit angepasst wurde.
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Zum Schluss fügen wir eine neue Zeile für bessere Lesbarkeit im seriellen Output hinzu und machen eine Pause von 5000 Millisekunden (5 Sekunden), bevor die Schleife wiederholt wird.
Serial.println(); delay(5000);
Beispielausgabe
Wenn du den Code hochlädst und den Serial Monitor öffnest, solltest du die UTC-Zeit der RTC und die Ortszeit (LOC) sehen:

Synchronisierung der DS3231 RTC mit SNTP-Server
Während der obige Code die Anpassung für Sommerzeit automatisch vornimmt, musst du die Zeit der RTC beim Start des ESP32 manuell einstellen. Noch schlimmer: Du musst den ESP32 an einen Computer anschließen, den Code ändern und neu programmieren. Das ist nervig!
Du könntest Tasten hinzufügen, um Zeit und Datum während des Betriebs des ESP32 zu ändern. Wenn du das machen willst, schau dir das Arduino and RTC Module DS3231 Tutorial an, wo wir zwei Tasten zum Einstellen der Zeit verwenden.
Die bessere Option ist jedoch, die RTC automatisch mit einem Internet-Zeitserver (SNTP) zu synchronisieren. Für mehr Hintergrundinfos siehe das How to synchronize ESP32 clock with SNTP server Tutorial.
Wenn du durchgehend Internetzugang hast und dir der Stromverbrauch egal ist, brauchst du keine RTC, da du die interne Uhr des ESP32 regelmäßig synchronisieren kannst. Das stellt die Uhr automatisch ein und berücksichtigt auch die Sommerzeit. Siehe die Automatic Daylight Savings Time Clock und Digital Clock on e-Paper Display Tutorials.
Für ein batteriebetriebenes Projekt willst du jedoch vermeiden, WiFi zu oft zu nutzen, da es viel Strom verbraucht. Ein typischer Anwendungsfall ist ein Datenlogger, z.B. für Temperatur, der möglichst lange mit Batterie laufen soll, aber genaue Zeitstempel braucht.
Der folgende Code zeigt dir, wie das geht. Er nutzt WiFi nur, wenn der ESP32 neu startet, um die RTC zu synchronisieren. Ansonsten ist der ESP32 im Deep-Sleep-Modus, um Strom zu sparen, und wacht nur gelegentlich auf, um die Zeit von der RTC zu holen und auszugeben:
#include "WiFi.h"
#include "esp_sntp.h"
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
const char* SSID = "SSID";
const char* PWD = "PASSWORD";
const int SLEEP = 10; // sec
DS3231 rtc;
Timezone loc;
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTzTime("UTC", "pool.ntp.org");
setRtcTime();
}
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
void printTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
}
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
void setup() {
Serial.begin(9600);
rtc.begin();
loc.setPosix(TIMEZONE);
if (isReset()) {
syncTime();
}
printTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
void loop() {
}
Lass uns den Code in seine Komponenten aufschlüsseln, um ihn besser zu verstehen.
Bibliotheken und Konstanten
Wir binden die notwendigen Bibliotheken für WiFi, SNTP (Simple Network Time Protocol), I2C-Kommunikation und das DS3231 RTC ein. Außerdem definieren wir Konstanten für die Zeitzone, WiFi-Zugangsdaten und Schlafdauer.
#include "WiFi.h" #include "esp_sntp.h" #include "Wire.h" #include "DS3231.h" #include "ezTime.h" const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne const char* SSID = "SSID"; const char* PWD = "PASSWORD"; const int SLEEP = 10; // sec
Natürlich musst du die WiFi-Zugangsdaten durch deine eigenen ersetzen.
RTC- und Zeitzonenobjekte
Wir erstellen Instanzen der DS3231 Klasse für die RTC und der Timezone Klasse zur Handhabung der Ortszeitberechnung.
DS3231 rtc; Timezone loc;
Sync-Time-Funktion
Die syncTime() Funktion verbindet sich mit dem WiFi-Netzwerk und konfiguriert die Zeitzone für den NTP-Server. Dann ruft sie setRtcTime() auf, um die RTC mit der aktuellen Zeit zu aktualisieren.
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTzTime("UTC", "pool.ntp.org");
setRtcTime();
}
Set-RTC-Time-Funktion
In der setRtcTime() Funktion holen wir die Ortszeit und setzen die Zeit und das Datum der RTC entsprechend. Das Jahr wird um 1900 erhöht, da das tm_year Feld die Anzahl der Jahre seit 1900 zurückgibt.
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
Beachte, dass wir auch 1 zu tm_mon addieren müssen, um den korrekten Monat zu erhalten, da die struct tm Datenstruktur inkonsistente Bereiche verwendet. Zum Beispiel beginnt der Tag des Monats bei 1, aber der Monat des Jahres bei 0:
Member Type Meaning Range tm_sec int seconds after the minute 0-61* tm_min int minutes after the hour 0-59 tm_hour int hours since midnight 0-23 tm_mday int day of the month 1-31 tm_mon int months since January 0-11 tm_year int years since 1900 tm_wday int days since Sunday 0-6 tm_yday int days since January 1 0-365 tm_isdst int Daylight Saving Time flag
Print-Time-Funktion
Die printTime() Funktion holt die aktuelle Zeit und das Datum von der RTC und gibt sie im Serial Monitor aus. Sie gibt auch die Ortszeit mit dem Zeitzonenobjekt aus.
void printTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
}
Check-Reset-Funktion
Die isReset() Funktion prüft, ob der ESP32 aus dem Deep-Sleep durch einen Timer oder einen anderen Grund aufgewacht ist. Das hilft zu entscheiden, ob die Zeit synchronisiert werden soll.
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
Setup-Funktion
In der setup() Funktion initialisieren wir die serielle Kommunikation, die RTC und setzen die Zeitzone. Wenn der ESP32 frisch startet (nicht aus dem Deep-Sleep aufwacht), synchronisieren wir die Zeit. Zum Schluss geben wir die Zeit aus und versetzen den ESP32 für die angegebene Dauer in den Deep-Sleep-Modus.
void setup() {
Serial.begin(9600);
rtc.begin();
loc.setPosix(TIMEZONE);
if (isReset()) {
syncTime();
}
printTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
Loop-Funktion
Die loop() Funktion ist leer, da der ESP32 im Deep-Sleep keinen Code ausführt. Er wacht nur auf, um die setup() Funktion nach der Schlafdauer erneut auszuführen.
void loop() { }
Anzeige der RTC-Zeit auf OLED
Als letztes Beispiel zeige ich dir, wie du ein OLED anschließt, um die Zeit und das Datum der RTC auf einem Bildschirm anzuzeigen. Das ist nur eine einfache Erweiterung des obigen Codes.
Das Anschließen des OLED ist einfach, da es ebenfalls ein I2C-Gerät ist. Verbinde einfach SDA, SCL, VCC und GND des OLED parallel zum DS3231 wie unten gezeigt

Unten ist der Code, der Zeit und Datum auf dem OLED anzeigt. Beachte, dass er die Adafruit_SSD1306 Bibliothek verwendet, die du install it via the Library Manager wie gewohnt installieren kannst.
#include "WiFi.h"
#include "esp_sntp.h"
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
#include "Adafruit_SSD1306.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3";
const char* SSID = "SSID";
const char* PWD = "PASSWORD";
const int SLEEP = 10; // sec
DS3231 rtc;
Timezone loc;
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTime(0, 0, "pool.ntp.org");
setRtcTime();
}
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
void displayTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
oled.clearDisplay();
oled.setCursor(10, 15);
oled.println(loc.dateTime("H:i:s"));
oled.setCursor(2, 45);
oled.println(loc.dateTime("d/m/Y"));
oled.display();
}
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
void setup() {
rtc.begin();
loc.setPosix(TIMEZONE);
oled_init();
if (isReset()) {
syncTime();
}
displayTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
void loop() {
}
Die einzigen Ergänzungen und Änderungen am Code sind die Funktion oled_init(), die das OLED initialisiert, und die Funktion displayTime(), die Zeit und Datum auf dem OLED anzeigt. Wenn du den Code auf deinen ESP32 hochlädst, solltest du Folgendes auf dem OLED sehen:

Und das war’s! Du solltest jetzt in der Lage sein, das DS3231 RTC zusammen mit einem ESP32 zu verwenden.
Fazit
In diesem Tutorial hast du gelernt, wie du ein DS3231 Real Time Clock (RTC) Modul mit einem ESP32 verwendest.
Der ESP32 lite mit einer Echtzeituhr eignet sich besonders für batteriebetriebene Projekte, die genaue Zeit benötigen und wenig Strom verbrauchen. Häufige Anwendungsfälle sind data loggers oder elektronische Uhren. Für Letztere empfehle ich e-Paper-Displays, da sie fast keinen Strom verbrauchen. Siehe unsere Tutorials, Analog Clock on e-Paper Display und Digital Clock on e-Paper Display.
Wenn du mehr über Uhren mit verschiedenen Displaytypen und Zeitsynchronisation lernen möchtest, schau dir das Digital Clock on e-Paper Display an,
Wenn du Fragen hast, kannst du sie gerne im Kommentarbereich stellen.
Viel Spaß beim Tüfteln ; )

