This tutorial walks you through setting up Over-The-Air (OTA) firmware updates for your ESP32 or ESP8266 device using SinricPro. OTA allows you to remotely update your device’s firmware without physically connecting it to a computer — perfect for deployed IoT devices!
SinricPro OTA (Over-The-Air) is a feature that allows your ESP device to download and install new firmware from the server when triggered via the SinricPro dashboard.
Before you begin, ensure you have:
APP_KEY
and APP_SECRET
from portal.sinric.pro -> CredentialsSWITCH_ID
, etc.) for your device from portal.sinric.pro -> Devices💡 Complete code: here
In Arduino IDE:
SinricPro
Copy and paste the example code below into your Arduino IDE.
IMPORTANT:
FIRMWARE_VERSION
is the Firmware version. You can see in the Module section of Portal. It must be define above must be above SinricPro.h
// Uncomment the following line to enable serial debug output
// #define SINRICPRO_NOSSL // Uncomment if you have memory limitation issues.
// #define ENABLE_DEBUG // Enable SDK logging.
// Your firmware version. Must be above SinricPro.h. Do not rename this.
#define FIRMWARE_VERSION "1.1.1"
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include "ESP8266OTAHelper.h" // Ref: https://github.com/sinricpro/esp8266-esp32-sdk/tree/master/examples/OTAUpdate
#elif defined(ESP32)
#include <WiFi.h>
#include "ESP32OTAHelper.h" // Ref: https://github.com/sinricpro/esp8266-esp32-sdk/tree/master/examples/OTAUpdate
#elif defined(ARDUINO_ARCH_RP2040)
#include <WiFi.h>
#include "ESP8266OTAHelper.h" // Ref: https://github.com/sinricpro/esp8266-esp32-sdk/tree/master/examples/OTAUpdate
#endif
#include "SemVer.h"
#include "SinricPro.h"
#include "SinricProSwitch.h"
#define WIFI_SSID "YOUR-WIFI-SSID"
#define WIFI_PASS "YOUR-WIFI-PASSWORD"
#define APP_KEY "YOUR-APP-KEY" // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET "YOUR-APP-SECRET" // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define SWITCH_ID "SWITCH_ID" // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE 115200 // Change baudrate to your need
bool handleOTAUpdate(const String& url, int major, int minor, int patch, bool forceUpdate) {
Version currentVersion = Version(FIRMWARE_VERSION);
Version newVersion = Version(String(major) + "." + String(minor) + "." + String(patch));
bool updateAvailable = newVersion > currentVersion;
Serial.print("URL: ");
Serial.println(url.c_str());
Serial.print("Current version: ");
Serial.println(currentVersion.toString());
Serial.print("New version: ");
Serial.println(newVersion.toString());
if (forceUpdate) Serial.println("Enforcing OTA update!");
// Handle OTA update based on forceUpdate flag and update availability
if (forceUpdate || updateAvailable) {
if (updateAvailable) {
Serial.println("Update available!");
}
String result = startOtaUpdate(url);
if (!result.isEmpty()) {
SinricPro.setResponseMessage(std::move(result));
return false;
}
return true;
} else {
String result = "Current version is up to date.";
SinricPro.setResponseMessage(std::move(result));
Serial.println(result);
return false;
}
}
// setup function for WiFi connection
void setupWiFi() {
Serial.printf("\r\n[Wifi]: Connecting");
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.setAutoReconnect(true);
#elif defined(ESP32)
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
#endif
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.printf(".");
delay(250);
}
Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}
// setup function for SinricPro
void setupSinricPro() {
SinricProSwitch& mySwitch = SinricPro[SWITCH_ID];
// setup SinricPro
SinricPro.onConnected([]() {
Serial.printf("Connected to SinricPro\r\n");
});
SinricPro.onDisconnected([]() {
Serial.printf("Disconnected from SinricPro\r\n");
});
SinricPro.onOTAUpdate(handleOTAUpdate);
SinricPro.begin(APP_KEY, APP_SECRET);
}
// main setup function
void setup() {
Serial.begin(BAUD_RATE);
Serial.printf("\r\n\r\n");
setupWiFi();
setupSinricPro();
}
void loop() {
SinricPro.handle();
}
#define FIRMWARE_VERSION "1.1.1"
SinricPro.h
.MAJOR.MINOR.PATCH
).In Arduino IDE:
.bin
file in your sketch folder.Example:
your_sketch.ino.esp32.bin
Login to your Sinric Pro account.
Go to OTA Updates menu on left.
Click Add OTA Update button.
Enter the the new firmware version. Select the OTA .bin file (your_sketch.ino.esp32.bin
) and the modules you want to apply the OTA update.
Click Save
Once you click the Save button, the server will broadcast an OTA update request to the selected modules. If your module is currently offline, it will receive the update the next time it connects to the server.
Enable debug output by uncommenting:
#define ENABLE_DEBUG
Watch Serial Monitor (115200 baud
) for:
Common issues:
Symptom | Solution |
---|---|
Update failed: connection refused |
Check URL is publicly accessible |
Update failed: not enough space |
Reduce sketch size or use SINRICPRO_NOSSL |
Version not updating |
Ensure FIRMWARE_VERSION is updated in sketch before compiling new binary |
Device not responding after OTA |
Check for crashes — add delays or watchdog reset |
1.0.0
, 1.0.1
, 2.0.0
, etc.).SinricPro.handle()
in loop()
if device is unstable.✅ Yes! The OTA mechanism is device-type agnostic. Just register SinricPro.onOTAUpdate(...)
regardless of your device class.
The device will:
SinricPro.setResponseMessage(...)
.✅ Yes, by default. If you have memory issues on ESP8266, uncomment:
#define SINRICPRO_NOSSL
⚠️ This disables SSL — only use with trusted networks or HTTP URLs.
Depends on:
Average: 30 seconds to 3 minutes.
You can find the complete example code here: https://github.com/sinricpro/esp8266-esp32-sdk/tree/master/examples/OTAUpdate
If you are looking for local WiFI OTA Update here