Arduino Basic – RTC Modul (DS3231)

In diesem Tutorial zeige ich Dir, wie Du ein RTC Modul (in diesem Fall eines mit dem Chip DS3231) mit einem Arduino UNO ansteuerst. Der DS3231-Chip ist beispielsweise auf dem RTC-Modul ZS-042 verbaut.

Benötigte Teile

Für dieses Tutorial benötigst Du die folgenden Teile:

  • Arduino UNO oder vergleichbarer Mikrocontroller
  • RTC-Modul mit einem DS3231 Chip (bspw. das Modul ZS-042)
  • Einen Computer mit installierter Arduino IDE
  • Kabel und (optional) ein Breadboard

Anschließen des RTC-Moduls

Ich habe ein Arduino UNO zusammen mit einem ZS-042 Modul verwendet. Diese beiden Komponenten wurden von mir direkt verkabelt (ich habe also kein Breadboard benutzt), da die Verkabelung relativ einfach ist:

RTC-Modul: Verkabelung (schematisch)
Verbindung des Arduino UNO mit dem ZS-042 Modul (schematisch)

Fertig verkabelt sieht das Ganze dann so aus:

RTC-Modul: Verkabelung
Verbindung des Arduino UNO mit dem ZS-042 Modul

Installation der RTC-Bibliothek

Da sich dieses Tutorial an Einsteiger richtet, verwende ich eine fertige Bibliothek. Es ist natürlich auch möglich das RTC-Modul direkt anzusprechen, für die meisten Fälle reicht es aber eine bereits entwickelte Bibliothek einzusetzen.

In diesem Fall setze ich die RTClib von Adafruit (welche ein Fork von Jeelab’s RTC library ist) ein. Der Vorteil der RTClib von Adafruit ist, dass sich diese einfach über den Bibliotheksverwalter in der Arduino IDE installieren lässt. Den Bibliotheksverwalter findest Du in der Arduino IDE unter [Werkzeuge] -> [Bibliotheken verwelten …]

Gebe im Suchfeld einfach rtclib ein und installiere die Bibliothek von Adafruit:

Beispiel-Projekt

Öffne jetzt das Beispiel-Projekt, dass mit der RTClib ausgeliefert wird. Dieses findest Du unter [Datei] -> [Beispiele] -> [RTClib] -> [ds3231]:

RTC-Modul: Öffnen des Beispielprojektes aus der RTClib
Das Beispielprojekt findet sich in der Arduino IDE unter dem Punkt RTClib

Nun gehe ich mit Dir einmal Schritt-für-Schritt den Quellcode des Beispiels durch.

Imports

Zunächst wird die RTClib importiert und die beiden Variablen rtc und daysOfTheWeek initialisiert:

#include "RTClib.h" RTC_DS3231 rtc; char* daysOfTheWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
Code-Sprache: Arduino (arduino)

Die Variable rtc beinhaltet eine Instanz der RTClib, welche wir benötigen um das RTC-Modul anzusprechen. Die Variable daysOfTheWeek wird nur für die Ausgabe in der Konsole benötigt. Sie beinhaltet die ausgeschriebenen Tage der Woche und würde in Deutsch so aussehen:

char* daysOfTheWeek[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
Code-Sprache: Arduino (arduino)

Die Woche fängt dabei (wie in den meisten Programmiersprachen üblich) beim Sonntag an.

setup-Funktion

Die setup-Funktion beinhaltet im Grunde nur 7 für die Verwendung mit einem Arduino benötigte Zeilen (welche sich allerdings noch weiter kürzen lassen). Damit wir Informationen über die serielle Schnittstelle ausgeben können, wird diese zunächst initialisiert.

Anschließend wird die RTClib mit rtc.begin() initialisiert. Die Funktion gibt im Fall eines Fehlers false zurück, wodurch über die serielle Schnittstelle ein Fehler ausgegeben und das Programm beendet wird:

if (!rtc.begin()) { Serial.println("Couldn't find RTC"); Serial.flush(); abort(); }
Code-Sprache: Arduino (arduino)

Jetzt wird die Uhrzeit des RTC-Moduls eingestellt. Auch wenn ein RTC-Modul die Uhrzeit mithilfe der integrierten Batterie über längere Zeit speichern kann, ist es notwendig bei der ersten Inbetriebnahme oder einem Batteriewechsel die Uhrzeit manuell zu setzen.

Um zu erfahren, ob die Zeit des RTC-Moduls erneut gesetzt werden muss, wird dafür zunächst die Methode lostPower() der RTClib aufgerufen. Die Methode gibt false zurück, wenn der verbaute DS3231-Chip zwischenzeitlich kein Strom hatte und erneut die aktuelle Uhrzeit benötigt. In diesem Fall wird die „aktuelle“ Zeit gesetzt. Dies löst das Beispielprojekt der RTClib sehr elegant, indem es die Compilezeit des Arduino-Programms benutzt um die Zeit einzustellen:

if (rtc.lostPower()) { Serial.println("RTC lost power, let's set the time!"); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); }
Code-Sprache: Arduino (arduino)

Beachte allerdings, dass du das Programm einmal neu kompilieren und hochladen musst, wenn du die Batterie des RTC-Moduls tauschst. Ansonsten wird auf dem RTC-Modul die falsche Uhrzeit gespeichert.

