Difference between revisions of "SugarBush - The Firmware"
Jump to navigation
Jump to search
(Created page with "=platformio.ini= Yes, this looks insanely complex... The good news is that it's fairly straightforward once you wrap your head around what the various parts do. * <span styl...") |
(No difference)
|
Latest revision as of 18:38, 12 March 2021
Contents
platformio.ini
Yes, this looks insanely complex...
The good news is that it's fairly straightforward once you wrap your head around what the various parts do.
- [env] is fairly obvious. It's the definition of the hardware...
- [common] is all the stuff that's common to all of the builds.
- [env:WhatEver] blocks are the magic part. They define the differences between all of the various builds.
Note things like ${common.lib_deps} & ${common.build_flags}, These simply pull in the stuff from [common] for each individual build.
1 [platformio]
2 ; default_envs = SugarShack_Alert
3
4 [env]
5 platform = espressif8266
6 ; For now, let's stick with the 8266 family MCUs
7 board = d1_mini
8
9 framework = arduino
10
11 monitor_speed = 115200
12 ; I like my serial comms fast. (Without this line you get the default of 9600)
13
14 [common]
15 lib_deps =
16 PubSubClient
17 SimpleTimer
18
19 build_flags =
20 -D DEBUG ; This is just plain handy. Use it to turn debugging output on/off...
21 ; -D DEBUG0 ; Show WiFi Debug info
22 ; -D DEBUG1 ; Show extra WiFi Debug info
23 ; -D DEBUG2 ; Show Sensor Debug info
24 ; -D DEBUG3 ; Show extra Sensor Debug info
25 ; -D DEBUG4 ; Show MQTT Debug info
26 ; -D DEBUG5 ; Show Pixels Debug info
27 -D WAP=2 ; Select the WiFi Access Point. (Might also select servers based on WAP choice)
28 ; WAP 0 = TinkerToys (Test setup / Skeeter.tinkerNet.ca for MQTT)
29 ; WAP 1 = TinkerToysB (Victoria Drive setup / SkyNet.tinkerNet.ca for MQTT)
30 ; WAP 2 = vanneck (SugarBush setup / 192.168.0.222 for MQTT)
31 ; WAP 3 = paradise (paradise / SkyNet.MillersParadise.ca for MQTT)
32 ; WAP 4+ = VictoriaDrive2B ()
33
34 [env:SugarShack_Alert]
35 ; Little noisy blinkenbox
36 ; 4 Neopixels hung off GPIO 12
37 ; Speaker hung off GPIO 14
38 ; Pixel 1 GRN = 25%
39 ; Pixel 2 GRN = 50%
40 ; Pixel 3 GRN = 75%
41 ; All 4 RED = Tank Full!
42 ; Pixel 4 slowly blinking:
43 ; GRN = OK
44 ; ORA = No MQTT
45 ; RED = No WiFi
46 lib_deps =
47 ${common.lib_deps}
48 jfturcot/SimpleTimer
49 Adafruit NeoPixel
50
51 build_flags =
52 ${common.build_flags}
53 -D SS_Alert
54 -D d_Pixels
55 -D d_Audio
56
57 [env:SugarShack_PHTank]
58 ; Monitor depth probes in the PumpHouse Tank
59 ; ~25% Level: GPIO 4
60 ; ~50% Level: GPIO 5
61 ; ~75% Level: GPIO 12
62 ; 100% Level: GPIO 13
63 ; MIGHT need to do some sort of output for the relays on the lightbar
64 lib_deps =
65 ${common.lib_deps}
66 jfturcot/SimpleTimer
67
68 build_flags =
69 ${common.build_flags}
70 -D SS_PHTank
71 -D s_Depth
72
73 [env:SugarShack_PHLightBar]
74 ; Control the lightbar in the PupHouse camera view
75 lib_deps =
76 ${common.lib_deps}
77
78 build_flags =
79 ${common.build_flags}
80
81 [env:SugarShack_PHDumper]
82 ; Monitor the dumper cycles
83 ; Switch on GPIO 4 (Maybe Hall-Effect... Maybe Reed Switch...)
84 lib_deps =
85 ${common.lib_deps}
86 jfturcot/SimpleTimer
87
88 build_flags =
89 ${common.build_flags}
90 -D SS_Dumper
91
92 [env:SugarShack_RO]
93 ; Monitor the R/O system
94 lib_deps =
95 ${common.lib_deps}
96 build_flags =
97 ${common.build_flags}
98
99 [env:SugarShack_Evaporator]
100 ; Monitor the levels in the Evaporator
101 ; At least 2 depth probes
102 ; Some NeoPixels
103 ; Maybe a speaker
104 lib_deps =
105 ${common.lib_deps}
106 build_flags =
107 ${common.build_flags}
108
109 [env:SugarShack_BottlingTank]
110 ; Monitor temperature in Bottling Tank
111 ; Maybe depth too...
112 lib_deps =
113 ${common.lib_deps}
114 build_flags =
115 ${common.build_flags}
116 [env:SugarShack_Climate]
117 ; Monitor temperature, humidity & barometric pressure in the SugarShack
118 lib_deps =
119 ${common.lib_deps}
120 build_flags =
121 ${common.build_flags}
122
123 [env:SugarShack_HoldingTanks]
124 ; Monitor depth probes in the Outside Holding Tanks
125 lib_deps =
126 ${common.lib_deps}
127 build_flags =
128 ${common.build_flags}
129 [env:SugarShack_FeedTank]
130 ; Monitor depth probes in the Feed Tank for the Evaporator
131 ; (This unit will likely have more than 4 probes)
132 lib_deps =
133 ${common.lib_deps}
134 build_flags =
135 ${common.build_flags}
main.cpp
1 /*
2 * Monitor tele/TankLevel
3 *
4 * If Tank == PumpHouse && Level == 0
5 * Turn off all lights & Screamer
6 * If Tank == PumpHouse && Level >= 25
7 * Turn on Light 1
8 * If Tank == PumpHouse && Level >= 50
9 * Turn on Light 2
10 * If Tank == PumpHouse && Level >= 75
11 * Turn on Light 3
12 * If Tank == PumpHouse && Level >= 100
13 * Turn on Light Screamer
14 */
15
16 /*
17 * Maybe add a PAUSE button...
18 * (Disable the screamer for half an hour?)
19 */
20
21 #include "libraries.h"
22 #include "functions.h"
23 #include "externs.h"
24 #include "TopSecret.h"
25
26 SimpleTimer timer;
27
28 #ifdef SS_Dumper
29 int ReedPin = 4;
30 int HallPin = 5;
31 // int Dumptime = 0;
32 #endif // SS_Dumper
33
34 void setup()
35 {
36 char debugTEXT[46];
37
38 Serial.begin(115200);
39 delay(500); // Delay to let the ESP get booted before sending out serial data
40 debug_TitleScreen();
41
42 // WiFi //////////////////////////////////////////////////////////////////////
43 WiFi_init();
44 debug_Separator();
45
46 // MQTT //////////////////////////////////////////////////////////////////////
47 MQTT_init();
48
49 // Pixels ////////////////////////////////////////////////////////////////////
50 #ifdef d_Pixels
51
52 Pixels_init();
53
54 for (int i = 0; i < PixelCount; i++)
55 {
56 SetAPixel(i, BLU);
57 }
58
59 #endif // d_Pixels
60
61 // Depth Probes ////////////////////////////////////////////////////////////////
62 #ifdef s_Depth
63
64 Depth_init();
65
66 #endif // d_Depth
67
68 // Audio ////////////////////////////////////////////////////////////////
69 #ifdef d_Audio
70
71 Noise_init();
72
73 #endif // d_Audio
74
75 // Hall-Effect ///////////////////////////////////////////////////////////////
76 #ifdef SS_Dumper
77 debug_Separator();
78 debug_SectionTitle("Hall Effect Sensor");
79 pinMode(HallPin, INPUT);
80 attachInterrupt(digitalPinToInterrupt(ReedPin), DumpDetect, CHANGE);
81 sprintf(debugTEXT, "Reed Switch on pin %d", ReedPin);
82 debug_LineOut(debugTEXT);
83 attachInterrupt(digitalPinToInterrupt(HallPin), DumpDetect2, CHANGE);
84 sprintf(debugTEXT, "Hall Effect Sensor on pin %d", HallPin);
85 debug_LineOut(debugTEXT);
86 #endif // SS_Dumper
87
88 // Interval Timers ///////////////////////////////////////////////////////////
89 debug_Separator();
90 debug_SectionTitle("Interval Timers");
91
92 timer.setInterval(20, MQTT_handler);
93 debug_LineOut("MQTT");
94
95 timer.setInterval(2000, WiFi_Test);
96 debug_LineOut("WiFiCheck");
97
98 #ifdef s_Depth
99 timer.setInterval(5000, CheckProbes);
100 debug_LineOut("Check Probes");
101 #endif // s_Depth
102
103 // READY /////////////////////////////////////////////////////////////////////
104 debug_ReadyScreen();
105 }
106
107 void loop()
108 {
109 // Run the interval timers
110 // Running processes here in loop() is a synchronous flow.
111 // Running processes via the interval timers is assynchronous.
112 // If your actions don't depend directly on each other,
113 // synchronous flow makes no sense at all...
114 timer.run();
115
116 #ifdef SS_Dumper
117 // This is just here to give me console output while developing...
118 // Serial.print(".");
119 // delay(1000);
120 #endif // SS_Dumper
121 }
Debugging.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 void debug_TitleScreen()
5 {
6 Serial.printf("\n\n#================================================#\n");
7 #ifdef SS_Alert
8 Serial.printf("# SugarShack PumpHuose Alerter #\n");
9 Serial.printf("# ESP With a Peizo & Pixels #\n");
10 Serial.printf("+------------------------------------------------+\n");
11 #endif //SS_Alert
12 #ifdef SS_PHTank
13 Serial.printf("# SugarShack PumpHuose Tank Monitor #\n");
14 Serial.printf("+------------------------------------------------+\n");
15 #endif // SS_PHTank
16 #ifdef SS_Dumper
17 Serial.printf("# SugarShack PumpHuose Dumper Monitor #\n");
18 Serial.printf("+------------------------------------------------+\n");
19 #endif // SS_Dumper
20 Serial.printf("# WiFi Enabled... #\n");
21 Serial.printf("# Speaks fluent MQTT... #\n");
22 Serial.printf("#================================================#\n");
23 }
24
25 void debug_ReadyScreen()
26 {
27 Serial.printf("#================================================#\n");
28 Serial.printf("# Ready To Run. #\n");
29 Serial.printf("#================================================#\n");
30 }
31
32 void debug_Separator()
33 {
34 Serial.printf("+------------------------------------------------+\n");
35 }
36
37 void debug_SectionTitle(const char *Title)
38 {
39 Serial.printf("| %-46s |\n", Title);
40 }
41
42 void debug_LineOut(const char *Line)
43 {
44 Serial.printf("| %-43s |\n", Line);
45 }
46
47 void debug_Action(const char *Line)
48 {
49 {
50 const char* SPACE = " ";
51 char BUFFER[100];
52 char BUFFER2[100];
53
54 int BuffSize = (23 - (strlen(Line) / 2));
55
56 strcpy(BUFFER, SPACE);
57 BUFFER[BuffSize] = '\0';
58
59 sprintf(BUFFER2, "%s%s", BUFFER, Line);
60 Serial.printf("| %-46s |\n", BUFFER2);
61 }
62 }
63
64 void debug_Trouble(const char *Line)
65 {
66 Serial.printf("* %-46s *\n", Line);
67 }
68
69 void debug_Success(const char *Line)
70 {
71 Serial.printf("+ %-46s +\n", Line);
72 }
73
74 void debug_ProgressBar0()
75 {
76 Serial.printf("| ");
77 }
78 void debug_ProgressBar1()
79 {
80 Serial.printf(".");
81
82 }
83 void debug_ProgressBar2(int dotcount)
84 {
85 for (int i = 0; i < (47 - dotcount); i++)
86 {
87 Serial.printf(" ");
88 }
89 Serial.printf("|\n");
90 }
WiFi.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 ////////////////////////////////////////////////////////////////
5 // These exist because the variables are declared elsewhere in
6 // the project. (Specifically, in TopSecret.h)
7 extern char *WiFi_ssid;
8 extern char *WiFi_password;
9 extern char *WiFi_ClientName;
10 ////////////////////////////////////////////////////////////////
11
12 // Initialize the WiFi
13 //
14 // If we don't get a connection, we just keep trying forever.
15 // Probably be an idea to eventually just give up, but most
16 // ESP8266 devices are kinda useless without the connection...
17 void WiFi_init()
18 {
19 char debugTEXT[46];
20
21 WiFi.mode(WIFI_STA); // Connecting as a STATION
22 WiFi.begin(WiFi_ssid, WiFi_password);
23
24 // We start by connecting to a WiFi network
25 sprintf(debugTEXT, "Connecting to: %-22s", WiFi_ssid);
26 debug_SectionTitle(debugTEXT);
27 {
28 debug_ProgressBar0();
29 int dotcount = 0;
30 while (WiFi.status() != WL_CONNECTED) // Give it a bit of time to establish the WiFi connection...
31 {
32 dotcount++;
33 delay(500);
34 debug_ProgressBar1();
35 if (dotcount >= 46)
36 {
37 debug_ProgressBar2(dotcount);
38 dotcount = 0;
39 debug_ProgressBar0();
40 }
41 // SSD1306_Static(" no WiFi ", 3);
42 }
43 debug_ProgressBar2(dotcount);
44 }
45 sprintf(debugTEXT, "WiFi connected on Channel %-2d", WiFi.channel());
46 debug_LineOut(debugTEXT);
47 sprintf(debugTEXT, "IP address: %-15s", WiFi.localIP().toString().c_str());
48 debug_LineOut(debugTEXT);
49
50 sprintf(debugTEXT, "My name is NOT %-22s", wifi_station_get_hostname());
51 debug_LineOut(debugTEXT);
52 sprintf(debugTEXT, "Really... It's %-22s", WiFi_ClientName);
53 debug_LineOut(debugTEXT);
54
55 // SSD1306_Static(" WiFi good ", 3);
56
57 // Add "build_flags = -D DEBUG1" to your platformio.ini to get some extra WiFi stats
58 #ifdef DEBUG1
59 WiFi.printDiag(Serial);
60 sprintf(debugTEXT, "RSSI: %d dBm", WiFi.RSSI());
61 debug_LineOut(debugTEXT);
62 sprintf(debugTEXT, "HostName: %-13s !!!! BULLSHIT !!!!", WiFi.hostname().c_str());
63 debug_LineOut(debugTEXT);
64 // Apparently, the ESP8266WiFi library does not actually support DHCP completely
65 // { https://www.reddit.com/r/arduino/comments/d6mvc7/getting_hostname_from_dhcp_with_esp8266/ }
66 // { https://github.com/esp8266/Arduino/issues/5695 }
67 #endif
68 }
69
70 int WiFi_strength()
71 {
72 return (WiFi.RSSI());
73 }
74
75 int blip[3] = {000, 255, 000}; // GRN
76
77 void WiFi_Test() // Is Good... Maybe
78 {
79 if (WiFi.status() != WL_CONNECTED)
80 {
81 Serial.println("Oh Poop!");
82 blip[0] = 128;
83 blip[1] = 128;
84 }
85 else
86 {
87 if (blip[1] == 255)
88 blip[1] = 0;
89 else
90 blip[1] = 255;
91 }
92 #ifdef d_Pixels
93 SetAPixel(3, blip);
94 #endif // d_Pixels
95 }
96
97 int blip2[3] = {255, 000, 000}; // RED
98
99 void WiFi_Test2() // Lost WiFi
100 {
101 if (blip2[0] == 255)
102 blip2[0] = 0;
103 else
104 blip2[0] = 255;
105 #ifdef d_Pixels
106 SetAPixel(3, blip2);
107 #endif // d_Pixels
108 }
109
110 int blip3[3] = {255, 128, 000}; // ORA
111
112 void WiFi_Test3() // lost MQTT
113 {
114 if (blip3[0] == 255)
115 {
116 blip3[0] = 0;
117 blip3[1] = 0;
118 blip3[2] = 0;
119 }
120 else
121 {
122 blip3[0] = 255;
123 blip3[1] = 128;
124 blip3[2] = 000;
125 }
126 #ifdef d_Pixels
127 SetAPixel(3, blip3);
128 #endif // d_Pixels
129 }
MQTT.cpp
1 #include "libraries.h"
2 #include "functions.h"
3 #include "externs.h"
4
5 #include "MQTT.h"
6
7 WiFiClient espClient;
8 PubSubClient MQTT_client(espClient);
9
10 void MQTT_handler()
11 {
12 if (!MQTT_client.connected())
13 {
14 MQTT_reconnect();
15 }
16 MQTT_client.loop();
17 // MQTT_beacon();
18 }
19
20 ////////////////////////////////////////////////////////////////
21 // MQTT Functions
22 ////////////////////////////////////////////////////////////////
23
24 void MQTT_init()
25 {
26 MQTT_client.setServer(MQTT_broker, 1883);
27 MQTT_client.setCallback(MQTT_callback);
28
29 // Build the topic names
30 strcpy(MQTT_inTopic, "cmnd/"); // in - Commands
31 strcat(MQTT_inTopic, MQTT_ClientName);
32 strcat(MQTT_inTopic, "/#");
33 strcpy(MQTT_teleTopic, "tele/"); // out - Telemetry
34 strcat(MQTT_teleTopic, MQTT_ClientName);
35 strcpy(MQTT_statTopic, "stat/"); // out - Status
36 strcat(MQTT_statTopic, MQTT_ClientName);
37 strcpy(MQTT_outTopic, "noti/"); // out - Notifications
38 strcat(MQTT_outTopic, MQTT_ClientName);
39
40 MQTT_reconnect();
41 }
42
43 void MQTT_callback(char *topic, byte payload[100], int length)
44 {
45 char debugTEXT[46];
46
47 char MQTT_msg_in[MQTT_BUFFER_SIZE];
48 char *MQTT_command = strrchr(topic, '/');
49 char CNasT[MQTT_BUFFER_SIZE];
50 strcpy(CNasT, "/");
51 strcat(CNasT, MQTT_ClientName); // "ClientName as Topic"
52
53 #ifdef DEBUG4
54 debug_SectionTitle("Message arrived");
55 sprintf(debugTEXT, "Topic: %30s", MQTT_command);
56 debug_LineOut(debugTEXT);
57 #endif
58
59 // if (length < MQTT_BUFFER_SIZE)
60 // if (length < 63)
61 // Messages 63 characters long or bigger make BOOM
62 // with a "Soft WDT reset"
63 // MQTT_BUFFER_SIZE is 100
64 // I R cornfoozed...
65 if (length < 59) // & now 59 is bad... :|
66 {
67
68 MQTT_msg_in[0] = '\0'; // start with an empty string!
69 for (int i = 0; i < length; i++)
70 {
71 MQTT_msg_in[i] = (char)payload[i];
72 MQTT_msg_in[i + 1] = '\0';
73 }
74
75 #ifdef DEBUG4
76 sprintf(debugTEXT, "Message: %28s", MQTT_msg_in);
77 debug_LineOut(debugTEXT);
78 sprintf(debugTEXT, "Message Size: %d", length);
79 debug_LineOut(debugTEXT);
80 #endif
81
82 /////////////////////////////////////////////////////
83 // Message handling goes here...
84 /////////////////////////////////////////////////////
85
86 if (strcmp(MQTT_command, CNasT) == 0) // MQTT_ClientName as Topic
87 {
88 // Missing topic
89 #ifdef DEBUG4
90 debug_Trouble("Missing topic...");
91 #endif
92 }
93 else if (strcmp(MQTT_command, "/Level") == 0) // Tank Level
94 {
95 if (strcmp(MQTT_msg_in, "") == 0)
96 {
97 #ifdef DEBUG4
98 debug_Trouble("No actual message...");
99 #endif
100 // Might be a good way to request status...
101 }
102 else
103 {
104 int level = atoi(MQTT_msg_in);
105 sprintf(debugTEXT, "Tank Level is: %d", level);
106 debug_Action(debugTEXT);
107
108 #ifdef d_Pixels
109
110 if (level == 0)
111 {
112 SetAPixel(0, BLK);
113 SetAPixel(1, BLK);
114 SetAPixel(2, BLK);
115 SetAPixel(3, BLK);
116 STFU();
117 }
118 if (level >= 25)
119 {
120 SetAPixel(0, GRN);
121 SetAPixel(1, BLK);
122 SetAPixel(2, BLK);
123 SetAPixel(3, BLK);
124 STFU();
125 }
126 if (level >= 50)
127 {
128
129 SetAPixel(1, GRN);
130 SetAPixel(2, BLK);
131 SetAPixel(3, BLK);
132 STFU();
133 }
134 if (level >= 75)
135 {
136 SetAPixel(2, GRN);
137 SetAPixel(3, BLK);
138 STFU();
139 }
140 if (level >= 100)
141 {
142 SetAPixel(0, RED);
143 SetAPixel(1, RED);
144 SetAPixel(2, RED);
145 SetAPixel(3, RED);
146 ScreamBloodyMurder();
147 }
148 #endif // d_Pixels
149 }
150 }
151 else if (strcmp(MQTT_command, "/Dump") == 0) // Dumper has dumped
152 {
153 Boop();
154 }
155 else if (strcmp(MQTT_command, "/Screen") == 0) // Screen control
156 {
157 if (strcmp(MQTT_msg_in, "") == 0)
158 {
159 #ifdef DEBUG4
160 debug_Trouble("No actual message...");
161 #endif
162 // Might be a good way to request status...
163 }
164 // else if ((strcmp(MQTT_msg_in, "1") == 0) || (strcmp(MQTT_msg_in, "ON") == 0))
165 // SSD1306_on();
166 // else if ((strcmp(MQTT_msg_in, "0") == 0) || (strcmp(MQTT_msg_in, "OFF") == 0))
167 // SSD1306_off();
168 // else if ((strcmp(MQTT_msg_in, "+") == 0) || (strcmp(MQTT_msg_in, "UP") == 0))
169 // SSD1306_Bright();
170 // else if ((strcmp(MQTT_msg_in, "-") == 0) || (strcmp(MQTT_msg_in, "DOWN") == 0))
171 // SSD1306_Dim();
172 else
173 debug_Trouble("Say What?");
174 }
175 else
176 {
177 #ifdef DEBUG4
178 debug_Trouble("Dunno Whatcha want...");
179 #endif
180 }
181 }
182 else
183 {
184 #ifdef DEBUG4
185 debug_Trouble("But, it's TOO Bloody Big!");
186 #endif
187 }
188 }
189
190 void MQTT_reconnect()
191 {
192 char debugTEXT[46];
193
194 // Loop until we're reconnected
195 while (!MQTT_client.connected())
196 {
197 /////////////////////////////////////////////////////////////////////////////////////////////////
198 sprintf(debugTEXT, "WiFi:%d dBm", WiFi_strength());
199 debug_Action(debugTEXT);
200 /////////////////////////////////////////////////////////////////////////////////////////////////
201 debug_SectionTitle("Attempting MQTT connection...");
202
203 // Create a random client ID
204 String clientId = MQTT_ClientName;
205 clientId += String(random(0xffff), HEX);
206
207 // Attempt to connect
208 if (MQTT_client.connect(clientId.c_str()))
209 {
210 /////////////////////////////////////////////////////////////////////////////////////////////////
211 sprintf(debugTEXT, "WiFi:%d dBm", WiFi_strength());
212 debug_Action(debugTEXT);
213 /////////////////////////////////////////////////////////////////////////////////////////////////
214 // SSD1306_Static(" MQTT good ", 3);
215 // delay(500);
216 // SSD1306_Static(" ", 3);
217 sprintf(debugTEXT, "connected to %-24s", MQTT_broker);
218 debug_LineOut(debugTEXT);
219 sprintf(debugTEXT, "My Name: %-27s", MQTT_ClientName);
220 debug_LineOut(debugTEXT);
221 // Once connected, publish an announcement...
222 char MQTT_statTopic_Device[100];
223 strcpy(MQTT_statTopic_Device, MQTT_statTopic);
224 strcat(MQTT_statTopic_Device, "/HELLO");
225 // MQTT_client.publish(MQTT_statTopic_Device, "world");
226 MQTT_client.publish(MQTT_statTopic_Device, WiFi_ssid);
227 // ... and resubscribe
228 MQTT_client.subscribe(MQTT_inTopic);
229 }
230 else
231 {
232 /////////////////////////////////////////////////////////////////////////////////////////////////
233 sprintf(debugTEXT, "WiFi:%d dBm", WiFi_strength());
234 debug_Action(debugTEXT);
235 /////////////////////////////////////////////////////////////////////////////////////////////////
236
237 if (WiFi.status() != WL_CONNECTED)
238 {
239 WiFi_Test2();
240 debug_Trouble("UH OH!!! No WiFi!!!");
241 }
242 else
243 {
244 // SSD1306_Static(" no MQTT ", 3);
245 WiFi_Test3();
246 debug_Trouble("UH OH!!! No MQTT!!!");
247 }
248
249 sprintf(debugTEXT, "failed, rc=%d", MQTT_client.state());
250 debug_Trouble(debugTEXT);
251 debug_Trouble("trying again in 2 seconds");
252 // Wait 5 seconds before retrying
253 delay(2000);
254 }
255 }
256 }
257
258 void MQTT_beacon()
259 {
260 /* Beacon signal published at set interval to indicate the device
261 * is still powered up and actively connected to MQTT...
262 * A keepalive of sorts
263 * also updates state within MQTT so it can be captured for
264 * indicator light elsewhere
265 * &, as a bonus, it's sending the WiFi strength.
266 */
267 char MQTT_statTopic_Device[100];
268 char WiFiSignal[10];
269 strcpy(MQTT_statTopic_Device, MQTT_statTopic);
270 strcat(MQTT_statTopic_Device, "/WiFi_strength");
271 sprintf(WiFiSignal, "%d dBm", WiFi_strength());
272 #ifdef DEBUG0
273 debug_SectionTitle("WiFi:");
274 debug_LineOut(WiFiSignal);
275 #endif
276
277 MQTT_client.publish(MQTT_statTopic_Device, WiFiSignal);
278 blinkLED(5);
279
280 #ifdef DEBUG4
281 debug_Action("Beacon sent");
282 #endif
283 }
284
285 void MQTT_Status(char const *Device, char const *Status) // Send status messages
286 {
287 char MQTT_statTopic_Device[100];
288 strcpy(MQTT_statTopic_Device, MQTT_statTopic);
289 strcat(MQTT_statTopic_Device, "/");
290 strcat(MQTT_statTopic_Device, Device);
291
292 #ifdef DEBUG4
293 char debugTEXT[46];
294
295 sprintf(debugTEXT, "}- %16s = %-16s -{", Device, Status);
296 debug_Trouble(debugTEXT);
297 #endif
298 MQTT_client.publish(MQTT_statTopic_Device, Status);
299 }
300
301 void MQTT_SendTELE(const char *Topic, char *Message)
302 {
303 char MQTT_teleTopic_Device[100];
304 strcpy(MQTT_teleTopic_Device, MQTT_teleTopic);
305 strcat(MQTT_teleTopic_Device, "/");
306 strcat(MQTT_teleTopic_Device, Topic);
307 MQTT_client.publish(MQTT_teleTopic_Device, Message);
308 }
309
310 void MQTT_SendSTAT(const char *Topic, char *Message)
311 {
312 char MQTT_statTopic_Device[100];
313 strcpy(MQTT_statTopic_Device, MQTT_statTopic);
314 strcat(MQTT_statTopic_Device, "/");
315 strcat(MQTT_statTopic_Device, Topic);
316 MQTT_client.publish(MQTT_statTopic_Device, Message);
317 }
318
319 void MQTT_SendCMND(const char *Topic, char *Message)
320 {
321 char MQTT_statTopic_Device[100];
322 strcpy(MQTT_statTopic_Device, Topic);
323 // strcat(MQTT_statTopic_Device, "/");
324 // strcat(MQTT_statTopic_Device, Topic);
325 MQTT_client.publish(MQTT_statTopic_Device, Message);
326 }
327
328 void HandleMessages()
329 {
330 }
Sensing
Depth.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 /*
5 * Puplish to tele/TankLevel
6 *
7 * If all probes are high
8 * publish {"Tank":"PumpHouse", "Level":0}
9 * If bottom probe is low
10 * publish {"Tank":"PumpHouse", "Level":25}
11 * If bottom probe is low
12 * publish {"Tank":"PumpHouse", "Level":50}
13 * If bottom probe is low
14 * publish {"Tank":"PumpHouse", "Level":75}
15 * If bottom probe is low
16 * publish {"Tank":"PumpHouse", "Level":100}
17 */
18
19 int Probe1 = 4; // no pullup...
20 int Probe2 = 5;
21 int Probe3 = 12; // no pullup...
22 int Probe4 = 13;
23
24 void Depth_init()
25 {
26 char debugTEXT[46];
27 debug_Separator();
28 debug_SectionTitle("Configuring Depth Probes...");
29 // pinMode(Probe1, INPUT_PULLUP);
30 // pinMode(Probe2, INPUT_PULLUP);
31 // pinMode(Probe3, INPUT_PULLUP);
32 // pinMode(Probe4, INPUT_PULLUP);
33 pinMode(Probe1, INPUT);
34 pinMode(Probe2, INPUT);
35 pinMode(Probe3, INPUT);
36 pinMode(Probe4, INPUT);
37 #ifdef DEBUG
38 sprintf(debugTEXT, "Depth Probes on GPIOs %d %d %d & %d", Probe1, Probe2, Probe3, Probe4);
39 debug_LineOut(debugTEXT);
40 #endif
41 }
42
43 void CheckProbes()
44 {
45 Serial.print("Probes: ");
46 Serial.print(digitalRead(Probe1));
47 Serial.print(" ");
48 Serial.print(digitalRead(Probe2));
49 Serial.print(" ");
50 Serial.print(digitalRead(Probe3));
51 Serial.print(" ");
52 Serial.print(digitalRead(Probe4));
53 Serial.println(" ");
54 if (!digitalRead(Probe4)) // 14 D5
55 {
56 MQTT_SendTELE("Level", "{\"Tank\":\"PumpHouse\", \"Level\":100}");
57 // MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "{\"Tank\":\"PumpHouse\", \"Level\":100}");
58 MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "100");
59 // Serial.println("PROBE 4");
60 }
61 // return 100;
62 else if (!digitalRead(Probe3)) // 13 D7
63 {
64 MQTT_SendTELE("Level", "{\"Tank\":\"PumpHouse\", \"Level\":75}");
65 // MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "{\"Tank\":\"PumpHouse\", \"Level\":75}");
66 MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "75");
67 // Serial.println("PROBE 3");
68 }
69 // return 75;
70 else if (!digitalRead(Probe2)) // 12 D6
71 {
72 MQTT_SendTELE("Level", "{\"Tank\":\"PumpHouse\", \"Level\":50}");
73 // MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "{\"Tank\":\"PumpHouse\", \"Level\":50}");
74 MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "50");
75 // Serial.println("PROBE 2");
76 }
77 // return 50;
78 else if (!digitalRead(Probe1)) // 5 D1
79 {
80 MQTT_SendTELE("Level", "{\"Tank\":\"PumpHouse\", \"Level\":25}");
81 // MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "{\"Tank\":\"PumpHouse\", \"Level\":25}");
82 MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "25");
83 // Serial.println("PROBE 1");
84 }
85 // return 25;
86 else
87 {
88 MQTT_SendTELE("Level", "{\"Tank\":\"PumpHouse\", \"Level\":0}");
89 // MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "{\"Tank\":\"PumpHouse\", \"Level\":0}");
90 MQTT_SendCMND("cmnd/SugarShack_Alarm/Level", "0");
91 // Serial.println("NO PROBE");
92 }
93 // return 0;
94 }
HallEffect.cpp
1 #include "libraries.h"
2 #include "functions.h"
3 #include "externs.h"
4
5 extern int ReedPin;
6 extern int HallPin;
7
8 unsigned long Dumptime;
9 unsigned long TIK = 0;
10 unsigned long TOK = 0;
11
12 volatile bool DiDiT;
13
14 void ICACHE_RAM_ATTR DumpDetect()
15 {
16 char debugTEXT[46];
17
18 TOK = millis();
19 Dumptime = (TOK - TIK) / 1000;
20 TIK = TOK;
21
22 if ((digitalRead(ReedPin) == HIGH) && (!DiDiT))
23 {
24 DiDiT = true;
25 sprintf(debugTEXT, "{\"Device\":\"Dumper\",\"Type\":\"Reed A\",\"Time\":%d}", Dumptime);
26 MQTT_SendTELE("Cycle", debugTEXT);
27 Serial.printf("\nWoo Hoo! It Dumped! (Reed A)\t(%d Seconds)", Dumptime);
28 }
29 else if ((digitalRead(ReedPin) == LOW) && (DiDiT))
30 {
31 DiDiT = false;
32 sprintf(debugTEXT, "{\"Device\":\"Dumper\",\"Type\":\"Reed B\",\"Time\":%d}", Dumptime);
33 MQTT_SendTELE("Cycle", debugTEXT);
34 Serial.printf("\nWoo Hoo! It Dumped! (Reed B)\t(%d Seconds)", Dumptime);
35 }
36 }
37
38 void ICACHE_RAM_ATTR DumpDetect2()
39 {
40 char debugTEXT[46];
41
42 TOK = millis();
43 Dumptime = (TOK - TIK) / 1000;
44 TIK = TOK;
45
46 sprintf(debugTEXT, "{\"Device\":\"Dumper\",\"Type\":\"Hall\",\"Time\":%d}", Dumptime);
47 MQTT_SendTELE("Cycle", debugTEXT);
48 Serial.printf("\nWoo Hoo! It Dumped! (Hall)\t(%d Seconds)", Dumptime);
49 }
Alerts
Noise.cpp
1 #include "libraries.h"
2 #include "functions.h"
3 #include "Noise.h"
4
5 void Noise_init()
6 {
7 char debugTEXT[46];
8
9 debug_Separator();
10 debug_SectionTitle("Configuring Audio");
11 sprintf(debugTEXT, "Configured speaker/piezo on pin %d", piezoPin);
12 debug_LineOut(debugTEXT);
13 }
14
15 void ScreamBloodyMurder()
16 {
17 for (int counter = 0; counter < 5; counter++)
18 {
19 tone(piezoPin, 666);
20 delay(500);
21 noTone(piezoPin);
22 tone(piezoPin, 333);
23 delay(500);
24 noTone(piezoPin);
25 }
26 debug_Action("Holy POOP! The Pumphouse is gonna flood!");
27 }
28
29 void STFU()
30 {
31 noTone(piezoPin);
32 }
33
34 void Boop()
35 {
36 tone(piezoPin, 111);
37 debug_Action("BOOP!");
38 delay(125);
39 noTone(piezoPin);
40 }#include "libraries.h"
41 #include "functions.h"
42 #include "Noise.h"
43
44 void Noise_init()
45 {
46 char debugTEXT[46];
47
48 debug_Separator();
49 debug_SectionTitle("Configuring Audio");
50 sprintf(debugTEXT, "Configured speaker/piezo on pin %d", piezoPin);
51 debug_LineOut(debugTEXT);
52 }
53
54 void ScreamBloodyMurder()
55 {
56 for (int counter = 0; counter < 5; counter++)
57 {
58 tone(piezoPin, 666);
59 delay(500);
60 noTone(piezoPin);
61 tone(piezoPin, 333);
62 delay(500);
63 noTone(piezoPin);
64 }
65 debug_Action("Holy POOP! The Pumphouse is gonna flood!");
66 }
67
68 void STFU()
69 {
70 noTone(piezoPin);
71 }
72
73 void Boop()
74 {
75 tone(piezoPin, 111);
76 debug_Action("BOOP!");
77 delay(125);
78 noTone(piezoPin);
79 }
Pixels.cpp
1 #ifdef d_Pixels
2
3 #include "libraries.h"
4 #include "functions.h"
5 #include "Pixels.h"
6
7 void Pixels_init()
8 {
9 char debugTEXT[46];
10
11 debug_Separator();
12 debug_SectionTitle("Configuring Pixels");
13
14 pixels.begin();
15 for (int i = 0; i < PixelCount; i++)
16 {
17 SetAPixel(i, BLK);
18 } // strip.clear(); would be better if it worked right!
19 // for(int i = 0; i < 8; i++) { pixels1.setPixelColor(i, 0, 0, 0); }
20 pixels.setBrightness(PixelBright);
21 pixels.show();
22
23 sprintf(debugTEXT, "Configured %d Pixels on pin %d", PixelCount, PixelPin);
24 debug_LineOut(debugTEXT);
25 sprintf(debugTEXT, "Brightness: %d", PixelBright);
26 debug_LineOut(debugTEXT);
27 }
28
29 void SetAPixel(int PixelNumber, int Colour[])
30 {
31 char debugTEXT[46];
32 // Serial.printf(" -> %d, %d\n", PixelNumber, Colour);
33 pixels.setPixelColor(PixelNumber, Colour[0], Colour[1], Colour[2]);
34 pixels.show();
35 #ifdef DEBUG5
36 sprintf(debugTEXT, "Pixel %d Pixel colour: %03d,%03d,%03d", PixelNumber, Colour[0], Colour[1], Colour[2]);
37 debug_LineOut(debugTEXT);
38 #endif
39 }
40
41 #endif // d_Pixels
Controls
Triggers.cpp
1 /*
2 * Simple GPIO pull downs to turn on relays...
3 */
Header Files
TopSecret.h
1 #ifndef TOPSECRET_H
2 #define TOPSECRET_H
3
4 #ifdef SugarBush
5 const char* WiFi_ClientName = "SugarShack_Climate";
6 const char* MQTT_ClientName = "SugarShack_Climate";
7 const char* DISP_Title = "SugarBush";
8 #elif SugarBushDev
9 const char* WiFi_ClientName = "SugarShack_Climate_Dev";
10 const char* MQTT_ClientName = "SugarShack_Climate_Dev";
11 const char* DISP_Title = "SugarBush";
12 #elif SS_Alert
13 const char* WiFi_ClientName = "SugarShack_Alarm";
14 const char* MQTT_ClientName = "SugarShack_Alarm";
15 const char* DISP_Title = "SugarBush";
16 #elif SS_PHTank
17 const char* WiFi_ClientName = "SugarShack_TankLevel";
18 const char* MQTT_ClientName = "SugarShack_TankLevel";
19 const char* DISP_Title = "SugarBush";
20 #elif SS_Dumper
21 const char* WiFi_ClientName = "SugarShack_Dumper";
22 const char* MQTT_ClientName = "SugarShack_Dumper";
23 const char* DISP_Title = "SugarBush";
24 #else
25 const char* WiFi_ClientName = "Test";
26 const char* MQTT_ClientName = "Test";
27 const char* DISP_Title = "Dude!";
28 #endif
29
30 // WiFi
31
32 #if WAP==0
33 const char* WiFi_ssid = "TinkerToys";
34 const char* WiFi_password = "Password";
35 const char* MQTT_broker = "skeeter.tinkernet.ca";
36 const char* MQTT_user = "";
37 const char* MQTT_pass = "";
38
39 #elif WAP==1
40 const char* WiFi_ssid = "TinkerToysB";
41 const char* WiFi_password = "Password";
42 const char* MQTT_broker = "skynet.tinkernet.ca";
43 const char* MQTT_user = "";
44 const char* MQTT_pass = "";
45 #elif WAP==2
46 const char* WiFi_ssid = "vanneck";
47 const char* WiFi_password = "Password";
48 const char* MQTT_broker = "192.168.0.222";
49 const char* MQTT_user = "";
50 const char* MQTT_pass = "";
51 #elif WAP==3
52 const char* WiFi_ssid = "paradise";
53 const char* WiFi_password = "Password";
54 const char* MQTT_broker = "skynet.millersparadise.ca";
55 const char* MQTT_user = "";
56 const char* MQTT_pass = "";
57 #else
58 const char* WiFi_ssid = "VictoriaDrive2B";
59 const char* WiFi_password = "Password";
60 const char* MQTT_broker = "skynet.tinkernet.ca";
61 const char* MQTT_user = "";
62 const char* MQTT_pass = "";
63 #endif
64
65 #endif // TOPSECRET_H
MQTT.h
1 #ifndef MQTT_H
2 #define MQTT_H
3
4 #define MQTT_BUFFER_SIZE (100) // This number is arbitrary
5 // Topic can be up to 65,536 bytes
6 // Message can be up to 268,435,456 bytes
7
8 char MQTT_outTopic[MQTT_BUFFER_SIZE];
9 char MQTT_inTopic[MQTT_BUFFER_SIZE];
10 char MQTT_teleTopic[MQTT_BUFFER_SIZE];
11 char MQTT_statTopic[MQTT_BUFFER_SIZE];
12
13 char MQTT_msg_out[MQTT_BUFFER_SIZE *10];
14
15 unsigned long beacon_timer = 0;
16 #define BEACON_INTERVAL 30000 // Timer interval for the "keep-alive" status beacon
17
18 extern char *MQTT_broker;
19 extern char *MQTT_user;
20 extern char *MQTT_pass;
21 extern char *MQTT_ClientName;
22
23 extern char *WiFi_ssid;
24
25 #endif // MQTT_H
functions.h
1 #ifndef FUNCTIONS_H
2 #define FUNCTIONS_H
3
4 // WiFi ////////////////////////////////////////////////////////////////////////
5
6 void WiFi_init(); // Initialize the WiFi
7 int WiFi_strength(); // Check the signal strength
8 void WiFi_Test();
9 void WiFi_Test2();
10 void WiFi_Test3();
11
12 // MQTT ////////////////////////////////////////////////////////////////////////
13
14 void MQTT_init();
15
16 void MQTT_callback(char *topic, byte *payload, int length);
17 void MQTT_reconnect();
18 void MQTT_beacon();
19
20 void MQTT_handler();
21
22 void MQTT_SendTELE(const char *Topic, char *Message);
23 void MQTT_SendSTAT(const char *Topic, char *Message);
24 void MQTT_SendCMND(const char *Topic, char *Message);
25
26 void HandleMessages();
27
28 // Supplimental Stuff //////////////////////////////////////////////////////////
29
30 void blinkLED(int speed); // Just a little function to blink the LED
31
32 // Debug ///////////////////////////////////////////////////////////////////////
33 void debug_TitleScreen(); // Title block for the project
34 void debug_ReadyScreen(); // Indicate setup is finished
35 void debug_Separator(); // Make a line
36 void debug_SectionTitle(const char* Title); // Text at the left
37 void debug_LineOut(const char* Line); // Text 3 characters inset
38 void debug_Action(const char* Line); // Text centred
39 void debug_Trouble(const char* Line); //
40 void debug_Success(const char* Line); //
41 void debug_ProgressBar0();
42 void debug_ProgressBar1();
43 void debug_ProgressBar2(int dotcount);
44
45 // Pixels //////////////////////////////////////////////////////////////////////
46 void Pixels_init();
47 void SetAPixel(int, int*);
48
49 // Noise ///////////////////////////////////////////////////////////////////////
50 void Noise_init();
51 void ScreamBloodyMurder();
52 void STFU();
53 void Boop();
54
55 // Depth Probes ////////////////////////////////////////////////////////////////
56 void Depth_init();
57 void CheckProbes();
58
59 // Hall Effect Trigger /////////////////////////////////////////////////////////
60 void DumpDetect();
61 void DumpDetect2();
62
63 #endif // FUNCTIONS_H
libraries.h
1 #ifndef LIBRARIES_H
2 #define LIBRARIES_H
3
4 // WiFi ////////////////////////////////////////////////////////////////////////
5 #include <ESP8266WiFi.h>
6
7 // MQTT ////////////////////////////////////////////////////////////////////////
8 #include <PubSubClient.h>
9
10 // Supplimental Stuff //////////////////////////////////////////////////////////
11 #include <SimpleTimer.h>
12
13 #include <Wire.h>
14
15 // Pixels //////////////////////////////////////////////////////////////////////
16 #ifdef d_Pixels
17 #include <Adafruit_NeoPixel.h>
18 #endif
19
20 #endif // LIBRARIES_H
externs.h
1 #ifndef EXTERNS_H
2 #define EXTERNS_H
3
4 #ifdef d_Pixels
5
6 extern int RED[];
7 extern int GRN[];
8 extern int BLU[];
9 extern int BLK[];
10 extern int YEL[];
11 extern int PixelCount;
12
13
14 #endif // d_Pixels
15
16 #endif // EXTERNS_H
Noise.h
1 #ifndef NOISE_H
2 #define NOISE_H
3
4 int piezoPin = 14;
5
6 #endif // NOISE_H
Pixels.h
1 #ifndef PIXELS_H
2 #define PIXELS_H
3
4 ///////////////////////////////////////////////////
5 // Which pin is your neoPixel strip connected to
6 #define PixelPin 12 // GPIO13 / Tarduino D7
7 int PixelCount = 4;
8 #define OBL 2
9
10 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PixelCount, PixelPin, NEO_GRB + NEO_KHZ800);
11
12
13 // Setup some constants for use in SetAPixel()
14
15 //int Bright1 = 6; // 0-255 // No-Name strip
16 //int Bright2 = 1; // 0-255 // AdaFruit strip
17
18 int PixelBright = 5; // 0-255 // No-Name strip
19
20 // The colours:
21 int RED[] = {255, 000, 000};
22 int GRN[] = {000, 255, 000};
23 int BLU[] = {000, 000, 255};
24 int BLK[] = {000, 000, 000};
25 int YEL[] = {255, 255, 000};
26
27 #endif // PIXELS_H