cryeffect.net

DS1307 RTC programmieren

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

// 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

void setDateTime()
{
byte second = 0, minute = 0, hour = 0, weekday = 0, monthday = 0, month = 0, year = 0;

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.