loop-Funktion

Die loop-Funktion besteht aus 3 Teilen. Zunächst die aktuelle Zeit ausgegeben. Anschließend wird gezeigt, wie man mithilfe der RTClib mit Datumsformaten rechnen kann und zuletzt wird noch die Temperatur ausgeben (ja, das RTC-Modul beinhaltet auch ein Thermometer). Die Ausgabe dieser Daten wird alle 3 Sekunden wiederholt.

Die loop-Funktion beginnt damit, dass die aktuelle Zeit mithilfe der Methode now() vom RTC-Modul abgefragt wird:

DateTime now = rtc.now();
Code-Sprache: Arduino (arduino)

Anschließend wird die aktuelle Zeit in einem lesbaren Format ausgegeben:

Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(" ("); Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); Serial.print(") "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println();
Code-Sprache: Arduino (arduino)

Hier wird auch die bereits definierte Variable daysOfTheWeek verwendet. Die Methode dayOfTheWeek gibt eine Zahl von 0 (Sonntag) bis 6 (Samstag) zurück. Mithilfe dieser Zahl wird der entsprechende Tag aus der Variable daysOfTheWeek ausgegeben. Die Ausgabe des Datums erfolgt in dem folgenden Format: <Jahr>/<Monat>/<Tag>.

Anschließend wird die Zeit in Sekunden seit dem 1.1.1970 in Sekunden und in Tagen ausgegeben. Die seit dem 1.1.1970 vergangenen Sekunden nennt man auch Unix epoch, Unix time, POSIX time oder (Unix) timestamp. Hierbei werden Schaltsekunden allerdings nicht beachtet. Diese Aufgabe übernimmt der folgende Quellcode:

Serial.print(" since midnight 1/1/1970 = "); Serial.print(now.unixtime()); Serial.print("s = "); Serial.print(now.unixtime() / 86400L); Serial.println("d");
Code-Sprache: PHP (php)

Die Zahl 86400 sind hierbei die Sekunden eines Tages. Wenn der Unix-Timestamp durch 86400 geteilt erhält man daher die vollständig vergangenen Tage seit dem 1.1.1970.

Jetzt wird mithilfe der aktuellen Zeit ein Zeitpunkt berechnet, der 7 Tage, 12 Stunden, 30 Minuten und 6 Sekunden in der Zukunft liegt. Hierfür wird ein TimeSpan-Objekt mit den entsprechenden Parametern erstellt. Dieses TimeSpan-Objekt wird jetzt zu dem aktuellen Zeitpunkt hinzugefügt und darauf ein neues DateTime-Objekt erzeugt:

DateTime future (now + TimeSpan(7, 12, 30, 6));
Code-Sprache: Arduino (arduino)

Anschließend folgt die Ausgabe dieses DateTime-Objektes in dem bereits oben beschriebenen Format:

Serial.print(" now + 7d + 12h + 30m + 6s: "); Serial.print(future.year(), DEC); Serial.print('/'); Serial.print(future.month(), DEC); Serial.print('/'); Serial.print(future.day(), DEC); Serial.print(' '); Serial.print(future.hour(), DEC); Serial.print(':'); Serial.print(future.minute(), DEC); Serial.print(':'); Serial.print(future.second(), DEC); Serial.println();
Code-Sprache: PHP (php)

Zuletzt wird mit der Methode getTemperature() des rtc-Objektes noch die aktuelle Temperatur ausgelesen und anschließend über die serielle Schnittstelle ausgegeben:

Serial.print("Temperature: "); Serial.print(rtc.getTemperature()); Serial.println(" C");
Code-Sprache: Arduino (arduino)

Dies war auch schon der gesamte Quellcode des Beispielprojektes.

Ausführen des Beispielprojektes

Du kannst das Beispielprojekt jetzt, wie jedes andere Arduino-Projekt, über den Pfeil in der Arduino IDE auf den Arduino hochladen. Öffne anschließend über die Lupe oben rechts in der Arduino IDE den seriellen Monitor.

Da das Beispielprojekte standardmäßig mit einer Baudrate von 57.600 arbeitet, wirst du vmtl. nur irgendwelche kryptischen Symbole sehen. Wechsel in diesem Fall einfach die Baudrate mit der Auswahlliste direkt neben dem „Ausgabe löschen“ Knopf.

Die Ausgabe sollte jetzt wie folgt aussehen (natürlich mit der bei dir aktuellen Uhrzeit und Temperatur):

RTC-Modul: Ausgabe des Beispielprojektes
Serielle Ausgabe des RTClib Beispielprogrammes

Du hast jetzt erfolgreich das RTC-Modul eingesetzt um die aktuelle Uhrzeit und Temperatur auszulesen. Testweise kannst du den Arduino auch kurz vom Strom trennen und dich anschließend nochmal per seriellen Monitor mit diesem verbinden. Es sollte dir jetzt immer noch die richtige Uhrzeit ausgegeben werden.

Wir hoffen, dass wir dir mit diesem Beitrag bei deinem Start mit dem RTC-Modul am Arduino helfen konnten. Falls du auf Grundlage dieses Beitrags ein interessantes Projekt realisiert hast, würden wir uns freuen, wenn du uns per E-Mail ([email protected]) daran teilhaben lässt.