Difference between revisions of "IoT - Firmware - Coldstuff"
Jump to navigation
Jump to search
Line 42: | Line 42: | ||
===TopSecret.h=== | ===TopSecret.h=== | ||
<syntaxhighlight lang="cpp" line="1"> | <syntaxhighlight lang="cpp" line="1"> | ||
− | const char * | + | const char *WiFi_ssid = "SSID"; |
− | const char * | + | const char *WiFi_password = "Password"; |
− | const char * | + | const char* MQTT_broker = "skynet.tinkernet.ca"; |
+ | const char* MQTT_user = ""; | ||
+ | const char* MQTT_pass = ""; | ||
+ | const char* WiFi_ClientName = "ColdStuff"; | ||
+ | const char* MQTT_ClientName = "ColdStuff"; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Latest revision as of 20:53, 8 May 2021
Contents
platformio.ini
1 [env]
2 platform = espressif8266
3 ; For now, let's stick with the 8266 family MCUs
4
5 framework = arduino
6
7 monitor_speed = 115200
8 ; I like my serial comms fast. (Without this line you get the default of 9600)
9
10 lib_deps =
11 Adafruit GFX Library
12 Adafruit SSD1306
13 Adafruit BusIO
14 SimpleTimer
15 OneWire
16 DallasTemperature
17 PubSubClient
18
19 [env:Testing]
20 platform = espressif8266
21 board = esp07
22 framework = arduino
23 build_flags =
24 -D DEBUG ; This is just plain handy. Use it to turn debugging output on/off...
25 ; -D DEBUG0 ; Show extra WiFi Debug info
26 ; -D DEBUG1
27 -D WAP=0
28
29 [env:LIVE]
30 platform = espressif8266
31 board = d1_mini
32 framework = arduino
33 build_flags =
34 -D WAP=4
#includes, Defines, etc...
TopSecret.h
1 const char *WiFi_ssid = "SSID";
2 const char *WiFi_password = "Password";
3 const char* MQTT_broker = "skynet.tinkernet.ca";
4 const char* MQTT_user = "";
5 const char* MQTT_pass = "";
6 const char* WiFi_ClientName = "ColdStuff";
7 const char* MQTT_ClientName = "ColdStuff";
libraries.h
1 // WiFi ////////////////////////////////////////////////////////////////////////
2 #include <ESP8266WiFi.h>
3
4 // MQTT ////////////////////////////////////////////////////////////////////////
5 #include <PubSubClient.h>
6
7 // OLED ////////////////////////////////////////////////////////////////////////
8 #include <Wire.h>
9 #include <Adafruit_GFX.h>
10 #include <Adafruit_SSD1306.h>
11 #include <Fonts/FreeMonoBold12pt7b.h>
12 #include <Fonts/FreeMonoBold9pt7b.h>
13
14 // DS18B20 /////////////////////////////////////////////////////////////////////
15 #include <OneWire.h>
16 #include <DallasTemperature.h>
17
18 // Supplimental Stuff //////////////////////////////////////////////////////////
19 #include <SimpleTimer.h>
functions.h
1 #ifndef FUNCTIONS_H
2 #define FUNCTIONS_H
3
4 // WiFi ////////////////////////////////////////////////////////////////////////
5
6 void WiFi_init();
7
8 int WiFi_strength();
9
10 // MQTT ////////////////////////////////////////////////////////////////////////
11
12 void MQTT_init();
13
14 void MQTT_callback(char *topic, byte *payload, int length);
15 void MQTT_reconnect();
16 void MQTT_beacon();
17
18 void DOtheBloodyMQTT();
19
20 void MQTT_SendData(float Temp0, float Temp1);
21
22 // OLED ////////////////////////////////////////////////////////////////////////
23
24 void SSD1306_init();
25 void SSD1306_title(const char *Title);
26 void SSD1306_Static(const char *Line, int Row);
27 void SSD1306_DisplayTemps();
28 void SSD1306_Dotty();
29 // void SSD1306_StickDude();
30 void DrawStickDude(int DudeNum, int TOP, int LEFT);
31 void DrawStickDude2(int DudeNum, int TOP, int LEFT);
32 void walkStickDude(int TOP, int LEFT);
33 void waveStickDude(int TOP, int LEFT);
34
35 // DS18B20 /////////////////////////////////////////////////////////////////////
36
37 int DS18B20_init();
38 float DS18B20_getReading(int deviceNumber);
39
40 // Supplimental Stuff //////////////////////////////////////////////////////////
41
42 bool getTimer(unsigned long &timer, unsigned long interval);
43 void blinkLED(); // Just a little function to blink the LED for the beacon function.
44
45 #endif // FUNCTIONS_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
DS18B20.h
1 #ifndef DS18B20_H
2 #define DS18B20_H
3
4 const int oneWireBus = 4; // Where the sensor(s) connect (GPIO4 == Tarduino D2)
5
6 OneWire oneWire(oneWireBus); // Setup a oneWire instance to communicate with any OneWire devices
7 DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature sensor
8
9 #endif // DS18B20_H
SSD1306.h
1 #ifndef SSD1306_H
2 #define SSD1306_H
3
4 // I2C pins suitable for the ESP-M3-Everything!
5 const int SSD1306_SDA = 14; // Tarduino D5
6 const int SSD1306_SCL = 12; // Tarduino D6
7
8 #define SCREEN_WIDTH 128 // OLED display width, in pixels
9 #define SCREEN_HEIGHT 64 // OLED display height, in pixels
10
11 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
12 // Static Information Canvases
13 // Full width of the display
14 // GFXcanvas1 Scanvas1(120, 15);
15 // GFXcanvas1 Scanvas2(120, 15);
16 GFXcanvas1 Scanvas3(120, 15);
17 // Dynamic Information Canvases
18 // Sized specifically for '%5.1f' temperature readings
19 GFXcanvas1 Dcanvas1(55, 12);
20 GFXcanvas1 Dcanvas2(55, 12);
21 // GFXcanvas1 Dcanvas3(55, 12);
22
23 // GFXcanvas1 StickDude(8, 11);
24 GFXcanvas1 StickDudePIC(8, 12);
25
26 int row_Y[] = {27, 42, 57}; // Locations the rows in the main screen part (Blue)
27
28 //
29 int DottyX = 0; // Initialize the dots position OUTSIDE of the actual loop...
30
31 #endif // SSD1306_H
StickDude.h
1 #define DUDE_HEIGHT 12
2 #define DUDE_WIDTH 8
3
4 static const unsigned char PROGMEM StickDude_wave[][12] = {
5
6 {
7 B00000000, // . .
8 B00001000, // . 0 .
9 B00011100, // . 000 .
10 B00001000, // . 0 .
11 B00001000, // . 0 .
12 B00011100, // . 000 .
13 B00101010, // . 0 0 0 .
14 B01001001, // . 0 0 0.
15 B00001000, // . 0 .
16 B00010100, // . 0 0 .
17 B00100010, // . 0 0 .
18 B01000001 // . 0 0.
19 },
20
21 {
22 B00000000, // . .
23 B00001000, // . 0 .
24 B00011100, // . 000 .
25 B00001000, // . 0 .
26 B00001000, // . 0 .
27 B00111110, // . 00000 .
28 B01001001, // . 0 0 0.
29 B00001000, // . 0 .
30 B00001000, // . 0 .
31 B00010100, // . 0 0 .
32 B00100010, // . 0 0 .
33 B01000001 // . 0 0.
34 },
35
36 {
37 B00000000, // . .
38 B00001000, // . 0 .
39 B00011100, // . 000 .
40 B00001000, // . 0 .
41 B00001000, // . 0 .
42 B01111111, // . 0000000.
43 B00001000, // . 0 .
44 B00001000, // . 0 .
45 B00001000, // . 0 .
46 B00010100, // . 0 0 .
47 B00100010, // . 0 0 .
48 B01000001 // . 0 0.
49 },
50
51 {
52 B00000000, // . .
53 B00001000, // . 0 .
54 B00011100, // . 000 .
55 B00001000, // . 0 .
56 B01001001, // . 0 0 0.
57 B00111110, // . 00000 .
58 B00001000, // . 0 .
59 B00001000, // . 0 .
60 B00001000, // . 0 .
61 B00010100, // . 0 0 .
62 B00100010, // . 0 0 .
63 B01000001 // . 0 0.
64 },
65
66 {
67 B00000000, // . .
68 B00001000, // . 0 .
69 B00011100, // . 000 .
70 B01001001, // . 0 0 0.
71 B00101010, // . 0 0 0 .
72 B00011100, // . 000 .
73 B00001000, // . 0 .
74 B00001000, // . 0 .
75 B00001000, // . 0 .
76 B00010100, // . 0 0 .
77 B00100010, // . 0 0 .
78 B01000001 // . 0 0.
79 },
80 };
81
82 int StickDude_wave_height = sizeof(StickDude_wave[0]);
83 int StickDude_wave_count = sizeof(StickDude_wave) / StickDude_wave_height;
84 int StickDude_wave_width = 8;
85
86 static const unsigned char PROGMEM StickDude_walk[][12] = {
87 {
88 B00000000, // ........
89 B00001000, // ....0...
90 B00011100, // ...000..
91 B00001000, // ....0...
92 B00001000, // ....0...
93 B00001110, // ....000.
94 B00001000, // ....0...
95 B00001000, // ....0...
96 B00001000, // ....0...
97 B00001000, // ....0...
98 B00001000, // ....0...
99 B00001000, // ....0...
100 }, // A
101
102 {
103 B00000000, // ........
104 B00001000, // ....0...
105 B00011100, // ...000..
106 B00001000, // ....0...
107 B00001000, // ....0...
108 B00001110, // ....000.
109 B00001000, // ....0...
110 B00001000, // ....0...
111 B00001000, // ....0...
112 B00001100, // ....00..
113 B00011000, // ...00...
114 B00001000, // ....0...
115 }, // B
116
117 {
118 B00000000, // ........
119 B00001000, // ....0...
120 B00011100, // ...000..
121 B00001000, // ....0...
122 B00001000, // ....0...
123 B00001110, // ....000.
124 B00001000, // ....0...
125 B00001000, // ....0...
126 B00001100, // ....00..
127 B00001010, // ....0.0.
128 B00001100, // ....00..
129 B00001000, // ....0...
130 }, // C
131
132 {
133 B00000000, // ........
134 B00001000, // ....0...
135 B00011100, // ...000..
136 B00001000, // ....0...
137 B00001000, // ....0...
138 B00001110, // ....000.
139 B00001000, // ....0...
140 B00001000, // ....0...
141 B00001100, // ....00..
142 B00001010, // ....0.0.
143 B00001010, // ....0.0.
144 B00001000, // ....0...
145 }, // D
146
147 {
148 B00000000, // ........
149 B00001000, // ....0...
150 B00011100, // ...000..
151 B00001000, // ....0...
152 B00001000, // ....0...
153 B00001110, // ....000.
154 B00001000, // ....0...
155 B00001000, // ....0...
156 B00001000, // ....0...
157 B00001100, // ....00..
158 B00001010, // ....0.0.
159 B00001001, // ....0..0
160 }, // E
161
162 {
163 B00000000, // ........
164 B00001000, // ....0...
165 B00011100, // ...000..
166 B00001000, // ....0...
167 B00001000, // ....0...
168 B00001110, // ....000.
169 B00001000, // ....0...
170 B00001000, // ....0...
171 B00001000, // ....0...
172 B00001100, // ....00..
173 B00010010, // ...0..0.
174 B00010001, // ...0...0
175 }, // F
176
177 {
178 B00000000, // ........
179 B00001000, // ....0...
180 B00011100, // ...000..
181 B00001000, // ....0...
182 B00001000, // ....0...
183 B00001110, // ....000.
184 B00001000, // ....0...
185 B00001000, // ....0...
186 B00001000, // ....0...
187 B00010100, // ...0.0..
188 B00100010, // ..0...0.
189 B01000001, // .0.....0
190 }, // G
191
192 {
193 B00000000, // ........
194 B00001000, // ....0...
195 B00011100, // ...000..
196 B00001000, // ....0...
197 B00001000, // ....0...
198 B00001110, // ....000.
199 B00001000, // ....0...
200 B00001000, // ....0...
201 B00001000, // ....0...
202 B00011000, // ...00...
203 B00100100, // ..0..0..
204 B01000100, // .0...0..
205 }, // H
206
207 };
208
209 int StickDude_walk_height = sizeof(StickDude_walk[0]);
210 int StickDude_walk_count = sizeof(StickDude_walk) / StickDude_walk_height;
211 int StickDude_walk_width = 8;
212
213 static const unsigned char PROGMEM StickDude_beer[][12] = {
214
215 {
216 B00000000, // ........
217 B00001000, // ....0...
218 B00011100, // ...000..
219 B00001000, // ....0...
220 B00001000, // ....0...
221 B00001000, // ....0...
222 B00001000, // ....0...
223 B00001000, // ....0...
224 B00001000, // ....0...
225 B00001000, // ....0...
226 B00001000, // ....0...
227 B00001100, // ....01..
228 }, // A
229
230 {
231 B00000000, // ........
232 B00001000, // ....0...
233 B00011100, // ...000..
234 B00001000, // ....0...
235 B00001000, // ....0...
236 B00001000, // ....0...
237 B00001100, // ....00..
238 B00001100, // ....00..
239 B00001100, // ....00..
240 B00001000, // ....0...
241 B00001000, // ....0...
242 B00001100, // ....01..
243 }, // B
244
245 {
246 B00000000, // ........
247 B00001000, // ....0...
248 B00011100, // ...000..
249 B00001000, // ....0...
250 B00001000, // ....0...
251 B00001100, // ....00..
252 B00001010, // ....0.0.
253 B00001010, // ....0.0.
254 B00001000, // ....0...
255 B00001000, // ....0...
256 B00001000, // ....0...
257 B00001100, // ....01..
258 }, // C
259
260 {
261 B00000000, // ........
262 B00001000, // ....0...
263 B00011100, // ...000..
264 B00001000, // ....0...
265 B00001000, // ....0...
266 B00001100, // ....00..
267 B00001011, // ....0.00
268 B00001001, // ....0..0
269 B00001000, // ....0...
270 B00001000, // ....0...
271 B00001000, // ....0...
272 B00001100, // ....01..
273 }, // D
274
275 {
276 B00000000, // ........
277 B00001000, // ....0...
278 B00011100, // ...000..
279 B00001000, // ....0...
280 B00001000, // ....0...
281 B00001101, // ....00.0
282 B00001011, // ....0.00
283 B00001000, // ....0...
284 B00001000, // ....0...
285 B00001000, // ....0...
286 B00001000, // ....0...
287 B00001100, // ....01..
288 }, // E
289
290 {
291 B00000000, // ........
292 B00001000, // ....0...
293 B00011100, // ...000..
294 B00001000, // ....0...
295 B00001000, // ....0...
296 B00001111, // ....0000
297 B00001001, // ....0..0
298 B00001000, // ....0...
299 B00001000, // ....0...
300 B00001000, // ....0...
301 B00001000, // ....0...
302 B00001100, // ....01..
303 }, // F
304
305 {
306 B00000000, // ........
307 B00001000, // ....0...
308 B00011100, // ...000..
309 B00001000, // ....0...
310 B00001001, // ....0..0
311 B00001111, // ....0000
312 B00001000, // ....0...
313 B00001000, // ....0...
314 B00001000, // ....0...
315 B00001000, // ....0...
316 B00001000, // ....0...
317 B00001100, // ....01..
318 }, // G
319
320 {
321 B00000000, // ........
322 B00001000, // ....0...
323 B00011100, // ...000..
324 B00001010, // ....0.0.
325 B00001001, // ....0..0
326 B00001110, // ....000.
327 B00001000, // ....0...
328 B00001000, // ....0...
329 B00001000, // ....0...
330 B00001000, // ....0...
331 B00001000, // ....0...
332 B00001100, // ....01..
333 }, // H
334
335 {
336 B00000000, // ........
337 B00001000, // ....0...
338 B00011100, // ...000..
339 B00001001, // ....0..0
340 B00001011, // ....0.00
341 B00001100, // ....00..
342 B00001000, // ....0...
343 B00001000, // ....0...
344 B00001000, // ....0...
345 B00001000, // ....0...
346 B00001000, // ....0...
347 B00001100, // ....01..
348 }, // I
349
350 {
351 B00000000, // ........
352 B00001000, // ....0...
353 B00011100, // ...000..
354 B00001011, // ....0.00
355 B00001010, // ....0.0.
356 B00001100, // ....00..
357 B00001000, // ....0...
358 B00001000, // ....0...
359 B00001000, // ....0...
360 B00001000, // ....0...
361 B00001000, // ....0...
362 B00001100, // ....01..
363 }, // J
364
365 {
366 B00000000, // ........
367 B00001000, // ....0...
368 B00011100, // ...000..
369 B00001110, // ....000.
370 B00001010, // ....0.0.
371 B00001100, // ....00..
372 B00001000, // ....0...
373 B00001000, // ....0...
374 B00001000, // ....0...
375 B00001000, // ....0...
376 B00001000, // ....0...
377 B00001100, // ....01..
378 }, // K
379
380 {
381 B00000000, // ........
382 B00001000, // ....0...
383 B00011100, // ...000..
384 B00001110, // ....00..
385 B00001010, // ....0.0.
386 B00001100, // ....00..
387 B00001000, // ....0...
388 B00001000, // ....0...
389 B00001000, // ....0...
390 B00001000, // ....0...
391 B00001000, // ....0...
392 B00001100, // ....01..
393 }, // A
394
395 };
396
397 int StickDude_beer_height = sizeof(StickDude_beer[0]);
398 int StickDude_beer_count = sizeof(StickDude_beer) / StickDude_beer_height;
399 int StickDude_beer_width = 8;
The Code
main.cpp
1 #include "libraries.h"
2 #include "functions.h"
3 #include "TopSecret.h"
4
5 SimpleTimer timer;
6
7 void setup()
8 {
9 // Enable and turn off the On-board LED
10 // (notice that it's inverted on most ESP boards)
11 pinMode(LED_BUILTIN, OUTPUT);
12 digitalWrite(LED_BUILTIN, HIGH);
13
14 Serial.begin(115200);
15 delay(500); // Delay to let the ESP get booted before sending out serial data
16 Serial.printf("\n+---------------------------------------+\n");
17 Serial.printf("| ESP With a little OLED & 2 DS18B20s |\n");
18 Serial.printf("| WiFi Enabled... |\n");
19 Serial.printf("| Sends readings out through MQTT... |\n");
20 Serial.printf("| Able to respond to MQTT... |\n");
21 Serial.printf("| (Now, with excitable StickDude) |\n");
22 // Serial.printf("+---------------------------------------+\n");
23
24 // SSD1306 ///////////////////////////////////////////////////////////////////
25 SSD1306_init();
26
27 // Display static text
28 SSD1306_title("ColdStuff");
29 SSD1306_Static("Beer:", 1);
30 SSD1306_Static("Food:", 2);
31
32 Serial.printf("| Static Text on-screen |\n");
33
34 SSD1306_Static(" Booting ", 3);
35
36 // DS18B20 ///////////////////////////////////////////////////////////////////
37
38 DS18B20_init();
39
40 // Interval Timers ///////////////////////////////////////////////////////////
41
42 Serial.printf("+---------------------------------------+\n");
43 timer.setInterval(80, SSD1306_Dotty);
44 timer.setInterval(20, DOtheBloodyMQTT);
45 // delay(66);
46 timer.setInterval(10000, SSD1306_DisplayTemps);
47
48 Serial.printf("| Interval Timers running |\n");
49
50 WiFi_init();
51
52 MQTT_init();
53
54 // SSD1306_StickDude();
55
56 Serial.printf("#=======================================#\n");
57 Serial.printf("# Ready To Run. #\n");
58 Serial.printf("#=======================================#\n");
59 }
60
61 void loop()
62 {
63 // Run the interval timers
64 // Running processes here in loop() is a synchronous flow.
65 // Running processes via the interval timers is assynchronous.
66 // If your actions don't depend directly on each other,
67 // synchronous flow makes no sense at all...
68 timer.run();
69 }
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.
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
20 // We start by connecting to a WiFi network
21 Serial.printf("+---------------------------------------+\n");
22 Serial.printf("| Connecting to: %-22s |\n", WiFi_ssid);
23 Serial.printf("| ");
24
25 WiFi.mode(WIFI_STA); // Connecting as a STATION
26 WiFi.begin(WiFi_ssid, WiFi_password);
27
28 int dotcount = 0;
29 while (WiFi.status() != WL_CONNECTED) // Give it a bit of time to establish the WiFi connection...
30 {
31 dotcount++;
32 delay(500);
33 Serial.printf(".");
34 SSD1306_Static(" no WiFi ", 3);
35 }
36
37 for (int i = 0; i < (38 - dotcount); i++)
38 {
39 Serial.printf(" ");
40 }
41 Serial.printf("|\n");
42
43 Serial.printf("| WiFi connected on Channel %-2d |\n", WiFi.channel());
44 Serial.printf("| IP address: %-15s |\n", WiFi.localIP().toString().c_str());
45
46 Serial.printf("| My name is NOT %-22s |\n", wifi_station_get_hostname());
47 Serial.printf("| Really... It's %-22s |\n", WiFi_ClientName);
48
49 SSD1306_Static(" WiFi good ", 3);
50
51 // Add "build_flags = -D DEBUG0" to your platformio.ini to get some extra WiFi stats
52 #ifdef DEBUG0
53 WiFi.printDiag(Serial);
54 Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());
55 Serial.print("HostName: ");
56 Serial.print(WiFi.hostname());
57 Serial.println(" !!!!!!!!! BULLSHIT !!!!!!!!!");
58 // Apparently, the ESP8266WiFi library does not actually support DHCP completely
59 // { https://www.reddit.com/r/arduino/comments/d6mvc7/getting_hostname_from_dhcp_with_esp8266/ }
60 // { https://github.com/esp8266/Arduino/issues/5695 }
61 #endif
62 }
63
64 int WiFi_strength()
65 {
66 // Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());
67 return (WiFi.RSSI());
68 }
MQTT.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 #include "MQTT.h"
5
6 WiFiClient espClient;
7 PubSubClient MQTT_client(espClient);
8
9 void DOtheBloodyMQTT()
10 {
11 if (!MQTT_client.connected())
12 {
13 MQTT_reconnect();
14 }
15 MQTT_client.loop();
16 MQTT_beacon();
17
18 }
19
20 ////////////////////////////////////////////////////////////////
21 // MQTT Functions
22 ////////////////////////////////////////////////////////////////
23
24 void MQTT_init()
25 {
26 Serial.printf("+---------------------------------------+\n");
27 MQTT_client.setServer(MQTT_broker, 1883);
28 MQTT_client.setCallback(MQTT_callback);
29
30 // Build the topic names
31 strcpy(MQTT_inTopic, "cmnd/"); // in - Commands
32 strcat(MQTT_inTopic, MQTT_ClientName);
33 strcat(MQTT_inTopic, "/#");
34 strcpy(MQTT_teleTopic, "tele/"); // out - Telemetry
35 strcat(MQTT_teleTopic, MQTT_ClientName);
36 strcpy(MQTT_statTopic, "stat/"); // out - Status
37 strcat(MQTT_statTopic, MQTT_ClientName);
38 strcpy(MQTT_outTopic, "noti/"); // out - Notifications
39 strcat(MQTT_outTopic, MQTT_ClientName);
40
41 MQTT_reconnect();
42 }
43
44 void MQTT_callback(char *topic, byte *payload, int length)
45 {
46
47 char MQTT_msg_in[MQTT_BUFFER_SIZE];
48 char *MQTT_command = strrchr(topic, '/');
49
50 #ifdef DEBUG
51 Serial.printf("| |\n");
52 Serial.printf("| Message arrived |\n");
53 Serial.printf("| Command: %28s |\n", MQTT_command);
54 #endif
55
56 if (length < MQTT_BUFFER_SIZE)
57 {
58 for (int i = 0; i < length; i++)
59 {
60 MQTT_msg_in[i] = (char)payload[i];
61 MQTT_msg_in[i + 1] = '\0';
62 }
63
64 #ifdef DEBUG
65 Serial.printf("| Message: %28s |\n", MQTT_msg_in);
66 #endif
67 /////////////////////////////////////////////////////
68 // Message handling goes here...
69 /////////////////////////////////////////////////////
70 if (strcmp(MQTT_command, "/lights") == 0)
71 {
72 // DoLights(MQTT_msg_in);
73 }
74 else if (strcmp(MQTT_command, "/respond") == 0)
75 {
76 // DoAnswer(MQTT_msg_in);
77 }
78 else if (strcmp(MQTT_command, "/control") == 0)
79 {
80 // DoControl(MQTT_msg_in);
81 }
82 else
83 {
84 #ifdef DEBUG
85 Serial.printf("| Dunno Whatcha want... |\n");
86 #endif
87 }
88 }
89 else
90 {
91 #ifdef DEBUG
92 Serial.printf("| But, it's TOO Bloody Big! |\n");
93 #endif
94 }
95 }
96
97 void MQTT_reconnect()
98 {
99 // Loop until we're reconnected
100 while (!MQTT_client.connected())
101 {
102 Serial.printf("| Attempting MQTT connection... |\n");
103 // Create a random client ID
104 String clientId = MQTT_ClientName;
105 clientId += String(random(0xffff), HEX);
106 // Attempt to connect
107 if (MQTT_client.connect(clientId.c_str()))
108 {
109 SSD1306_Static(" MQTT good ", 3);
110 delay(500);
111 SSD1306_Static(" ", 3);
112 Serial.printf("| connected to %-24s |\n", MQTT_broker);
113 Serial.printf("| My Name: %-27s |\n", MQTT_ClientName);
114 // Once connected, publish an announcement...
115 char MQTT_statTopic_Device[100];
116 strcpy(MQTT_statTopic_Device, MQTT_statTopic);
117 strcat(MQTT_statTopic_Device, "/HELLO");
118 // MQTT_client.publish(MQTT_statTopic_Device, "world");
119 MQTT_client.publish(MQTT_statTopic_Device, WiFi_ssid);
120 // ... and resubscribe
121 MQTT_client.subscribe(MQTT_inTopic);
122 }
123 else
124 {
125
126 if (WiFi.status() != WL_CONNECTED)
127 {
128 SSD1306_Static(" no WiFi ", 3);
129 Serial.printf("| UH OH!!! No WiFi!!! |\n");
130 }
131 else
132 {
133 SSD1306_Static(" no MQTT ", 3);
134 }
135
136 Serial.printf("| |\n");
137 Serial.printf("| failed, rc=%d |\n", MQTT_client.state());
138 Serial.printf("| trying again in 5 seconds |\n");
139 // Wait 5 seconds before retrying
140 delay(5000);
141 }
142 }
143 }
144
145 void MQTT_beacon()
146 {
147 /* Beacon signal published at set interval to indicate the device
148 * is still powered up and actively connected to MQTT...
149 * A keepalive of sorts
150 * also updates state within MQTT so it can be captured for
151 * indicator light elsewhere
152 */
153 char MQTT_teleTopic_Device[100];
154 char WiFiSignal[5];
155 strcpy(MQTT_teleTopic_Device, MQTT_teleTopic);
156 strcat(MQTT_teleTopic_Device, "/beep");
157 if (getTimer(beacon_timer, BEACON_INTERVAL))
158 {
159 sprintf(WiFiSignal, "%d dBm", WiFi_strength());
160
161 // MQTT_client.publish(MQTT_teleTopic_Device, "boop");
162 MQTT_client.publish(MQTT_teleTopic_Device, WiFiSignal);
163 blinkLED();
164
165 #ifdef DEBUG
166 Serial.printf("| Beacon sent |\n");
167 #endif
168 }
169 }
170
171 void MQTT_Status(char const *Device, char const *Status) // Send status messages
172 {
173 char MQTT_statTopic_Device[100];
174 strcpy(MQTT_statTopic_Device, MQTT_statTopic);
175 strcat(MQTT_statTopic_Device, "/");
176 strcat(MQTT_statTopic_Device, Device);
177
178 #ifdef DEBUG
179 Serial.printf("}- %16s = %-16s -{\n", Device, Status);
180 #endif
181 MQTT_client.publish(MQTT_statTopic_Device, Status);
182 }
183
184 void MQTT_SendData(float Temp0, float Temp1)
185 {
186 char MQTT_teleTopic_Device[100];
187 strcpy(MQTT_teleTopic_Device, MQTT_teleTopic);
188 strcat(MQTT_teleTopic_Device, "/");
189 strcat(MQTT_teleTopic_Device, "SENSOR");
190
191 char JSONstream[100];
192 sprintf(JSONstream,
193 "{\"DS18B20_1\":{\"Temperature\":%5.1f},\"DS18B20_2\":{\"Temperature\":%5.1f}}",
194 Temp0, Temp1);
195 MQTT_client.publish(MQTT_teleTopic_Device, JSONstream);
196
197 }
DS18B20.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 #include "DS18B20.h"
5
6 // Start the DS18B20 sensor(s)
7 // returns number of devices found, if you're interested...
8 int DS18B20_init()
9 {
10 Serial.printf("+---------------------------------------+\n");
11 sensors.begin();
12 Serial.printf("| Sensor(s) initialised |\n");
13
14 // Grab a count of devices on the wire
15 int numberOfDevices = sensors.getDeviceCount();
16
17 Serial.printf("| Found %2d DS18B20s |\n", numberOfDevices);
18
19 return (numberOfDevices);
20 }
21
22 // Read a DS18B20 sensor
23 // Accepts a device number (in case you have more than one)
24 // Returns the current reading (Celsius because Farhenheit is for losers)
25 // (If you're a loser... Change getTempCByIndex to getTempFByIndex :)
26 float DS18B20_getReading(int deviceNumber)
27 {
28 sensors.requestTemperatures();
29 return (sensors.getTempCByIndex(deviceNumber));
30 }
SSD1306.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 #include "StickDude.h"
5
6 #include "SSD1306.h"
7
8 ////////////////////////////////////////////////////////////////////////////////
9 // This code is based on using an
10 // IZOKEE 0.96" SSD1306 based 128x64 OLED (Yellow/Blue) from Amazon
11 // { https://www.amazon.ca/gp/product/B076PNP2VD/ }
12 ////////////////////////////////////////////////////////////////////////////////
13
14 // Initialize the display
15 void SSD1306_init()
16 {
17 Serial.printf("+---------------------------------------+\n");
18 Wire.begin(SSD1306_SDA, SSD1306_SCL); // Select SDA & SCL pins
19
20 { // debug output (StickDude Stats)
21 Serial.printf("StickDude_wave: %d\n", sizeof(StickDude_wave));
22 Serial.printf("StickDude_wave height: %d\n", StickDude_wave_height);
23 Serial.printf("StickDude_wave count: %d\n", StickDude_wave_count);
24 Serial.printf("StickDude_wave width: %d\n", StickDude_wave_width);
25
26 Serial.printf("StickDude_walk: %d\n", sizeof(StickDude_walk));
27 Serial.printf("StickDude_walk height: %d\n", StickDude_walk_height);
28 Serial.printf("StickDude_walk count: %d\n", StickDude_walk_count);
29 Serial.printf("StickDude_walk width: %d\n", StickDude_walk_width);
30 }
31
32 // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
33 if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
34 {
35 Serial.printf("| SSD1306 allocation failed |\n");
36 for (;;)
37 ; // Don't proceed, loop forever
38 // Does this ever actually happen?
39 }
40
41 display.clearDisplay();
42
43 display.dim(true); // These displays are excessively bright
44
45 // Set up the active (changing) parts of the display
46 Dcanvas1.setFont(&FreeMonoBold9pt7b);
47 Dcanvas2.setFont(&FreeMonoBold9pt7b);
48 // Dcanvas3.setFont(&FreeMonoBold9pt7b);
49
50 // Set up the static (non-changing) parts of the display
51 // Scanvas1.setFont(&FreeMonoBold9pt7b);
52 // Scanvas2.setFont(&FreeMonoBold9pt7b);
53 Scanvas3.setFont(&FreeMonoBold9pt7b);
54
55 display.setTextColor(WHITE, BLACK);
56 display.setTextSize(1);
57
58 Serial.printf("| SSD1306 initialized |\n");
59 }
60
61 // Place static text on the yellow part of the OLED display
62 // Accepts the string (max 9 characters)
63 void SSD1306_title(const char *Title)
64 { // Max 9 characters...
65 display.setFont(&FreeMonoBold12pt7b);
66 display.setCursor(0, 14);
67 display.print(Title);
68 display.display();
69 }
70
71 // Place static text on the blue part of the OLED display
72 // Accepts the string (max 11 characters) and the row number (1-3)
73 void SSD1306_Static(const char *Line, int Row)
74 { // Max 11 characters
75 Scanvas3.fillScreen(BLACK);
76 Scanvas3.setCursor(0, 11);
77 Scanvas3.print(Line);
78 display.drawBitmap(4, row_Y[Row - 1] - 9, Scanvas3.getBuffer(), 120, 15, WHITE, BLACK);
79
80 display.display();
81 }
82
83 // Create an activity indicator
84 // Just a little dot that crawls across the bottom edge of the display
85 int DudeStep = 0;
86 void SSD1306_Dotty()
87 {
88 DottyX++;
89 if (DottyX > SCREEN_WIDTH)
90 {
91 DottyX = 0;
92 }
93 if (DudeStep >= StickDude_walk_count)
94 {
95 DudeStep = 0;
96 }
97 // display.drawPixel(DottyX, SCREEN_HEIGHT - 1, WHITE); // Bottom line
98 // display.drawPixel(DottyX - 1, SCREEN_HEIGHT - 1, BLACK);
99 DrawStickDude2(DudeStep, 0, 0);
100 DudeStep++;
101 display.drawBitmap(DottyX, 64 - 12, StickDudePIC.getBuffer(), 8, 12, WHITE, BLACK);
102 display.display();
103 }
104
105 // Display the temperatures on the pre-formatted OLED display
106 void SSD1306_DisplayTemps()
107 {
108 float Beer = DS18B20_getReading(0); // * .3;
109 float Food = DS18B20_getReading(1); // * -1;
110
111 char BeerTemp[6];
112 char FoodTemp[6];
113
114 Dcanvas1.fillScreen(BLACK);
115 if (Beer == -127)
116 {
117 sprintf(BeerTemp, "-----");
118 Beer = 0;
119 }
120 else
121 sprintf(BeerTemp, "%5.1f", Beer);
122
123 Dcanvas2.fillScreen(BLACK);
124 if (Food == -127)
125 {
126 sprintf(FoodTemp, "-----");
127 Food = 0;
128 }
129 else
130 sprintf(FoodTemp, "%5.1f", Food);
131
132 Dcanvas1.setCursor(0, 11);
133 Dcanvas1.print(BeerTemp);
134 display.drawBitmap(64, row_Y[0] - 9, Dcanvas1.getBuffer(), 55, 12, WHITE, BLACK);
135
136 Dcanvas2.setCursor(0, 11);
137 Dcanvas2.print(FoodTemp);
138 display.drawBitmap(64, row_Y[1] - 9, Dcanvas2.getBuffer(), 55, 12, WHITE, BLACK);
139
140 display.display();
141
142 MQTT_SendData(Beer, Food);
143
144 waveStickDude(0, 0);
145 // walkStickDude(0, 0);
146 // waveStickDude(0, 0);
147
148 #ifdef DEBUG
149 Serial.printf("| Sensor 0: %5s - Sensor 1: %5s |\n", BeerTemp, FoodTemp);
150 #endif
151 }
152
153 void DrawStickDude(int DudeNum, int TOP, int LEFT)
154 {
155 // display.clearDisplay();
156 StickDudePIC.fillScreen(BLACK);
157
158 StickDudePIC.drawBitmap(
159 (0),
160 (0),
161 StickDude_beer[DudeNum], DUDE_WIDTH, DUDE_HEIGHT, 1);
162
163 // display.display();
164 }
165
166 void walkStickDude(int TOP, int LEFT)
167 {
168 // Serial.printf("| Loop through StickDudes Poses... |\n");
169 int FOO;
170
171 for (FOO = 0; FOO < StickDude_walk_count; FOO++)
172 {
173 {
174 DrawStickDude2(FOO, 0, 0);
175 display.drawBitmap(DottyX, 64 - 12, StickDudePIC.getBuffer(), 8, 12, WHITE, BLACK);
176 display.display();
177 delay(30);
178 }
179 }
180 FOO--;
181 for (; FOO >= 0; FOO--)
182 {
183 {
184 DrawStickDude2(FOO, 0, 0);
185 display.drawBitmap(DottyX, 64 - 12, StickDudePIC.getBuffer(), 8, 12, WHITE, BLACK);
186 display.display();
187 delay(30);
188 }
189 }
190 }
191
192 void waveStickDude(int TOP, int LEFT)
193 {
194 // Serial.printf("| Loop through StickDudes Poses... |\n");
195 int FOO;
196
197 for (FOO = 0; FOO < StickDude_beer_count; FOO++)
198 {
199 {
200 DrawStickDude(FOO, 0, 0);
201 display.drawBitmap(DottyX, 64 - 12, StickDudePIC.getBuffer(), 8, 12, WHITE, BLACK);
202 display.display();
203 delay(60);
204 }
205 }
206 FOO--;
207 for (; FOO >= 0; FOO--)
208 {
209 {
210 DrawStickDude(FOO, 0, 0);
211 display.drawBitmap(DottyX, 64 - 12, StickDudePIC.getBuffer(), 8, 12, WHITE, BLACK);
212 display.display();
213 delay(30);
214 }
215 }
216 }
217
218 void DrawStickDude2(int DudeNum, int TOP, int LEFT)
219 {
220 // display.clearDisplay();
221 StickDudePIC.fillScreen(BLACK);
222
223 StickDudePIC.drawBitmap(
224 (0),
225 (0),
226 StickDude_walk[DudeNum], DUDE_WIDTH, DUDE_HEIGHT, 1);
227
228 // display.display();
229 }
Supplimentary.cpp
1 #include "libraries.h"
2 #include "functions.h"
3
4 ////////////////////////////////////////////////////////////////
5 // Supplimentary Functions
6 ////////////////////////////////////////////////////////////////
7
8 // Good chance this is entirely useless because SimpleTimer exists...
9 bool getTimer(unsigned long &timer, unsigned long interval)
10 /* Global timer function, used a lot
11 *
12 * @param unsigned long time - The current timer
13 * @param unsigned long interval - Length of time to run timer
14 *
15 * @return bool True when timer is complete
16 * @return bool False when timer is counting
17 */
18 {
19
20 if (timer < 1)
21 {
22 timer = millis();
23 }
24
25 if (millis() - timer >= interval)
26 {
27 timer = 0;
28 return true;
29 }
30
31 return false;
32 }
33
34 void blinkLED() // Just a little function to blink the on-board LED for the beacon function.
35 {
36 // On most ESP8266-based modules, GPIO2 is connected to the
37 // on-board LED (& it's inverted... so pulling this GPIO low
38 // will turn on the on-board LED.
39
40 digitalWrite(LED_BUILTIN, LOW);
41 delay(5);
42 digitalWrite(LED_BUILTIN, HIGH);
43 }