2

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 Answers1

2

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!

Nino
  • 401
  • 4
  • 9
  • 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 Aug 11 '21 at 09:37
  • @Abhishekbhatia, how does the ESP32 do MQTT without access to the server? – Juraj Aug 11 '21 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 Aug 11 '21 at 15:20
  • @Juraj would you suggest me which library is better to use for my use case ArduinoOTA or update ?? – Abhishek bhatia Aug 11 '21 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. – Juraj Aug 11 '21 at 15:33