14
14
// Include for SD Card reader on TFT
15
15
#include " SdFat.h"
16
16
17
+ // Include MQTT Library to enable the Azure IoT Hub to call back to our device
18
+ #include " MQTT.h"
19
+
17
20
// App Version Constant
18
21
void setup ();
19
22
void loop ();
20
23
void resetFermentationVariables ();
21
24
long getFermentationRate ();
25
+ int checkFermentationRate (String args);
26
+ int checkTemp (String args);
27
+ int checkVoltage ();
22
28
void activateBrewStage ();
23
29
int setBrewMode (String command);
24
30
void printSplash ();
@@ -31,14 +37,17 @@ void postFermentationRate();
31
37
void printReading (float reading);
32
38
void displayStageName (String stagename);
33
39
void displayFermentationHeading ();
40
+ void displayFermentationModeDelta ();
34
41
void displayTimeHeading ();
35
42
void displayTempHeading ();
36
43
void displayTempHistoryHeading ();
37
44
void displayFermentationRate (long rate);
38
45
void displayTime (float elapsedTime);
46
+ void displayVoltage (int voltage);
47
+ void displayLowBattAlert ();
39
48
String calcTimeToDisplay (float elapsedTime);
40
49
void updateChart (float temp);
41
- #line 16 "/Users/bsatrom/Development/brew-buddy/brew-buddy-firmware/src/brew-buddy-firmware.ino"
50
+ #line 19 "/Users/bsatrom/Development/brew-buddy/brew-buddy-firmware/src/brew-buddy-firmware.ino"
42
51
#define APP_VERSION " v1.0"
43
52
44
53
SYSTEM_THREAD (ENABLED);
@@ -65,6 +74,7 @@ int32_t width = 0, // BMP image dimensions
65
74
height = 0 ;
66
75
67
76
#define TFT_SPEED 120000000
77
+ #define BATT_LOW_VOLTAGE 90
68
78
69
79
// SD Card
70
80
SdFat sd;
@@ -85,6 +95,10 @@ float previousTemp = 0;
85
95
unsigned long postInterval = 120000 ;
86
96
unsigned long previousPostMillis = 0 ;
87
97
98
+ // Timing variables for checking the battery state
99
+ unsigned long battInterval = 300000 ;
100
+ unsigned long previousBattMillis = 0 ;
101
+
88
102
// Text Size Variables
89
103
const uint8_t headingTextSize = 4 ;
90
104
const uint8_t subheadTextSize = 2 ;
@@ -113,9 +127,15 @@ QueueArray<long> knockArray;
113
127
float fermentationRate = 0 ; // knocks per ms
114
128
unsigned long lastKnock;
115
129
130
+ String messageBase = " bb/" ;
131
+
116
132
String brewStage;
117
133
String brewId;
118
134
135
+ // MQTT Callback fw declaration and client
136
+ void mqttCB (char *topic, byte *payload, unsigned int length);
137
+ MQTT client (" brew-buddy-hub.azure-devices.net" , 8883 , mqttCB);
138
+
119
139
void setup ()
120
140
{
121
141
Serial.begin (9600 );
@@ -128,6 +148,8 @@ void setup()
128
148
129
149
// Brew Stage cloud functions
130
150
Particle.function (" setMode" , setBrewMode);
151
+ Particle.function (" checkTemp" , checkTemp);
152
+ Particle.function (" checkRate" , checkFermentationRate);
131
153
132
154
// Initialize TFT
133
155
tft.begin (TFT_SPEED);
@@ -148,12 +170,29 @@ void setup()
148
170
tft.fillScreen (ILI9341_BLACK);
149
171
printSubheadingLine (" Waiting for Brew..." );
150
172
173
+ // Check and display the battery level
174
+ int voltage = checkVoltage ();
175
+ displayVoltage (voltage);
176
+
177
+ // Connect to Azure MQTT Server
178
+ /* client.connect("e00fce681290df8ab5487791", "brew-buddy-hub.azure-devices.net/e00fce681290df8ab5487791/?api-version=2018-06-30", "SharedAccessSignature sr=brew-buddy-hub.azure-devices.net&sig=RKWH%2FV8CD595YeAnXOZ8jXsSYMnWf6RiJBnzhUoxCzE%3D&skn=iothubowner&se=1552683541");
179
+ if (client.isConnected())
180
+ {
181
+ Particle.publish("mqtt/status", "connected");
182
+ }
183
+ else
184
+ {
185
+ Particle.publish("mqtt/status", "failed");
186
+ } */
187
+
151
188
Particle.publish (" Version" , APP_VERSION);
152
189
Particle.publish (" Status" , " Brew Buddy Online" );
153
190
}
154
191
155
192
void loop ()
156
193
{
194
+ unsigned long currentMillis = millis ();
195
+
157
196
if (isFermentationMode)
158
197
{
159
198
int16_t knockVal = analogRead (KNOCK_PIN) / 16 ;
@@ -176,10 +215,10 @@ void loop()
176
215
tft.setTextColor (ILI9341_WHITE);
177
216
178
217
displayFermentationHeading ();
179
- // TODO: print delta btw mode start and fermentation start
218
+ displayFermentationModeDelta ();
180
219
181
220
waitUntil (Particle.connected );
182
- Particle.publish (" fermentation /state" , " start" );
221
+ Particle.publish (messageBase + " ferment /state" , " start" );
183
222
}
184
223
else
185
224
{
@@ -193,8 +232,6 @@ void loop()
193
232
}
194
233
else if (isBrewingMode)
195
234
{
196
- unsigned long currentMillis = millis ();
197
-
198
235
if (currentMillis - previousTempMillis > tempInterval)
199
236
{
200
237
previousTempMillis = currentMillis;
@@ -224,19 +261,34 @@ void loop()
224
261
225
262
displayTime (elapsedTime);
226
263
}
264
+ }
227
265
228
- if (currentMillis - previousPostMillis > postInterval)
266
+ if (currentMillis - previousBattMillis > battInterval)
267
+ {
268
+ int voltage = checkVoltage ();
269
+
270
+ displayVoltage (voltage);
271
+ Particle.publish (messageBase + " voltage" , String (voltage));
272
+
273
+ // If voltage < 30%, show a low batt message and publish message to cloud
274
+ if (voltage < BATT_LOW_VOLTAGE)
229
275
{
230
- previousPostMillis = millis ();
276
+ displayLowBattAlert ();
277
+ Particle.publish (messageBase + " alert" , " low-batt" );
278
+ }
279
+ }
231
280
232
- if (isBrewingMode)
233
- {
234
- postTemp (lastTemp);
235
- }
236
- else if (isFermentationMode)
237
- {
238
- postFermentationRate ();
239
- }
281
+ if (currentMillis - previousPostMillis > postInterval)
282
+ {
283
+ previousPostMillis = millis ();
284
+
285
+ if (isBrewingMode)
286
+ {
287
+ postTemp (lastTemp);
288
+ }
289
+ else if (isFermentationMode)
290
+ {
291
+ postFermentationRate ();
240
292
}
241
293
}
242
294
}
@@ -267,6 +319,38 @@ long getFermentationRate()
267
319
return rate;
268
320
}
269
321
322
+ int checkFermentationRate (String args)
323
+ {
324
+ if (isFermentationMode)
325
+ {
326
+ postFermentationRate ();
327
+
328
+ return 1 ;
329
+ }
330
+
331
+ return 0 ;
332
+ }
333
+
334
+ int checkTemp (String args)
335
+ {
336
+ if (isBrewingMode)
337
+ {
338
+ float temp = readTemp ();
339
+ postTemp (temp);
340
+
341
+ return 1 ;
342
+ }
343
+
344
+ return 0 ;
345
+ }
346
+
347
+ int checkVoltage ()
348
+ {
349
+ int voltage = analogRead (BATT) * 0.0011224 ;
350
+
351
+ return (int )((voltage / 4.2 ) * 100 + 0.5 )
352
+ }
353
+
270
354
void activateBrewStage ()
271
355
{
272
356
startTime = millis ();
@@ -398,14 +482,12 @@ float readTemp()
398
482
399
483
void postTemp (float temp)
400
484
{
401
- String payload = " { \" temperature\" :" + String (temp, 2 ) + " , \" time\" : \" " + millis () + " \" }" ;
402
- Particle.publish (" brewing/temp" , payload);
485
+ Particle.publish (messageBase + " brew/temp" , String (temp, 2 ));
403
486
}
404
487
405
488
void postFermentationRate ()
406
489
{
407
- String payload = " { \" current_rate\" :" + String (fermentationRate, 2 ) + " , \" time\" : \" " + millis () + " \" }" ;
408
- Particle.publish (" fermentation/rate" , payload);
490
+ Particle.publish (messageBase + " ferment/rate" , String (fermentationRate, 2 ));
409
491
}
410
492
411
493
void printReading (float reading)
@@ -423,7 +505,7 @@ void printReading(float reading)
423
505
}
424
506
else if (reading > 110 )
425
507
{
426
- tft.setTextSize (ILI9341_RED);
508
+ tft.setTextColor (ILI9341_RED);
427
509
}
428
510
429
511
tft.setTextSize (tempTextSize);
@@ -444,12 +526,22 @@ void displayStageName(String stagename)
444
526
445
527
void displayFermentationHeading ()
446
528
{
447
- tft.setCursor (0 , 40 );
529
+ tft.setCursor (0 , 100 );
448
530
tft.setTextSize (2 );
449
531
tft.println (" Fermentation Rate" );
450
532
tft.println (" (in seconds)" );
451
533
}
452
534
535
+ void displayFermentationModeDelta ()
536
+ {
537
+ unsigned long fermentationDelta = fermentationStartTime - fermentationModeStartTime;
538
+
539
+ tft.setCursor (0 , 40 );
540
+ tft.setTextSize (2 );
541
+ tft.println (" Time to fermentation (hours)" );
542
+ tft.println (fermentationDelta / 36000000.00 );
543
+ }
544
+
453
545
void displayTimeHeading ()
454
546
{
455
547
tft.setCursor (0 , 120 );
@@ -489,6 +581,23 @@ void displayTime(float elapsedTime)
489
581
tft.println (timeString);
490
582
}
491
583
584
+ void displayVoltage (int voltage)
585
+ {
586
+ tft.setCursor (160 , 10 );
587
+ tft.setTextSize (1 );
588
+ tft.print (" Batt: " );
589
+ tft.print (voltage);
590
+ tft.println (" %" );
591
+ }
592
+
593
+ void displayLowBattAlert ()
594
+ {
595
+ tft.setCursor (160 , 30 );
596
+ tft.setTextSize (2 );
597
+ tft.setTextSize (ILI9341_RED);
598
+ tft.println (" LOW BATT" );
599
+ }
600
+
492
601
String calcTimeToDisplay (float elapsedTime)
493
602
{
494
603
String padZero = " 0" ;
@@ -563,3 +672,8 @@ void updateChart(float temp)
563
672
tempGraphArray.enqueue (currentLocation);
564
673
}
565
674
}
675
+
676
+ void mqttCB (char *topic, byte *payload, unsigned int length)
677
+ {
678
+ Particle.publish (" mqtt/sub" , topic);
679
+ }
0 commit comments