OTA Firmware Updates
Vwire supports Cloud OTA — upload a new firmware binary from the dashboard and deploy it to any connected ESP32 or ESP8266 device remotely. No physical access, no USB cable.
Cloud OTA is built into the Vwire library. No extra OTA library or header is needed.
How it works
Dashboard → Upload .bin (Sketch > Export Compiled Binary)
→ Click "Upload & Deploy"
→ Server sends OTA command to device via MQTT
→ Device downloads firmware and flashes it
→ Device reboots with new firmware
Firmware setup
OTA support requires only one extra line — Vwire.enableCloudOTA() in setup(). No separate include or library needed.
#include <Vwire.h>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* AUTH_TOKEN = "YOUR_AUTH_TOKEN";
const char* DEVICE_ID = "YOUR_DEVICE_ID"; // VW-XXXXXX
VWIRE_CONNECTED() {
Serial.println("Connected to Vwire!");
}
void setup() {
Serial.begin(115200);
Vwire.config(AUTH_TOKEN);
Vwire.setDeviceId(DEVICE_ID);
// Enable Cloud OTA — device will accept firmware updates from the dashboard
Vwire.enableCloudOTA();
Vwire.begin(WIFI_SSID, WIFI_PASSWORD);
}
void loop() {
Vwire.run(); // handles OTA internally — no extra call needed
// ... your normal code
}
Uploading and deploying
- In Arduino IDE: Sketch → Export Compiled Binary — this creates a
.binfile next to your sketch
In PlatformIO: runpio run— find the.binin.pio/build/<env>/ - In the Vwire dashboard, open the device detail page
- Expand OTA Firmware Update
- Click Upload & Deploy and select the
.binfile - The dashboard shows real-time progress as the device downloads and flashes
Supported boards
| Board | Supported |
|---|---|
| ESP32 (all variants) | ✅ |
| ESP8266 (NodeMCU, Wemos D1, etc.) | ✅ |
| Arduino Uno / Nano / Mega | ❌ (no OTA partition) |
On unsupported boards Vwire.enableCloudOTA() is a no-op — the sketch still compiles without errors.
Safety
| Feature | Description |
|---|---|
| SHA256 verification | Binary hash validated before flashing |
| Rollback on boot failure | ESP32 marks the partition valid only after successful boot |
| Size check | Rejects binaries larger than the OTA partition |
| Download timeout | OTA aborted if download stalls for > 60 s |
Disabling OTA
If you want to build a firmware image with OTA permanently disabled:
#define VWIRE_DISABLE_CLOUD_OTA
#include <Vwire.h>
Troubleshooting
| Issue | Fix |
|---|---|
| "OTA failed: invalid hash" | Rebuild and re-upload the binary |
| Device reboots but runs old firmware | Partition table mismatch; ensure OTA partitions are defined |
| No OTA progress shown | Confirm Vwire.enableCloudOTA() is called before Vwire.begin() |
| Device offline after OTA | New firmware crashed; ESP32 auto-rolls back to previous partition |
How it works
Dashboard → Upload .bin → VWire Server stores binary
→ Press "Send OTA" button
→ Server publishes to vwire/{token}/ota
→ Device receives URL + hash
→ Device downloads binary from VWire Server
→ Device validates SHA256 hash
→ Device flashes using Update library
→ Device reboots with new firmware
Firmware requirements
Add OTA support to your sketch:
#include <VWire.h>
#include <VWireOTA.h>
VWireOTA ota(vwire);
void setup() {
Serial.begin(115200);
Vwire.begin(SSID, PASSWORD);
ota.begin(); // register OTA handler
}
void loop() {
Vwire.run();
ota.handle(); // check for pending OTA
// ... your normal code
}
Uploading a firmware binary
- Build your sketch: Sketch → Export Compiled Binary (Arduino IDE) or
pio run(PlatformIO). - Go to Dashboard → Device → Firmware → Upload Firmware.
- Select the
.binfile and click Upload. - Once uploaded, click Send OTA to push it to the device.
OTA progress
The device reports progress back to the server:
| Pin | Data | Description |
|---|---|---|
V254 (reserved) | "0" – "100" | Download progress % |
V255 (reserved) | "ok" / "error:<msg>" | Update result |
The dashboard shows a progress bar during the update.
Safety features
| Feature | Description |
|---|---|
| SHA256 verification | Binary hash validated before flashing |
| Rollback on boot failure | ESP32 marks partition valid only after successful boot |
| Size check | Rejects binaries larger than available OTA partition |
| Timeout | OTA aborted if download stalls > 60 s |
PlatformIO build flags
Ensure OTA partition is defined in your partitions.csv:
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1E0000,
app1, app, ota_1, 0x1F0000, 0x1E0000,
eeprom, data, 0x99, 0x3D0000, 0x1000,
spiffs, data, spiffs, 0x3D1000, 0x2F000,
Troubleshooting
| Issue | Fix |
|---|---|
| "OTA failed: invalid hash" | Re-build and re-upload the binary |
| Device reboots but still on old version | Partition table mismatch; check partitions.csv |
| "OTA timeout" | Device network is slow; increase timeout in VWireOTA config |
| Device offline after OTA | New firmware has a bug; device boots from old partition if rollback is enabled |