Arduino RTC Modul: DS3231, DS1307 und DS1302 als Echtzeituhr
Arduino RTC Modul: DS3231, DS1307 und DS1302 im Vergleich, Uhrzeit mit RTClib stellen, LCD-Uhr, zeitgesteuerte Bewässerung, CR2032-Ladefalle und ESP32-NTP.
Ein Arduino RTC Modul ist eine kleine Uhrenplatine, die Datum und Uhrzeit weiterzählt, auch wenn dein Board keinen Strom mehr hat. RTC steht für "Real Time Clock", also Echtzeituhr. Der Arduino-eigene Zähler millis() beginnt bei jedem Einschalten bei null und kann innerhalb weniger Tage um Minuten abweichen; ein RTC-Modul läuft dagegen dank seiner Knopfzelle (CR2032) jahrelang sekundengenau. Du findest es in Tischuhren, automatischen Bewässerungen, Futterautomaten, Datenloggern mit Zeitstempel und zeitgesteuerter Beleuchtung.
In dieser Anleitung vergleichst du die drei verbreitetsten Chips, DS1307, DS3231 und DS1302, und erfährst, welchen du warum wählen solltest. Danach stellen und lesen wir Schritt für Schritt die Uhrzeit mit der Bibliothek RTClib, zeigen Uhrzeit und Datum auf einem I2C-LCD, bauen einen Timer, der täglich zu festen Zeiten eine Pumpe einschaltet, und nutzen den Hardware-Alarm des DS3231. Die letzten Abschnitte behandeln die CR2032-Ladefalle, die viele Module ruiniert, die Uhrzeit aus dem Internet per NTP auf dem ESP32 und die eingebaute RTC des Raspberry Pi Pico.

