Before starting working, I am just researching around how can I achieve OTA over MQTT in ESP32 in using Arduino IDE. The process I understand the esp listen to MQTT messages and then received that file over MQTT(not fully at once may be in chunks). And then stored that in flash at specific address. And then change boot loader configuration for executing new firmware.
Here I am confused how can I change boot loader configuration settings to execute the new firmware memory address ?? Any help is appreciated.
is there any out of box library available for this work? Please share reference. I can take reference from there.
Thanks
1 Answer 1
I am not familiar with OTA for ESP32 but with SAMD21 using ArduinoOTA library and there the download is not done over MQTT but HTTPS.
Link to download is sent over MQTT but that's where it ends, download over HTTPS, verification of received data using checksum and bytes count and once InternalStorage.apply() executed it swaps the program downloaded with the older version and reboot.
EDIT:
As per Juraj request, I am adding the code as a guide you can use to get ideas. You can't run it as is, you would need to add variable declaration and wrap it in a function.
As updating wrong file will most likely brick your board, I would just add that before running this code I check the filename to make sure it is the correct BIN for the board downloading it, I am using constants like WIFI, GSM, and board name and expect to see them in the filename.
I also send the file length from the server as part of the MQTT update request and check it against my own bytes count and I am not relying on TCP to provide an error on corrupted data and do a my own checksum test.
#include <ArduinoOTA.h> // https://github.com/jandrassy/ArduinoOTA
// Access the file
HttpClient client(*transport, upgradeServer, upgradePort);
client.get(upgradePath);
int statusCode = client.responseStatusCode();
/*
0 HTTP_SUCCESS
-1 HTTP_ERROR_CONNECTION_FAILED The end of the headers has been reached. This consumes the '\n' Could not connect to the server
-2 HTTP_ERROR_API This call was made when the HttpClient class wasn't expecting it to be called.
Usually indicates your code is using the class incorrectly
-3 HTTP_ERROR_TIMED_OUT Spent too long waiting for a reply
-4 HTTP_ERROR_INVALID_RESPONSE The response from the server is invalid, is it definitely an HTTP server?
*/
if (statusCode != 200) {
client.stop();
// here you can do something with statusCode like notifying over MQTT
}
long length = client.contentLength();
if (length == HttpClient::kNoContentLengthHeader) {
client.stop();
//Server didn't provide Content-length header, abort.
return;
}
if (!InternalStorage.open(length)) {
client.stop();
// Not enough space to store the file, abort.
return;
}
// Start update, length holds the file size in bytes
client.setTimeout(5000);
byte b;
bool ok;
long fileLength = length;
unsigned long otaStartMillis = millis();
int localChecksum = 0;
while (length > 0) {
ok = client.readBytes(&b, 1);
if (!ok) {
// Abort, stopped after ((millis() - otaStartMillis)/1000) Sec
return;
}
InternalStorage.write(b);
int bValue = (int)b;
localChecksum = localChecksum + bValue;
length--;
}
InternalStorage.close();
client.stop();
if (localChecksum != remoteCkecksum) {
// Checksum mismatch, abort.
return;
}
if (length > 0) {
// Timeout at byte length, abort.
return;
}
InternalStorage.apply(); // this doesn't return, board should restart
Serial.println("Update failed"); //shown only if update failed
Another opportunity to thank Jurak for this library!
-
In my case, the ESP32 doesn't have access to public network. So I will prefer to send the file over MQTT from server side and client(ESP 32) will receive that and do the required things.Abhishek bhatia– Abhishek bhatia2021年08月11日 09:37:12 +00:00Commented Aug 11, 2021 at 9:37
-
@Abhishekbhatia, how does the ESP32 do MQTT without access to the server?2021年08月11日 11:52:38 +00:00Commented Aug 11, 2021 at 11:52
-
1@Juraj I mentioned that, In my use case ESP 32 doesn't have access to public network. It is connect to MQTT server hosted on edge device(They are on private network) . I just don't wanted to use http.Abhishek bhatia– Abhishek bhatia2021年08月11日 15:20:29 +00:00Commented Aug 11, 2021 at 15:20
-
@Juraj would you suggest me which library is better to use for my use case ArduinoOTA or update ??Abhishek bhatia– Abhishek bhatia2021年08月11日 15:26:02 +00:00Commented Aug 11, 2021 at 15:26
-
@Abhishekbhatia Update. because esp32 boards support package has a libray named ArduinoOTA. you would have to delete it to use the generic ArduinoOTA. The generic ArduinoOTA only wraps the Update library. Generic ArduinoOTA is useful for esp32 with W5500 or enc28j60 Ethernet module.2021年08月11日 15:33:08 +00:00Commented Aug 11, 2021 at 15:33
Update
library. Just feed it the right data.