Die Arduino Boards können vieles, verfügen aber nicht über eine Echtzeituhr. Das bedeutet, dass eine eventuell benötigte Zeitangabe im Arduino Sketch nach jedem Stromausfall oder Neustart neu gesetzt werden muss.
Für Projekte, bei denen man datum- oder zeitabhängig Ereignisse auslösen oder protokollieren will, benötigt man eine Echtzeituhr (Real Time Clock = RTC) als zusätzliches Bauelement. Eine nicht sonderlich genaue, aber dafür sehr preisgünstige Lösung ist die Real Time Clock DS1307, kompakt in einem IC verbaut. Mit einer 3V-Knopfzelle ist diese Echtzeituhr in der Lage, die Zeit bis zu 5 Jahre mitzuführen, allerdings mit einer relativ großen Ungenauigkeit von 1-2 Sekunden pro Tag. Adafruit bietet zum DS1307 ein Breakout Kit an, das mit ein wenig Lötarbeit selbst zusammengebaut werden kann.
Die benötigte Library gibts hier auf Github: https://github.com/adafruit/RTClib/archive/master.zip
Einfach das ZIP runterladen und dekomprimieren. Den erzeugten Ordner in „RTClib“ umbenennen (ohne das „-master“ hintendran) und über die Arduino IDE im Menü „Sketch -> Include Library -> Add .ZIP Library“ importieren.
Im Video-Tutorial erkläre ich den Aufbau und die Verwendung der Echtzeituhr DS1307.
Hier der erste Sketch, mit dem die aktuelle Systemzeit (fast richtig) vom PC in die Real Time Clock übertragen werden kann.
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> #include "RTClib.h" RTC_DS1307 rtc; void setup () { while (!Serial); // for Leonardo/Micro/Zero Serial.begin(57600); if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); } if (! rtc.isrunning()) { Serial.println("RTC is NOT running!"); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); Serial.println("RTC adjusted!"); } } void loop () { DateTime now = rtc.now(); Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); delay(3000); } |
Und der 2. Sketch, welcher die gesetzte Zeit zusätzlich auf einem seriellen 7-Segment-Display von Sparkfun anzeigt.
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> #include "RTClib.h" #include "SoftwareSerial.h" const int softwareTx = 8; const int softwareRx = 7; RTC_DS1307 rtc; SoftwareSerial s7s(softwareRx, softwareTx); char tempString[10]; // String für 7-Segment Display void setup () { while (!Serial); // for Leonardo/Micro/Zero Serial.begin(57600); if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); } // if (! rtc.isrunning()) { // Serial.println("RTC is NOT running!"); // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Serial.println("RTC adjusted!"); // } s7s.begin(9600); clearDisplay(); setDecimals(0b010000); setBrightness(255); } void loop () { DateTime now = rtc.now(); sprintf(tempString, "%02d%02d", now.hour(), now.minute()); s7s.print(tempString); Serial.println(tempString); delay(1000); } // Hilfsfunktionen für 7-Segment-Display void clearDisplay() { s7s.write(0x76); } void setBrightness(byte value) { s7s.write(0x7A); s7s.write(value); } void setDecimals(byte decimals) { s7s.write(0x77); s7s.write(decimals); } |
Die Breakout-Boards mit dem DS1307 kommunizieren alle per I²C mit dem Arduino. Die RTClib Library funktioniert also nicht nur mit dem Kit von Adafruit (z.B. hier erhältlich bei exp-tech.de), sondern auch mit jedem anderen Breakout Board, das diese Echtzeituhr verwendet.
Auch bei Amazon gibts zahlreiche Versionen.
Fragen, Wünsche und Anregungen bitte in die Kommentare. Danke.
Hallo Adi,
ich freue mich wieder von dir zu hören/sehen!
Danke für den Sketch. Ist ´ne gute Idee.
Jetzt wird´s ja wieder kälter und dunkler. Zeit um in den Bastelkeller zu gehen und wieder was zu löten. Hab den ganzen Sommer am RC-Car rumgeschraubt. :-)
Grüße aus dem Chiemgau!
Uwe
Hallo,
super Tutorial. Habe es ausprobiert – funktioniert prima!
Wenn ich auf einen kleinen Fehler aufmerksam machen darf: der 2. Sketch beginnt mit: „#include … und dann folgt nichts mehr. Wenn man als Anfänger diesen Sketch markiert und in die IDE übernimmt, bekommt man eine Fehlermeldung. Als Fortgeschrittener finden man diesen Fehler natürlich sofort.
Aber nochmal: Total verständlich und übersichtlich. Bin begeister.
Vielen Dank für den Hinweis! Das Plugin zur Darstellung des C-Codes im WordPress schluckt gelegentlich die spitzen Klammern. Ist jetzt korrigiert.
Hey :D
Habe genau diesen Sketch ausprobiert. Allerdings zeigt er bei mir im seriellem Monitor etwas komplett anderes an. Laut der Echtzeituhr ist es gerade der 02.01.2000. Die Uhrzeit stimmt auch nicht überein wüsste jemand woran das liegt :)
Hast du auch den 1. Sketch ausgeführt, der die aktuelle Systemzeit auf die RTC überspielt?
Bei mir gibt es genau das selbe Problem… Der übernimmt glaub ich die Systemzeit vom ersten Start des PCs überhaupt. Könnte man nicht einfach auch die Uhrzeit manuell im Sketch reinschreiben?
Hi,
kann man die Echtzeituhr und den Arduino so programmieren, dass wenn die RTC Alarm gibt ein Sketch ausgeführt wird? Wenn der Sketch ausgeführt wurde, soll die RTC genau 24h Später wieder Alarm geben.
Es soll ein Jahreszeitraffer entstehen. Der Arduino löst also eine Kamera aus.
Gruß,
Sandro
Grüss Euch liebe Spezialisten!
habe den RTC laut Anweisung über Examples — SetTime auf die richtige Zeit (im SerialMon ersichtlich) eingestellt, a b e r nach einer Unterbrechung der Vin fangt meine Uhr wieder bei 00:00:01 an!?!?
die CR2032 am RTC liefert volle 3V
kann man den Zeitgeber „irgendwie“ überprüfen, ob er funktioniert?
DANKE im voraus – lg, Gustl
Hallo Gustl,
falls Du ein RTC Modul DS3231 benutzt: Bei mir startet nach der Unterbrechung von Vin die RTC „automatisch“ bei 00:00:00, sobald die Versorgungsspannung wieder anliegt. Damit erscheint die RTC für Adis 1. Sketch als „running“ und entsprechend der if-Bedingung wird die Befehlszeile
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
nicht ausgeführt.
Du kannst das RTC sehr leicht auf die aktuelle (Compiler-)Zeit setzen, indem du die o.g. Befehlszeile ohne if-Bedingung in einen kleinen Sketch einbaust und ausführst.
VG, Waldemar