-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.ino
185 lines (147 loc) · 4.12 KB
/
controller.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
#include <Wire.h>
#include "RTClib.h"
#include <string.h>
RTC_DS3231 timer;
#define MANUAL_DRIVEN 0
#define CONTEXT_DRIVEN 1
#define MAX_TIMERS 10
#define SPRAY_DURATION 12 // Seconds
#define SPRAY_INTERVAL 30 // Minutes
struct Timer {
DateTime time;
int expired;
};
// Pin Definitions
int togglePumpIn = 7;
int togglePumpOut = 8;
// Global Variables
Timer currentTimers[MAX_TIMERS * sizeof(Timer)];
String oldTime;
DateTime pauseAnchor;
int timersActive = 1;
int timerIndex = 0;
int togglePumpDebounce = 0;
int recursiveMode = 1;
String formatDate(DateTime date);
int setTimer(DateTime time);
int expireTimer(int timerId);
int checkTimers(DateTime currentTime);
int isDuplicateTimer(DateTime time);
int pauseTimers();
int resumeTimers();
int clearTimers();
int beginCycle();
int beginRecursiveCycle();
void testTimer();
void setup() {
pinMode(togglePumpIn, INPUT);
pinMode(togglePumpOut, OUTPUT);
Serial.begin(115200);
delay(3000); // wait for console opening
if (!timer.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (timer.lostPower()) { // Reset timer
Serial.println("RTC lost power, lets set the time!");
timer.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
for (int i = 0; i < MAX_TIMERS; i++) { // Fill timer array with invalid timer placeholders
Timer newTimer;
newTimer.expired = 1;
currentTimers[i] = newTimer;
}
}
void loop() {
int togglePump = digitalRead(togglePumpIn);
DateTime currentTimeRaw = timer.now();
String currentTime = formatDate(currentTimeRaw);
// Listen to button to add new timer
if (togglePump == HIGH && togglePumpDebounce == 0) {
testTimer();
togglePumpDebounce = 1;
} else if (togglePump == LOW && togglePumpDebounce == 1) {
togglePumpDebounce = 0;
}
if (oldTime && currentTime.compareTo(oldTime)) { // Runs once per second
// Serial.print(currentTime + "\n");
// Serial.print("----------------------- \n");
checkTimers(currentTimeRaw);
}
oldTime = currentTime;
}
String formatDate(DateTime date) {
String minute = String(date.minute());
String hour = String(date.hour());
String second = String(date.second());
return hour + ":" + minute + ":" + second + "\n";
}
int setTimer(DateTime time) {
if (isDuplicateTimer(time)) {
return 0;
}
for (int i = 0; i < MAX_TIMERS; i++) {
if (currentTimers[i].expired) {
Timer nextTimer = { time: time, expired: 0 };
currentTimers[i] = nextTimer;
break;
}
}
return 1;
}
int expireTimer(int timerId) {
currentTimers[timerId].expired = 1;
return 1;
}
int pauseTimers() {
pauseAnchor = timer.now();
timersActive = 0;
}
int resumeTimers() {
TimeSpan timeElapsed = timer.now() - pauseAnchor;
if (!timersActive) { // Just in case resume is called while timers are active
for (int i = 0; i < MAX_TIMERS; i++) {
if (!currentTimers[i].expired) {
currentTimers[i].time = currentTimers[i].time + timeElapsed;
}
}
}
timersActive = 1;
}
int clearTimers() {
for (int i = 0; i < MAX_TIMERS; i++) {
expireTimer(i);
}
}
int checkTimers(DateTime currentTime) {
for (int i = 0; i < MAX_TIMERS; i++) {
if (!currentTimers[i].expired && currentTimers[i].time <= currentTime) {
beginCycle();
expireTimer(i);
}
}
return 1;
}
int beginCycle() {
Serial.print("Spraying Starting\n");
digitalWrite(togglePumpOut, HIGH);
delay(SPRAY_DURATION * 1000);
Serial.print("Spraying Ending\n");
digitalWrite(togglePumpOut, LOW);
if (recursiveMode == 1) {
setTimer(timer.now() + TimeSpan(SPRAY_INTERVAL * 60));
}
}
void testTimer() {
setTimer(timer.now() + TimeSpan(1));
Serial.println("Timer Set");
}
int isDuplicateTimer(DateTime time) {
int isDuplicate = 0;
for (int i = 0; i < MAX_TIMERS; i++) {
if (currentTimers[i].time == time) {
isDuplicate = 1;
}
}
return isDuplicate;
}