-
Notifications
You must be signed in to change notification settings - Fork 30
/
ReadDS1307.ino
136 lines (115 loc) · 3.19 KB
/
ReadDS1307.ino
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
134
135
136
#include <SoftWire.h>
#include <AsyncDelay.h>
#if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL)
int sdaPin = PIN_WIRE_SDA;
int sclPin = PIN_WIRE_SCL;
#else
int sdaPin = SDA;
int sclPin = SCL;
#endif
// I2C address of DS1307
const uint8_t I2C_ADDRESS = 0x68;
SoftWire sw(sdaPin, sclPin);
// These buffers must be at least as large as the largest read or write you perform.
char swTxBuffer[16];
char swRxBuffer[16];
AsyncDelay readInterval;
// Print with leading zero, as expected for time
void printTwoDigit(int n)
{
if (n < 10) {
Serial.print('0');
}
Serial.print(n);
}
void readTime(void)
{
// Ensure register address is valid
sw.beginTransmission(I2C_ADDRESS);
sw.write(uint8_t(0)); // Access the first register
sw.endTransmission();
uint8_t registers[7]; // There are 7 registers we need to read from to get the date and time.
int numBytes = sw.requestFrom(I2C_ADDRESS, (uint8_t)7);
for (int i = 0; i < numBytes; ++i) {
registers[i] = sw.read();
}
if (numBytes != 7) {
Serial.print("Read wrong number of bytes: ");
Serial.println((int)numBytes);
return;
}
int tenYear = (registers[6] & 0xf0) >> 4;
int unitYear = registers[6] & 0x0f;
int year = (10 * tenYear) + unitYear;
int tenMonth = (registers[5] & 0x10) >> 4;
int unitMonth = registers[5] & 0x0f;
int month = (10 * tenMonth) + unitMonth;
int tenDateOfMonth = (registers[4] & 0x30) >> 4;
int unitDateOfMonth = registers[4] & 0x0f;
int dateOfMonth = (10 * tenDateOfMonth) + unitDateOfMonth;
// Reading the hour is messy. See the datasheet for register details!
bool twelveHour = registers[2] & 0x40;
bool pm = false;
int unitHour;
int tenHour;
if (twelveHour) {
pm = registers[2] & 0x20;
tenHour = (registers[2] & 0x10) >> 4;
} else {
tenHour = (registers[2] & 0x30) >> 4;
}
unitHour = registers[2] & 0x0f;
int hour = (10 * tenHour) + unitHour;
if (twelveHour) {
// 12h clock? Convert to 24h.
hour += 12;
}
int tenMinute = (registers[1] & 0xf0) >> 4;
int unitMinute = registers[1] & 0x0f;
int minute = (10 * tenMinute) + unitMinute;
int tenSecond = (registers[0] & 0xf0) >> 4;
int unitSecond = registers[0] & 0x0f;
int second = (10 * tenSecond) + unitSecond;
// ISO8601 is the only sensible time format
Serial.print("Time: ");
Serial.print(year);
Serial.print('-');
printTwoDigit(month);
Serial.print('-');
printTwoDigit(dateOfMonth);
Serial.print('T');
printTwoDigit(hour);
Serial.print(':');
printTwoDigit(minute);
Serial.print(':');
printTwoDigit(second);
Serial.println();
}
void setup(void)
{
#if F_CPU >= 12000000UL
Serial.begin(115200);
#else
Serial.begin(9600);
#endif
Serial.println("Read DS1307 example");
Serial.print(" SDA pin: ");
Serial.println(int(sdaPin));
Serial.print(" SCL pin: ");
Serial.println(int(sclPin));
Serial.print(" I2C address: ");
Serial.println(int(I2C_ADDRESS), HEX);
sw.setTxBuffer(swTxBuffer, sizeof(swTxBuffer));
sw.setRxBuffer(swRxBuffer, sizeof(swRxBuffer));
sw.setDelay_us(5);
sw.setTimeout(1000);
sw.begin();
readInterval.start(2000, AsyncDelay::MILLIS);
}
void loop(void)
{
if (readInterval.isExpired()) {
readTime();
readInterval.restart();
}
}