-
Notifications
You must be signed in to change notification settings - Fork 0
/
Arduino Alarm Clock.ino
241 lines (196 loc) · 5.37 KB
/
Arduino Alarm Clock.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include <TimeLib.h>
#include <DS3232RTC.h>
#include <Wire.h>
#include <Timezone.h>
#include <TM1637Display.h>
#include <Adafruit_LEDBackpack.h>
#include <SoftwareSerial.h>
TimeChangeRule myDST = {"MESZ", Last, Sun, Mar, 2, +120};
TimeChangeRule mySDT = {"MEZ", Last, Sun, Oct, 3, +60};
Timezone DE(myDST, mySDT);
TimeChangeRule *tcr;
time_t utc, local;
#define TM_CLK 2
#define TM_DIO 3
int pinAM = 4;
int pinBM = 5;
int pinBMLast;
int pinBMval;
int pinAH = 6;
int pinBH = 7;
int pinAHLast;
int pinAHval;
int ahour;
int amin;
unsigned long alarmMillis;
unsigned long actualAlarmMillis = 0;
unsigned long oldMillis;
int i = 0;
uint16_t dfCMD[10] {0x7E, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF};
//initialize the DFPlayer (10 RX, 11 TX)
SoftwareSerial dfPlayer(10, 11);
//initialize the alarm display
TM1637Display alarmDisplay(TM_CLK, TM_DIO);
//initilize a variable for the clock display
Adafruit_7segment clockDisplay = Adafruit_7segment();
void setup() {
Serial.begin(9600);
Serial.setTimeout(0);
//initilize the DFPlayer
dfPlayer.begin(9600);
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
if (dfPlayer.isListening())
Serial.println("DFPlayer is online!");
//initilize the clock display
clockDisplay.begin(0x70);
//set to max brightness
alarmDisplay.setBrightness(5, true);
clockDisplay.setBrightness(16);
//set the pin configuration of the rotary encoder
pinMode(pinAM, INPUT);
pinMode(pinBM, INPUT);
pinMode(pinAH, INPUT);
pinMode(pinBH, INPUT);
pinBMLast = digitalRead(pinBM);
pinAHLast = digitalRead(pinAH);
//Sync the internal clock
setSyncProvider(RTC.get);
setSyncInterval(3600); //sync every hour
if (timeStatus() != timeSet)
Serial.println("unable to sync with the RTC!");
else
Serial.println("synchronized with the RTC!");
displayPrintAlarm();
DFsendCommand(0x09, 0x00, 0x02);
DFsendCommand(0x06, 0x00, 0x12);
DFsendCommand(0x07, 0x00, 0x00);
DFsendCommand(0x0D, 0x00, 0x00);
}
void loop() {
if (Serial.available()) {
//input the Alarm-Time (Serial)
String serialString = Serial.readString();
processSyncMessage(serialString);
}
pinBMval = digitalRead(pinBM);
if (pinBMval != pinBMLast) { //the encoder is rotating
if (digitalRead(pinAM) == pinBMval)//clockwise, because A changed first
amin++;
else
amin--;
pinBMLast = pinBMval;
alarmMillis = millis();
//print ALARM time (Display)
displayPrintAlarm();
}
pinAHval = digitalRead(pinAH);
if (pinAHval != pinAHLast) {
//the encoder is rotating
if (digitalRead(pinBH) != pinAHval) {
//clockwise, because A changed first
i++;
}
else {
//counter clockwise, because B changed first
i--;
}
pinAHLast = pinAHval;
alarmMillis = millis();
if (i%2 == 0) {
ahour = ahour + (i/2);
i = 0;
}
//print ALARM time (Display)
displayPrintAlarm();
}
if ((millis() - oldMillis) >= 5000) {
utc = now();
local = DE.toLocal(utc, &tcr);
//print clock time (Display)
clockDisplayPrint();
if ((millis() - actualAlarmMillis) >= 60000)
testAlarm();
oldMillis = millis();
DFsendCommand(0x0D, 0x00, 0x00);
}
}
//display the time!
void clockDisplayPrint() {
//make out of hours and minutes one variable
int timeValue = hour(local)*100 + minute(local);
//display the given time with dots
clockDisplay.print(timeValue, DEC);
//print zeros when given hour is <10 || <1
if (timeValue <= 1000)
clockDisplay.writeDigitNum(0, 0);
if (timeValue <= 100)
clockDisplay.writeDigitNum(1, 0);
clockDisplay.drawColon(true);
clockDisplay.writeDisplay();
}
/* code to process time sync messages from the serial port */
#define TIME_HEADER 'T' // Header tag for serial time sync message
void processSyncMessage(String serialString) {
unsigned long pctime;
if (serialString[0] == TIME_HEADER) {
serialString.remove(0, 1);
pctime = serialString.toInt();
//Serial.println(pctime);
RTC.set(pctime);
setTime(pctime);
Serial.println("Time Set!");
}
}
void alarmConversion() {
if (ahour >= 24)
ahour = 0;
if (ahour <= -1)
ahour = 23;
if (amin >= 60) {
amin = 0;
ahour++;
}
if (amin <= -1) {
amin = 59;
ahour--;
}
}
//check if the alarm should ring
void testAlarm() {
//Serial.println("Check for Alarm");
if (ahour == hour(local) && amin == minute(local) && (millis() - alarmMillis) >= 5000) {
Serial.println("ALARM!");
actualAlarmMillis = millis();
}
}
//display the alarm time
void displayPrintAlarm() {
alarmConversion();
alarmDisplay.showNumberDecEx(ahour, 0x10, true, 2, 0); //show alarm hours with dot on the alarm display
alarmDisplay.showNumberDecEx(amin, 0x10, true, 2, 2); //show alarm minutes with dot on the alarm display
}
//calculate the checksum
void DFchecksum() {
uint16_t sum = 0;
for (int j = 1; j <= 6; j++) {
sum += dfCMD[j];
//Serial.println(dfCMD[j]);
}
//Serial.print("vorher: ");
//Serial.println(sum);
sum = (0-sum);
//Serial.println();
//Serial.println(sum);
dfCMD[7] = (uint8_t) (sum >> 8);
dfCMD[8] = (uint8_t) (sum);
//Serial.println(dfCMD[7]);
//Serial.println(dfCMD[8]);
}
void DFsendCommand(int cmd, int para1, int para2) {
dfCMD[3] = cmd;
dfCMD[5] = para1;
dfCMD[6] = para2;
DFchecksum();
}