IoT - Collabs - ESP Firmware with Guru
Contents
Modular Firmware
main.cpp
Baseline
This is the basis for pretty much ANY ESP-based firmware project. It'll get your device online.
main.cpp
#includes, Defines, etc...
You'll note this is currently aimed at the SugarBush project.
1 #include "libraries.h"
2 #include "functions.h"
3
4 #ifdef s_CLIMATE
5 #include "s-Climate.h"
6 #endif // s_CLIMATE
7
8 #include "externs.h"
9 #include "TopSecret.h"
10
11 /************************************************************************************************/
12 struct CLIMATE_Readings
13 {
14 byte Status;
15
16 float Temperature;
17 float Humidity;
18 float AbsPressure;
19 float SeaPressure;
20 };
21
22 struct CLIMATE_Readings CLIMATE_Datum;
23 /************************************************************************************************/
24
25 // I2C pins suitable for the ESP-M3-Everything!
26 const int SSD1306_SDA = 14; // Tarduino D5
27 const int SSD1306_SCL = 12; // Tarduino D6
28
29 #ifdef d_SDD1306
30 bool WalkingDudeIndicator = false;
31 bool WavingDudeIndicator = true;
32 #endif
33
34 SimpleTimer timer;
35
36 extern int BMP180_Count;
37 extern int BME280_Count;
38
39 #ifdef SS_Dumper
40 int ReedPin = 4;
41 int HallPin = 5;
42 // int Dumptime = 0;
43 #endif // SS_Dumper
setup()
You'll note this is currently aimed at the SugarBush project.
1 void setup()
2 {
3 char debugTEXT[46];
4 sprintf(debugTEXT, "nothing yet");
5
6 Serial.begin(115200);
7 delay(500); // Delay to let the ESP get booted before sending out serial data
8
9 debug_TitleScreen();
10
11 if (I2C_Test(SSD1306_SDA, SSD1306_SCL)) // Force a reset of the I2C bus if needed
12 {
13 Wire.begin(SSD1306_SDA, SSD1306_SCL); // Select SDA & SCL pins
14 /////////////////////////////
15 pinMode(SSD1306_SDA, INPUT);
16 pinMode(SSD1306_SCL, INPUT);
17 }
18 else
19 {
20 //////////////////////////////// Need to send an MQTT error status message!
21 debug_Action("POOP!");
22 }
23
24 // ESP Info //////////////////////////////////////////////////////////////////
25 #ifdef DEBUG6
26 debug_Separator();
27 debug_ESP_info();
28 #endif // DEBUG6
29
30 // WiFi //////////////////////////////////////////////////////////////////////
31 debug_Separator();
32 WiFi_init();
33
34 // MQTT //////////////////////////////////////////////////////////////////////
35 debug_Separator();
36 MQTT_init();
37
38 debug_Separator();
39 debug_Action("Initialising Outputs...");
40
41 // Pixels //////////////////////////////////////////////////////////////////////
42 #ifdef d_Pixels
43
44 Pixels_init();
45
46 for (int i = 0; i < PixelCount; i++)
47 {
48 SetAPixel(i, BLU);
49 }
50
51 #endif // d_Pixels
52
53 // Audio ///////////////////////////////////////////////////////////////////////
54 #ifdef d_Audio
55 Noise_init();
56 #endif // d_Audio
57
58 #ifdef d_SDD1306
59 SSD1306_init();
60 // Display static text
61 // SSD1306_title("ColdStuff");
62 SSD1306_title("SugarBush");
63 #ifdef DEBUG
64 debug_LineOut("Title on-screen");
65 #endif
66 #endif // d_SDD1306
67
68 debug_Separator();
69 debug_Action("Initialising Sensors...");
70
71 // Event Triggers //////////////////////////////////////////////////////////////
72 #ifdef SS_Dumper
73 debug_LineOut("Dumper Sensor");
74 pinMode(HallPin, INPUT);
75 attachInterrupt(digitalPinToInterrupt(ReedPin), DumpDetect, CHANGE);
76 sprintf(debugTEXT, "Reed Switch on pin %d", ReedPin);
77 debug_LineOut(debugTEXT);
78 attachInterrupt(digitalPinToInterrupt(HallPin), DumpDetect2, CHANGE);
79 sprintf(debugTEXT, "Hall Effect Sensor on pin %d", HallPin);
80 debug_LineOut(debugTEXT);
81 #endif // SS_Dumper
82
83 // Depth Probes ////////////////////////////////////////////////////////////////
84 #ifdef s_Depth
85 Depth_init();
86 #endif // d_Depth
87
88 // BMP180 ////////////////////////////////////////////////////////////////////
89 #ifdef s_BMP180
90 BMP180_Count = BMP180_init();
91 #endif
92
93 // BME280 ////////////////////////////////////////////////////////////////////
94 #ifdef s_BME280
95 BME280_Count = BME280_init();
96 #endif
97
98 #ifdef s_CLIMATE
99 BMP180_Count = BMP180_init();
100 if (BMP180_Count > 0)
101 {
102 #define s_BMP180
103 }
104 BME280_Count = BME280_init();
105 if (BME280_Count > 0)
106 {
107 #define s_BME280
108 }
109 #endif
110
111 // Hall-Effect ///////////////////////////////////////////////////////////////
112 // #ifdef SS_Dumper
113 // debug_Separator();
114 // debug_SectionTitle("Hall Effect Sensor");
115 // pinMode(HallPin, INPUT);
116 // attachInterrupt(digitalPinToInterrupt(ReedPin), DumpDetect, CHANGE);
117 // sprintf(debugTEXT, "Reed Switch on pin %d", ReedPin);
118 // debug_LineOut(debugTEXT);
119 // attachInterrupt(digitalPinToInterrupt(HallPin), DumpDetect2, CHANGE);
120 // sprintf(debugTEXT, "Hall Effect Sensor on pin %d", HallPin);
121 // debug_LineOut(debugTEXT);
122 // #endif // SS_Dumper
123
124 // Interval Timers ///////////////////////////////////////////////////////////
125 debug_Separator();
126 debug_SectionTitle("Interval Timers");
127
128 timer.setInterval(20, MQTT_handler);
129 debug_LineOut("MQTT");
130
131 timer.setInterval(2000, WiFi_Test);
132 debug_LineOut("WiFiCheck");
133
134 #ifdef s_Depth
135 timer.setInterval(5000, CheckProbes);
136 debug_LineOut("Check Probes");
137 #endif // s_Depth
138
139 #ifdef s_BMP180
140 if (BMP180_Count != 0)
141 {
142 timer.setInterval(10000, BMP180_main);
143 debug_LineOut("BMP180 Handler");
144 }
145 #endif
146
147 #ifdef s_BME280
148 if (BME280_Count != 0)
149 {
150 timer.setInterval(10000, BME280_main);
151 debug_LineOut("BME280 Handler");
152 }
153 #endif
154
155 #ifdef s_CLIMATE
156 if (BMP180_Count != 0)
157 {
158 timer.setInterval(10000, BMP180_main);
159 debug_LineOut("BMP180 Handler");
160 }
161 if (BME280_Count != 0)
162 {
163 timer.setInterval(10000, BME280_main);
164 debug_LineOut("BME280 Handler");
165 }
166 #endif
167
168 #ifdef d_SDD1306
169 timer.setInterval(100, WavingDude); // Waving Dude in the top-right corner
170 debug_LineOut("Waving Dude Indicator");
171 #endif
172
173 // READY /////////////////////////////////////////////////////////////////////
174 debug_ReadyScreen();
175 }
loop()
You'll note this is currently aimed at the SugarBush project.
1 void loop()
2 {
3 // Run the interval timers
4 // Running processes here in loop() is a synchronous flow.
5 // Running processes via the interval timers is assynchronous.
6 // If your actions don't depend directly on each other,
7 // synchronous flow makes no sense at all...
8 timer.run();
9
10 #ifdef SS_Dumper
11 // This is just here to give me console output while developing...
12 // Serial.print(".");
13 // delay(1000);
14 #endif // SS_Dumper
15 }
The parts
Work Environment (Platformio/VSC setup)
MQTT
This is intended to be added to the baseline.
You'll need to add:
lib_deps = PubSubClient
to your platformio.ini
file.
main.cpp
Add:
setup_mqtt();
to setup() after the setup_wifi();
call.
Put:
DOtheBloodyMQTT();
inside loop()
The rest of the parts
OTA
Gurus source code...
Ffffffuuuuuuuu......
Configuration HotSpot
Wiegand RFID keypad
NeoPixels
Extreme WIP
This is intended to be added to the baseline.
You'll need to add:
lib_deps = Adafruit NeoPixel
to your platformio.ini
file.
and put
#include <Adafruit_NeoPixel.h>
in your source
Web Serving
TFT Display
OLED Display
(upcoming)
Climate Sensing
Sensors
- DS18B20
- BME280
- Si7021
- HiH6130
Energy Monitoring
Multitasking
Jean-Francois Turcots SimpleTimer Library makes this fairly straightforward. It allows you to specify that any function run repeatedly (triggered independantly of whatever is going on in loop().
Add SimpleTimer
to the lib_deps
in yout platformio.ini
file.
an Example
1 #include <SimpleTimer.h>
2
3 // the timer object
4 SimpleTimer timer;
5
6 // functions to be executed periodically
7 void repeatMe() {
8 Serial.print("Uptime (s): ");
9 Serial.println(millis() / 1000);
10 }
11
12 void repeatMe2() {
13 Serial.print("Boop: ");
14 Serial.println(millis() / 1000);
15 }
16
17 void setup() {
18 Serial.begin(9600);
19 timer.setInterval(1000, repeatMe); // Run RepeatMe() every 1000 miliseconds.
20 timer.setInterval(100, repeatMe2); // Run RepeatMe2() every 100 miliseconds.
21 }
22
23 void loop() {
24 timer.run();
25 }
Modularization Tutorial (WIP)
The source code...