Over the air ESP32 update, fetching firmware from folder in remote server.
The new .bin file is located in a remote webserver. The Arduino program will periodically check if a file exist with the new firmware. If found, it will download and install it.
The current firmware version is stated in a #define, for example #define 3. This program will look out for a file named myprogram_v4.bin, as 4 is the next version. When you place the file myprogram_v4.bin in the server, the program will download and install it. It will then periodically look for myprogram_v5.bin, and so on.
/* Update ESP32 firmware via external web server
*
*
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <Update.h>
// location of firmware file on external web server
// change to your actual .bin location
#define FWURL "http://www.yourwebsite.com/firmware/folder/myprogram_v" //software will add the version and .bin at the end,
#define FWversion 3
HTTPClient client;
// Your WiFi credentials
const char* ssid = "yourSSID";
const char* password = "password"
// Global variables
int totalLength; //total size of firmware
int currentLength = 0; //current size of written firmware
//--------------------------------------------------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
// Start WiFi connection
WiFi.mode(WIFI_MODE_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//************************************************************
void loop() {
Serial.print("Current firmware: v"); Serial.println(FWversion);
checkupdate();
delay(10000);
}
//************************************************************
void checkupdate(){
// Connect to external web server
Serial.println("Checking if new firmware is available.");
int fwNewVersion = FWversion+1; //cerca la versione successiva del firmware.
String fwVersionURL = FWURL + String(fwNewVersion) + ".bin";
client.begin(fwVersionURL);
// Get file, just to check if each reachable
int resp = client.GET();
Serial.print("Response: ");
Serial.println(resp);
// If file is reachable, start downloading
if(resp == 200){
// get length of document (is -1 when Server sends no Content-Length header)
totalLength = client.getSize();
// transfer to local variable
int len = totalLength;
// this is required to start firmware update process
Update.begin(UPDATE_SIZE_UNKNOWN);
Serial.printf("FW Size: %u\n",totalLength);
// create buffer for read
uint8_t buff[128] = { 0 };
// get tcp stream
WiFiClient * stream = client.getStreamPtr();
// read all data from server
Serial.println("Updating firmware...");
while(client.connected() && (len > 0 || len == -1)) {
// get available data size
size_t size = stream->available();
if(size) {
// read up to 128 byte
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
// pass to function
updateFirmware(buff, c);
if(len > 0) {
len -= c;
}
}
delay(1);
}
}else{
Serial.println("Cannot download firmware file.");
}
client.end();
}
//----------------------------------------------------------------------------------------------------------------------
// Function to update firmware incrementally
// Buffer is declared to be 128 so chunks of 128 bytes
// from firmware is written to device until server closes
void updateFirmware(uint8_t *data, size_t len){
Update.write(data, len);
currentLength += len;
// Print dots while waiting for update to finish
//Serial.print('.');
// if current length of written firmware is not equal to total firmware size, repeat
if(currentLength != totalLength) return;
Update.end(true);
Serial.printf("\nUpdate Success, Total Size: %u\nRebooting...\n", currentLength);
// Restart ESP32 to see changes
ESP.restart();
}