OTA (Over-the-Air) Update in ESP8266

OTA Stands for over the air. An over-the-air (OTA) update is a mechanism for remotely updating internet-connected hardware with new settings, software, and / or firmware. The OTA programming allows updating/uploading a new program to ESP/IoT  Boards using Wi-Fi instead of requiring the user to connect the Board to a computer via USB to perform the update.

OTA functionality is extremely useful in case of no physical access to the ESP/IoT module. It helps reduce the amount of time spent for updating each ESP/IoT module at the time of maintenance.


over-the-air updates

Benefits of Over-The-Air

  • Incremental OTAS allow continuous improvement of devices even after they are in the hands of consumers
  • They increase functionality through updates to one or more devices
  • They save costs  as you manage the firmware updates from a remote platform
  • OTAs allows to quickly correct security vulnerabilities
  • They Increase scalability by adding new features and infrastructure to the products after their launch.

Ways To Implement OTA In ESP8266

There are three ways to implement OTA functionality in ESP8266.

  • Basic OTA – Over-the-air updates are sent through Arduino IDE.
  • Web Updater OTA – Over-the-air updates are sent through a web browser.
  • HTTP based OTA – Over-the-air updates are sent through and HTTP server (In this approach, the device can be anywhere in the world. It just needs to be connected to the internet.)

Here We Will implement Basic OTA using ESP8266, i.e., updates sent through Arduino IDE.

Steps To Use Basic Over-The-Air with ESP8266

  1. Install Python 2.7.x series – The first step is to install Python 2.7.x series in your computer.
  2. Upload Basic OTA Firmware Serially  –  Upload the sketch containing OTA firmware serially. It’s a mandatory step, so that you’re able to do the next updates/uploads over-the-air.
  3. Upload New Sketch Over-The-Air- Now, you can upload new sketches to the ESP8266 from Arduino IDE over-the-air.

Code to Implement Basic OTA using ESP8266 in Arduino IDE

For Basic Firmware Code you can refer below or go to your Arduino IDE and Open File > Examples > ArduinoOTA > BasicOTA.

This Code will Create a Network Port which can be displayed in your Arduino IDE were you usually find Serial port and accordingly you can upload new codes without actually connecting it physically from your computer via USB. You can edit this code so that you can use OTA firmware and implement various others things simultaneously.

Include Libraries and define your Wifi SSID and Password

ESP8266Wifi.h – With the ESP8266  WiFi Shield, this library allows an ESP board to connect to the internet. It can serve as either a server accepting incoming connections or a client making outgoing ones

ESP8266mDNS.h – the service we will setup in the ESP8266 is a simple HTTP web server, using the async HTTP web server library

WiFiUdp.h – Creates a named instance of the WiFi UDP class that can send and receive UDP messages. On AVR based boards, outgoing UDP packets are limited to 72 bytes in size currently. For non-AVR boards the limit is 1446 bytes.

Arduino OTA – Provides serial commands to activate OTA firmware.

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>


#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK  "your-password"
#endif


const char* ssid = STASSID;
const char* password = STAPSK;

Serial and Wifi Initialization Setup

We will configure a Baud Rate of 115200 to establish serial communication and will initialize wifi.begin so that board connects with the wifi which you will define in above part.

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();
  }

Configuration of Over-The-Air Functionality in ESP8266

A new ESP8266 doesn’t have an OTA Upgrade capability. So, we need to load the OTA firmware on the ESP8266 through serial interface first. Only after doing that we will be able to flash our code Over-The-Air.

It’s a mandatory step to initially update the firmware, so that you’re able to do the next updates/uploads over-the-air.

The ESP8266 add-on for the Arduino IDE comes with a OTA library & BasicOTA example. You can access it through File > Examples > ArduinoOTA > BasicOTA.

This Code will call the ArduinoOTA library once we flash the code into our ESP8266 Board , basically it will create a network port on the IP Address using TCP/IP Stack

If you wanna know more about OTA Update Library firmware visit : arduino-esp8266.readthedocs

The following code handles the OTA part.

 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());
}

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

Putting it all together, the first code that we need to flash is this:

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "..........";
const char* 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("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());
}

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

Once the above code is uploaded, open the Serial Monitor at a baud rate of 115200. And press the RST button on ESP8266. If everything is OK, it will output the dynamic IP address obtained from your router. Note it down.

Upload new stetch Over-The-Air

To try this part out, we will flash the blinky code over-the air.

Remember! we need to add the code for OTA in every sketch we upload. Otherwise, we’ll loose OTA capability and will not be able to do next uploads over-the-air. So, it’s recommended to modify the above code to include the new code.

Also remember to modify the SSID and password variables with your network credentials.

Now, coming to the code. We will add a few lines of code to the OTA code we flashed earlier. These lines are related to the blinky that we are trying to do.

//variabls for blinking an LED with Millis
const int led = D0; // ESP8266 Pin to which onboard LED is connected
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

void setup() {
pinMode(led, OUTPUT);

And in the void loop(), we will add the following:

//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);
  }

So our complete new code becomes:

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "..........";
const char* password = "..........";

//variabls for blinking an LED with Millis
const int led = D0; // ESP8266 Pin to which onboard LED is connected
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

void setup() {
pinMode(led, OUTPUT);
    
  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("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());
}

void loop() {
  ArduinoOTA.handle();

//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);
  }
}

 

Once you have Flashed the above code in your ESP8266 Board , You’ll find Network port on your Arduino IDE port section referred in the figure below . Use that port to upload Blink code attached below.

Once you upload the code using Network port you’ll find that the onboard LED will start blinking.

In case you face any problem, do let me know in the comments and I will try my best to resolve and help you.

Sharing is Caring!!

Leave a Reply

Your email address will not be published.