ESP32 OTA update with Arduino IDE: filesystem, firmware, and password

Spread the love

The ESP32 is a powerful microcontroller that has gained popularity among developers for its versatility and ease of use.

One of the most important features of the ESP32 is the ability to perform over-the-air (OTA) updates, which allows developers to remotely update the firmware of the device without the need for physical access.

In this article, we will explore how to perform an OTA update on an ESP32 using the Arduino IDE. We will cover the entire process, including updating the filesystem and firmware, as well as securing the OTA update with a password.

By the end of this article, you will have a comprehensive understanding of how to perform OTA updates on your ESP32 devices using the Arduino IDE.

ESP32 OTA update with Arduino IDE: filesystem, firmware and password
ESP32 OTA update with Arduino IDE: filesystem, firmware and password

OTA (Over the Air) update is the process of uploading firmware to an ESP32 module using a Wi-Fi connection rather than a serial port. Such functionality becomes extremely useful in case of limited or no physical access to the module.

OTA may be done using the following:

  • Arduino IDE
  • Web Browser
  • HTTP Server

First of all, check the tutorial “ESP32: flash compiled firmware (.bin)“.

In this article, we are going to explain the Arduino IDE OTA update of the firmware and filesystem.

Here some common esp32 device I use ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S

Introduction

First, we look that the core component of ESP32 core needs python installed, and when installing It remember to add to the path (for windows)

ESP Tools Install Python and add It to path
ESP Tools Install Python and add It to path

OTA upload use UDP protocol, so It can work (with ArduinoIDE) only in the local network because uses broadcast to discover the devices, and It’s limited to the LAN.

The UDP protocol is rather old, simple, and powerful. I use it in other projects to discover all the devices on my network from a simple Android application

Basic example

Now upload BasicOTA.ino, available under File -> Examples -> ArduinoOTA -> BasicOTA.ino

Or copy and paste from here.

#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "<YOUR-SSID>";
const char* password = "<YOUR-PASSWD>";

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // Port defaults to 3232
  // ArduinoOTA.setPort(3232);

  // Hostname defaults to esp3232-[MAC]
  // ArduinoOTA.setHostname("myesp32");

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });

  ArduinoOTA.begin();

  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  ArduinoOTA.handle();
}

The code is concise, and the library ArduinoOTA does all for us.

The serial output is:

Booting
Ready 
IP address: 192.168.1.200

Remember to set the SSID and PASSWD of your WiFi network.

ArduinoOTA needs to be started ArduinoOTA.begin(); and the relative handle ArduinoOTA.handle();, the full logic is managed by the library, and It offers some listeners to follow the process and apply your additional logic.

void onStart(OTA_CALLBACK(fn));
void onEnd(OTA_CALLBACK(fn));
void onProgress(OTA_CALLBACK_PROGRESS(fn));
void onError(OTA_CALLBACK_ERROR (fn));

The meaning of this method is written in the name, but in the example code, we can find some information that can help you to understand some additional features:

    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })

You can check if It’s an OTA update of the FLASH or of the FS, this means that you can upload the sketch and FileSystem in the same way, but we are going to check it next.

You can upload the Firmware or FileSystem

Caricare lo sketch

Sketch OTA update File system EEPROM WiFi config

Now if we are going to open, Tools -> Port we can find our device listed (discovered by broadcast UDP).

Probably, if you use windows, It asks to allow network access.

ArduinoOTA esp32 on ArduinoIDE request network permission
ArduinoOTA esp32 on ArduinoIDE requests network permission

Allow It, and now the menu.

ArduinoOTA esp32 select OTA port device on ArduinoIDE
ArduinoOTA esp32 select OTA port device on ArduinoIDE

And now, we can disconnect the device from the PC, power it on via an external power supply, and upload the code.

Sketch uses 776093 bytes (59%) of program storage space. Maximum is 1310720 bytes.
Global variables use 36448 bytes (11%) of dynamic memory, leaving 291232 bytes for local variables. Maximum is 327680 bytes.
C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0/tools/espota.exe -i 192.168.1.200 -p 3232 --auth= -f C:\Users\renzo\AppData\Local\Temp\arduino_build_18433/BasicOTA.ino.bin 
Sending invitation to 192.168.1.200 
Uploading............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

And the serial output of the microcontroller is:

Booting
Ready 
IP address: 192.168.1.200
Start updating sketch
Progress: 0% Error[2]: Connect Failed
Error[4]: End Failed
Start updating sketch
Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0%
Progress: 1% Progress: 1% Progress: 1%
Progress: 1% Progress: 1%
Progress: 1% Progress: 1%
Progress: 1% Progress: 1%
Progress: 1%
Progress: 1% Progress: 1%
Progress: 1% Progress: 2%
Progress: 2% Progress: 2% Progress: 2%
Progress: 2% Progress: 2% Progress: 2%
Progress: 2% Progress: 2% Progress: 2%
Progress: 2% Progress: 3% Progress: 3% Progress: 3% Progress: 3%

[...]

Progress: 97% Progress: 97%
Progress: 97% Progress: 98%
Progress: 98%
Progress: 98%
Progress: 98% Progress: 98%
Progress: 98% Progress: 98% Progress: 98%
Progress: 98%
Progress: 98%
Progress: 98% Progress: 99% Progress: 99% Progress: 99% Progress: 99%
Progress: 99% Progress: 99%
Progress: 99% Progress: 99% Progress: 99%
Progress: 99%
Progress: 99%
Progress: 99% Progress: 100% 
End
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Booting
Ready
IP address: 192.168.1.186

Upload FileSystem (SPIFFS, LittleFS, or FFatFS)

