Difference between revisions of "SugarBush - The Firmware"

From The TinkerNet Wiki
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

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