Im heutigen Artikel geht es darum, wie man ein RTC (Real Time Clock) programmiert. Wenn wir einen frisch gekauften RTC anschließen, ist das Problem oft, dass dieser nicht korrekt eingestellt ist. Mit einen kleinen Sketch haben wir nun die Möglichkeit, über den “seriellen Monitor” das RTC Modul auf die korrekte Uhrzeit und Datum einzustellen. Hierfür verdrahten wir unseren Arduino Nano über den I2C Bus mit dem DS1307 Modul. Das ganze wird wie folgt verdrahtet.
Haben wir die beiden miteinander verdrahtet, können wir auch schon mit dem Sketch starten. Dafür nutzen wir den Beispiel Sketch vom DS1307.
// Sets the date/time of an DS1307 RTC module via serial monitor // (c) 2018 Christian Grieger // GNU GENERAL PUBLIC LICENSE
// I²C Address for the RTC module #define DS1307_ADDRESS 0x68
#include <Wire.h>
void setup() { Wire.begin(); Serial.begin(9600); while (!Serial); // wait for serial port to connect. Needed for native USB Serial.flush(); printDateTime();
Serial.println("Please change to newline ending the settings of the Serial Monitor"); Serial.println("Would you like to set the date and time now? Y/N"); while (!Serial.available()) delay(10); if (Serial.read() == 'y' Serial.read() == 'Y') { Serial.read(); setDateTime(); printDateTime(); } }
void loop() { }
// Sets date/time of the RTC module via the serial monitor
Serial.print(F("Year (00-99): ")); year = readByte(); Serial.println(year); Serial.print(F("Month (1-12): ")); month = readByte(); Serial.println(month); Serial.print(F("Day of the month (1-31): ")); monthday = readByte(); Serial.println(monthday); Serial.print(F("Day of the week (1-7): ")); weekday = readByte(); Serial.println(weekday); Serial.print(F("Hour (0-23): ")); hour = readByte(); Serial.println(hour); Serial.print(F("Minute (0-59): ")); minute = readByte(); Serial.println(minute); second = 0; // The following codes transmits the data to the RTC Wire.beginTransmission(DS1307_ADDRESS); Wire.write(byte(0)); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(weekday)); Wire.write(decToBcd(monthday)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.write(byte(0)); Wire.endTransmission(); } byte readByte() { while (!Serial.available()) { delay(10); } byte reading = 0; byte incomingByte = Serial.read(); while (incomingByte != '\n') { if (incomingByte >= '0' && incomingByte <= '9') { reading = reading * 10 + (incomingByte - '0'); } incomingByte = Serial.read(); } Serial.flush(); return reading; } // Prints the current date/time set in the RTC module to the serial monitor void printDateTime() { Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0x00); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); byte nowSeconds = bcdToDec(Wire.read()); byte nowMinute = bcdToDec(Wire.read()); byte nowHour = bcdToDec(Wire.read() & 0b111111); byte nowWeekDay = bcdToDec(Wire.read()); byte nowMonthDay = bcdToDec(Wire.read()); byte nowMonth = bcdToDec(Wire.read()); byte nowYear = bcdToDec(Wire.read()); char data[20] = ""; sprintf(data, "20%02d-%02d-%02d %02d:%02d:%02d", nowYear, nowMonth, nowMonthDay, nowHour, nowMinute, nowSeconds); Serial.print("Current datetime: "); Serial.println(data); } // Converts a decimal (Base-10) integer to BCD (Binary-coded decimal) int decToBcd(int value) { return ((value/10*16) + (value%10)); } // Converts a BCD (Binary-coded decimal) to decimal (Base-10) integer int bcdToDec(int value) { return ((value/16*10) + (value%16)); }
Haben wir den Sketch hochgeladen, können wir uns mittels “Seriellen Monitor” und einer Baudrate von 9600 verbinden, um die aktuelle Zeit einzustellen. Durch die verbaute Batterie läuft der RTC auch ohne externen Strom weiter und speichert die Zeit. Wenn alles geklappt hat, gibt der RTC, über den I2C Bus, die aktuelle Zeit an unseren Arduino Nano weiter, was wir über den “Seriellen Monitor” sehen.