You can also upload filesystem data with the classic method via the plugin, to install SPIFFS, LittleFS, or FFat plugin, refer to the relative tutorial:

After that operation, you can use the plugin like usual.

Arduino IDE esp32 SPIFFS Sketch Data Upload
Arduino IDE esp32 SPIFFS Sketch Data Upload
esp32 SPIFFS LittleFS FatFS file uploader from Arduino IDE
esp32 SPIFFS LittleFS FatFS file uploader from Arduino IDE

You can check the IDE console output to check what happened.

Chip : esp32
Using partition scheme from Arduino IDE.
Start: 0x290000
Size : 0x170000
mkspiffs : C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\tools\mkspiffs\0.2.3\mkspiffs.exe

espota : C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\espota.exe

[SPIFFS] data   : D:\Projects\Arduino\sloeber-workspace-OTA\ArduinoOTAesp32_basic_arduino\data
[SPIFFS] offset : 0
[SPIFFS] start  : 2686976
[SPIFFS] size   : 1472
[SPIFFS] page   : 256
[SPIFFS] block  : 4096
->/version.txt
[SPIFFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin
[SPIFFS] IP     : 192.168.1.186
Running: C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\espota.exe -i 192.168.1.186 -p 3232 -s -f C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin

_>Sending invitation to 192.168.1.186 
_>Uploading................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
_>09:21:38 [ERROR]: Error response from device
SPIFFS Upload failed!

The IDE console returns an error, but the upload work. I think there is a little bug now when I write this article.

IDE gives an error but it is a bug, the loading works correctly

And on the microcontroller

Booting
Ready 
IP address: 192.168.1.186
Start updating filesystem
Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0% Progress: 0%
Progress: 0%
Progress: 0%
Progress: 1% Progress: 1%
Progress: 1% Progress: 1%
Progress: 1%
Progress: 1%
Progress: 1% Progress: 1%
Progress: 1% Progress: 1%
Progress: 1% Progress: 1%
Progress: 1%

[...]

Progress: 99% Progress: 99%
Progress: 99%
Progress: 99% Progress: 99% Progress: 99%
Progress: 99% Progress: 99%
Progress: 99% Progress: 99%
Progress: 99%
Progress: 99%
Progress: 99%
Progress: 99%
Progress: 99% Progress: 100% 
End
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Booting
Ready
IP address: 192.168.1.186

Protect upload with a password

Adding a password is very simple, and you must only uncomment this line

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

Now when you try to upload the code, a popup appears and asks you to add a password

Password popup for upload Arduino OTA sketch
Password popup for upload Arduino OTA sketch

You can also verify the process in the console.

Sketch uses 776309 bytes (59%) of program storage space. Maximum is 1310720 bytes.
Global variables use 36448 bytes (11%) of dynamic memory, leaving 291232 bytes for local variables. Maximum is 327680 bytes.
C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0/tools/espota.exe -i 192.168.1.186 -p 3232 --auth=admin -f C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.ino.bin 
Sending invitation to 192.168.1.186 
Authenticating...OK
Uploading............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

Thanks

  1. ESP32: pinout, specs and Arduino IDE configuration
  2. ESP32: integrated SPIFFS Filesystem
  3. ESP32: manage multiple Serial and logging
  4. ESP32 practical power saving
    1. ESP32 practical power saving: manage WiFi and CPU
    2. ESP32 practical power saving: modem and light sleep
    3. ESP32 practical power saving: deep sleep and hibernation
    4. ESP32 practical power saving: preserve data, timer and touch wake up
    5. ESP32 practical power saving: external and ULP wake up
    6. ESP32 practical power saving: UART and GPIO wake up
  5. ESP32: integrated LittleFS FileSystem
  6. ESP32: integrated FFat (Fat/exFAT) FileSystem
  7. ESP32-wroom-32
    1. ESP32-wroom-32: flash, pinout, specs and IDE configuration
  8. ESP32-CAM
    1. ESP32-CAM: pinout, specs and Arduino IDE configuration
    2. ESP32-CAM: upgrade CamerWebServer with flash features
  9. ESP32: use ethernet w5500 with plain (HTTP) and SSL (HTTPS)
  10. ESP32: use ethernet enc28j60 with plain (HTTP) and SSL (HTTPS)
  11. How to use SD card with esp32
  12. esp32 and esp8266: FAT filesystem on external SPI flash memory
  1. Firmware and OTA update management
    1. Firmware management
      1. ESP32: flash compiled firmware (.bin)
      2. ESP32: flash compiled firmware and filesystem (.bin) with GUI tools
    2. OTA update with Arduino IDE
      1. ESP32 OTA update with Arduino IDE: filesystem, firmware, and password
    3. OTA update with Web Browser
      1. ESP32 OTA update with Web Browser: firmware, filesystem, and authentication
      2. ESP32 OTA update with Web Browser: upload in HTTPS (SSL/TLS) with self-signed certificate
      3. ESP32 OTA update with Web Browser: custom web interface
    4. Self OTA uptate from HTTP server
      1. ESP32 self OTA update firmware from the server
      2. ESP32 self OTA update firmware from the server with version check
      3. ESP32 self-OTA update in HTTPS (SSL/TLS) with trusted self-signed certificate
    5. Non-standard Firmware update
      1. ESP32 firmware and filesystem update from SD card
      2. ESP32 firmware and filesystem update with FTP client
  1. Integrating LAN8720 with ESP32 for Ethernet Connectivity with plain (HTTP) and SSL (HTTPS)
  2. Connecting the EByte E70 to ESP32 c3/s3 devices and a simple sketch example
  3. ESP32-C3: pinout, specs and Arduino IDE configuration

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *