-
Notifications
You must be signed in to change notification settings - Fork 1
/
pomodoro_tracker_1.cpp
416 lines (393 loc) · 11.2 KB
/
pomodoro_tracker_1.cpp
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
/*
Pomodoro Tracker 1.0 by Damian M.G.(IgorJorobus)
================================================
Physic needed materials
=======================
* 3 leds 5mm green
* 2 leds 5mm blue
* 1 led 5mm red
* 8 resistances 100 ohm
* 1 buzzer
* 1 switch
* Arduino Uno
* Cables
To assemble
===========
* Welder
* Insulator(silicone)
* Container
Pins used
================
* 2 = OUTPUT, green led 0
* 3 = OUTPUT, green led 1
* 4 = OUTPUT, green led 2
* 5 = OUTPUT, blue led 0
* 6 = OUTPUT, blue led 1
* 7 = OUTPUT, red led 0
* 8 = INPUT, switch
* 12 = OUTPUT, buzzer
Changes vs. version 0.1
=======================
* Software built with Ruby now replaces many functions that the Arduino have been doing by itself.
* Strongly use of serial port reading.
* Arduino becomes more passive. Button start/break isn't needed anymore.
* Now the switch that defines if Arduino is active has become the only input from the Arduino itself. If it is not active all leds are off and remains hanging.
* The system must not flush the serial port by itself, only if the switch is censused "on".
* The system can read an event or a state. The state can be pomodor running, break running or stopped. The events are any light game or sounds.
*/
// include aliases of sounds as frecuencies
#include "pitches.h"
/* Function prototypes */
void checkSwitch(void);
void makeSystemOnLightGame(void);
void soundSadBuzzer(void);
void soundHappyBuzzer(void);
void makePomodoroFinishedLightGame(void);
void makePomodoroN12FinishedLightGame(void);
void makePomodoroN22FinishedLightGame(void);
void makeBreakFinishedLightGame(void);
void resetEverything(void);
void inspectSerialPortInput(void);
boolean isCodeAnEvent(String);
void showPomodoroRunning(long secondsSincePomodoroStart);
void showBreakRunning(long pomodorosCompleted);
void showSystemStopped(void);
/* Deprecated function prototypes
void checkButton(void);
void startPomodoro(void);
void cancelCurrentPomodoro(void);
void checkCurrentPomodoro(void);
void startBreak(void);
void cancelBreak(void);
void checkCurrentBreak(void);
void finishBreak(void);
*/
/* Global variables */
int switchInitialPosition = 0;
// system is on when the switch is not in the initial position
bool systemOn = false;
/* Arduino functions*/
// This runs once.
void setup() {
// set input/output pings
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, INPUT);
pinMode(12, OUTPUT);
// system never start "on", doesn't matter in which position is the switch, its turning-on depends on the contrary state in which it begins
switchInitialPosition = digitalRead(8);
// open thy serial port
Serial.begin(9600);
}
// This can run up to 16000 times per second, but most of the time runs around 3000 times per second.
void loop() {
// check if system should be on
checkSwitch();
// main process
if(systemOn) {
// inspect serial port looking for input
inspectSerialPortInput();
} else {
// shut down everything
resetEverything();
}
}
/* Helper functions */
// Check if the switch has changed its original state.
void checkSwitch() {
// see if the switch is on
if(systemOn) {
if(digitalRead(8) == switchInitialPosition) {
// the initial position is reached again
systemOn = false;
}
} else {
if(digitalRead(8) != switchInitialPosition) {
systemOn = true;
// execute light game on on
makeSystemOnLightGame();
// flush the serial port
Serial.readString();
}
}
}
// Triggered when system is turned on.
void makeSystemOnLightGame() {
digitalWrite(7, HIGH);
delay(500);
digitalWrite(7, LOW);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(6, LOW);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(5, LOW);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(4, LOW);
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
delay(500);
digitalWrite(7, HIGH);
}
// Checks if Serial port has any data written on it. If it does, read it, and interpret it.
void inspectSerialPortInput() {
// check if there's at least one char to read
if(Serial.available()) {
// there is some data available to read
String code = Serial.readStringUntil('-');
// detect if the code talks about an event or state
if(isCodeAnEvent(code)) {
// event, find out which
if(code == "MSOLG") {
makeSystemOnLightGame();
} else if(code == "MPFLG") {
makePomodoroFinishedLightGame();
} else if(code == "MPN12FLG") {
makePomodoroN12FinishedLightGame();
} else if(code == "MPN22FLG") {
makePomodoroN22FinishedLightGame();
} else if(code == "MBFLG") {
makeBreakFinishedLightGame();
} else if(code == "SSB") {
soundSadBuzzer();
} else if(code == "SHB") {
soundHappyBuzzer();
}
} else {
// state, kind of "16R0288", this is pomodoros completed, actual state, seconds since beggining of actual phase, first thing of interest is state taking part now
switch(code[2]) {
case 'R':
// pomodoro running, pass the seconds since the start of it
showPomodoroRunning(code.substring(3).toInt());
break;
case 'B':
// break running, pass the amount of pomodoros completed
showBreakRunning(code.substring(0, 2).toInt());
break;
case 'S':
// stopped
showSystemStopped();
break;
}
}
}
}
// The code will have 7 characters length if it's a state, otherwise will be an event.
boolean isCodeAnEvent(String code) {
int codeLength = code.length();
if(codeLength != 7) {
return(true);
} else {
return(false);
}
}
// Shows to the user leds that represent a pomodoro running.
void showPomodoroRunning(long secondsSincePomodoroStart) {
// depending on how many seconds has passed since the start of the pomodoro, 1, 2 or 3 green leds will be on
if(secondsSincePomodoroStart > 1000) {
// 3 leds on
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
} else if(secondsSincePomodoroStart > 500) {
// 2 leds on
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
} else {
// 1 led on
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
}
}
// Shows to the user leds that represent a break running.
void showBreakRunning(long pomodorosCompleted) {
// check if on long or short break
if((pomodorosCompleted % 4) == 0) {
// long
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
} else {
// short
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
}
}
// Shows to the user leds that represent the system stopped.
void showSystemStopped() {
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, HIGH);
}
// :( Why did you interrupted that pomodoro? Bio meaby? Is ok...
void soundSadBuzzer() {
// setup of notes
int melody[] = {
NOTE_E3, NOTE_D3, NOTE_C3
};
int noteDurations[] = {
8, 8, 2
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 3; thisNote++) {
// to calculate the note duration, take one second divided by the note type i.e.: quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(12, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them; the note's duration + 30% seems to work well
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(12);
}
}
// Yes! Completed!
void soundHappyBuzzer() {
// setup of notes
int melody[] = {
NOTE_C6, NOTE_D6, NOTE_E6
};
int noteDurations[] = {
8, 8, 8
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 3; thisNote++) {
// to calculate the note duration, take one second divided by the note type i.e.: quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(12, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them; the note's duration + 30% seems to work well
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(12);
}
}
// Executes the light game triggered by the finish of a pomodoro.
void makePomodoroFinishedLightGame() {
// clean leds just in case
resetEverything();
// do the game
for(int counter = 0; counter < 5; counter++) {
// turn off all green leds
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
// rest
delay(1000);
// turn on all green leds
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
// rest
delay(1000);
}
// and off every green leds
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
delay(1000);
}
// Called when pomodoro number 12 is reached.
void makePomodoroN12FinishedLightGame() {
// clean leds just in case
resetEverything();
// do the game
for(int counter = 0; counter < 4; counter++) {
digitalWrite(2, HIGH);
digitalWrite(7, HIGH);
delay(500);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
delay(500);
digitalWrite(3, LOW);
digitalWrite(6, LOW);
delay(500);
digitalWrite(2, LOW);
digitalWrite(7, LOW);
delay(500);
}
delay(500);
}
// Called when pomodoro number 22 is reached.
void makePomodoroN22FinishedLightGame() {
// clean leds just in case
resetEverything();
// do the game
int led;
bool currentState = 1;
digitalWrite(2, HIGH);
delay(100);
digitalWrite(2, LOW);
for(int counter = 0; counter < 20; counter++) {
for(led = 3; led < 8; led++) {
digitalWrite(led, HIGH);
delay(100);
digitalWrite(led, LOW);
}
for(led = 6; led > 1; led--) {
digitalWrite(led, HIGH);
delay(100);
digitalWrite(led, LOW);
}
}
}
// Triggered when break time is done.
void makeBreakFinishedLightGame() {
// clean leds just in case
resetEverything();
// do the game
for(int counter = 0; counter < 2; counter++) {
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(1000);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(1000);
}
// clean leds
resetEverything();
}
// Called when system has been turned off. Resets everything to its pristine status.
void resetEverything() {
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
}