ESP32 self updating from web server

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();
}

Potrebbe interessarti: