Quick guide that shows how to do over-the-air (OTA) programming with the ESP32 using the OTA Web Updater in Arduino IDE. The OTA Web Updater allows you to update/upload new code to your ESP32 using a browser, without the need to make a serial connection between the ESP32 and your computer.
OTA programming is useful when you need to update code to ESP32 boards that are not easily accessible. The example we’ll show here works when the ESP32 and your browser are on your local network.
The only disadvantage of the OTA Web Updater is that you have to add the code for OTA in every sketch you upload, so that you’re able to use OTA in the future.
How does OTA Web Updater Work?
- The first sketch should be uploaded via serial port. This sketch should contain the code to create the OTA Web Updater, so that you are able to upload code later using your browser.
- The OTA Web Updater sketch creates a web server you can access to upload a new sketch via web browser.
- Then, you need to implement OTA routines in every sketch you upload, so that you’re able to do the next updates/uploads over-the-air.
- If you upload a code without a OTA routine you’ll no longer be able to access the web server and upload a new sketch over-the-air.
Prerequisites
Before proceeding with this tutorial you should have the ESP32 add-on installed in your Arduino IDE. Follow one of the next tutorials to install the ESP32 on the Arduino IDE, if you haven’t already.
- Installing the ESP32 Board in Arduino IDE (Windows instructions)
- Installing the ESP32 Board in Arduino IDE (Mac and Linux instructions)
ESP32 OTA Web Updater
When you install the ESP32 add-on for the Arduino IDE, it will automatically install the ArduinoOTA library. Go to File > Examples >ArduinoOTA> OTAWebUpdater.
The following code should load.
/*
* OTAWebUpdater.ino Example from ArduinoOTA Library
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
const char* host = "esp32";
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
WebServer server(80);
/*
* Login page
*/
const char* loginIndex =
"<form name='loginForm'>"
"<table width='20%' bgcolor='A09F9F' align='center'>"
"<tr>"
"<td colspan=2>"
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
"<br>"
"</td>"
"<br>"
"<br>"
"</tr>"
"<td>Username:</td>"
"<td><input type='text' size=25 name='userid'><br></td>"
"</tr>"
"<br>"
"<br>"
"<tr>"
"<td>Password:</td>"
"<td><input type='Password' size=25 name='pwd'><br></td>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
"</tr>"
"</table>"
"</form>"
"<script>"
"function check(form)"
"{"
"if(form.userid.value=='admin' && form.pwd.value=='admin')"
"{"
"window.open('/serverIndex')"
"}"
"else"
"{"
" alert('Error Password or Username')/*displays error message*/"
"}"
"}"
"</script>";
/*
* Server Index Page
*/
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
/*
* setup function
*/
void setup(void) {
Serial.begin(115200);
// Connect to WiFi network
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());
/*use mdns for host name resolution*/
if (!MDNS.begin(host)) { //http://esp32.local
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
/*return index page which is stored in serverIndex */
server.on("/", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", loginIndex);
});
server.on("/serverIndex", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
/*handling uploading firmware file */
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
});
server.begin();
}
void loop(void) {
server.handleClient();
delay(1);
}
You should change the following lines on the code to include your own network credentials:
const char* ssid = ""; const char* password = "";
The OTAWebUpdater example for the ESP32 creates an asynchronous web server where you can upload new code to your board without the need for a serial connection.
Upload the previous code to your ESP32 board. Don’t forget to enter your network credentials and select the right board and serial port.
After uploading the code, open the Serial Monitor at a baud rate of 115200, press the ESP32 enable button, and you should get the ESP32 IP address:
Now, you can upload code to your ESP32 over-the-air using a browser on your local network.
To test the OTA Web Updater you can disconnect the ESP32 from your computer and power it using a power bank, for example (this is optional, we’re suggesting this to mimic a situation in which the ESP32 is not connected to your computer).
Update New Code using OTA Web Updater
Open a browser in your network and enter the ESP32 IP address. You should get the following:
Enter the username and the password:
- Username: admin
- Password: admin
You can change the username and password on the code.
Note: After you enter the username and password, you are redirected to the /serverIndex URL. You don’t need to enter the username and password to access the /serverIndex URL. So, if someone knows the URL to upload new code, the username and password don’t protect the web page from being accessible from others.
A new tab should open on the /serverIndex URL. This page allows you to upload a new code to your ESP32. You should upload .bin files (we’ll see how to do that in a moment).
Preparing the New Sketch
When uploading a new sketch over-the-air, you need to keep in mind that you need to add code for OTA in your new sketch, so that you can always overwrite any sketch with a new one in the future. So, we recommend that you modify the OTAWebUpdater sketch to include your own code.
For learning purposes let’s upload a new code that blinks an LED (without delay). Copy the following code to your Arduino IDE.
/*
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
const char* host = "esp32";
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
//variabls to blink without delay:
const int led = 2;
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 1000; // interval at which to blink (milliseconds)
int ledState = LOW; // ledState used to set the LED
WebServer server(80);
/*
* Login page
*/
const char* loginIndex =
"<form name='loginForm'>"
"<table width='20%' bgcolor='A09F9F' align='center'>"
"<tr>"
"<td colspan=2>"
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
"<br>"
"</td>"
"<br>"
"<br>"
"</tr>"
"<td>Username:</td>"
"<td><input type='text' size=25 name='userid'><br></td>"
"</tr>"
"<br>"
"<br>"
"<tr>"
"<td>Password:</td>"
"<td><input type='Password' size=25 name='pwd'><br></td>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
"</tr>"
"</table>"
"</form>"
"<script>"
"function check(form)"
"{"
"if(form.userid.value=='admin' && form.pwd.value=='admin')"
"{"
"window.open('/serverIndex')"
"}"
"else"
"{"
" alert('Error Password or Username')/*displays error message*/"
"}"
"}"
"</script>";
/*
* Server Index Page
*/
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
/*
* setup function
*/
void setup(void) {
pinMode(led, OUTPUT);
Serial.begin(115200);
// Connect to WiFi network
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());
/*use mdns for host name resolution*/
if (!MDNS.begin(host)) { //http://esp32.local
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
/*return index page which is stored in serverIndex */
server.on("/", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", loginIndex);
});
server.on("/serverIndex", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
/*handling uploading firmware file */
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
});
server.begin();
}
void loop(void) {
server.handleClient();
delay(1);
//loop to blink without delay
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState = not(ledState);
// set the LED with the ledState of the variable:
digitalWrite(led, ledState);
}
}
As you can see, we’ve added the “blink without delay” code to the OTAWebUpdater code, so that we’re able to make updates later on.
After copying the code to your Arduino IDE, you should generate a .bin file.
Generate a .bin file in Arduino IDE
Save your sketch as LED_Web_Updater.
To generate a .bin file from your sketch, go to Sketch > Export compiled Binary
A new file on the folder sketch should be created. Go to Sketch > Show Sketch Folder. You should have two files in your Sketch folder: the .ino and the .bin file. You should upload the .bin file using the OTA Web Updater.
Upload a new sketch over-the-air to the ESP32
In your browser, on the ESP32 OTA Web Updater page, click the Choose File button. Select the .bin file generated previously, and then click Update.
After a few seconds, the code should be successfully uploaded.
The ESP32 built-in LED should be blinking.
Congratulations! You’ve uploaded a new code to your ESP32 over-the-air.
Wrapping Up
Over-the-air updates are useful to upload new code to your ESP32 board when it is not easily accessible. The OTA Web Updater code creates a web server that you can access to upload new code to your ESP32 board using a web browser on your local network.
We hope you’ve found this article interesting. If you like ESP32 you may also like:
Thanks, very useful!
Would it be possible in zhis example to access the server from outside the local net?
If not, how could this be achieved?
Thanks again!
Paul,
You can do this in a couple of steps:
1. Use a dynamic DNS service to assign a domain name to your home network. So the outside world can get the your home LAN using something like: my router.dnsservice.com
Google: dynamic DNS home router
2. Enable port forwarding on your home router. So a web browser request can be sent to ”myrouter.dnsservice.com:5000” and your router will pass it along from Port 5000 to the IP address assigned to your Arduino/ESP32 device.
Google: port forwarding
The are some security implications in all of this – but Google searches will highlight these for you.
-Kim
Hi Kim.
Thank you so much for sharing your solution here.
Regards,
Sara 🙂
thank you for this question – that exactly what I need
and thanks to Author for good answer and good article
btw
there should be the way to do that without static ip, portforwarding, etc.
u can use HttpClient, obtain your updates from eg AWS S3 and then just use Update
Dakujem pekná práca.
Vieme to aj v micropythone?
pošlem na kavu!
Hi.
I just understand Portuguese and English (I’ve used Google Translator to understand what you mean).
At the moment, we don’t have an example like this is micropython. But I’ll do a research about that, and probably write a blog post about that soon.
Thank you so much for supporting our work.
Regards,
Sara 🙂
Hello Sara,
that will be fantastic. I’d like to move to Micropython, but for me, ability of OTA Programmierung is a precondition.
Thank you very much for all the great work here.
Kind regards,
Äd
Hi.
At the moment, we don’t have any tutorial for OTA with micropython.
We’ll release a new tutorial in a week or two about OTA for ESP32 (but with Arduino IDE and PlatformIO)
Regards,
Sara
Rui,
How difficult would it be to make this work on a ESP8266 featherwing?
This solution is what I am looking for to allow clients to update the ESP8266 without having to connect a USB cable.
Hi Randy.
This instructions are for the ESP32.
For the ESP8266, we have the following tutorial for OTA (this is not web OTA, this is classic OTA): https://randomnerdtutorials.com/esp8266-ota-updates-with-arduino-ide-over-the-air/
For more information about web ota with the ESP8266, it is best taking a look at the following tutorial
esp8266.github.io/Arduino/versions/2.0.0/doc/ota_updates/ota_updates.html#web-browser
Regards,
Sara 🙂
Your tutorial is great but there is some ambiguity in your explanation. I am not certain if “REPLACE_WITH_YOUR_SSID” and “REPLACE_WITH_YOUR_PASSWORD” refers to the SSID and password on my local network (the router wifi login credentials) or one I am creating for my ESP device. If it is my local router does that mean that I can only update the ESP when I am in range of that router? What I need is the ability to distribute ESP devices to many different remote locations and the users at those locations need to be able to get updates whenever they are available. Also, I do not have a web server that they can connect to. So what I need is to email them the latest BIN file which they then save on their local PC. Then they connect their PC to the ESP via WiFi using the SSID and password set up in the ESP code. Then they enter the IP set up in the ESP code (192.168.1.114 for example). Then the ESP serves then an initial menu page with everything that they can do with their ESP, including updating the ESP firmware. When they choose that option, the ESP web server serves them the same page that you showed by pointing the browser to 192.168.1.148/serverIndex, allowing them to point to the location that they stored the BIN file. And when they click the Update button, the update proceeds. Could you show a way to accomplish this? It would be immensely helpful!
Hi.
SSID and Password refers to the router wifi login credentials. With this example, you can only update code when the ESP is in the range of the router.
I think you’ve just described what you need to do. I don’t understand what is really your question.
Regards,
Sara.
vc precisará abrir uma porta no firewall da rede, ou no roteador que tem em casa, endereçar esta porta na hora de chamar a pagina. Exemplo: http://www.suarede.com/xxx onde suarede é o endereço IP perante o mundo (endereço que sua rede tem para o mundo e não a rede interna) e xxx é o numero da porta que vc liberou no seu roteador
Great Tutorial Guys! Thanks a lot!
In regards to OTA updates, is there a way to only update Config parameters and not write the entire FW? For example to simple update the reporting interval or specific Config settings/Config file from the server without being on the same network?
Thanks and keep the great tutorials coming! 🙂
Perhaps have the config files on an external Db (MySQL) and get the ESP32 to check for updates routinely or each time it wakes
As always, an excellent post and I am learning with each one of them.Thanks Rui!!!
Thank you for supporting our work.
Regards,
Sara 🙂
For some reason this site will not let me reply to your reply to my question so I am posting it as a top level question.
Sorry I wasn’t clear. I need to distribute identical ESPs to many different people, all with router logins that I do not and cannot know. Since your code requires knowing their SSIDs and passwords and entering them into the code, I cannot use your code as written. Is there a way to do this without knowing the SSID and password of my clients’ routers? If so, could you show the code? Thank you!
Hi.
One solution is to add WiFi manager to the ESP32 code. WiFiManager allows you to connect your ESP32 to different Access Points (AP) without having to hard-code and upload new code to your board.
This is the library repository: https://github.com/zhouhan0126/WIFIMANAGER-ESP32
We have a tutorial about Wi-Fi manager, but it is with the ESP8266 – but you can take a look to better understand how it works:
https://randomnerdtutorials.com/wifimanager-with-esp8266-autoconnect-custom-parameter-and-manage-your-ssid-and-password/
I hope this helps.
(Sorry for the trouble about answering previous comments).
Regards,
Sara
Thank you very for the post. It is very informative and a plus to developing home automation solutions
Thanks 🙂
Is it possible /serverIndex to open in the same tab? Also if the login failure happens, the address bar to NOT show the whole link including the pass and userid?
In case I need to include some small icons, which directory/where do I need to put them in the code?
Thank you!
This method is not secure, so I wouldn’t rely on the login, because anyone with the URL we’ll be able to access the web page. This sketch comes with the OTA library. In the future, I plan to create a real login to prevent anyone to access and upload a new firmware. Thanks for asking.
Boa tarde!
O código funciona bem quando fazemos upload de um sketch pela primeira vez, mas se fizermos upload de outro sketch deixa de funcionar.
É possível solucionar este problema?
Olá Francisco.
Quando faz upload the um novo sketch, esse sketch precisa de ter o código para OTA.
Se fizer upload de um sketch que não tem a parte de código para OTA, deixa de existir OTA a correr na ESP32.
Espero que tenha sido claro.
Cumprimentos,
Sara 🙂
Sim, já estava a falar de sketch’s que incluíam o código OTA.
Mas mesmo assim o segundo upload não funciona.
Cumprimentos,
Francisco
Hello, I’m a little new to the Esp32 and OTA updates. Can someone explain how the server.on callback works with the /update? I see two inline functions, where the first one has the ESP.restart. How does the ESP32 collect the data from the second inline function before performing the software restart?
It’s a non-blocking function, so it runs in the background when it receives a new firmware…
Is it possible to use this OTA capability along with a web server application? I have an IOT application that uses a server to provide a web page for control of a device (similar to your server example). I’d like to be able to use OTA updates so the devices would not need to be accessed to update the software. How could these be integrated together?
Thanks,
Leon
Hi Leon. and libraries to create a web server in which you can upload new code on the /serverIndex URL.
The OTA example we provide here uses the
One solution is to build your web server on a different URL using these libraries. However, I don’t have any example or tutorial about this.
Anyway, I hope this suggestion can help you.
Regards,
Sara
I had exactly the same question. It would be really useful to have some guidance on how to do this. I also have a webserver application that I would like to update remotely. I am not an html person, but quite capable of adapting an example
I found your message just now, after our long discussion on the subject. I am therefore placing a link here to our exchange, which may perhaps be able to enlighten the path of all those who seek to achieve the same thing:
https://rntlab.com/question/using-webserver-and-ota-updates/
As promised, as soon as I have the time, I will prepare an example to illustrate my words, which you can easily reproduce to adapt to your needs.
Any news on this? Would love to see a tutorial on this, or at least some quick guidance on how to combine the two. I think we understand each of the parts by itself, but its the combining that is tricky.
It seems to me you’ve already found the answer to your question…
You probably followed the discussion I had with David, or you saw my post announcing the publication of my project on GitHub :
https://rntlab.com/question/esp32-web-apps-with-websockets-ota-web-updates/
By the way, I answered your questions about GitHub…
I hope you were able to apply the technique I implemented for your own projects. I took care to comment my code to make it easier to understand.
This works great. Now I want to use OTA reprogramming on an ESP32 that is asleep in light sleep mode most of the time, and not easily accessible to plug in with wires. How long does it need to be awake for to be able to reprogram it?
Hi Steve.
I haven’t tested how much time it needs to completely update the code via OTA.
You need to test it yourself. But I think that maybe 20 to 30 seconds is enough (it probably needs less time).
Sorry that I can’t help much.
Thank you for supporting our work.
Regards.
Thank you for your help.
How can I used a external web services.
I have storage in my web server.
Help me please.
Best regards.
Angel
Hi Angel.
Unfortunately, we don’t have any resources about what you’re looking for.
Regards,
Sara
Hi All,
I’ve done an Android app that communicates with my ESP32 via BLE. I am thinking of using the Android app to download a new software image to the ESP32. My thought are to store the ESP32 image on Firebase. The phone will check every so often to see if there is a new image. If there is, it will download it onto itself and then program the ESP32.
Questions:
1) Has anyone done this before?
2) Are there better ways of doing it?
3) How do I transfer the image from the phone to the esp32? (Some server listening for an image or a command to download the file as described above or a direct Wifi connection?
4) Any code available?
Any suggestions will be appreciated
Hi.
That’s quite of a project!
Unfortunately, we don’t have any tutorials related with what you want to do, and I’m not familiar with those specific subjects to give you advice.
I’m sorry that I can’t help much.
Regards,
Sara
I am trying to do do something very similar to this.
Nice article – I was able to learn many new things here. Simple Understandable Instructions with snapshots. Was easy to learn.
Good Luck,
My question : I want to blink GPIO 26 instead of the onboard LED.
How do I go about it – I tried “const int led=26” – did not work .
Appreciate a reply.
Shashi
Hi Shashi.
Have you changed anything else in the code?
Changing the pin to 26 should work. Please make sure that you’ve wired the LED correctly.
Regards,
Sara
GPIO26 is in group ADC2 which are to be avoided when WiFi is used. Choose a pin from ADC1
For the ones asking to use the ESP32 as a webserver AND some OTA, try IOTAppstory. I have tried to combine this Santos-OTA with webserver applications and was not successful
Hi.
Thank you so much for sharing.
We’ll certainly take a look at it to see how it works.
Regards,
Sara
Did you have a look at IoTAppStory.com?
Regards
Max
Hi,
Each days better than before. You are my best.
Please keep it with same maner.
Yasar
Hi,
Great tutorial to explain how to do OTA. My question is: I am going to create an application that will search for the Wi-Fi enabled device and connect to it. If my mobile application connects to the ESP32 and I just want to update the SSID and PASSWORD inside of ESP32 to connect it with Home router how will I achieve this? Just SSID and PASSWORD OTA without creating and uploading .bin file and all.
Hi.
I think you’re looking for something like WiFi Manager: github.com/zhouhan0126/WIFIMANAGER-ESP32
I hope this helps.
Regards,
Sara
Already gone through that, didn’t help. But thanks.
Hi All,
How would it work if one wants to do an update using a gsm modem instead of wifi?
Hi Random Nerds,
I use an ESP32 and separate the code to the two core. One shall handle the Wifi and Modbus connection to my Home Central. The other shall handle the main program with fetching data from sensors and execute actors.
At which core shall I assign the web server for the OTA functions?
In the Arduino IDE is an option under Tools to change code and Wifi. I think this must be set to code only, right?
Thank you! After wasting a lot of time on other forums and blogs your tutorial just works as it should. You are doing a great servide to the maker community; keep up the good work!
James
That’s great!
Thank you for following our work.
Regards,
Sara
There is a grammatical error in the title of the section named “How does OTA Web Updater Works?”. It should instead say “How Does OTA Web Updater Work?” (“does” -> “Does” and “Works?” to “Work?”).
BTW, I love your ESP8266 pinout guide!
Thanks for noticing.
It is fixed now.
Regards,
Sara
Yet another great tutorial – thank you.
I now have my esp32 workshop environs controller using esp NOW many to many to pass sensor readings back and forth between two workshops and the house and they are OTA capable with a Web accessed dashboard.
I am on a roll.
Thanks again Rui and Sara
That’s great!
Thanks for following our work.
Regards,
Sara
I’m using Basic OTA rather than Web Updater OTA. But in any case I understood that OTA updates only allow you to use up to 50% of program memory, since during the update both the old and new copies of the application need to be stored. After successful update the updater would then switch to using the new version.
At this point my application is well over 50% but OTA still works fine:
Sketch uses 876226 bytes (66%) of program storage space. Maximum is 1310720 bytes.
Global variables use 46784 bytes (14%) of dynamic memory, leaving 280896 bytes for local variables. Maximum is 327680 bytes.
How is it that my updates still succeed, and is there some OTHER hard limit at which OTA updates will not work?
Is it possible to update SPIFFS file by this application?
How can I update SPIFFS files?
Hi Rui, Thanks for sharing, One tutorial that we are much missing and expecting from you, to update firmware automatically by a link online, kindly do have some consideration on it.
ArduinoOTA is probably better option these days.
https://tttapa.github.io/ESP8266/Chap13%20-%20OTA.html
Hello Sara!
how are you?
Congratulations on the work!
The update is stopping at 12% and does not end, would you have any idea why?
I’m using esp32 cam!
Thank you for your help
You probably have the answer by now but my suggestion would be to check partition type, it may be of type with “No OTA” and select something like “Minimal SPIFFS with OTA”.
I have the same issue like you. First time on arduino example it worked, now when I uploaded my code with web upload I see that upload sto on laptop on 24% and on phone on 53%. Can somebody help please?
Ok, I’ve found the reason. It was watchdog timer. I’ve added line to disable timer in UPLOAD_FILE_START.
how did you disable the timer? can you share the code?
I have used timerAlarmDisable(timer) ; in this part of the code:
if (upload.status == UPLOAD_FILE_START) {
timerAlarmDisable(timer) ;
Serial.printf(“Update: %s\n”, upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
Update.printError(Serial);
}
WDT Timer like this:
github.com/espressif/arduino-esp32/issues/841
Or this:
techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
Hi all,
I am trying to use this OTA example but into my .ino program I am getting “WebServer does not name a type” error .
Any idea ?
Thank
Hi.
Make sure you have the OTAWebUpdater library installed and that you have an ESP32 selected when compiling and uploading the code.
Regards,
Sara
Great article!
How could this be implemented with the ESP32 Now-Many to one? I tried and it does an uploadonce but fails to connect to the IP after that.
thanks.
dave
Thanks for sharing this great information with us.
I’m trying to find ESPmDNS library but unfortunately, I couldn’t find it.
Could you please share with me a link where I can download the library?
Many thanks,
Nadav
Hi,
Another great tutorial, thank you.
I do have a query though.
I have complied the example using PlatformIO and it works fine by serial or by uploading the .bin file but the compiler reports this:
RAM: [= ] 12.7% (used 41504 bytes from 327680 bytes)
Flash: [====== ] 58.5% (used 767182 bytes from 1310720 bytes)
This does correspond with the .bin file size of 750k.
So, the ‘Flash’ (58%), the amount that will be used out of the total, in which case as it is greater than half, how does it fit in along with the current running code.
Or is this 58% of ‘AVAILABLE’ flash?
It also raises another question, it reports I have 1310720 bytes (1.3MB), so where is the rest as it is supposed to have 4MB of flash.
Thanks
Martin
Good question and query, anyone know?
also looking for an answer to this
Hi,
Just wanted to thank you both for your excellent work. I have read several of your tutorials and they are very well written, concise and clear. Muchas gracias!
Gracias 🙂
Great tutorial. I have done the OTA update lessons and they have worked great. I have also purchased your How to make esp32 a server book. However, I need something different. I have an esp32 in the field behind a router (that I have no access to) that I want to do OTA with. I also cannot put ngrok server on the local network with the esp32 to make it accessible from the outside of its local network. At my home base (from where I want to load the OTA) I can make a server accessible from the outside via a port forward on my router. So, can I have the esp32 in the field initiate contact with my local server periodically to ask it if there is an OTA available and it so, download it and update itself. Since the esp32 in the field is making the contact there would no need to be able to initiate the the contact with it via a gnrok arrangement. I hope I have made myself clear. Any help would be appreciated.
Hi Ed.
I’m not sure that I understand what you want to do.
Have you taken a look at IoTAppStory: https://iotappstory.com/ ?
I think that will help.
Regards,
Sara
Sara
Thanks for the response. I was not aware of AppStory. It sounds like exactly what I was trying to do. I will check it out. I was just trying to do this by having the code in the remote esp32 “call back to my server” at my home for an update. Then a connection could created directly between the two. The server could then push a binary to the remote esp32 to allow it to update itself. This seems what appstory is doing except in that case the remote esp32 connects to their cloud service instead of my home server. Sounds simple to do but I’ll check appstory out.
Ed
BTW you guys have a great website!
Thanks Ed.
I haven’t experimented with the IoT App Story myself, but I heard good things about it.
Regards,
Sara
Hello Random Nerd team,
I followed your tutorial which definitely helped me achieving OTA capabilities. Additionally, could you kindly suggest if there is a way to POST the bin over network without manually opening the form on browser? I have seen some examples where the ESP was used as a client which downloaded the file? But can we keep the server capabilities intact and yet download the file in the same manner ?
Thank you again.
Regards,
Shariq
Hello All,
Thankfully I was able to solve my own problem by doing a post request using a python script. Pasting it here for any future reference..
#!Python
import requests
files = {‘file’: open(r””, ‘rb’)}
final_resp = requests.post(“http://update”, files=files)
Regards,
Shariq
What’s the difference between this 2018 one, and the new 2021 version?
https://randomnerdtutorials.com/esp32-ota-over-the-air-arduino
This uses the asyncwebserver library. So, it it easy to integrate and it is compatible with web servers built using the asyncwebserver library.
It also allows to upload files to the filesystem.
Regards,
Sara
Hello everyone!
Is it possble to make ESP download the bin from url and to burn it itself? I want to code web API for this, but I cannot understand how wifi client will download bin and run it.
Best,
Uliana
Hi,
i’ve tried your code but get the following error message on browser after having selected a *.bin-file and pressed the upload button:
“Not found:/serverIndex”
The only thing i changed in the code is Wifi-AP instead of station.
Can you help me? What does this message meach ;-(
Hi.
I’m not sure.
Check this discussion: https://github.com/espressif/arduino-esp32/issues/3076
Regards,
Sara
Hi Sara,
Thanks for your work with these libraries. It seems that ElegantOTA is locked into Wifi access only. Is there a way to use it over GSM?
Best Paul
Hi.
I’m not sure.
It is best to ask the developer: https://github.com/ayushsharma82
Regards,
Sara
Hallo…
Why didn’t they put user and password form on the same page of upload file form?
I think it’s more security and simple…
@}-,-‘——-
Gianfranco
Hi house, i was trying use OTA programming with esp32. The example given in the arduino ide only to set the esp as station not as AP. So i cannot use OTA without using a router. But i want to use only my computer with the esp because i need to program the esp on the field which no access to router.
I checked online but i didnt see something substantial. I decided to do it my way and it worked. Its very easy and i decided to share the idea.
From the example given in the arduino.
Changed STA to AP using WiFi.mode(WIFI_AP);
Wifi.softAP instead of wifi.begin
I forced the local IP address to 192.168.4.1 with. “IPAddress local_IP(192,168,4,1);”
I removed the while loop so i dont need to check if wifi is connected.
Boom…. It worked…. I can now upload program to esp32 without a router.
Hi.
That’s great!
Thanks for sharing.
Regards,
Sara
Hello, i need some help,
How can i get the bin file from the arduino web editor?
Hi.
It’s explained in the tutorial.
What happens if the OTA is interrupted in between, say the power in unplugged or the WiFi goes off? Will I lose the old firmware that was running before the OTA?
I’ve added a sample code for anyone trying to make it work on access point mode, and get the serverIndex or similar errors caused by the jquery.min.js. -> https://github.com/italocjs/ESP32_OTA_APMODE
Thanks for sharing.
Regards,
Sara
Thanks for this (and all the other excellent) tutorials!
I am just a little bit concerned about the lack of security in this one. The username and password are visible in the HTML code of the login page, but you do not even need those, you can directly go to the completely unsecured /update page.
Your tutorial https://randomnerdtutorials.com/esp32-esp8266-web-server-http-authentication/ shows how it is done correctly, and that it is really easy: just send a 401 response code (which makes the browser ask the user for credentials) until you receive a valid “Authorization: Basic …” Header. No need for a login page and much more secure.
Hello, the “Hello” part is working for me, but not the upload.
It jumps to 18% and stays stuck there. Tried in 2 different esp32 boards, different browsers. The code is copy/paste from the tutorial.
I also noticed it reboots the ESP on upload, I get this:
“abort() was called at PC 0x40081f62 on core 1”
….
“Rebooting”
Any clues?
Hi,
Thank you for the amazing tutorials. I followed your steps to install ESP32 for IDE 2 (I am on 2.0.4) but I get the error about WebServer.h:
C:.…\Arduino\OTA_WEBUPDATE\OTA_WEBUPDATE.ino:4:10: fatal error: WebServer.h: No such file or directory
4 | #include <WebServer.h>
What is the correct WebServer.H file?
I also tried this on the Cloud Editor and it didn’t like Update.h.
Any help?
Hi.
What’s the ESP32 version that you have installed?
Regards,
Sara
Very useful!!
But probably a validation via TOKEN on the upload page itself would be more useful than this login screen, which in reality just hides the upload URL.
Hi:
just to report a strange situation. I’ve an esp32 that simply does not update over OTA. The software works well on others ESP32. Only this one doesn’t work. It will however update using a cable connection. This is of course result from a chine bad esp32 board…
Hi Sara,
I have been using the OTA very much but I have 500 devices each having unique ID configure using mDNS with hostname so that I can access the device by devicename.local, Please suggest a method how I can update my code update for the all the device with 1 bin file, as it is very tedious to make bin file for all 500 device
Thanks
Siva
I want to work OTA with esp32 with ethernet( W5500) but those library doesn’t support Ethernet at all. Can anyone give some solution ?
Add a delay before restarting or the page will not receive a return value
I tried examples for both ArduinoOTA and ElegantOTA. The page with web server never loads for me. I use Arduino ESP32 core version 2.0.14. Does anyone have any ideas?
Hi, at the first look, I think there are missing close tags in serverIndex.