Adding OTA

From The TinkerNet Wiki
Jump to navigation Jump to search

So...

You've created the most awesomest IoT device ever...

& you're gonna sell a million...

Whatcha gonna do when you find a bug?

Make the end user get programming hardware out? Go on-site & update it in person? Use the IDE to update?

Hell No!

Current state of OTA in my Modular Firmware

(As of: 2021/05/06)

(WIP: 2021/05/07)

platformio.ini

 1 [env:ESP32]
 2 platform = espressif32
 3 board = fm-devkit
 4 framework = arduino
 5 monitor_speed = 115200
 6 lib_deps =
 7     AsyncElegantOTA
 8     ESPAsyncTCP
 9     ESP Async WebServer
10 build_flags =
11     -D MPU=ESP32
12 
13 [env:ESP8266]
14 platform = espressif8266
15 board = d1_mini
16 framework = arduino
17 monitor_speed = 115200
18 lib_deps =
19     AsyncElegantOTA
20     ESPAsyncTCP
21     ESP Async WebServer
22 build_flags =
23     -D MPU=ESP8266

#includes, Defines, etc...

TopSecret.h

1 const char *host = "Device Name";
2 const char *ssid = "SSID";
3 const char *password = "Password";

libraries.h

 1 #ifndef LIBRARIES_H
 2 #define LIBRARIES_H
 3 
 4 // WiFi ////////////////////////////////////////////////////////////////////////
 5 #if MPU == ESP8266
 6 #include <ESP8266WiFi.h>
 7 #elif MPU == ESP32
 8 #include <WiFi.h>
 9 #endif
10 
11 #endif // LIBRARIES_H

functions.h

 1 // OTA /////////////////////////////////////////////////////////////////////////
 2 
 3 void WiFi_Setup();
 4 void OTA_init();
 5 void OTA_Loop();
 6 void Actual_Setup();
 7 void Actual_Loop();
 8 
 9 // Debug ///////////////////////////////////////////////////////////////////////
10 void debug_TitleScreen();                   // Title block for the project
11 void debug_ReadyScreen();                   // Indicate setup is finished
12 void debug_Separator();                     // Make a line
13 void debug_SectionTitle(const char *Title); // Text at the left
14 void debug_LineOut(const char *Line);       // Text 3 characters inset
15 void debug_Action(const char *Line);        // Text centred
16 void debug_Trouble(const char *Line);       //
17 void debug_Success(const char *Line);       //
18 void debug_ProgressBar0();
19 void debug_ProgressBar1();
20 void debug_ProgressBar2(int dotcount);
21 void debug_ESP_info();

debug.h

1 const char DeviceName[] = "ESP Web OTA";
2 const char DeviceDesc[] = "ESP Web OTA";

OTA_Web.h

 1 #ifndef OTA_WEB_H
 2 #define OTA_WEB_H
 3 
 4 #include "OTA_poop.h"
 5 
 6 /* Style */
 7 String style =
 8     "<style>"
 9     "#file-input,"
10     "input{width:100%;height:44px;border-radius:4px;margin:10px auto;font-size:15px}"
11     "input{background:#f1f1f1;border:0;padding:0 15px}"
12 
13     "body{background:#004400;font-family:sans-serif;font-size:14px;color:#777}"
14 
15     "#file-input{padding:0;border:1px solid #ddd;line-height:44px;text-align:left;display:block;cursor:pointer}"
16     "#bar,"
17     "#prgbar{background-color:#f1f1f1;border-radius:10px}"
18 
19     "#bar{background-color:#3498db;width:0%;height:10px}"
20     "form{background:#fff;max-width:512px;margin:75px auto;padding:30px;border-radius:5px;text-align:center}"
21     ".btn{background:#660066;color:#fff;cursor:pointer}"
22     "</style>";
23 
24 /* Login page */
25 String RootPage =
26     "<form name=loginForm>"
27     "<h1>"
28     // + Type +
29     // " "
30     + sDeviceName +
31     // " "
32     // + DeviceName +
33     " </h1>"
34     "<input type=submit "
35     "onclick=window.open('/update')"
36     " class=btn value=Update>"
37 
38     "<input type=submit "
39     "onclick=check(this.form)"
40     " class=btn value=Downdate>"
41 
42     "<input type=submit "
43     "onclick=puke(this.form)"
44     " class=btn value=Maybe>"
45 
46     "</form>"
47     "<script>"
48     "function check(form) {"
49     "{window.open('/Test', '_self')}"
50     "}"
51     "</script>"
52 
53     "<script>"
54     "function puke(form) {"
55     // "{window.open(\"/Test\", \"_self\")}"
56     "{window.open(\"/Test\")}"
57     "}"
58     "</script>" +
59     style;
60 
61 String TestPage =
62     "<H1>This</H1>"
63     "<H2>is only a</H2>"
64     "<H1>TEST!</H1>";
65 #endif // OTA_WEB_H