Was ist ein RTC-Modul und wie funktioniert es?
Im Herzen eines RTC-Chips sitzt ein Uhrenquarz mit 32,768 kHz. Diese Zahl ist kein Zufall: 32.768 ist 2 hoch 15, der Chip halbiert diese Frequenz also 15-mal und erhält so einen exakten Takt von 1 Sekunde. Bei jedem Takt werden die Register für Sekunden, Minuten, Stunden, Tag, Monat und Jahr aktualisiert; Monatslängen und Schaltjahre werden bis zum Jahr 2100 automatisch berücksichtigt. Der Arduino liest diese Register über I2C oder schreibt eine neue Uhrzeit hinein. Die Werte liegen im BCD-Format vor (59 Sekunden werden zum Beispiel als 0x59 gespeichert); die Umrechnung übernehmen die Bibliotheken für dich.
Der eigentliche Trick einer RTC sind ihre zwei Versorgungseingänge. Fällt VCC weg, schaltet der Chip automatisch auf den Batterieeingang (VBAT) um und zieht nur so viel Strom, wie er zum Weiterzählen braucht: weniger als ein Mikroampere oder wenige Mikroampere. Der DS1307 sperrt in dieser Zeit den I2C-Zugriff, der DS3231 lässt sich auch im Batteriebetrieb auslesen; die Uhr läuft in beiden Fällen weiter. Kommt der Strom zurück, startet der Arduino, liest die richtige Uhrzeit aus der RTC und macht dort weiter, wo er aufgehört hat. Wegen der Toleranz des Keramikresonators auf dem Arduino Uno kann eine mit millis() geführte Uhr pro Tag um Minuten abweichen und geht bei jedem Reset verloren; deshalb braucht jedes zeitabhängige Projekt eine eigene RTC.
DS1307, DS3231 und DS1302 im Vergleich
| Merkmal | DS1307 | DS3231 | DS1302 |
|---|---|---|---|
| Schnittstelle | I2C (100 kHz), Adresse 0x68 | I2C (bis 400 kHz), Adresse 0x68 | 3-Draht-seriell: CE (RST), I/O (DAT), SCLK (CLK) |
| Versorgungsspannung | 4,5–5,5 V | 2,3–5,5 V | 2,0–5,5 V |
| Quarz | Extern, 32,768 kHz (12,5 pF) | Im Chip integriert, temperaturkompensiert (TCXO) | Extern, 32,768 kHz (6 pF) |
| Genauigkeit | Abhängig vom Quarz; bei ±20 ppm ca. 1,7 s/Tag, ca. 1 min/Monat | ±2 ppm (0–40 °C): ca. 5 s/Monat, ca. 1 min/Jahr | Abhängig vom Quarz; ähnlich wie DS1307 oder schlechter |
| Extras | 56 Byte batteriegepuffertes RAM, Rechtecksignal-Ausgang (SQW) | 2 Alarme, INT/SQW-Ausgang, Temperatursensor (±3 °C), Alterungskorrektur | 31 Byte RAM, eingebaute Ladeschaltung (Trickle Charger) |
| Batteriestrom | Ca. 300–500 nA | Ca. 1–3 µA | Unter 300 nA bei 2 V |
| Arduino-Bibliothek | RTClib (Adafruit) | RTClib (Adafruit) | Rtc by Makuna |
| Geeignet für | Einfache 5-V-Uhrenprojekte | Fast jedes Projekt; auch ideal für ESP32 und Pico | Ältere Kits und Lernprojekte |
Machen wir den Genauigkeitsunterschied greifbar: 1 ppm bedeutet ein Millionstel, und ein Tag hat 86.400 Sekunden. Ein gewöhnlicher Quarz mit ±20 ppm kann um bis zu 1,7 Sekunden pro Tag abweichen, also etwa 52 Sekunden im Monat; je weiter die Temperatur von der Raumtemperatur entfernt ist, desto stärker ändert sich die Quarzfrequenz und desto größer wird der Fehler. Der DS3231 trägt seinen Quarz dagegen im Chip, misst alle 64 Sekunden die Temperatur und korrigiert die Frequenz entsprechend. So erreicht er zwischen 0 und 40 °C ±2 ppm, also etwa eine Minute pro Jahr, und bleibt selbst von -40 bis +85 °C innerhalb von ±3,5 ppm.
Welches RTC-Modul soll ich wählen?
- Neues Projekt, ESP32 oder Pico: Nimm einen DS3231. Er läuft mit 3,3 V und 5 V, hat Alarme und liefert die genaueste Uhrzeit. Der Preisunterschied ist minimal.
- Du hast schon einen DS1307 und nutzt einen Arduino Uno: Setz ihn ruhig ein; rechne nur mit etwa einer Minute Abweichung pro Monat und stelle die Uhr ab und zu nach.
- In deinem Starterkit lag ein DS1302: Um zu lernen, wie eine RTC funktioniert, ist er gut geeignet, eine monatelang genaue Uhr solltest du aber nicht erwarten.
- ESP32 mit ständiger Internetverbindung: Starte ohne Modul mit NTP; füge einen DS3231 hinzu, wenn die Uhrzeit nach einem Stromausfall schon vor der Rückkehr des Internets bekannt sein muss.
Am häufigsten begegnen dir zwei fertige Platinen: das ZS-042 mit DS3231-Chip und das Tiny RTC mit DS1307. Beide tragen zusätzlich ein 4-KB-EEPROM vom Typ AT24C32 zum Speichern von Daten. Deshalb ist es normal, dass ein I2C-Scanner neben 0x68 eine zweite Adresse findet (beim ZS-042 meist 0x57, beim Tiny RTC 0x50); sie gehört zum EEPROM, nicht zur Uhr. Der DS1302 nutzt dagegen gar kein I2C: Er spricht ein eigenes 3-Draht-Protokoll und belegt drei digitale Pins.
RTC-Modul anschließen: Arduino Uno, ESP32 und Pico
| RTC-Pin | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 (DS3231) | 3V3(OUT), physischer Pin 36 (DS3231) |
| GND | GND | GND | GND |
| SDA | A4 | GPIO 21 | GP4 (I2C0) |
| SCL | A5 | GPIO 22 | GP5 (I2C0) |
| SQW / INT (optional) | D2 (Interrupt-Pin) | Beliebiger GPIO (z. B. GPIO 4) | Beliebiger GP-Pin (z. B. GP15) |
Beim Uno R3 sind die SDA- und SCL-Buchsen neben dem AREF-Pin ebenfalls mit A4 und A5 verbunden; welche du nutzt, ist egal. Die RTC kann sich die beiden Leitungen mit einem I2C-LCD oder OLED-Display teilen; jedes Gerät hat eine eigene Adresse, daher gibt es keinen Konflikt. Halte die Kabel kürzer als 20–30 cm, das verhindert zufällige Lesefehler, besonders auf dem Breadboard. Den SQW/INT-Pin musst du nur anschließen, wenn du den Hardware-Alarm nutzen willst.
RTClib installieren und die Uhrzeit stellen
- Öffne in der Arduino IDE den Bibliotheksverwalter, suche nach RTClib und installiere die Bibliothek von Adafruit. Bei der Frage nach Abhängigkeiten wählst du Install all, damit auch Adafruit BusIO installiert wird. Falls du noch nie eine Bibliothek hinzugefügt hast, erklärt dir Arduino-Bibliothek hinzufügen jeden Schritt.
- Schließe das Modul wie in der Tabelle oben an und setze die Knopfzelle in die Halterung.
- Lade den folgenden Code hoch. Beim ersten Start kennt das Modul die Uhrzeit nicht, also schreibt der Code die Kompilierzeit deines Computers in die RTC.
- Öffne den seriellen Monitor mit 9600 Baud und dem Zeilenende "Neue Zeile". Willst du die Uhr sekundengenau stellen, tippe die Zeit im Format 2026-11-03 14:30:00 ein und drücke Enter.
- Zieh das USB-Kabel ab, warte ein paar Minuten und stecke es wieder ein. Läuft die Uhr korrekt dort weiter, wo sie war, funktioniert die Batteriepufferung.
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc; // DS1307 kullanıyorsan: RTC_DS1307 rtc; / for a DS1307: RTC_DS1307 rtc;
5
6void setup() {
7 Serial.begin(9600);
8 if (!rtc.begin()) { // modül I2C hattında yok / module not found on the I2C bus
9 Serial.println(F("RTC bulunamadi / RTC not found"));
10 while (true);
11 }
12 if (rtc.lostPower()) { // ilk çalıştırma ya da pil bitmiş / first run or dead battery
13 rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // derleme saatini yaz / write the compile time
14 Serial.println(F("Saat derleme zamanina ayarlandi / Clock set to compile time"));
15 }
16 Serial.println(F("Ayar icin yaz / To set, type: 2026-11-03 14:30:00"));
17}
18
19void loop() {
20 // Seri monitörden saat geldiyse ayarla / set the time sent from the Serial Monitor
21 if (Serial.available()) {
22 String line = Serial.readStringUntil('\n');
23 int y, mo, d, h, mi, s;
24 if (sscanf(line.c_str(), "%d-%d-%d %d:%d:%d", &y, &mo, &d, &h, &mi, &s) == 6) {
25 rtc.adjust(DateTime(y, mo, d, h, mi, s));
26 Serial.println(F("Saat ayarlandi / Time set"));
27 }
28 }
29
30 DateTime now = rtc.now();
31 char buf[] = "DD.MM.YYYY hh:mm:ss"; // biçim şablonu / format template
32 Serial.print(now.toString(buf));
33 Serial.print(F(" "));
34 Serial.print(rtc.getTemperature()); // yalnız DS3231 / DS3231 only
35 Serial.println(F(" C"));
36 delay(1000);
37}rtc.begin() liefert false, wenn das Modul am I2C-Bus nicht gefunden wird; prüfe dann zuerst die Verkabelung. rtc.lostPower() liest das Oscillator-Stop-Flag (OSF) des DS3231: Es ist true, wenn das Modul zum ersten Mal läuft oder die Uhr wegen leerer Batterie stehen geblieben ist, und der Code stellt die Uhr dann auf die Kompilierzeit. DateTime(F(__DATE__), F(__TIME__)) verwendet den Zeitpunkt, an dem der Compiler deinen Code übersetzt hat; da das Hochladen ein paar Sekunden dauert, geht die Uhr danach leicht nach, deshalb ist das Feinjustieren über den seriellen Monitor praktisch. toString() ersetzt die Buchstaben in der Vorlage "DD.MM.YYYY hh:mm:ss" durch die echten Werte.
| Funktion | Was sie macht |
|---|---|
| rtc.begin() | Startet das Modul; liefert false, wenn es nicht gefunden wird |
| rtc.adjust(DateTime(...)) | Schreibt Uhrzeit und Datum |
| rtc.now() | Liest die aktuelle Zeit als DateTime-Objekt |
| now.year(), now.month(), now.day() | Jahr, Monat, Tag |
| now.hour(), now.minute(), now.second() | Stunde (0–23), Minute, Sekunde |
| now.dayOfTheWeek() | Wochentag: 0 = Sonntag, 6 = Samstag |
| now.unixtime() | Sekunden seit dem 1. Januar 1970; ideal zum Vergleichen zweier Zeitpunkte |
| now + TimeSpan(0, 1, 30, 0) | Addiert 1 Stunde 30 Minuten (Tage, Stunden, Minuten, Sekunden) |
| rtc.lostPower() / rtc.isrunning() | Zeigt, ob die Uhrzeit gültig ist (DS3231 / DS1307) |
| rtc.getTemperature() | Chiptemperatur in °C (nur DS3231) |
Nutzt du einen DS1307, unterscheidet sich nur der Objektname: Schreibe RTC_DS1307 rtc;, prüfe statt lostPower() mit !rtc.isrunning() und lösche die Zeile mit getTemperature(). Beim allerersten Einschalten startet der Oszillator des DS1307 angehalten (CH-Bit auf 1); adjust() löscht dieses Bit und startet die Uhr. Im 56 Byte großen, batteriegepufferten RAM des DS1307 kannst du mit rtc.writenvram() und rtc.readnvram() kleine Einstellungen wie eine Weckzeit speichern; dank der Batterie überstehen auch diese Daten einen Stromausfall.
Uhrzeit und Datum auf dem LCD anzeigen
Die Uhrzeit auf einem Display statt im seriellen Monitor zu sehen, macht aus dem Projekt eine echte Tischuhr. Ein 16x2-I2C-LCD und die RTC hängen am selben SDA-SCL-Bus: Das LCD hat meist die Adresse 0x27 oder 0x3F, die RTC 0x68. Der folgende Code schreibt in die obere Zeile das Datum und das Wochentagskürzel, in die untere die Uhrzeit und die vom DS3231 gemessene Temperatur. Zum Anschluss des LCD und zur Installation der Bibliothek lies I2C-LCD-Display verwenden.
1#include <Wire.h>
2#include <RTClib.h>
3#include <LiquidCrystal_I2C.h>
4
5RTC_DS3231 rtc;
6LiquidCrystal_I2C lcd(0x27, 16, 2); // adres 0x27 ya da 0x3F / address 0x27 or 0x3F
7
8// dayOfTheWeek(): 0 = Pazar / 0 = Sunday
9const char* const days[7] = {"Paz", "Pzt", "Sal", "Car", "Per", "Cum", "Cmt"};
10int lastSecond = -1;
11
12void setup() {
13 lcd.init();
14 lcd.backlight();
15 if (!rtc.begin()) {
16 lcd.print("RTC yok!"); // modül bulunamadı / module not found
17 while (true);
18 }
19 if (rtc.lostPower()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
20}
21
22void loop() {
23 DateTime now = rtc.now();
24 if (now.second() == lastSecond) return; // saniye değişmediyse yazma / skip until the second changes
25 lastSecond = now.second();
26
27 char line1[17], line2[17];
28 snprintf(line1, sizeof(line1), "%02d.%02d.%04d %s",
29 now.day(), now.month(), now.year(), days[now.dayOfTheWeek()]);
30 snprintf(line2, sizeof(line2), "%02d:%02d:%02d %2dC",
31 now.hour(), now.minute(), now.second(), (int)rtc.getTemperature());
32 lcd.setCursor(0, 0);
33 lcd.print(line1); // ör. / e.g. 03.11.2026 Sal
34 lcd.setCursor(0, 1);
35 lcd.print(line2); // ör. / e.g. 14:05:09 23C
36}Das %02d in snprintf ergänzt einstellige Zahlen um eine führende Null, so erscheint die Zeit als 09:05:03 statt 9:5:3 und die Zeilenlänge bleibt immer gleich. Dank der festen Länge brauchst du kein lcd.clear(); das Display in jedem Durchlauf zu löschen, führt zu Flackern. Der Code schreibt nur dann aufs Display, wenn sich die Sekunde ändert, und belegt so den I2C-Bus nicht unnötig. Das Array days enthält türkische Kürzel; ersetze sie durch So, Mo, Di usw., wobei Sonntag an erster Stelle stehen muss.
Alarm und zeitgesteuerte Aufgaben: automatische Bewässerung und Futterautomat
Das Nützlichste an einer RTC ist, Aufgaben nach Zeitplan zu erledigen: jeden Morgen um 08:00 die Pflanzen gießen, abends um 19:30 das Katzenfutter ausgeben oder nachts das Aquarienlicht ausschalten. Dafür gibt es zwei Wege. Der erste ist ein Vergleich in Software: Du liest in loop() die Uhrzeit und prüfst, ob die Zeit für eine Aufgabe gekommen ist. Das ist einfach, und du kannst beliebig viele Aufgaben hinzufügen. Der zweite ist der Hardware-Alarm des DS3231: Zum eingestellten Zeitpunkt zieht der Chip seinen INT-Pin auf LOW und meldet sich per Interrupt beim Arduino; er kann sogar einen schlafenden Mikrocontroller wecken.
Ein häufiger Fehler beim Software-Vergleich ist die Prüfung auf eine exakte Sekunde wie now.second() == 0. Steht in loop() ein langes delay(), kann diese Sekunde verstreichen und die Aufgabe läuft nie. Der folgende Code vergleicht Stunde und Minute, merkt sich einen Schlüssel aus Tag und Minute, damit die Aufgabe nicht zweimal in derselben Minute startet, und misst die Laufzeit der Pumpe mit millis(). Die Pumpe wird über ein Relaismodul geschaltet; den Anschluss der Pumpe findest du im Artikel Mini-Wasserpumpe.
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;
5
6const byte RELAY_PIN = 7;
7const byte RELAY_ON = LOW; // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
8const byte RELAY_OFF = HIGH;
9const unsigned long RUN_MS = 10000; // pompa 10 saniye çalışır / the pump runs for 10 seconds
10
11struct Task { byte hour; byte minute; };
12Task tasks[] = { {8, 0}, {19, 30} }; // her gün 08:00 ve 19:30 / every day at 08:00 and 19:30
13const byte TASK_COUNT = sizeof(tasks) / sizeof(tasks[0]);
14
15long lastRunKey = -1; // aynı dakikada ikinci kez çalışmasın / never run twice in one minute
16bool running = false;
17unsigned long startMs = 0;
18
19void setup() {
20 pinMode(RELAY_PIN, OUTPUT);
21 digitalWrite(RELAY_PIN, RELAY_OFF); // açılışta kapalı / off at start-up
22 rtc.begin();
23}
24
25void loop() {
26 DateTime now = rtc.now();
27 long key = (long)now.day() * 1440 + now.hour() * 60 + now.minute(); // gün + dakika / day + minute
28
29 for (byte i = 0; i < TASK_COUNT; i++) {
30 if (now.hour() == tasks[i].hour && now.minute() == tasks[i].minute && key != lastRunKey) {
31 lastRunKey = key;
32 running = true;
33 startMs = millis();
34 digitalWrite(RELAY_PIN, RELAY_ON); // pompayı aç / pump on
35 }
36 }
37
38 if (running && millis() - startMs >= RUN_MS) {
39 running = false;
40 digitalWrite(RELAY_PIN, RELAY_OFF); // pompayı kapat / pump off
41 }
42 delay(200);
43}Dass der Tag im Schlüssel steckt, ist wichtig: Würdest du nur die Minute speichern und gäbe es nur eine Aufgabe, wäre der Schlüssel am nächsten Tag zur selben Minute noch gleich und die Aufgabe liefe nie wieder. Für einen Futterautomaten nimmst du statt des Relais einen Servomotor: Dreht er zur Aufgabenzeit auf 90 Grad und eine Sekunde später zurück, öffnet sich die Klappe des Vorratsbehälters und eine Portion Futter fällt heraus. Für eine intelligentere Bewässerung liest du zur Aufgabenzeit einen Bodenfeuchtesensor aus und lässt die Pumpe aus, wenn die Erde noch feucht ist. Das zweite Beispiel unten erledigt dieselbe Aufgabe mit dem Hardware-Alarm des DS3231.
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;
5const byte ALARM_PIN = 2; // DS3231 SQW/INT -> D2 (kesme pini / interrupt pin)
6volatile bool alarmFlag = false;
7
8void onAlarm() { // kesme fonksiyonu kısa olmalı / keep the ISR short
9 alarmFlag = true;
10}
11
12void setup() {
13 Serial.begin(9600);
14 rtc.begin();
15 rtc.disable32K(); // 32K çıkışını kapat / turn off the 32K output
16 rtc.writeSqwPinMode(DS3231_OFF); // SQW pini alarm çıkışı olur / SQW becomes the alarm output
17 rtc.clearAlarm(1);
18 rtc.clearAlarm(2);
19 rtc.disableAlarm(2);
20
21 // Her gün 07:30:00; tarih kısmı yok sayılır / every day at 07:30:00; the date part is ignored
22 rtc.setAlarm1(DateTime(2026, 1, 1, 7, 30, 0), DS3231_A1_Hour);
23
24 pinMode(ALARM_PIN, INPUT_PULLUP); // INT çıkışı open-drain / INT is an open-drain output
25 attachInterrupt(digitalPinToInterrupt(ALARM_PIN), onAlarm, FALLING);
26}
27
28void loop() {
29 if (alarmFlag) {
30 alarmFlag = false;
31 rtc.clearAlarm(1); // temizlenmezse pin LOW kalır / the pin stays LOW until cleared
32 Serial.println(F("Alarm: mama vakti / Feeding time"));
33 // Servo, röle ya da buzzer kodunu buraya yaz / put your servo, relay or buzzer code here
34 }
35}Der DS3231 hat zwei Alarme. Alarm 1 arbeitet sekundengenau; der Modus DS3231_A1_Hour löst aus, wenn Stunden, Minuten und Sekunden übereinstimmen, also jeden Tag zur selben Zeit. Mit den anderen Modi stellst du einen Alarm jede Sekunde (PerSecond), jede Minute (Second), jede Stunde (Minute), an einem bestimmten Tag des Monats (Date) oder an einem bestimmten Wochentag (Day). Alarm 2 arbeitet minutengenau. Der SQW/INT-Pin ist ein Open-Drain-Ausgang, aktiv LOW: Er geht beim Alarm auf LOW und bleibt dort, bis clearAlarm() aufgerufen wird. Deshalb setzt du in der Interrupt-Funktion am besten nur ein Flag und erledigst die eigentliche Arbeit in loop(). Wie Interrupts funktionieren, erfährst du unter Arduino Interrupts.
Wie lange hält die RTC-Batterie?
Die Batterielaufzeit lässt sich leicht abschätzen: Laufzeit (Stunden) = Batteriekapazität (mAh) ÷ Stromaufnahme (mA). Eine CR2032 hat etwa 220 mAh. Im Batteriebetrieb zieht der DS3231 im ungünstigsten Fall rund 3 µA, also 0,003 mA: 220 ÷ 0,003 ≈ 73.000 Stunden, das sind ungefähr 8 Jahre. Die Batterie wird nur genutzt, solange VCC fehlt; steckt das Modul in einem Gerät, das ständig Strom hat, wird sie kaum belastet und hält viel länger. In der Praxis setzen meist die Lagerfähigkeit der Zelle und die Ladeschaltung des Moduls die Grenze.
| Chip | Batteriestrom | Berechnete Laufzeit mit CR2032 (220 mAh) |
|---|---|---|
| DS1307 | ~0,5 µA | ~50 Jahre; praktisch begrenzt durch die Lagerfähigkeit der Zelle (ca. 10 Jahre) |
| DS3231 | ~3 µA (ungünstigster Fall) | ~8 Jahre |
| DS1302 | ~0,3 µA | Begrenzt durch die Lagerfähigkeit der Zelle |
| Modul mit aktiver Ladeschaltung + CR2032 | Strom wird in die Zelle gedrückt | Unvorhersehbar; die Zelle kann sich aufblähen und früh ausfallen |
Die Falle mit CR2032 und Ladeschaltung
Die meisten günstigen DS3231- (ZS-042) und DS1307-Module (Tiny RTC) enthalten eine einfache Ladeschaltung, die eigentlich für einen wiederaufladbaren LIR2032-Akku gedacht ist. Beim ZS-042 fließt Strom von VCC über eine 1N4148-Diode und einen 200-Ω-Widerstand zur Zelle; das Tiny RTC hat eine ähnliche Schaltung. Das Problem: Diese Module werden oft mit einer nicht wiederaufladbaren CR2032 verkauft. Läuft das Modul mit 5 V, drücken die nach der Diode verbleibenden rund 4,3 V ständig Strom in die 3-V-Lithiumzelle. Eine Zelle, die nie geladen werden sollte, kann sich mit der Zeit aufblähen, auslaufen und vorzeitig leer werden, und du hast das Problem "Batterie drin, aber die Uhr setzt sich immer wieder zurück".
- Wenn du eine CR2032 nutzt, unterbrich den Ladepfad: Löte beim ZS-042 den 200-Ω-SMD-Widerstand mit der Aufschrift "201" in der Nähe der Stiftleiste oder die Diode daneben aus. Für Widerstände, deren Code du nicht lesen kannst, hilft der SMD-Code-Rechner. Das ist die verbreitetste und sicherste Lösung.
- Wenn du die Schaltung so lässt, setze einen LIR2032 ein: Die Kapazität des Akkus (ca. 40 mAh) beträgt nur etwa ein Fünftel einer CR2032 (ca. 220 mAh), er wird aber voll gehalten, solange das Modul Strom hat.
- Wenn du das Modul mit 3,3 V versorgst: Hinter der Diode kommen nur etwa 2,6 V an der Zelle an; ein LIR2032 wird nie ganz voll, und in eine CR2032 fließt praktisch kein Strom. Den Widerstand auszulöten bleibt trotzdem die sauberste Lösung.
- Die eingebaute Ladeschaltung des DS1302 ist beim Einschalten deaktiviert; nutzt du eine CR2032, aktiviere sie nicht im Code.
- Miss die Zelle: Eine neue CR2032 zeigt 3,0–3,2 V; fällt sie unter 2,5 V, tausche sie aus.
DS1302 verwenden (3-Draht-Anschluss)

Das DS1302-Modul hat fünf Pins: VCC, GND, CLK, DAT und RST. Da es kein I2C nutzt, wird es nicht an A4-A5, sondern an drei beliebige digitale Pins angeschlossen; im Beispiel unten geht DAT an D4, CLK an D5 und RST an D2, versorgt wird das Modul mit 5V. Die RTClib von Adafruit unterstützt den DS1302 nicht, installiere dafür im Bibliotheksverwalter die Bibliothek Rtc by Makuna. Der DS1302 hat zwei Schutzbits: Bei aktivem Schreibschutz lässt sich die Uhr nicht stellen, und bei gesetztem Clock-Halt-Bit läuft sie nicht weiter. Der Code prüft beides und stellt die Uhr auf die Kompilierzeit, wenn die gespeicherte Zeit ungültig ist.
1#include <RtcDS1302.h>
2
3ThreeWire myWire(4, 5, 2); // DAT, CLK, RST pinleri / DAT, CLK, RST pins
4RtcDS1302<ThreeWire> rtc(myWire);
5
6void setup() {
7 Serial.begin(9600);
8 rtc.Begin();
9 if (rtc.GetIsWriteProtected()) rtc.SetIsWriteProtected(false); // yazma korumasını kaldır / remove write protection
10 if (!rtc.GetIsRunning()) rtc.SetIsRunning(true); // saati başlat / start the clock
11
12 RtcDateTime compiled(__DATE__, __TIME__);
13 if (!rtc.IsDateTimeValid() || rtc.GetDateTime() < compiled) {
14 rtc.SetDateTime(compiled); // derleme saatine ayarla / set to compile time
15 }
16}
17
18void loop() {
19 RtcDateTime now = rtc.GetDateTime();
20 char buf[20];
21 snprintf(buf, sizeof(buf), "%02u.%02u.%04u %02u:%02u:%02u",
22 now.Day(), now.Month(), now.Year(), now.Hour(), now.Minute(), now.Second());
23 Serial.println(buf);
24 delay(1000);
25}Die häufigste Beschwerde über DS1302-Module ist, dass die Uhr pro Woche um Minuten abweicht. Ein Grund: Der Chip braucht einen Quarz, der auf eine Lastkapazität von 6 pF abgestimmt ist, während günstige Module Quarze mit anderen Werten verwenden können. Auch lange, wackelige Kabel verursachen Lesefehler auf der seriellen Leitung des DS1302. Hast du einen DS1302, ist er ein prima Einstieg, um RTCs zu verstehen; baust du aber eine Uhr, die monatelang genau bleiben soll, steig auf den DS3231 um.
NTP statt RTC beim ESP32: die Uhrzeit aus dem Internet
Weil sich der ESP32 mit dem WLAN verbinden kann, braucht er oft gar kein RTC-Modul: Per NTP (Network Time Protocol) holt er sich in wenigen Sekunden die genaue Uhrzeit von Zeitservern wie pool.ntp.org. Der Arduino-Core des ESP32 bringt dafür die fertigen Funktionen configTzTime() und getLocalTime() mit; die Zeitzone wird als Regel-String übergeben. Die Türkei bleibt seit 2016 ohne Sommerzeit bei UTC+3, daher ist die Regel im Code ein fester Versatz von +3 Stunden. Für Deutschland, Österreich und die Schweiz nimmst du die mitteleuropäische Regel aus dem Kommentar im Code; sie berechnet die Umstellungstage der Sommerzeit selbst.
Die Schwachstelle von NTP ist die Abhängigkeit vom Internet: Nach einem Stromausfall, bis der Router hochgefahren ist, oder wenn sich das WLAN-Passwort ändert, kennt der ESP32 die Uhrzeit nicht. Der interne RTC-Timer des ESP32 hält die Zeit zwar während des Deep Sleep, wird aber bei komplettem Stromverlust zurückgesetzt. Am robustesten ist die Kombination aus beidem: Erreicht der ESP32 beim Start einen NTP-Server, gleicht er den DS3231 mit der Internetzeit ab; sonst liest er die Uhrzeit aus dem DS3231 und synchronisiert einmal täglich neu. Mehr zu NTP findest du unter ESP32-Uhrzeit per NTP.
1#include <WiFi.h>
2#include <Wire.h>
3#include <RTClib.h>
4#include <time.h>
5
6const char* WIFI_SSID = "AgAdin"; // Wi-Fi ağ adı / Wi-Fi network name
7const char* WIFI_PASS = "Sifren"; // Wi-Fi şifresi / Wi-Fi password
8// Türkiye: UTC+3, yaz saati yok / Turkey: UTC+3, no daylight saving
9// Orta Avrupa / Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
10const char* TZ_INFO = "<+03>-3";
11
12RTC_DS3231 rtc;
13unsigned long lastSync = 0;
14
15void syncFromNtp() {
16 struct tm t;
17 if (getLocalTime(&t, 10000)) { // en fazla 10 sn bekle / wait up to 10 s
18 rtc.adjust(DateTime(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec));
19 Serial.println("DS3231 NTP ile ayarlandi / DS3231 synced from NTP");
20 }
21 lastSync = millis();
22}
23
24void setup() {
25 Serial.begin(115200);
26 Wire.begin(21, 22); // SDA, SCL pinleri / SDA, SCL pins
27 rtc.begin();
28
29 WiFi.begin(WIFI_SSID, WIFI_PASS);
30 unsigned long start = millis();
31 while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) delay(250);
32
33 if (WiFi.status() == WL_CONNECTED) {
34 configTzTime(TZ_INFO, "pool.ntp.org", "time.google.com");
35 syncFromNtp();
36 } else {
37 Serial.println("Wi-Fi yok, DS3231 saati kullaniliyor / No Wi-Fi, using the DS3231");
38 }
39}
40
41void loop() {
42 DateTime now = rtc.now();
43 char buf[] = "DD.MM.YYYY hh:mm:ss";
44 Serial.println(now.toString(buf));
45
46 if (WiFi.status() == WL_CONNECTED && millis() - lastSync > 86400000UL) {
47 syncFromNtp(); // günde bir kez eşitle / sync once a day
48 }
49 delay(1000);
50}Die eingebaute RTC des Raspberry Pi Pico
Der RP2040-Chip des Raspberry Pi Pico enthält eine RTC-Einheit, der RP2350 im Pico 2 erledigt dieselbe Aufgabe mit einem Always-on-Timer (AON-Timer). In MicroPython nutzt du beide über dieselbe Klasse machine.RTC: RTC().datetime() liest oder schreibt die Zeit als (Jahr, Monat, Tag, Wochentag, Stunde, Minute, Sekunde, Subsekunden), und auch time.localtime() verwendet diese Uhr. Sie hat aber keine Batterie: Verliert der Pico die Stromversorgung, startet MicroPython die Uhr am 1. Januar 2021 um 00:00.
Hier lauert eine Falle für Einsteiger: Thonny gleicht die Uhr des Pico beim Verbinden standardmäßig mit der Uhr deines Computers ab. Beim Testen sieht also alles richtig aus, doch sobald der Pico an einem Handy-Netzteil oder an einer Batterie hängt, springt die Uhr auf 2021 zurück. Die Lösung: Schließe einen DS3231 an den Pico an und stelle die interne RTC beim Start danach. Der folgende Code braucht keine Treiberdatei; er liest die ersten sieben Register des DS3231 über I2C und rechnet sie von BCD in Dezimalzahlen um. Mit einem Pico W kannst du die Zeit auch per ntptime.settime() aus dem Internet holen; da die Funktion UTC liefert, musst du den Versatz deiner Zeitzone selbst addieren (in Mitteleuropa im Winter +1, im Sommer +2 Stunden). Bist du neu beim Pico, beginne mit Was ist der Raspberry Pi Pico?.
1from machine import Pin, I2C, RTC
2import time
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
5DS_ADDR = 0x68 # DS3231 ve DS1307 adresi / DS3231 and DS1307 address
6
7def bcd2dec(b):
8 return (b >> 4) * 10 + (b & 0x0F)
9
10def dec2bcd(d):
11 return ((d // 10) << 4) | (d % 10)
12
13def ds_read():
14 b = i2c.readfrom_mem(DS_ADDR, 0x00, 7) # saniyeden yıla 7 kayıt / 7 registers, seconds to year
15 return (2000 + bcd2dec(b[6]), bcd2dec(b[5] & 0x1F), bcd2dec(b[4] & 0x3F),
16 bcd2dec(b[2] & 0x3F), bcd2dec(b[1] & 0x7F), bcd2dec(b[0] & 0x7F))
17
18def ds_write(y, mo, d, h, mi, s):
19 # 24 saat biçiminde yazar; 4. bayt haftanın günü (1-7) / writes 24-hour time; 4th byte is day of week (1-7)
20 i2c.writeto_mem(DS_ADDR, 0x00, bytes([dec2bcd(s), dec2bcd(mi), dec2bcd(h), 1,
21 dec2bcd(d), dec2bcd(mo), dec2bcd(y - 2000)]))
22
23# İlk kurulumda bir kez çalıştır, sonra satırı sil / run once on first setup, then delete the line
24# ds_write(2026, 11, 3, 14, 30, 0)
25
26y, mo, d, h, mi, s = ds_read()
27RTC().datetime((y, mo, d, 0, h, mi, s, 0)) # dahili RTC'yi ayarla / set the internal RTC
28
29while True:
30 t = time.localtime() # artık dahili RTC'den okunur / now read from the internal RTC
31 print("{:02d}.{:02d}.{} {:02d}:{:02d}:{:02d}".format(t[2], t[1], t[0], t[3], t[4], t[5]))
32 time.sleep(1)Projektideen mit dem RTC-Modul
- Digitale Tischuhr mit Kalender: Zeige Uhrzeit, Datum und die vom DS3231 gemessene Temperatur auf einem LCD, OLED oder einer LED-Matrix.
- Automatische Pflanzenbewässerung: Prüfe jeden Morgen die Bodenfeuchte und lass die Pumpe bei Bedarf eine festgelegte Zeit laufen.
- Futterautomat für Haustiere: Öffne zwei- oder dreimal am Tag mit einem Servo die Klappe des Behälters und gib eine Portion Futter aus.
- Datenlogger mit Zeitstempel: Schreibe Temperatur- und Feuchtewerte zusammen mit Datum und Uhrzeit auf ein SD-Kartenmodul und erstelle danach in Excel ein Diagramm.
- Schul- oder Werkstattklingel: Lass zu Beginn und Ende jeder Stunde einen Buzzer oder eine Klingel per Relais ertönen und überspringe Wochenenden mit dayOfTheWeek().
- Zeitschaltuhr für Aquarium- und Pflanzenlicht: Schalte das Licht morgens ein und abends aus und dimme es per PWM langsam für einen Sonnenaufgangs- und Sonnenuntergangseffekt.
Häufige Fehler und Lösungen
- "RTC nicht gefunden", begin() liefert false: SDA und SCL sind vertauscht, GND ist nicht gemeinsam oder das Modul hat keine Versorgung. Lass einen I2C-Scanner laufen und prüfe, ob die Adresse 0x68 erscheint.
- Unsinnige Werte wie das Jahr 2165, 165 oder 85: Vom Chip kommen keine Daten, alle gelesenen Bytes sind 0xFF. Prüfe die Verkabelung; versorgst du einen DS1307 mit 3,3 V, wechsle auf 5 V.
- Nach jedem Reset springt die Uhr auf denselben Zeitpunkt: Die Zeile rtc.adjust() steht ohne Bedingung in setup(); knüpfe sie an lostPower().
- Nach einem Stromausfall ist die Uhrzeit weg: Die Batterie ist leer, falsch herum eingesetzt oder fehlt. Miss ihre Spannung und denk daran, dass die Ladeschaltung die CR2032 zerstört haben kann.
- Die Uhr weicht pro Woche um Minuten ab: Ursache sind der Quarz von DS1307 oder DS1302 und Temperaturschwankungen. Steig auf einen DS3231 um oder synchronisiere regelmäßig per NTP.
- Die Uhrzeit liegt genau eine oder mehrere Stunden daneben: Zeitzone oder Sommerzeit ist falsch eingestellt. Schreibe die Ortszeit in die RTC; nutzt du NTP, wähle die richtige Zeitzonenregel.
- Der DS3231 zeigt eine höhere Temperatur als im Raum: Der Wert ist die Temperatur des Chips selbst, auf ±3 °C genau und von der Erwärmung der Platine beeinflusst. Für die Raumtemperatur nimm einen eigenen Sensor.
Kurz gesagt: Für fast jedes Projekt, das Uhrzeit und Datum braucht, ist der DS3231 die richtige Wahl; der DS1307 reicht für einfache 5-V-Projekte, der DS1302 zum Lernen. Auf dem ESP32 nimmst du NTP, wenn Internet da ist, sonst einen DS3231; beim Pico ist es am zuverlässigsten, die interne RTC beim Start aus einem DS3231 zu stellen. In der BlueGrays-App findest du Schritt-für-Schritt-Projekte mit Schaltplänen und Code: DS1302-Uhr einrichten und LCD-Uhr, DS1307-Dot-Matrix-Uhr mit Kalender, ESP32-Digitaluhr mit RTC, Internetzeit per NTP und einen Temperaturlogger mit Zeitstempel.
Häufige Fragen
Funktioniert ein RTC-Modul ohne Batterie?
Solange VCC anliegt, läuft die Uhr und lässt sich auslesen. Sobald aber der Strom ausfällt, bleibt die Uhr stehen oder wird zurückgesetzt, und du musst sie beim nächsten Start neu stellen. Da der Sinn einer RTC gerade darin liegt, die Zeit über Stromausfälle zu retten, brauchst du fast immer eine Batterie; nutzt du einen DS1307 ohne Batterie, muss sein VBAT-Pin mit GND verbunden werden.
Was ist besser, DS3231 oder DS1307?
In fast allen Fällen der DS3231. Dank seines temperaturkompensierten, eingebauten Quarzes weicht er nur etwa eine Minute pro Jahr ab, ein DS1307 dagegen bis zu einer Minute pro Monat. Außerdem läuft der DS3231 mit 2,3–5,5 V und funktioniert damit direkt an ESP32 und Pico; er hat zwei Alarme und einen Temperatursensor. Mit RTClib ist der Code für beide fast identisch.
Wie lange hält die Batterie eines RTC-Moduls?
Im reinen Batteriebetrieb zieht ein DS3231 höchstens etwa 3 µA, ein DS1307 rund 0,5 µA. Rechnerisch hält eine CR2032 mit 220 mAh bei diesen Strömen mehr als 8 Jahre. In der Praxis können die Lagerfähigkeit der Zelle und die Ladeschaltung des Moduls das verkürzen; in einem Modul mit aktiver Ladeschaltung kann eine CR2032 deutlich früher leer sein.
Warum setzt mein RTC-Modul die Uhrzeit immer wieder zurück?
Es gibt drei häufige Ursachen: Die Zeile rtc.adjust() in setup() stellt die Uhr bei jedem Start auf die Kompilierzeit zurück, die Batterie ist leer oder verkehrt herum eingesetzt, oder die Ladeschaltung hat die CR2032 zerstört. Knüpfe zuerst adjust() an lostPower(), miss dann die Batteriespannung mit dem Multimeter und tausche die Zelle unter 2,5 V aus.
Brauche ich beim ESP32 ein RTC-Modul?
Nicht, wenn das Gerät ständig online ist; der ESP32 holt sich die genaue Uhrzeit per NTP in wenigen Sekunden. Bei Projekten, in denen das Internet ausfallen kann, die Uhrzeit nach einem Stromausfall schon vor dem Router bekannt sein muss oder die komplett offline laufen, ist ein zusätzlicher DS3231 die sicherste Wahl. Am besten nutzt du beides und gleichst den DS3231 einmal täglich per NTP ab.
Kann ich eine CR2032 in ein DS3231-Modul einsetzen?
Ja, aber bei Modulen mit Ladeschaltung wie dem ZS-042 musst du zuerst den Ladepfad unterbrechen. Lötest du den 200-Ω-Widerstand (Code 201) oder die Diode daneben aus, läuft eine CR2032 sicher über Jahre. Willst du die Platine nicht verändern, nimm stattdessen einen wiederaufladbaren LIR2032-Akku.
Projekte, die du danach bauen kannst
Alle Projekte ansehen
DS1302-RTC-Uhrenmodul einrichten
Du bringst ein kleines Uhrmodul zum Laufen, das die Zeit nicht vergisst, selbst wenn der Arduino ausgeschaltet ist. Das Modul hat seine eigene winzige Batterie, und sobald die Uhr einmal gestellt ist,

DS1302 RTC-Uhr mit LCD-Anzeige
Eine kleine Tischuhr, die die Zeit auch bei Stromausfall nicht vergisst. Das Uhrmodul DS1302 hält die Zeit mit seiner eigenen kleinen Batterie; jede Sekunde liest der Arduino sie aus und schreibt Uhrz

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.

Punktmatrixuhr und Kalender (MAX7219, DS1307)
Eine leuchtende Tafel für Tisch oder Wand, die Uhrzeit und Datum als Laufschrift zeigt. Auf dem 8x32-LED-Display steht eine Uhr mit großen Ziffern, deren zwei Punkte jede Sekunde blinken; zu Beginn je

Punktmatrix-Uhr, Kalender und Wetterstation (MAX7219, DS1307)
Eine Laufschrift-Tafel für Tisch oder Wand, die abwechselnd Uhrzeit, Datum und das Raumklima zeigt. Auf dem 8x32-LED-Display erscheint zuerst die Temperatur in Celsius und Fahrenheit, dann die Luftfeu

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

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

Digitaluhr mit 4-stelliger 7-Segment-Anzeige
Eine leuchtende vierstellige Digitaluhr, ähnlich wie die am Backofen. Das Uhrmodul DS1302 hält die Zeit, der Arduino liest jede Sekunde Stunden und Minuten aus und zeigt sie auf der vierstelligen Anze
Weitere Artikel
BlueGrays-App
Diese Schaltung Schritt für Schritt auf dem Handy nachbauen
Schaltplan, Code und Teileliste auf einem Bildschirm. Über 160 Arduino-, ESP32- und Pico-Projekte zum Nachbauen.
Mit dem Handy scannen
Richte die Kamera auf den Code, dann öffnet sich der App-Store deines Handys.
oder im Store öffnen

