#BLUEHASH
← Docs

Guide

OTA Firmware Updates

Update your device wirelessly after the first USB flash. The device downloads and installs new firmware over WiFi automatically.

First flash only: The first time you flash a device you need USB + Web Serial. After that, OTA handles all updates wirelessly — no cable needed.

How it works

1
Flow triggers the OTA node

Usually wired after wifi_connect so the device is online. Can be triggered on boot, on button press, or on a timer.

2
Device fetches version.json

The OTA node calls your update server at {url}/version.json and compares the returned version string to the running firmware version.

3
Version mismatch → download

If a newer version exists, the device downloads {url}/firmware.bin and streams it directly to the second OTA flash partition.

4
Reboot into new firmware

On success the device reboots automatically. The upToDate output fires if already on the latest version. failed fires on network error or bad binary.

Example flow

Wire the OTA node after WiFi connect. The updating output fires immediately — the device then reboots itself if successful.

[start] boot → [wifi_connect ssid="MyNet" pass="secret"] connected → [ota_update url="http://192.168.1.10:3001/ota"] upToDate → [show_text "Up to date"] failed → [show_text "Update failed"] updating → (device reboots itself — flow stops here)

OTA node config

Only one config field — the update server URL.

urltext field

Base URL of your update server. The node appends /version.json and /firmware.bin automatically.

http://192.168.1.10:3001/ota
Output ports
upToDateFired if device is already on latest version
updatingFired immediately before download starts (device will reboot)
failedFired on network error, bad URL, or download failure

Setting up the update server

The compiler service serves the OTA endpoint automatically — no separate server needed. Just point the OTA node at your compiler.

version.json
{ "version": "0.2.0" }

Must contain a "version" key. The HAL compares this to the running BH_VERSION_STR.

firmware.bin
(binary — compiled by the compiler service)

The raw ESP32 firmware binary. Download it from the compiler after a successful build.

# In bluehash-compiler/.env OTA_BASE_URL=http://192.168.1.10:3001/ota # The compiler already serves: # GET /ota/version.json → { "version": "current build version" } # GET /ota/firmware.bin → last successful firmware.bin

Flash partition layout

BLUEHASH firmware uses a dual-OTA partition layout. The device alternates between app0 and app1 on each successful update. NVS (your saved variables) is in a separate partition and survives every OTA.

# partitions_8mb_ota.csv (already in bluehash-firmware/) # Name, Type, SubType, Offset, Size nvs, data, nvs, 0x9000, 0x5000 otadata, data, ota, 0xe000, 0x2000 app0, app, ota_0, 0x10000, 0x330000 ← runs first app1, app, ota_1, 0x340000, 0x330000 ← OTA writes here spiffs, data, spiffs, 0x670000, 0x190000
NVS survives OTA: All keys stored with nvs_store nodes persist across firmware updates. Your WiFi credentials, high scores, and settings are never erased by an OTA.