OTA_poop.h

 1 const char* OTAuser = "root";
 2 const char* OTApass = "F00Bar!";
 3 
 4 #ifdef SS_Alert
 5 const String sDeviceName = "SugarShack PumpHouse Alerter";
 6 
 7 #elif SS_PHTank
 8 const String sDeviceName = "SugarShack PumpHouse Tank Monitor";
 9 
10 #elif SS_PHLightBar
11 const String sDeviceName = "SugarShack PumpHouse LightBar Driver";
12 
13 #elif SS_Dumper
14 const String sDeviceName = "SugarShack PumpHouse Dumper Monitor";
15 
16 #elif SS_RO
17 const String sDeviceName = "SugarShack Reverse-Osmosis Unit Monitor";
18 
19 #elif SS_Evaporator
20 const String sDeviceName = "SugarShack Evaporator Monitor";
21 
22 #elif SS_BottlingTank
23 const String sDeviceName = "SugarShack Bottling Tank Monitor";
24 
25 #elif SS_Climate
26 const String sDeviceName = "SugarShack Climate Monitor";
27 
28 #elif SS_HoldingTanks
29 const String sDeviceName = "SugarShack Holding Tank Monitor";
30 
31 #elif SS_FeedTank
32 const String sDeviceName = "SugarShack Feed Tank Monitor";
33 
34 #else
35 const String sDeviceName = "NFC What this one is...";
36 #endif // FOOBAR

ActualStuff.h

1 void ActualSetup();
2 void ActualLoop();

The Code Itself

main.cpp

 1 #include <Arduino.h>
 2 
 3 #if MPU == ESP8266
 4 const char *MPUtype = "ESP8266";
 5 #elif MPU == ESP32
 6 const char *MPUtype = "ESP32";
 7 #endif
 8 
 9 #include "functions.h"
10 
11 void setup(void)
12 {
13   Serial.begin(115200);
14   delay(500);
15   Serial.println(MPUtype);
16 
17   WiFi_Setup();
18   OTA_init();
19   Actual_Setup();
20 }
21 
22 void loop(void)
23 {
24   OTA_Loop();
25   Actual_Loop();
26 }

WiFi.cpp

 1 #if MPU == ESP8266
 2 #include <ESP8266WiFi.h>
 3 #include <ESPAsyncTCP.h>
 4 // const char *MPUtype = "ESP8266";
 5 #elif MPU == ESP32
 6 #include <WiFi.h>
 7 #include <WiFiClient.h>
 8 // #include <ESPmDNS.h>
 9 // const char *MPUtype = "ESP32";
10 #endif
11 
12 #include "TopSecret.h"
13 
14 void WiFi_Setup()
15 {
16   WiFi.mode(WIFI_STA);
17   WiFi.begin(ssid, password);
18 
19   // Wait for connection
20   while (WiFi.status() != WL_CONNECTED)
21   {
22     delay(500);
23     Serial.print(".");
24   }
25   Serial.println("");
26   Serial.printf("Connected to %s\n", ssid);
27   Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str());
28 }

OTA.cpp

 1 #include <ESPAsyncWebServer.h>
 2 #include <AsyncElegantOTA.h>
 3 #include "functions.h"
 4 // #include "debug.h"
 5 
 6 AsyncWebServer server(80);
 7 
 8 #include "OTA_Web.h"
 9 
10 void OTA_init()
11 {
12         debug_SectionTitle("Initializing OTA System...");
13 
14   server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
15     request->send(200, "text/html", RootPage);
16   });
17 
18   server.on("/Test", HTTP_GET, [](AsyncWebServerRequest *request) {
19     request->send(200, "text/html", TestPage);
20   });
21 
22   AsyncElegantOTA.begin(&server, OTAuser, OTApass); // Start ElegantOTA
23   server.begin();
24   debug_LineOut("HTTP server started");
25 }
26 
27 void OTA_Loop()
28 {
29   AsyncElegantOTA.loop();
30 }

ActualStuff.cpp

 1 #include <Arduino.h>
 2 
 3 //variabls for blinking an LED with Millis
 4 const int led = 2;                // ESP32 Pin to which onboard LED is connected
 5 unsigned long previousMillis = 0; // will store last time LED was updated
 6 const long interval = 1000;       // interval at which to blink (milliseconds)
 7 int ledState = LOW;               // ledState used to set the LED
 8 
 9 void Actual_Setup()
