An OTA (Over the Air) update is the process of installing new firmware on an ESP8266 module using a WiFi connection rather than serial transmission. When there is no physical access to the ESP module, this type of capability is incredibly useful.
The following typical scenarios are intended for wirelessly uploading a new sketch from the Arduino IDE:
- during firmware development, as a quicker alternative to uploading a new sketch over a serial
- for updating the firmware of multiple ESPs in your network.
Let’s get started!

Step 1: Uploading BasicOTA.ino with serial communication
You must first upload the BasicOTA.ino sketch example to your ESP8266 to wirelessly upload firmware to it.
Having the latest Arduino IDE software installed at arduino.cc/en/Main/Software The next step is to:
1) Connect your ESP8266 to your computer with a USB cable:

2) Go to Tools to select your ESP board model. You also have to choose your ESP’s COM port.

3) Open the BasicOTA.ino example: File > Examples > Arduino OTA > BasicOTA.ino, or copy the following sketch to your Arduino IDE.
/*********
LEDEdit PRO
Complete project details at https://lededitpro.com
Arduino IDE example: Examples > Arduino OTA > BasicOTA.ino
*********/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
// Replace with your network credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
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 8266
// ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
// ArduinoOTA.setHostname("myesp8266");
// No authentication by default
// ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
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());
}
void loop() {
ArduinoOTA.handle();
}
Note: You have to change the sketch example with your SSID and password.
4) Press the “Upload” button in the Arduino IDE and wait for the “Done uploading” message.

5) Start the Arduino IDE serial monitor at 115200 baud. You should see your ESP IP address within a few seconds if you input the right network credentials:

Step 2: Uploading a new sketch OTA (Over the Air)
The ESP8266 is now ready to receive OTA firmware upgrades. You may unplug your ESP8266 from your computer and power it with any power source (such as a power bank). If your ESP8266 is connected to your network wirelessly, you should be OK uploading new firmware.

1) Go to your Arduino IDE. Open the “Tools” tab, select the “Port” option, and you should see something like this: “esp8266-xxxxxx at your_esp_ip_address“.

2) On your ESP8266, upload the following sketch using the Arduino IDE: This sketch blinks the built-in LED of the ESP12-E NodeMCU kit every second.
/*********
LEDEdit PRO
Complete project details at https://lededitpro.com
Arduino IDE example: Examples > Arduino OTA > BasicOTA.ino
*********/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
// Replace with your network credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const int ESP_BUILTIN_LED = 2;
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 8266
// ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
// ArduinoOTA.setHostname("myesp8266");
// No authentication by default
// ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
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());
pinMode(ESP_BUILTIN_LED, OUTPUT);
}
void loop() {
ArduinoOTA.handle();
digitalWrite(ESP_BUILTIN_LED, LOW);
delay(1000);
digitalWrite(ESP_BUILTIN_LED, HIGH);
delay(1000);
}
Note: You have to replace the sketch example with your SSID and password.
3) Press the “Upload” button in the Arduino IDE and wait for the “Done uploading” message.
4) Your ESP should have its built-in LED blinking every second.
Conclusion
I hope you find this tutorial useful. You can now ESP8266 OTA firmware updates from a remote location without having physical access to the ESP device.
If you like ESP8266, you may also like:
- Get MAC Address of ESP32/ESP8266 and Change It (Arduino IDE)
- ESP8266 NodeMCU Static/Fixed IP Address – Working & Testing
- ESP8266 Pinout Guide: How should I use the GPIO pins?
- Send Email from ESP8266 NodeMCU via SMTP Server
We hope you find this tutorial useful. Thanks for reading.