DS3231 RTC Modul, einfach erklärt!
von Edi · 18/02/2023
Das DS3231 RTC Modul
Das DS3231 Real time Clock Modul, kurz RTC, kann verwendet werden um die genaue Zeit an einem Microcontroller zu übergeben, auch wenn die Spannung unterbrochen wurde. Das wird durch den Einsatz einer CR2032 Batterie oder einem LIR2032 Akku bewerkstelligt der das Zeit zählen aktiv hält. Der DS3231 wird von einem temperaturkompensierten 32-kHz Quarzoszillator (TCXO) gesteuert, der sehr unempfindlich gegenüber externen Temperaturschwankungen ist und dadurch eine Genauigkeit von ± 2 Minuten pro Jahr erreichen kann. Kommuniziert werden kann mit diesem Modul über I2C und es kann zwischen acht unterschiedlichen Adressen gewählt werden. Auf der rechten Seite werden noch einmal die I2C und die Pins für die Spannungsversorgung ausgeführt um ein weiteres I2C Gerät anzuschiessen.
Verwendung mit einer CR2032 Batterie
Auf dem Modul ist eine einfache Ladeschaltung mit einer IN4148 Zener Diode und einem 200 Ω Widerstand für die Verwendung mit einem LIR2032 Akku verbaut. Wenn ihr lieber eine CR2032 Batterie einsetzen wollt, dann muss der Widerstand entfernt werden, da es ansonsten zu Schäden kommen kann, wenn man versucht eine Batterie zu laden!
I2C Adresse für den EEPROM konfigurieren
Wir haben die Möglichkeit beim DS3231 Modul zwischen acht unterschiedlichen I2C Adressen zu wählen, um auf den EEPROM zugreifen zu können. Wenn keine Brücke verlötet ist, haben wir standardmässig die Adresse 0x57. Je nachdem welche Brücken wir setzen, können wir die unterschiedlichen Adressen von 0x50 bis zu 0x57 erzeugen.
Praktisches Beispiel - Grundlagen
Befehle für die Zeit Darstellung:
jetzt.day() – Zeigt den Tag an
jetzt.month() – Zeigt das Monat an
jetzt.year() – Zeigt das Jahr an
wochentage[jetzt.dayOfTheWeek()] – Zeigt den Wochentag vom Array an
jetzt.hour() – Zeigt die Stunden an
jetzt.minute() – Zeigt die Minuten an
jetzt.second() – Zeigt die Sekunden an
jetzt.unixtime() – Zeigt die Unixtime an
Formatierung der Zeitausgabe
Wir können das Datum und die Zeit nach unseren Wünschen formatieren. Dazu wird das Format folgendermassen geschrieben.
hh – Stunden mit einer Null davor (00 bis 23)
mm – Minuten mit einer Null davor (00 bis 59)
ss – Sekunden mit einer Null davor (00 bis 59)
YYYY – Das Jahr mit vier Ziffern
YY – Das Jahr mit zwei Ziffern (00 bis 99)
MM – Das Monat mit zwei Ziffern (01-12)
MMM – Das Monat verkürzt auf Englisch geschrieben (Jan bis Dec)
DD – Der Tag mit zwei Ziffern (01 bis 31)
DDD – Der Tag verkürzt auf Englisch geschrieben (Mon bis Sun)
Es können zur besseren Formatierung auch Punkte, Bindestriche und Doppelpunkte verwendet werden.
Praktisches Beispiel Alarm
Parameter DS3231_A1_ | Alarm1, wenn… | Parameter DS3231_A2_ | Alarm2, wenn... |
---|---|---|---|
PerSecond | Einmal pro Sekunde | PerMinute | Einmal pro Minute (00 Sekunden jeder Minute) |
Second | Wenn Sekunden übereinstimmen | Minute | Wenn Minuten und Sekunden übereinstimmen |
Minute | Wenn Minuten und Sekunden übereinstimmen | Hour | Wenn Stunden, Minuten und Sekunden übereinstimmen |
Hour | Wenn Stunden, Minuten und Sekunden übereinstimmen | Date | Wenn Datum, Stunden, Minuten und Sekunden übereinstimmen |
Date | Wenn Datum, Stunden, Minuten und Sekunden übereinstimmen (Tag des Monats) | Day | Wenn Tag, Stunden, Minuten und Sekunden übereinstimmen |
Day | Wenn Tag, Stunden, Minuten und Sekunden übereinstimmen (Tag der Woche) | - | - |
Das DS3231 Modul können wir als Wecker oder Timer verwenden und dafür haben wir zwei Alarme zur Verfügung. Die Alarmfunktion erwartet zwei Argumente. Als erstes Argument wird der Zeitpunkt für den Alarm angegeben und als zweites Argument der alarm-mode, der den Alarm auslösen soll. Interessanterweise sind die erlaubten Parameter für Alarm1 und Alarm 2 unterschiedlich.
rtc.setAlarm1(Zeitpunkt, alarm-mode);
Als Beispiel ist hier der Alarm auf 5 Minuten gestellt. TimeSpan(Tage, Stunden, Minuten, Sekunden) Dieser Alarm löst jetzt 5 Minuten nach jeder Stunde aus. Eine Tabelle mit den möglichen alarm-mode, findet ihr im Anschluss.
rtc.setAlarm1(rtc.now() + TimeSpan(0,0,5,0), DS3231_A1_Minute);
Der SQW Pin kann auch zur Ausgabe von Rechteckwellen verwendet werden, und deswegen ergibt es Sinn, dass wir diese Funktion deaktivieren, da wir den Pin als Interrupt Pin benutzen. Dazu können wir diesen Befehl verwenden.
rtc.writeSqwPinMode(DS3231_OFF);
Es ist auch ratsam, dass wir alle vorhandenen Alarme löschen, bevor wir neue anlegen, da ein Alarm so lange bestehen bleibt, bis er gelöscht wird. Dazu verwenden wir den Befehl
rtc.clearAlarm(1); rtc.clearAlarm(2);
Mit dem Befehl disableAlarm wird der Alarm eins oder zwei deaktiviert.
rtc.disableAlarm(1); rtc.disableAlarm(2);
Es kann mit alarmFired das Register überprüft werden, ob der Alarm eins oder zwei ausgelöst hat.
rtc.alarmFired(1); rtc.alarmFired(2);
Der 24C32 EEPROM
EEPROM steht für Electrically Erasable Programmable Read-Only Memory, was so viel wie Elektrisch löschbarer und programmierbarer Festspeicher bedeutet. Der verbaute 24C32 EEPROM am DS3231 Modul hat eine Speichergrösse von 32 kBit und kann eine Million Schreibzyklen bewerkstelligen.
Für diesen Sketch wird die uEEPROMLib Library verwendet, die für das Beschreiben von einem EEPROM über I2C zuständig ist. Jedes Byte (8 bits) im EEPROM kann Werte von 0 bis 255 speichern. Wird mehr als ein Byte benötigt, dann kann der zu speichernde Wert auf mehrere Bytes aufgeteilt werden. Es muss beim Beschreiben von Werten immer der Speicherplatz im EEPROM angegeben werden und es muss darauf geachtet werden, dass man schon vorhandene Speicherplätze nicht überschreibt. Deswegen lieber immer etwas mehr Abstand zwischen den einzelnen Speicherplätzen lassen, wann immer möglich. Als Beispiel für einen 2 Byte Integer (0,2,4,6…)
Befehl zum Beschreiben von einem Wert:
eeprom.eeprom_write(Adresse, Wert);
Befehl zum Auslesen und den Wert in die Variable inttmp schreiben:
eeprom.eeprom_read(Adresse, &inttmp);