10 {
11     pinMode(led, OUTPUT);
12 }
13 
14 void Actual_Loop()
15 {
16     //loop to blink without delay
17     unsigned long currentMillis = millis();
18     if (currentMillis - previousMillis >= interval)
19     {
20         // save the last time you blinked the LED
21         previousMillis = currentMillis;
22         // if the LED is off turn it on and vice-versa:
23         ledState = not(ledState);
24         // set the LED with the ledState of the variable:
25         digitalWrite(led, ledState);
26     }
27 }

Debugging.cpp

  1 #include "libraries.h"
  2 #include "functions.h"
  3 #include "debug.h"
  4 
  5 void debug_TitleScreen()
  6 {
  7     Serial.printf("\n\n#================================================#\n");
  8     Serial.printf("# %-46s #\n", DeviceName);
  9     Serial.printf("# %-46s #\n", DeviceDesc);
 10     Serial.printf("+------------------------------------------------+\n");
 11     Serial.printf("# WiFi Enabled...                                #\n");
 12     Serial.printf("# Speaks fluent MQTT...                          #\n");
 13     Serial.printf("#================================================#\n");
 14 }
 15 
 16 void debug_ReadyScreen()
 17 {
 18     Serial.printf("#================================================#\n");
 19     Serial.printf("#                 Ready To Run.                  #\n");
 20     Serial.printf("#================================================#\n");
 21 }
 22 
 23 void debug_Separator()
 24 {
 25     Serial.printf("+------------------------------------------------+\n");
 26 }
 27 
 28 void debug_SectionTitle(const char *Title)
 29 {
 30     Serial.printf("| %-46s |\n", Title);
 31 }
 32 
 33 void debug_LineOut(const char *Line)
 34 {
 35     Serial.printf("|    %-43s |\n", Line);
 36 }
 37 
 38 void debug_Action(const char *Line)
 39 {
 40     {
 41         const char *SPACE = "                              ";
 42         char BUFFER[100];
 43         char BUFFER2[100];
 44 
 45         int BuffSize = (23 - (strlen(Line) / 2));
 46 
 47         strcpy(BUFFER, SPACE);
 48         BUFFER[BuffSize] = '\0';
 49 
 50         sprintf(BUFFER2, "%s%s", BUFFER, Line);
 51         Serial.printf("| %-46s |\n", BUFFER2);
 52     }
 53 }
 54 
 55 void debug_Trouble(const char *Line)
 56 {
 57     Serial.printf("* %-46s *\n", Line);
 58 }
 59 
 60 void debug_Success(const char *Line)
 61 {
 62     Serial.printf("+ %-46s +\n", Line);
 63 }
 64 
 65 void debug_ProgressBar0()
 66 {
 67     Serial.printf("| ");
 68 }
 69 
 70 void debug_ProgressBar1()
 71 {
 72     Serial.printf(".");
 73 }
 74 
 75 void debug_ProgressBar2(int dotcount)
 76 {
 77     for (int i = 0; i < (47 - dotcount); i++)
 78     {
 79         Serial.printf(" ");
 80     }
 81     Serial.printf("|\n");
 82 }
 83 
 84 void debug_ESP_info()
 85 {
 86 #if MPU == ESP8266
 87     char Line[46];
 88     // Check and report on the flash memory on this board
 89     debug_SectionTitle("Board flash memory Info");
 90     uint32_t realSize = ESP.getFlashChipRealSize();
 91     uint32_t ideSize = ESP.getFlashChipSize();
 92     FlashMode_t ideMode = ESP.getFlashChipMode();
 93     sprintf(Line, "Flash real id:   %08X", ESP.getFlashChipId());
 94     debug_LineOut(Line);
 95     sprintf(Line, "Flash real size: %u", realSize);
 96     debug_LineOut(Line);
 97     sprintf(Line, "Flash ide  size: %u", ideSize);
 98     debug_LineOut(Line);
 99     sprintf(Line, "Flash ide speed: %u", ESP.getFlashChipSpeed());
100     debug_LineOut(Line);
101     sprintf(Line, "Flash ide mode:  %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
102                                                                   : ideMode == FM_DIO    ? "DIO"
103                                                                   : ideMode == FM_DOUT   ? "DOUT"
104                                                                                          : "UNKNOWN"));
105     debug_LineOut(Line);
106     if (ideSize != realSize)
107     {
108         sprintf(Line, "Flash Chip configuration wrong!");
109     }
110     else
111     {
112         sprintf(Line, "Flash Chip configuration ok.");
113     }
114     debug_LineOut(Line);
115 #elif MPU == ESP32
116 //
117 #endif
118 }