Hi. I have a setup in which there is an Arduino Mega2560 and an ESP8266 and I want to implement some basic firmware OTA functionality. The workflow which I had in mind was as follows:
- Query the server for a JSON payload that checks if a new firmware version is available.
- If yes, download that version (an Intel
.hex
file). - Transfer it over serial to the Mega after restarting it so the Mega's bootloader can accept it and write it to application flash.
Steps 1 and 2 were relatively easy to accomplish with some standard ESP8266 wifi libraries and ArduinoJson. However step 3 has really stumped me and I have found myself trying, for the last few days, to unsuccessfully emulate the behavior of code that is way too sophisticated for me to understand (it did give me an opportunity to learn about bootloaders, fuse and lock bits and all that though).
So I was wondering if it would be possible to have libraries in the likes of ArduinoOTA handle ONLY step 3 for me whilest still doing steps 1 and 2 via the regular ESP8266 libraries on the ESP end? .
Here is the skeleton of the code that I have in mind:
// Code for ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <ArduinoJson.h>
void setup()
{
// step 1
connect2WiFi(ssid, password); // uses WiFi.begin() and WiFi.status()
if (fimwareUpdateAvailable(API1_url)) // uses HTTPClient::begin(), HTTPClient::POST() and ArduinoJson
{
// step 2
String hexfile = download(URL); // uses HTTPClient::GET()
File file = write2SPIFFS(hexfile); // uses SPIFFS.open(), write(), etc.
// step 3
bool transferComplete = false;
while (!transferComplete)
transferComplete = transfer2Mega(file); // using Serial.write() over UART
}
}
I'm not sure what to do on the Mega 2560 end. Looking through the code examples I found the InternalStorage
class with its .write()
function (here onwards):
byte b;
while (length > 0) {
if (!client.readBytes(&b, 1)) // reading a byte with timeout
break;
InternalStorage.write(b);
length--;
}
InternalStorage.close();
client.stop();
if (length > 0) {
Serial.print("Timeout downloading update file at ");
Serial.print(length);
Serial.println(" bytes. Can't continue with update.");
return;
}
Serial.println("Sketch update apply and reset.");
Serial.flush();
InternalStorage.apply(); // this doesn't return
so, I'm thinking something like:
#include <ArduinoOTA.h>
void setup()
{
byte b;
while (b = receiveFromESP()) // over Serial UART
{
InternalStorage.write(b);
}
InternalStorage.close();
InternalStorage.apply();
}
Would this be a valid way of approaching this? is there some thing that I am missing or perhaps something that can be handled more easily with ArduinoOTA itself? (I have read the notes about installing Optiboot bootloader for Arduino Mega and will be trying that out as well). Any advice is welcome.