This tutorial shows how to do OTA (over-the-air) updates to your ESP32 boards using the ElegantOTA library (V3 version) with Arduino IDE. This library sets up a web server that lets you update the firmware (a new sketch) on your board wirelessly. This way, you don’t need a connection between the ESP32 and your computer to upload a new sketch. This library also allows uploading files to the filesystem (LittleFS or SPIFFS) wirelessly.
By the end of this tutorial, you’ll be able to easily add OTA capabilities to your web server projects with the ESP32 to upload new firmware and files to the filesystem wirelessly in the future.
Table Of Contents
Throughout this tutorial, we’ll cover:
- Add the ElegantOTA feature to your web server
- Upload new firmware via OTA to the ESP32 board
- Upload files to LittleFS via OTA to the ESP32 board
We recommend that you follow all the tutorial steps to understand how the ElegantOTA library works and how you can use it in your projects. To demonstrate how to do this, we’ll upload files to build different web server projects.
ESP32 OTA (Over-the-Air) Programming
OTA (Over-the-Air) update is the process of loading new firmware to the ESP32 board using a Wi-Fi connection rather than a serial communication. This functionality is extremely useful in case of no physical access to the ESP32 board. You don’t need a connection between your computer and the board to upload new code.
There are different ways to perform OTA updates. In this tutorial, we’ll cover how to do that using the ElegantOTA library (version V3 — this is the successor of the deprecated AsyncElegantOTA library). In our opinion, this is one of the best and easiest ways to perform OTA updates.
The ElegantOTA library creates a web server that you can access on your local network to upload new firmware or files to the filesystem (SPIFFS or LittleFS). The files you upload should be in .bin format. We’ll show you later in this tutorial how to convert your files to .bin format.
The only disadvantage of OTA programming is that you need to add the code for OTA in every sketch you upload so that you’re able to use OTA in the future. In case of the ElegantOTA library, it consists of just three lines of code.
ElegantOTA Library
Here are some great features of this library:
- It is compatible with the built-in WebServer.h library and with several forks of the ESPAsyncWebServer library.
- You just need to add three lines of code to add OTA capabilities to your “regular” web server;
- It allows you to update not only new firmware to the board but also files to the ESP32 filesystem (LittleFS or SPIFFS);
- It provides a beautiful and modern web server interface;
- It is available as a pro paid version that adds more features.
OTA Updates with the ElegantOTA Library – Quick Summary
To add OTA capabilities to your projects using the ElegantOTA library, follow these steps:
1) Install the ElegantOTA, AsyncTCP, and ESPAsyncWebServer libraries;
2) Include ElegantOTA library at the top of the Arduino sketch:
#include <ElegantOTA.h>;
3) Add the following line in the setup before server.begin();
ElegantOTA.begin(&server);
4) In the loop(), add the following line:
ElegantOTA.loop();
5) Open your browser and go to http://<IPAddress>/update, where <IPAddress> is your ESP32 IP address to access the web server page for the OTA updates.
Continue reading the tutorial for more detailed steps.
How does OTA Web Updater Work?
The first sketch must be uploaded using a serial connection. This sketch should include the code to set up the OTA Web Updater, allowing you to upload new sketches through a web browser.
The OTA Web Updater creates a web server where you can upload sketches wirelessly.
If your code doesn’t include an OTA routine, you won’t be able to use the web server to upload new sketches wirelessly.
After that, make sure every sketch you upload includes OTA routines so you can continue updating the board wirelessly in the future.
Installing the ElegantOTA Library
To install the ElegantOTA library in the Arduino IDE go to Sketch > Include Library > Manage Libraries, search for ElegantOTA and install the ElegantOTA library by Ayush Sharma.
Enabling Async Mode
For the ElegantOTA library to work in async mode (with the ESPAsyncWebServer library), you need to do the following procedure.
1) Go to your Arduino libraries directory.
2) Open the ElegantOTA folder and then open the src folder.
3) Locate the ELEGANTOTA_USE_ASYNC_WEBSERVER macro in the ElegantOTA.h file, and set it to 1 as follows:
#define ELEGANTOTA_USE_ASYNC_WEBSERVER 1
4) Save the changes to the ElegantOTA.h file.
5) Now you can use the ElegantOTA in async mode for your OTA updates and with the ESPAsyncWebServer library.
Install AsyncTCP and ESPAsyncWebServer Libraries
To test the examples in this tutorial, you also need to install the AsyncTCP and the ESPAsyncWebServer libraries.
Note: the ElegantOTA library works with different forked versions of the ESPAsyncWebServer and the AsyncTCP web server libraries, so you don’t necessarily need to use the same ones that we’re using.
Follow the next instructions to install those libraries.
Click the links below to download the libraries’ .zip folders.
These libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library .zip files to the Arduino Installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the libraries you’ve just downloaded.
ElegantOTA ESP32 Basic Example
Let’s start with a basic example (based on one of the library’s examples). The following code creates a simple web server with the ESP32. The root URL displays some text, and the /update URL displays the interface to update the firmware and the filesystem.
Copy the following code to your Arduino IDE.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-ota-elegantota-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Softwar
*********/
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
AsyncWebServer server(80);
void setup(void) {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain", "Hi! I am ESP32.");
});
server.begin();
Serial.println("HTTP server started");
ElegantOTA.begin(&server); // Start ElegantOTA
}
void loop(void) {
ElegantOTA.loop();
}
Insert your network credentials and the code should work straight away.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
How Does the Code Work?
Start by including the required libraries.
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>
Insert your network credentials in the following variables so that the ESP32 can connect to the Wi-Fi on your local network.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Create an AsyncWebServer object on port 80:
AsyncWebServer server(80);
In the setup(), initialize the Serial Monitor:
Serial.begin(115200);
Initialize Wi-Fi:
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Then, handle the client requests. The following lines, send some text Hi! I am ESP32. when you access the root (/) URL:
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain", "Hi! I am ESP32.");
});
If your web server needs to handle more requests you can add them (we’ll show you in the next example).
Initialize the server:
server.begin();
Then, add the next line to start ElegantOTA:
ElegantOTA.begin(&server); // Start ElegantOTA
In the loop(), add the following line:
ElegantOTA.loop();
Accessing the Web Server
After uploading code to the board, open the Serial Monitor at a baud rate of 115200. Press the ESP32 on-board RST button. It should display the ESP IP address as follows (yours may be different):
In your local network, open your browser and type the ESP32 IP address. You should get access the root (/) web page with some text displayed.
Now, if you want to modify your web server code via OTA, go to the ESP IP address followed by /update. The following web page should load.
To upload new code to your board or files to the filesystem, you need to upload them in .bin format. Follow the next section to learn how to generate a .bin file from your sketch in Arduino IDE.
Upload New Code to the ESP32 via OTA
Every file that you upload via OTA should be in .bin format. You can generate a .bin file from your sketch using the Arduino IDE.
With your sketch opened, you just need to select the ESP32 board you’re using in Tools > Board, and then go to Sketch > Export Compiled Binary. A .bin file will be generated from your sketch.
The generated file will be saved under your project folder inside a series of other folders. The file with the .ino.bin extension is the one you should upload to your board using the ElegantOTA web page.
Upload a New Web Server Sketch via OTA – Example
Imagine that after uploading the previous sketch, you want to upload a new one that allows you to control an LED via a web interface like this project. Here’s the steps you need to follow:
1. Copy the following code to your Arduino IDE. Don’t forget to insert your network credentials.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-ota-elegantota-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Softwar
*********/
// Import required libraries
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
bool ledState = 0;
const int ledPin = 2;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>
html {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
h1 {
font-size: 1.8rem;
color: white;
}
h2{
font-size: 1.5rem;
font-weight: bold;
color: #143642;
}
.topnav {
overflow: hidden;
background-color: #143642;
}
body {
margin: 0;
}
.content {
padding: 30px;
max-width: 600px;
margin: 0 auto;
}
.card {
background-color: #F8F7F9;;
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
padding-top:10px;
padding-bottom:20px;
}
.button {
padding: 15px 50px;
font-size: 24px;
text-align: center;
outline: none;
color: #fff;
background-color: #0f8b8d;
border: none;
border-radius: 5px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
/*.button:hover {background-color: #0f8b8d}*/
.button:active {
background-color: #0f8b8d;
box-shadow: 2 2px #CDCDCD;
transform: translateY(2px);
}
.state {
font-size: 1.5rem;
color:#8c8c8c;
font-weight: bold;
}
</style>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
<div class="topnav">
<h1>ESP WebSocket Server</h1>
</div>
<div class="content">
<div class="card">
<h2>Output - GPIO 2</h2>
<p class="state">state: <span id="state">%STATE%</span></p>
<p><button id="button" class="button">Toggle</button></p>
</div>
</div>
<script>
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener('load', onLoad);
function initWebSocket() {
console.log('Trying to open a WebSocket connection...');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage; // <-- add this line
}
function onOpen(event) {
console.log('Connection opened');
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
function onMessage(event) {
var state;
if (event.data == "1"){
state = "ON";
}
else{
state = "OFF";
}
document.getElementById('state').innerHTML = state;
}
function onLoad(event) {
initWebSocket();
initButton();
}
function initButton() {
document.getElementById('button').addEventListener('click', toggle);
}
function toggle(){
websocket.send('toggle');
}
</script>
</body>
</html>)rawliteral";
void notifyClients() {
ws.textAll(String(ledState));
}
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
AwsFrameInfo *info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
data[len] = 0;
if (strcmp((char*)data, "toggle") == 0) {
ledState = !ledState;
notifyClients();
}
}
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
void *arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
handleWebSocketMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
void initWebSocket() {
ws.onEvent(onEvent);
server.addHandler(&ws);
}
String processor(const String& var){
Serial.println(var);
if(var == "STATE"){
if (ledState){
return "ON";
}
else{
return "OFF";
}
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
initWebSocket();
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
// Start server
server.begin();
ElegantOTA.begin(&server); // Start ElegantOTA
}
void loop() {
ws.cleanupClients();
digitalWrite(ledPin, ledState);
ElegantOTA.loop();
}
This is the same code used in this project, but it contains the needed lines of code to handle ElegantOTA:
#include <ElegantOTA.h>
ElegantOTA.begin(&server);
ElegantOTA.loop();
2. Save your sketch: File > Save and give it a name. For example: Web_Server_LED_OTA_ESP32.
3. Generate a .bin file from your sketch. First, select the board model you’re using in Tools > Board. Then, go to Sketch > Export Compiled Binary.
Go to your sketch folder. You should have a build folder. Inside that folder, you’ll have another folder related to your board model. Open that folder. There’ll be several files. You should upload the file with the ino.bin extension.
4. Now, you need to upload that file using the ElegantOTA page. Go to your ESP IP address followed by /update. Make sure you have the firmware option selected. Click on Choose File and select the .ino.bin file you’ve just generated.
5. After a few seconds, you should get a success message. Then, click on the Back button.
6. Now, you can go to the root (/) URL to access the new web server. This is the page you should see when you access the ESP IP address on the root (/) URL.
You can click on the button to turn the ESP32 on-board LED on and off.
Because we’ve also added OTA capabilities to this new web server, we can upload a new sketch in the future if needed. You just need to go to the ESP32 IP address followed by /update.
Congratulations, you’ve uploaded new code to your ESP32 via Wi-Fi using ElegantOTA.
Continue reading if you want to learn how to upload files to the ESP32 filesystem (LittleFS) using the ElegantOTA library.
Upload Files to Filesystem via OTA to the ESP32
In this section you’ll learn to upload files to the ESP32 filesystem (LittleFS) using the ElegantOTA library.
ESP32 Filesystem Uploader Plugin
Before proceeding, you need to have the ESP32 Filesystem Uploader Plugin installed in your Arduino IDE. Follow the next tutorial before proceeding:
Web Server with Files from LittleFS
Imagine the scenario that you need to upload files to the ESP32 filesystem, for example: configuration files; HTML, CSS and JavaScript files to update the web server page; or any other file that you may want to save in the LittleFS filesystem via OTA.
To show you how to do this, we’ll create a new web server that serves files from LittleFS: HTML, and CSS files to build a web page that controls the ESP32 built-in LED remotely using a different interface.
Copy the following code to your Arduino IDE.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-ota-elegantota-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Softwar
*********/
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "LittleFS.h"
#include <ElegantOTA.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Set LED GPIO
const int ledPin = 2;
// Stores LED state
String ledState;
// Initialize LittleFS
void initLittleFS() {
if (!LittleFS.begin(true)) {
Serial.println("An error has occurred while mounting LittleFS");
}
else {
Serial.println("LittleFS mounted successfully");
}
}
// Initialize WiFi
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
// Replaces placeholder with LED state value
String processor(const String& var) {
if(var == "STATE") {
if(digitalRead(ledPin)) {
ledState = "ON";
}
else {
ledState = "OFF";
}
return ledState;
}
return String();
}
void setup() {
Serial.begin(115200);
initWiFi();
initLittleFS();
// Set GPIO2 as an OUTPUT
pinMode(2, OUTPUT);
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(LittleFS, "/index.html", "text/html", false, processor);
});
server.serveStatic("/", LittleFS, "/");
// Route to set GPIO state to HIGH
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request) {
digitalWrite(ledPin, HIGH);
request->send(LittleFS, "/index.html", "text/html", false, processor);
});
// Route to set GPIO state to LOW
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request) {
digitalWrite(ledPin, LOW);
request->send(LittleFS, "/index.html", "text/html", false, processor);
});
// Start server
server.begin();
ElegantOTA.begin(&server); // Start ElegantOTA
}
void loop() {
ElegantOTA.loop();
}
Note: this example is covered and explained in our eBook: Build Web Severs with the ESP32 and ESP8266.
Insert your network credentials in the following variables and save the code.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Update Firmware
Create a .ino.bin file from this sketch as shown previously (this sketch also includes the needed lines of code to provide OTA capabilities).
Go to the ESP32 IP address followed by /update and upload the new firmware.
Next, we’ll see how to upload the files.
Update the Filesystem
Under the project folder, create a folder called data and move the following HTML and CSS files (click on the links to download the files):
To find your project folder, you can simply go to Sketch > Show Sketch Folder.
This is the folder structure of your project and where the data folder should be located:
- Web_Server_OTA_ESP32_Example_2
- data
- style.css
- index.html
- Web_Server_OTA_ESP32_Example_2.ino
- build
- esp32.es32.esp32doit-devkit-v1 (or similar depending on the selected board)
- Web_Server_OTA_ESP32_Example_2.ino.bin
- esp32.es32.esp32doit-devkit-v1 (or similar depending on the selected board)
- data
After this, with the ESP32 disconnected from your computer (that’s the whole purpose of OTA), let’s pretend we’ll upload the files to the filesystem. Press [Ctrl] + [Shift] + [P] to open the command palette. An instruction called ‘Upload Little FS to Pico/ESP8266/ESP32‘ should be there (just scroll down or search for the name of the instruction).
If you don’t have that option, it means you don’t have the Filesystem Uploader Plugin installed in your Arduino IDE. Follow the next tutorial to install it: Arduino IDE 2: Install ESP32 LittleFS Uploader (Upload Files to the Filesystem).
You’ll get an error because there isn’t any ESP32 board connected to your computer – don’t worry. It will still create a .bin file from the data folder.
On the debugging window you’ll see the .littlefs.bin file location. That’s that file that you should upload (in our case the file is called tmp-29172-heLR8chx1V9e-.littlefs.bin.
In our case, this is the path where that file is located:
C:\Users\sarin\AppData\Local\Temp\tmp-29172-heLR8chx1V9e-.littlefs.bin.
Find that file in your computer.
To make things easier, you can copy that file to your project folder.
Now that we have a .litlefs.bin file from the data folder, we can upload that file. Go to your ESP32 IP address followed by /update. Make sure you have the Filesystem option selected in the OTA Mode option.
Then, select the file with the .littlefs.bin extension.
After successfully uploading, click the Back button. And go to the root (/) URL again. You should get access to the following web page that controls the ESP32 built-in LED with two buttons.
If you need to update something on your project, you just need to go to your ESP32 IP address followed by /update.
Congratulations! You’ve successfully uploaded files to the ESP32 filesystem using the ElegantOTA library.
Wrapping Up
In this tutorial you’ve learned how to add OTA capabilities to your Async Web Server projects using the ElegantOTA library. This library is straightforward to use—you just need to add three lines of code to your project.
Additionally, this library also allows you to upload new firmware or files to the LittleFS filesystem effortlessly using a web page.
We hope you’ve found this tutorial useful.
Learn more about the ESP32 with our resources:
- Learn ESP32 with Arduino IDE (eBook)
- Build ESP32 Web Servers with Arduino IDE (eBook)
- More ESP32 Projects and Tutorials…
Thanks for reading.
Thank you all for publishing this Very interesting subject. Ofcourse I will try it.
The only remark I have is that a third party like “ElegantOta” will be involved in our, sometimes privacy related, ESP- projects. In my case I prefer to setup an Ftp- server/client for remotely update sketches or scripts to my ESP- boards.
Anyhow thank you very much for ALL of your effort in publishing these interesting projects!!
Alex
Hi , in order to integrate this code to mine , should I change this define ELEGANTOTA_USE_ASYNC_WEBSERVER 1 again ? Or I might move src file to my project file. I also want to define the functions that initialize the sensors in a separate source file to improve the readability of the code. Then I can include that file like #include “file.h”. What can you suggest for this?
Thanks for your efforts.
– Ugur
I would be interested about, why this code does not run on esp32-s3 ?
Hi.
What’s the issue you get on your board?
Regards,
Sara
assert failed: tcp_alloc /IDF/components/lwip/lwip/src/core/tcp.c:1851 (Required to lock TCPIP core functionality!)
Backtrace: 0x403764ce:0x3fca9720 0x4037cc2d:0x3fca9740 0x40383621:0x3fca9760 0x42022a1b:0x3fca9890 0x42022b85:0x3fca98b0 0x420059c4:0x3fca98d0 0x4200b712:0x3fca9920 0x42002c86:0x3fca9940 0x4200f75f:0x3fca9980 0x4037d91a:0x3fca99a0
ELF file SHA256: bdf4fae64
Rebooting…
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x2b (SPI_FAST_FLASH_BOOT)
Saved PC:0x4037a8f6
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x1188
load:0x403c8700,len:0x4
load:0x403c8704,len:0xbf0
load:0x403cb700,len:0x30e4
entry 0x403c88ac
There is an issue with current version of ESP32 core 3.1.0.
Please downgrade to 3.0.7.
That should solve the issue.
Regards,
Sara
If its any help, I have had this same ‘Assert’ failure using the Arduino IDE 1.8.19, and spent many hours trying to find a suitable solution. Eventually, I used the Arduino 2 IDE, and the same code compiled with no problems.
Hi !! Did all changes, it keeps rebooting once and again. ESP32WROOM DA module. Any idea ?
Thanks !
should be very helpful.
Will this work with ESPNow running on two ESP32s?
I am using ESPNow to send and receive data to and from the two micros.
Thank you
Hi Sara,
thanks for your nice OTA code. I have been following your instructions including downgrading to the esp 3.0.7 version. But i get this awful message while compiling:
cannot convert ‘AsyncWebServer‘ to ‘WebServer‘
This message refers to the line
ElegantOTA.begin(&server); // Start ElegantOTA
Any idea which bloody mistake I’m making?
Thank for any help
Hans
Hi.
Please read all the instructions.
You missed this section of the tutorial: Enabling Async Mode
Regards,
Sara
Hello Sara,
please accept my deep thanks. Indeed, I missed to change the library setting. And now everything works fine.
Since long I have an ESP32 in my garden as wheater station, transmitting the data to my portable phone. Now it’s much easier to make any changes.
By the way: The ESP actually operates in deep sleep mode waking up every 30 min. If I add for instance a 30 sec waiting time after data transmission, may I update during that period?
Have a wonderful Christmas time
Best regards from Germany
Hans
Hi.
Yes. If you can send the new sketch before the board goes to sleep again.
Regards,
Sara
If you include the ElegantOTA.h file, it has code to include <AsyncTCP.h> and
<ESPAsyncWebServer.h>, so there is no need to #include these at the start of your own code.
Hello !
I integrated my sketch with ElegantOTA and started the web server, it gives IP 192.168.1.133. I can access the server using my Android tablet (192.168.1.133/update) shows the OTA update screen. However using my PC (where my bins are) browser just cannot connect to the server. I have tested Firefox and Brave, and also typing http://192.168.1.133/update, no success. What is the problem ?
Is it some browser setting or should I modify my sketch ?
Hi.
What do you get when you try to access the web server on your browser?
Have you tried Google Chrome?
Is your computer on the same network?
Regards,
Sara
Thanks Sara,
my Android devices and ESP32 are connected to Wifi-router (same network) but the PC was connected vai Ethernet cable (for speed), this is not same network, (I didn’t know this). When PC is connected wirelessy,
it works as excepted !
Thanks and Merry Christmas for you in RNT !!
Keep going for your excellent tutorials
Great.
I’m glad we found the issue,
Thank you and Merry Christmas for you too.
Regards,
Sara
Hello Heikki,
sometimes I experience the same problem.
My hint:
make sure that your browser OPENS the site and is not searching the site.
Rgds Hans
Hello,
I have two problems with running the two examples shown.
1. In the first example “ElegantOTA ESP32 Basic Example”
I cannot connect to my WLAN (name and password → OK)
2. In the second example “Upload a New Web Server Sketch via OTA – Example”
I get the following error messages when compiling:
E:\MeineProgramme\Arduino_Uno\ESP32_OTA\ESP32_OTA_02\ESP32_OTA_02.ino: In function ‘void onEvent(AsyncWebSocket*, AsyncWebSocketClient*, AwsEventType, void*, uint8_t*, size_t)’:
E:\MeineProgramme\Arduino_Uno\ESP32_OTA\ESP32_OTA_02\ESP32_OTA_02.ino:171:21: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘uint32_t’ {aka ‘long unsigned int’} [-Wformat=]
171 | Serial.printf(“WebSocket client #%u connected from %s\n”, client->id(), client->remoteIP().toString().c_str());
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~
| |
| uint32_t {aka long unsigned int}
E:\MeineProgramme\Arduino_Uno\ESP32_OTA\ESP32_OTA_02\ESP32_OTA_02.ino:174:21: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘uint32_t’ {aka ‘long unsigned int’} [-Wformat=]
174 | Serial.printf(“WebSocket client #%u disconnected\n”, client->id());
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~
| |
| uint32_t {aka long unsigned int}
E:\MeineProgramme\Arduino_Uno\ESP32_OTA\ESP32_OTA_02\ESP32_OTA_02.ino: In lambda function:
E:\MeineProgramme\Arduino_Uno\ESP32_OTA\ESP32_OTA_02\ESP32_OTA_02.ino:224:18: error: no matching function for call to ‘AsyncWebServerRequest::send(int, const char [10], const char [2845], String (&)(const String&))’
224 | request->send(200, “text/html”, index_html, processor);
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from E:\MeineProgramme\Arduino_Uno\ESP32_OTA\ESP32_OTA_02\ESP32_OTA_02.ino:14:
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:241:10: note: candidate: ‘void AsyncWebServerRequest::send(const String&, size_t, AwsResponseFiller, AwsTemplateProcessor)’
241 | void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
| ^~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:241:72: note: no known conversion for argument 3 from ‘const char [2845]’ to ‘AwsResponseFiller’ {aka ‘std::function’}
241 | void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
| ~~~~~~~~~~~~~~~~~~^~~~~~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:240:10: note: candidate: ‘void AsyncWebServerRequest::send(Stream&, const String&, size_t, AwsTemplateProcessor)’
240 | void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
| ^~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:240:23: note: no known conversion for argument 1 from ‘int’ to ‘Stream&’
240 | void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
| ~~~~~~~~^~~~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:238:10: note: candidate: ‘void AsyncWebServerRequest::send(FS&, const String&, const String&, bool, AwsTemplateProcessor)’
238 | void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
| ^~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:238:19: note: no known conversion for argument 1 from ‘int’ to ‘AsyncWebServerRequest::FS&’ {aka ‘fs::FS&’}
238 | void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
| ~~~~^~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:236:10: note: candidate: ‘void AsyncWebServerRequest::send(AsyncWebServerResponse*)’
236 | void send(AsyncWebServerResponse *response);
| ^~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:236:10: note: candidate expects 1 argument, 4 provided
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:237:10: note: candidate: ‘void AsyncWebServerRequest::send(int, const String&, const String&)’
237 | void send(int code, const String& contentType=String(), const String& content=String());
| ^~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:237:10: note: candidate expects 3 arguments, 4 provided
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:239:10: note: candidate: ‘void AsyncWebServerRequest::send(File, const String&, const String&, bool, AwsTemplateProcessor)’
239 | void send(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
| ^~~~
e:\MeineProgramme\Arduino_Uno\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:239:20: note: no known conversion for argument 1 from ‘int’ to ‘AsyncWebServerRequest::File’ {aka ‘fs::File’}
239 | void send(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
| ~~~~~^~~~~~~
Compilation error: no matching function for call to ‘AsyncWebServerRequest::send(int, const char [10], const char [2845], String (&)(const String&))’
Kind Regards
Juergen
Hello,
I use:
Arduino IDE 2.3.4
ESP32 V3.1.0 von Espressif
Device: ESP32 Dev Module
Juergen
Hi.
Downgrade the ESP32 boards version to 3.0.7 and try again.
Let me know if this fixes the issue.
Regards,
Sara
Hi,
During the compilation of the code included in: “Upload a New Web Server Sketch via OTA – Example”, I got following message:
“no matching function for call to ‘AsyncWebServerRequest::send(int, const char [10], const char [2845], String (&)(const String&))’ “
What is wrong, please? My version of Arduino IDE is 1.8.12.
Thank you
Milan
Hi.
Check the version of your libraries and the ESP32 core.
I also recommend doing the upgrade for Arduino IDE 2.
Regards,
Sara
To avoid the error change this line
request->send(200, “text/html”, index_html, processor);
to
request->send(200, “text/html”, index_html);
To see the status as soon as you load the page add the line “notifyClients();” to the case WS_EVT_CONNECT.
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
notifyClients();
break;
Hello,
I have downgrade the ESP32 boards to the version 3.07 but with this I have the same
problems.
Kind Regards
Juergen
Hello,
In the second example “Upload a New Web Server Sketch via OTA – Example“
I get the following error message when compiling:
With the program code:
// Route for root / web page
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, “text/html”, index_html, processor);
});
in the function “void setup()“
I get the message:
Compilation error: no matching function for call to ‘AsyncWebServerRequest::send(int, const char [10], const char [2845], String (&)(const String&))’
I use.
OS = WINDOWS 11
Arduino IDE v 2.3.2
LIB’s: AsyncTCP, ESPAsyncWebServer from the website
ESP32 boards v3.07
Juergen
To avoid the error change this line
request->send(200, “text/html”, index_html, processor);
to
request->send(200, “text/html”, index_html);
To see the status as soon as you load the page add the line “notifyClients();” to the case WS_EVT_CONNECT.
case WS_EVT_CONNECT:
Serial.printf(“WebSocket client #%u connected from %s\n”, client->id(), client->remoteIP().toString().c_str());
notifyClients();
break;
Hello,
thank you very much for the changes shown, so I can compile the sketch and perform an update.
Kind Regards
Juergen
i was thinking that version 2 works fine and version 3 includes upgrade messages to pro which doesn’t look very appealing though its understandable. What would be the concrete advantage to go to version 3 of the library?
Hi melt, Ayush here – author of ElegantOTA. It does have a lot of improvements and I’m happy to share the following key points:
Version 3 apart from new UI has bug fixes related to stability of OTA updates as reported by a few users.
It has built-in upload MAC validation so any kind of corruption while uploading your OTA file will be detected which prevents bricking your devices.
You also now have callbacks: onStart, onProgress and onEnd, which can be used to perform certain tasks based on your application. For example, updating the LCD etc.(docs.elegantota.pro/features/callbacks)
thank you for the info! and thank you for ur great work ! out of curiosity, how much time ur computer needs to compile the library? is it also for you about 2 minutes?
You’re welcome! It’s about 1 minute when compiling with Arduino IDE and 30 seconds on PlatformIO. This is totally dependent on how powerful is your PC.
oh didn’t know platformIO builds faster thank you very much! have a nice weekend!
I run OTA projects under Arduino IDE2. And it works, but there is a problem.
When I try to remotely upload subsequent file corrections in the ‘DATA’ directory to the ESP, it can only be done once.
After compiling the corrected project with the export function,
When I call the ‘CTLR+SHIFT+P’ function again,
No new file appears in C:\Users\PC\AppData\Local\Temp\xxx.littlefs.bin
I only get the message:
“LittleFS Filesystem Uploader v1.5.3 — github.com/earlephilhower/arduino-littlefs-upload
Sketch Path: C:\Users\PC\Documents\Arduino_ESP32_folder\ESP32_controllery_input\edit____ESP32__inp_mil_email_ota_181\controllerEmail
Data Path: C:\Users\PC\Documents\Arduino_ESP32_folder\ESP32_controllery_input\edit____ESP32__inp_mil_email_ota_181\controllerEmail\data
Device: ESP32 series, model esp32
Using partition: default
Partitions: C:\Users\PC\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.17\tools\partitions\default.csv
Start: 0x290000
End: 0x3f0000
ERROR: No port specified, check IDE menus.”
My question is why the file can’t be generated again. Does this version of ElegantOTA work like that? Where could the error be?
I spent many hours, made dozens of attempts to compile ‘data’ files. My conclusion is as follows.
As long as the Arduino platform is open, you can modify files in the data directory, compile them and send them remotely to the ESP board. However, if the Arduino is closed and reopened, the remote data file transfer function is canceled. And then you have to reconnect the ESP to the computer with a cable and repeat the steps again.
Hello and thank you for the description.
My project worked until today.
Suddenly, after downloading to the ESP32 dev module, I get the following message in the serial monitor:
assert failed: tcp_alloc /IDF/components/lwip/lwip/src/core/tcp.c:1851 (Required to lock TCPIP core functionality!)
Backtrace: 0x400826e9:0x3ffb1fc0 0x4008d23d:0x3ffb1fe0 0x4009359e:0x3ffb2000 0x400fa4ff:0x3ffb2130 0x400fa679:0x3ffb2150 0x400daa60:0x3ffb2170 0x400e08fe:0x3ffb21c0 0x400d3c6a:0x3ffb21e0 0x400e592f:0x3ffb2270 0x4008e372:0x3ffb2290
So far I haven’t had any problems.
The program hasn’t been changed!
I use Arduino IDE 2.3.3
AsyncTCP from dvarrel 1.1.1
ESP Async WebServer from Me-No-Dev 1.2.4
Best regards
Volker
Hi.
That’s currently an issue with the recent version of the ESP32 core.
Downgrade to version 3.0.7. Go to Tools > Boards > Boards Manager > ESP32 and downgrade to version 3.0.7.
It should solve that issue.
Regards,
Sara