-
Notifications
You must be signed in to change notification settings - Fork 0
/
alarmclock.ino
151 lines (123 loc) · 3.47 KB
/
alarmclock.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
#include <SoftwareSerial.h>
#include <Wire.h>
#include "ds3231.h"
//#include "rtc_ds3231.h"
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include "Buttons.h"
#include "CommandProcessor.h"
#define I2C_ADDR 0x27
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define BACKLIGHT_PIN 3
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define SNOOZE_INS 'Z'
#define SET_TIME_INS 'T'
#define TURN_OFF_INS 'O'
#define TURN_ON_INS 'F'
#define ACTIVATE_INS 'A'
#define DISPLAY_INS 'D'
#define UPDATE_INS 'U'
#define LCD_UPDATE_INTERVAL 1000
#define CONNECTION_INTERVAL 60000
#define DEBOUNCE_DELAY 50
#define BACKLIGHT_BUTTON_PIN 2
#define HOT_BUTTON_PIN 3
#define SNOOZE_BUTTON_PIN 4
#define RING_SAFETY 60000
#define ALARM_PIN 7
SoftwareSerial mySerial(10, 11); // RX, TX
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
struct ClockState {
boolean snoozed = false;
boolean hot = false;
boolean ringing = false;
boolean displayOn = true;
boolean backLightStateChanged = false;
unsigned long timeLCDUpdated = 0;
unsigned long timeReveivedMessage = 0;
boolean someStateChanged = false;
unsigned long timeStartRinging = 0;
};
struct Command c;
struct ClockState state;
struct Button backlightButton;
struct Button hotButton;
struct Button snoozeButton;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
mySerial.begin(9600);
Wire.begin();
DS3231_init(DS3231_INTCN);
memset(c.recv, 0, BUFF_MAX);
lcd.begin (16,2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home();
initializeButton(&backlightButton, BACKLIGHT_BUTTON_PIN);
initializeButton(&hotButton, HOT_BUTTON_PIN);
initializeButton(&snoozeButton, SNOOZE_BUTTON_PIN);
pinMode(ALARM_PIN, OUTPUT);
digitalWrite(ALARM_PIN, LOW);
}
void loop() {
// process input
readLine(&mySerial, &c);
//if message read then process and update state
if (c.readMessage) {
processCommand(&c, &state);
resetCommand(&c);
state.timeReveivedMessage = millis();
}
processBacklightButton(&backlightButton, &state);
processHotButton(&hotButton, &state);
processSnoozeButton(&snoozeButton, &state);
if (state.displayOn) {
updateLCD(&state);
}
updateBackLight(&state);
if (state.someStateChanged) {
sendUpdatedData(&mySerial, &state);
state.someStateChanged = false;
}
if (shouldTurnOff(&state)) {
state.ringing = false;
state.someStateChanged = true;
}
ringTheAlarm(&state);
}
boolean isConnected(struct ClockState* s) {
unsigned long now = millis();
return (now - s->timeReveivedMessage) < CONNECTION_INTERVAL;
}
boolean shouldTurnOff(struct ClockState* s) {
unsigned long now = millis();
return (now - s->timeStartRinging) > RING_SAFETY;
}
void sendUpdatedData(SoftwareSerial* bluetooth, struct ClockState* s) {
char buff[BUFF_MAX];
int ringing = convertBooleanToInt(s->ringing);
int snoozed = convertBooleanToInt(s->snoozed);
int hot = convertBooleanToInt(s->hot);
int displayOn = convertBooleanToInt(s->displayOn);
snprintf(buff, BUFF_MAX, "%c%d%d%d%d", UPDATE_INS,
ringing, snoozed, hot, displayOn);
bluetooth->println(buff);
}
int convertBooleanToInt(boolean value) {
return value ? 1 : 0;
}
void ringTheAlarm(struct ClockState* s) {
if (s->ringing && s->hot) {
Serial.println("Ringing alarm");
digitalWrite(ALARM_PIN, HIGH);
} else {
Serial.println("Switching off alarm");
digitalWrite(ALARM_PIN, LOW);
}
}