Skip to main content

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

  1. In Arduino IDE: Sketch → Export Compiled Binary — this creates a .bin file next to your sketch
    In PlatformIO: run pio run — find the .bin in .pio/build/<env>/
  2. In the Vwire dashboard, open the device detail page
  3. Expand OTA Firmware Update
  4. Click Upload & Deploy and select the .bin file
  5. The dashboard shows real-time progress as the device downloads and flashes

Supported boards

BoardSupported
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

FeatureDescription
SHA256 verificationBinary hash validated before flashing
Rollback on boot failureESP32 marks the partition valid only after successful boot
Size checkRejects binaries larger than the OTA partition
Download timeoutOTA 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

IssueFix
"OTA failed: invalid hash"Rebuild and re-upload the binary
Device reboots but runs old firmwarePartition table mismatch; ensure OTA partitions are defined
No OTA progress shownConfirm Vwire.enableCloudOTA() is called before Vwire.begin()
Device offline after OTANew 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

  1. Build your sketch: Sketch → Export Compiled Binary (Arduino IDE) or pio run (PlatformIO).
  2. Go to Dashboard → Device → Firmware → Upload Firmware.
  3. Select the .bin file and click Upload.
  4. Once uploaded, click Send OTA to push it to the device.

OTA progress

The device reports progress back to the server:

PinDataDescription
V254 (reserved)"0""100"Download progress %
V255 (reserved)"ok" / "error:<msg>"Update result

The dashboard shows a progress bar during the update.


Safety features

FeatureDescription
SHA256 verificationBinary hash validated before flashing
Rollback on boot failureESP32 marks partition valid only after successful boot
Size checkRejects binaries larger than available OTA partition
TimeoutOTA 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

IssueFix
"OTA failed: invalid hash"Re-build and re-upload the binary
Device reboots but still on old versionPartition table mismatch; check partitions.csv
"OTA timeout"Device network is slow; increase timeout in VWireOTA config
Device offline after OTANew firmware has a bug; device boots from old partition if rollback is enabled