2020/04/07

ESP32 - OTA firmware update using Arduino IDE

This post is a quick write up of me following the instructions provided by G6EJD on how to do OTA firmware from inside Arduino IDE.

His instruction video can be found at the link below:

https://www.youtube.com/watch?time_continue=1&v=lQavz_U8nd4&feature=emb_logo

Here is the link to his GitHub page for this project: https://github.com/G6EJD/ESP32-OTA-Example

The Arduino Sketch

Two files are needed for this: "ESP32_Basic_OTA.ino", and "credentials.h".

ESP32_Basic_OTA.ino

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

void setup(){
  // Setup needed for OTA
  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);
  });
  ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.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());
 //  My setup onwards
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  ArduinoOTA.handle();
  yield();
  // Your programme loop from here
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(100);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(100);                       // wait for a second
  // End of your programme loop
}

credentials.h

Note, be sure to change the said and password to that of your wifi network.

// Change to your WiFi credentials
const char* ssid     = "SSID";
const char* password = "Password";

Compile and upload the sketch to your ESP32 via the USB to serial link like you usually do with your other ESP32 projects. There is no need to burn special OTA bootloader to the ESP32 module before the upload.

Below is the output from the message window of the Arduino IDE.

Sketch uses 740194 bytes (56%) of program storage space. Maximum is 1310720 bytes.
Global variables use 42440 bytes (12%) of dynamic memory, leaving 285240 bytes for local variables. Maximum is 327680 bytes.
esptool.py v2.6
Serial port COM4
Connecting........_____....._____.
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 80:7d:3a:d5:3a:68
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47...

Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 3640.9 kbit/s)...
Hash of data verified.
Compressed 15328 bytes to 9994...

Writing at 0x00001000... (100 %)
Wrote 15328 bytes (9994 compressed) at 0x00001000 in 0.9 seconds (effective 136.9 kbit/s)...
Hash of data verified.
Compressed 740304 bytes to 414966...

Writing at 0x00010000... (3 %)
Writing at 0x00014000... (7 %)
Writing at 0x00018000... (11 %)
Writing at 0x0001c000... (15 %)
Writing at 0x00020000... (19 %)
Writing at 0x00024000... (23 %)
Writing at 0x00028000... (26 %)
Writing at 0x0002c000... (30 %)
Writing at 0x00030000... (34 %)
Writing at 0x00034000... (38 %)
Writing at 0x00038000... (42 %)
Writing at 0x0003c000... (46 %)
Writing at 0x00040000... (50 %)
Writing at 0x00044000... (53 %)
Writing at 0x00048000... (57 %)
Writing at 0x0004c000... (61 %)
Writing at 0x00050000... (65 %)
Writing at 0x00054000... (69 %)
Writing at 0x00058000... (73 %)
Writing at 0x0005c000... (76 %)
Writing at 0x00060000... (80 %)
Writing at 0x00064000... (84 %)
Writing at 0x00068000... (88 %)
Writing at 0x0006c000... (92 %)
Writing at 0x00070000... (96 %)
Writing at 0x00074000... (100 %)
Wrote 740304 bytes (414966 compressed) at 0x00010000 in 36.9 seconds (effective 160.4 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 144...

Writing at 0x00008000... (100 %)
Wrote 3072 bytes (144 compressed) at 0x00008000 in 0.0 seconds (effective 983.0 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

After the upload is completed, the built-in LED of the ESP32 module starts flashing almost immediately.

Below is the output of the Serial Monitor.

At the end of the output message, you could see the IP address assigned to the ESP32 module by your WiFi Router.


Restart your Arduino IDE, then go to "Tools" -> "Port". A new option is now available for you to upload firmware from the Arduino IDE to the ESP32 module via the wireless network.


Testing the OTA capability

1. Unplug ESP32 from your computer and plug it to a phone charger to provide power to the ESP32.

2. In the Arduino sketch, change the delay time from 100 to 1000 as highlighted below.

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

void setup(){
  // Setup needed for OTA
  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);
  });
  ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.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());
 //  My setup onwards
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  ArduinoOTA.handle();
  yield();
  // Your programme loop from here
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  //delay(100);                       // wait for a second
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  //delay(100);                       // wait for a second
  delay(1000);
  // End of your programme loop
}

3. Select the network port as the communication interface between the Arduino IDE and the ESP32 module.


4. Compile and upload the firmware to the ESP32 module.

Be sure to allow "espota.exe" to access the network if it's blocked by Windows firewall.


If all goes well, the new firmware will be uploaded to the ESP32 module wirelessly and the flashing of the LED will slow down after the upload is completed.


Reference:

Tech Note 082 - ESP32 Over-the-Air (OTA) Updating
https://www.youtube.com/watch?time_continue=1&v=lQavz_U8nd4&feature=emb_logo

An example of using the OTA function of the ESP32
https://github.com/G6EJD/ESP32-OTA-Example

No comments:

Post a Comment