IoT - Collabs - ESP Firmware with Guru

From The TinkerNet Wiki
Jump to navigation Jump to search

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)

Declarations and Defines

Individual Functions

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

Declarations and Defines

Individual Functions

OTA

Gurus source code...

Source code

Ffffffuuuuuuuu......

Configuration HotSpot

Source code

Wiegand RFID keypad

Source code

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

Declarations and Defines

Individual Functions

Web Serving

Source code

TFT Display

Source code

OLED Display

Source code

(upcoming)

Little OLEDs.jpg

Climate Sensing

Source code

Sensors

  • DS18B20
  • BME280
  • Si7021
  • HiH6130

Energy Monitoring

Source code

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...