1
2
3
4#include "RTClib.h"
5
6
7#include <Wire.h>
8#include <LiquidCrystal_I2C.h>
9
10
11
12#include "Arduino.h"
13#include "SoftwareSerial.h"
14#include "DFRobotDFPlayerMini.h"
15SoftwareSerial mySoftwareSerial(8, 9);
16DFRobotDFPlayerMini myDFPlayer;
17
18#define ALARM_SECONDS 10
19#define ALARM_REPEAT_DELAY 2000
20#define ALARM_VOLUME 15
21#define SESSION_TIME 30
22
23
24#define TPLUS_PIN 0
25#define TMINUS_PIN 1
26volatile int TPLUS_button = false;
27volatile int TMINUS_button = false;
28
29RTC_DS1307 rtc;
30LiquidCrystal_I2C lcd(0x27, 20, 4);
31
32char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
33
34void playalarm() {
35 myDFPlayer.volume(ALARM_VOLUME);
36 myDFPlayer.play(1);
37}
38
39void setup () {
40 Serial.begin(57600);
41
42 Serial.println("Shoni's Clock");
43
44 pinMode(TPLUS_PIN, INPUT_PULLUP);
45 pinMode(TMINUS_PIN, INPUT_PULLUP);
46
47 lcd.init();
48 lcd.backlight();
49 lcd.setCursor(0, 0);
50 lcd.print(" Shoni's Clock");
51 delay(1000);
52
53 mySoftwareSerial.begin(9600);
54
55 if (! rtc.begin()) {
56 Serial.println("Couldn't find RTC");
57 lcd.clear();
58 lcd.setCursor(0, 0);
59 lcd.print("RTC error!");
60 delay(3000);
61 }
62
63 if (! rtc.isrunning()) {
64 Serial.println("RTC is NOT running!");
65 lcd.clear();
66 lcd.setCursor(0, 0);
67 lcd.print("Clock time error!");
68 delay(3000);
69 }
70
71
72 rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
73
74
75
76 if (!myDFPlayer.begin(mySoftwareSerial)) {
77 Serial.println(F("Unable to begin:"));
78 Serial.println(F("1.Please recheck the connection!"));
79 Serial.println(F("2.Please insert the SD card!"));
80 while (true) {
81 delay(0);
82 }
83 }
84 myDFPlayer.volume(ALARM_VOLUME);
85 playalarm();
86
87 attachInterrupt(digitalPinToInterrupt(TPLUS_PIN), TPLUS_button_interrupt, LOW);
88 attachInterrupt(digitalPinToInterrupt(TMINUS_PIN), TMINUS_button_interrupt, LOW);
89}
90
91
92void TPLUS_button_interrupt() {
93 TPLUS_button = true;
94}
95
96void TMINUS_button_interrupt() {
97 TMINUS_button = true;
98}
99
100void check_buttons() {
101 int dir;
102 if (TPLUS_button | TMINUS_button) {
103 if (TPLUS_button) {
104 dir = 1;
105
106 delay(50);
107 TPLUS_button = false;
108 }
109 if (TMINUS_button) {
110 dir = -1;
111
112 delay(50);
113 TMINUS_button = false;
114 }
115 DateTime newtime = rtc.now() + (60 * dir);
116 rtc.adjust(newtime);
117 }
118}
119
120char d[16];
121int prevmin = 99;
122int alarmplaying;
123
124void loop () {
125 int minleft;
126 int updateDisplay = true;
127 check_buttons();
128
129 DateTime now = rtc.now();
130
131 if (prevmin == now.minute()) {
132 updateDisplay = false;
133 }
134 else {
135 updateDisplay = true;
136 prevmin = now.minute();
137 }
138
139 if (now.minute() == 0) {
140 minleft = 0;
141 }
142 else if (now.minute() > 30) {
143 minleft = 60 - now.minute();
144 }
145 else {
146 minleft = 30 - now.minute();
147 }
148
149
150 if (updateDisplay) {
151 sprintf(d, "%2d:%02d", TwentyFourToTwelve(now.hour()), now.minute());
152 Serial.println(d);
153 lcd.clear();
154 lcd.setCursor(5, 0);
155 lcd.print(d);
156 }
157
158
159 if (minleft == 0) {
160 if ((now.second() < ALARM_SECONDS)) {
161 if (!alarmplaying) {
162 playalarm();
163 alarmplaying = true;
164 }
165 lcd.setCursor(0, 1);
166 lcd.print("--Session over--");
167 Serial.println("--Session over--");
168 delay(ALARM_REPEAT_DELAY);
169 }
170 else {
171 minleft = SESSION_TIME;
172 alarmplaying = false;
173 }
174 }
175 lcd.setCursor(0, 1);
176 sprintf(d, "minutes left: %2d", minleft);
177 lcd.print(d);
178
179 delay(500);
180}
181
182int TwentyFourToTwelve(int hour) {
183 int h = hour % 12;
184 if (h == 0) {
185 h = 12;
186 }
187 return h;
188}
189