-
Notifications
You must be signed in to change notification settings - Fork 0
/
BRICK_EggTimer.pde
365 lines (282 loc) · 7.01 KB
/
BRICK_EggTimer.pde
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
/****************************************
* Egg Timer a la Justy ('functional' branch, where I refactor and simplify)
*
* A simple boiled egg timer
*
* This sketch was developed in tandem with Seeedstudio's brick system, however that system isn't needed- all that's required are the components used:
*
* • LCD module
* • Potentiometer
* • Buzzer
* • Pushbutton
* • Thermistor (optional)
*
* Have Fun and may your eggs be boiled to your specifications.
*
* Justy
*
*****************************************/
#include <LiquidCrystal.h> // include the library code:
#include <math.h>
#define PIN_Thermistor 5
#define PIN_Button 9
#define PIN_Buzzer 8
#define PIN_Pot 4
#define TIME_multiplier 250.0
enum e_tag{
STATE_Init,
STATE_SetTimer,
STATE_CountingDown,
STATE_Buzzing
}
var;
LiquidCrystal lcd(10,11,12,13,14,15,16); // initialize the library with the numbers of the interface pins
long timerValue = 0;
long timer = 0;
long lastMillis;
int animFrame = 0;
boolean blinkFlag;
int state = STATE_Init;
void setup() {
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
blinkFlag = false;
pinMode(PIN_Thermistor,INPUT);
pinMode(PIN_Pot, INPUT);
pinMode(PIN_Button, INPUT);
pinMode(PIN_Buzzer, OUTPUT);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Welcome... ");
beep();
delay(500);
lcd.setCursor(0,1);
lcd.print("to Eggysoft");
beep();
beep();
delay(1000);
}
// Run our state machine. This is written so that as little code as possible appears here.
void loop() {
switch (state) {
case STATE_Init:
DO_Init();
break;
case STATE_SetTimer:
DO_SetTimer();
break;
case STATE_CountingDown:
DO_CountingDown();
break;
case STATE_Buzzing:
DO_Buzzing();
break;
}
}
/**********************
* State Functions - one per state
*
***********************/
void DO_Init() {
lcd.clear();
delay(500);
lcd.print("Timer:"); // Print a message to the LCD.
state = STATE_SetTimer;
}
void DO_SetTimer() {
// Give the blink some sanity
delay(100);
// Get the raw timer value
int rawPot = analogRead(PIN_Pot); // [0..1023]
// Convert it to desired milliseconds (where a max of 4 minutes = 1023)
timerValue = TIME_multiplier * rawPot;
// Convert it to Human-friendly
int mins = int(timerValue/60000.0);
int secs = int(timerValue/1000) % 60;
lcd.setCursor(7,0);
if (blinkFlag) {
//lcd.print(timerValue, DEC);
lcd.print(mins, DEC);
lcd.print("m ");
lcd.print(secs, DEC);
lcd.print("s");
// pad out the end
lcd.print(" ");
}
else {
lcd.print(" ");
}
blinkFlag = !blinkFlag;
// Display the temp
displayTemp();
// Time to time?
if (!blinkFlag && digitalRead(PIN_Button) == HIGH) {
timer = timerValue;
state = STATE_CountingDown;
lastMillis = millis();
}
}
void DO_CountingDown() {
playAnim();
delay(100);
// Find out the *actual* delta t
long diff = millis() - lastMillis;
lastMillis = millis();
timer -= diff;
// Convert it to Human-friendly
int mins = int(timer/60000.0);
int secs = int(timer/1000) % 60;
lcd.setCursor(7,1);
if (blinkFlag || timer > 10000) {
//lcd.print(timerValue, DEC);
lcd.print(mins, DEC);
lcd.print("m ");
lcd.print(secs, DEC);
lcd.print("s");
// pad out the end
lcd.print(" ");
}
else {
lcd.print(" ");
}
blinkFlag = !blinkFlag;
displayTemp();
// If within half a second
if (timer < 500) {
state = STATE_Buzzing;
lcd.clear();
lcd.print("Your Eggs are");
lcd.setCursor(0,1);
lcd.print("Ready!! :)");
}
}
void DO_Buzzing() {
beep();
beep();
delay(500);
if (digitalRead(PIN_Button) == HIGH) {
timer = timerValue;
state = STATE_Init;
}
}
/**********************/
void displayTimer() {
}
void playAnim() {
animFrame++;
if (animFrame > 3) animFrame = 0;
delay(100);
switch(animFrame) {
case 0:
lcd.setCursor(14,0);
lcd.print("*");
lcd.setCursor(14,1);
lcd.print(".");
lcd.setCursor(15,1);
lcd.print(".");
lcd.setCursor(15,0);
lcd.print(" ");
break;
case 1:
lcd.setCursor(15,0);
lcd.print("*");
lcd.setCursor(14,0);
lcd.print(".");
lcd.setCursor(14,1);
lcd.print(".");
lcd.setCursor(15,1);
lcd.print(" ");
break;
case 2:
lcd.setCursor(15,1);
lcd.print("*");
lcd.setCursor(15,0);
lcd.print(".");
lcd.setCursor(14,0);
lcd.print(".");
lcd.setCursor(14,1);
lcd.print(" ");
break;
case 3:
lcd.setCursor(14,1);
lcd.print("*");
lcd.setCursor(15,1);
lcd.print(".");
lcd.setCursor(15,0);
lcd.print(".");
lcd.setCursor(14,0);
lcd.print(" ");
break;
}
}
void displayTemp() {
lcd.setCursor(0, 1);
// print the number of seconds since reset:
int temp = analogRead(PIN_Thermistor);
float tt = temperature(temp);
printFloat(tt, 1);
lcd.print("C");
}
// arduino.cc/playground/ComponentLib/Thermistor2
double temperature(int rawADC) {
return 0.1*((double)rawADC-248);
}
// printFloat prints out the float 'value' rounded to 'places' places after the decimal point
void printFloat(float value, int places) {
// this is used to cast digits
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;
// make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import
// if this rounding step isn't here, the value 54.321 prints as 54.3209
// calculate rounding term d: 0.5/pow(10,places)
float d = 0.5;
if (value < 0)
d *= -1.0;
// divide by ten for each decimal place
for (i = 0; i < places; i++)
d/= 10.0;
// this small addition, combined with truncation will round our values properly
tempfloat += d;
// first get value tens to be the large power of ten less than value
// tenscount isn't necessary but it would be useful if you wanted to know after this how many chars the number will take
if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}
// write out the negative if needed
if (value < 0)
lcd.print('-');
if (tenscount == 0)
lcd.print(0, DEC);
for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
lcd.print(digit, DEC);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}
// if no places after decimal, stop now and return
if (places <= 0)
return;
// otherwise, write the point and continue on
lcd.print('.');
// now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
lcd.print(digit,DEC);
// once written, subtract off that digit
tempfloat = tempfloat - (float) digit;
}
}
void beep() {
for (int i=0; i<5; i++) {
digitalWrite(PIN_Buzzer, HIGH);
delay(5);
digitalWrite(PIN_Buzzer, LOW);
delay(10);
}
}