Skip to the content.

How to Use OTA on SIMUT

Practical guide for updating Pico W firmware via web, without needing a USB cable or BOOTSEL button.

What It Is

OTA (Over-The-Air) updates the Pico W firmware remotely via web — no USB cable or BOOTSEL button needed.

Prerequisites

⚠️ WARNING Before You Start

OTA reformats LittleFS — you lose:

Recommended flow: backup before → OTA → restore backup after.

Procedure — Option 1: Automatic Orchestrator

The easiest way, with a single command:

cd /home/angelo/Documentos/SIMUT
./tools/ota_apply.py \
    --ip 192.168.3.195 \
    --user admin --pass 'YourCurrentPassword' \
    --firmware .pio/build/pico_w_release/firmware.bin

The script automatically: logs in → backs up .bkp → uploads firmware → commits → applies → waits for boot.

If admin is in factory state (freshly reset), also use --new-pass 'NewPassword' to chpass first.

Procedure — Option 2: Manual Step-by-Step

1. Build Firmware

cd /home/angelo/Documentos/SIMUT
~/.platformio/penv/bin/pio run

Confirm [SUCCESS] and generates .pio/build/pico_w_release/firmware.bin.

2. Web Login + Backup

Open http://<pico-IP> in the browser, log in with admin.

In FilesBackup button → save .bkp locally.

3. Upload Firmware via curl or Web UI

Via curl (more robust):

# Get a nonce
NONCE=$(curl -s http://192.168.3.195/api/login_init | jq -r .nonce)
PASS_HASH=$(echo -n 'YourPassword' | sha256sum | cut -d' ' -f1)

# Login (saves cookie)
curl -s http://192.168.3.195/api/login \
    -d "user=admin&pass=$PASS_HASH&nonce=$NONCE" \
    -c /tmp/simut.cookie

# Upload firmware with commit=1
curl -s http://192.168.3.195/api/restore?op=stage\&commit=1 \
    -F "file=@.pio/build/pico_w_release/firmware.bin" \
    -b /tmp/simut.cookie

Expected response: {"st":5,"bytes":...,"v":0,"committed":1}.

Time: ~30s for 947 KiB of firmware.

4. Trigger Apply

curl -s http://192.168.3.195/api/ota/apply -b /tmp/simut.cookie -X POST

Response: {"accepted":true,"mode":"apply"}. Device reboots immediately.

5. Wait for Boot

Expected time: 60-90 seconds. During this time:

If it takes more than 3 minutes without boot: physical power cycle (unplug + replug USB). This is the documented Bug 2 — related to CYW43/TFT chip state needing a real power-off to reset.

6. Capture OTP from USB Serial

After boot, connect to USB Serial and read the one-time admin password:

SEC-003: FACTORY DEFAULTS ACTIVE
Initial ADMIN password: ABCD1234
Change on first login (forced).

7. Reconfigure WiFi via Serial CLI

conf system ssid YourNetwork
conf system pass YourWiFiPassword
conf ip dhcp
write memory
reload confirm

8. Restore Backup

Web login with the OTP, do chpass, then in FilesRestore → select the .bkp downloaded in step 2.

Expected response: {"st":0,"chip":"...","fc":N,"fsm":0}.

Device reapplies config + history + sensors. No reload needed — restore applies directly.

Post-OTA Verification

Via CLI or web:

# CLI: confirm new version
SIMUT> show system info
 Firmware:  v1.0.0   ← new version

# Web: confirm restored config
curl -s http://192.168.3.195/api/perms -b /tmp/simut.cookie
# {"user":"admin","perms":65535,"version":"v1.0.0"}

Recovery If OTA Fails

Scenario A: Device in BOOTSEL (USB ID 2e8a:0003)

Boot2/firmware corrupted. Reflash via picotool:

# Have a local firmware backup? Use it
picotool load -f -x ~/firmware-rollback-simut/firmware-v1.0.0.uf2

# Or flash the current build
picotool load -f -x .pio/build/pico_w_release/firmware.uf2

Scenario B: Device in App Mode (USB ID 2e8a:f00a) but Firmware Silent (Bug 2)

  1. Try 1200bps trick to enter BOOTSEL:
    ./.venv/bin/python3 -c "
    import serial,time
    s=serial.Serial('/dev/serial/by-id/usb-Raspberry_Pi_Pico_W_*-if00',1200)
    time.sleep(0.5); s.close()
    "
    
  2. If 1200bps fails (even USB hung): physical power cycle — unplug USB for 30s+, replug.

  3. If device enters BOOTSEL or returns to app mode: follow scenario A or wait for complete boot.

Scenario C: Everything Frozen, BOOTSEL Inaccessible

Press and hold the BOOTSEL button on the Pico W while plugging in the USB cable. Device enters forced BOOTSEL. Reflash via picotool.

Technical Limits

Item Value
Maximum firmware size 1020 KiB (app slot)
Current v1.0.0 size 947 KiB (91.6% of limit)
Free margin ~85 KiB
Upload time ~32s for 947 KiB
Apply time (erase+write) ~13s
Post-apply boot time 60-90s typical
Apply attempts (anti-loop) 3 max

Quick FAQ

Q: Do I need to backup every OTA? A: Yes. The LFS partition is erased during the stage upload. Without backup, you lose everything.

Q: Can I OTA from compressed firmware (.bin.gz)? A: The server only accepts RAW (.bin). The PIO build already generates .bin directly.

Q: How many times can I apply OTA? A: No theoretical limit. Pico W QSPI flash withstands ~100k erase cycles per sector. Each apply does ~255 erases.

Q: Does it work over the internet (not just LAN)? A: Technically yes if the device has a public IP + port 80 forwarded. But there’s no HTTPS — credentials travel in the clear. Use only on LAN or via VPN.

Q: Does the .bkp backup work for another Pico W? A: No. The backup is tied to the chip_id (RP2040 unique 64-bit ID). Restore on a different chip returns error st=6 chip mismatch.


Last updated: latest firmware.