Backup RFP Infinity controller state before Resolume changes
This commit is contained in:
@@ -1,28 +1,42 @@
|
||||
# RFP Infinity Flashing
|
||||
|
||||
This document covers flashing for both the Infinity master and the ESP32-S3 render nodes.
|
||||
This document covers the two production firmware targets for the Infinity installation.
|
||||
There is intentionally no separate `coldboot` firmware anymore: the reliable N16R8
|
||||
boot settings are part of the normal master and node targets.
|
||||
|
||||
## Targets
|
||||
|
||||
- Master target: `rfp_esp32s3_wroom1_n16r8_master`
|
||||
- Conservative master cold-boot target: `rfp_esp32s3_wroom1_n16r8_master_coldboot`
|
||||
- Standard node target: `rfp_esp32s3_wroom1_n16r8_3x106`
|
||||
- Conservative cold-boot test target: `rfp_esp32s3_wroom1_n16r8_3x106_coldboot`
|
||||
- Node target: `rfp_esp32s3_wroom1_n16r8_3x106`
|
||||
|
||||
Use a cold-boot target when a board only starts reliably after pressing `RESET`
|
||||
following a long power loss.
|
||||
## Firmware Release Names
|
||||
|
||||
These names are compiled into the firmware as `WLED_RELEASE_NAME` and show up in
|
||||
WLED update metadata, OTA validation, serial boot logs, and `/json/info`.
|
||||
|
||||
- Master: `RFP_N16R8_MASTER_V20260511E`
|
||||
- Node: `RFP_N16R8_NODE3x106_V20260511E`
|
||||
|
||||
Both targets use the same robust ESP32-S3-WROOM-1 N16R8 boot configuration:
|
||||
|
||||
- Flash: QIO / 16 MB
|
||||
- Flash frequency: 80 MHz
|
||||
- PSRAM: OPI / 8 MB octal
|
||||
- Partition table: `tools/WLED_ESP32_16MB.csv`
|
||||
- USB CDC on boot: disabled
|
||||
- Boot delay: `WLED_BOOTUPDELAY=1200`
|
||||
|
||||
## Clean-Flash Warning
|
||||
|
||||
`erase_flash` removes the complete flash contents, including WLED's saved
|
||||
`cfg.json`, Wi-Fi credentials, static IP settings, presets, and filesystem data.
|
||||
|
||||
The RFP master and node targets now compile the show Wi-Fi as firmware defaults:
|
||||
The RFP master and node targets compile the show Wi-Fi as firmware defaults:
|
||||
|
||||
- SSID: `RFPLicht`
|
||||
- Password: configured in the RFP build flags
|
||||
|
||||
After a full erase the board can therefore join Wi-Fi again, but any runtime-only
|
||||
After a full erase the board can therefore join Wi-Fi again, but runtime-only
|
||||
settings that were stored through the WLED UI must be re-applied unless they are
|
||||
also encoded as firmware defaults.
|
||||
|
||||
@@ -33,66 +47,13 @@ also encoded as firmware defaults.
|
||||
- Runs the `/infinity` web UI
|
||||
- Accepts DMX and web commands
|
||||
- Sends Infinity Sync packets to the nodes
|
||||
- Keeps one dummy WLED pixel on `GPIO21` so the regular WLED UI remains
|
||||
valid
|
||||
- Keeps one dummy WLED pixel on `GPIO21` so the regular WLED UI remains valid
|
||||
- Keeps the real WLED status pixel exclusively on `GPIO48`
|
||||
- Repairs old master `cfg.json` LED-bus entries so `GPIO48` is not reused as
|
||||
a normal LED output
|
||||
- Nodes:
|
||||
- Usually `192.168.178.11` to `192.168.178.16`
|
||||
- Render the LED output locally
|
||||
- Receive Infinity Sync from the master
|
||||
|
||||
The flash procedure is similar for both roles, but the PlatformIO target and `firmware.bin` are different.
|
||||
|
||||
## WLED Backup Mode
|
||||
|
||||
The regular WLED UI is intentionally kept available as a fallback.
|
||||
|
||||
Important behavior:
|
||||
|
||||
- The master uses the WLED UI only for a dummy backup pixel on `GPIO21`; the
|
||||
actual onboard status pixel remains WLED's normal status pixel on `GPIO48`.
|
||||
- The master does not render the show LEDs directly.
|
||||
- The nodes can still be controlled through their regular WLED UI.
|
||||
- If Infinity Sync is enabled, the master sends scene state about every `100 ms`.
|
||||
- While those packets arrive, the node UI may appear to ignore changes because
|
||||
the next Infinity packet overwrites the local WLED state.
|
||||
|
||||
Use regular WLED control as backup in one of these ways:
|
||||
|
||||
1. Preferred: open `/infinity` on the master and use the mode button in the
|
||||
top bar:
|
||||
- `Show Mode: ON` means Infinity Sync is active.
|
||||
- `WLED Backup: ON` means Infinity Sync is stopped and regular WLED control
|
||||
can be used.
|
||||
|
||||
2. Or stop Infinity on the master by API:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.10/json/infinity \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"enabled":false}'
|
||||
```
|
||||
|
||||
3. Or disable Infinity on one node for local testing:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.11/json/infinity \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"enabled":false}'
|
||||
```
|
||||
|
||||
Re-enable later:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.10/json/infinity \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"enabled":true}'
|
||||
```
|
||||
|
||||
For hotspot testing, replace the IPs with the current addresses, for example
|
||||
`10.42.0.213`.
|
||||
- Use three LED outputs: `GPIO4/5/6`, each with `106` LEDs
|
||||
|
||||
## Build: Master
|
||||
|
||||
@@ -113,33 +74,11 @@ Master firmware output:
|
||||
|
||||
```text
|
||||
.pio/build/rfp_esp32s3_wroom1_n16r8_master/firmware.bin
|
||||
```
|
||||
|
||||
Conservative master cold-boot build:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
||||
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
||||
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
||||
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
||||
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
||||
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
||||
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio run -e rfp_esp32s3_wroom1_n16r8_master_coldboot
|
||||
```
|
||||
|
||||
Master cold-boot firmware output:
|
||||
|
||||
```text
|
||||
.pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/firmware.bin
|
||||
build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_MASTER_V20260511E.bin
|
||||
```
|
||||
|
||||
## Build: Nodes
|
||||
|
||||
Standard build:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
@@ -153,10 +92,74 @@ PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio run -e rfp_esp32s3_wroom1_n16r8_3x106
|
||||
```
|
||||
|
||||
Cold-boot test build:
|
||||
Node firmware output:
|
||||
|
||||
```text
|
||||
.pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_NODE3x106_V20260511E.bin
|
||||
```
|
||||
|
||||
## Recommended Update: Master USB First, Nodes Via Master
|
||||
|
||||
Use this for normal show updates. The laptop only needs USB access to the
|
||||
master; it does not need to join the RFP Wi-Fi. The workflow is:
|
||||
|
||||
1. Build master and node firmware locally.
|
||||
2. Flash the master app by USB.
|
||||
3. Hard-reset the master and verify its RFP release over the serial relay.
|
||||
4. Stream node OTA updates through the master to nodes `.11` to `.16`.
|
||||
|
||||
The master USB flash deliberately does **not** run `erase_flash` and does
|
||||
**not** run `uploadfs`. This avoids rewriting the large LittleFS area during a
|
||||
normal firmware update and keeps runtime config/filesystem data intact.
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_master_usb_then_nodes.py --port /dev/ttyACM0
|
||||
```
|
||||
|
||||
Use existing build artifacts without rebuilding:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_master_usb_then_nodes.py --port /dev/ttyACM0 --no-build
|
||||
```
|
||||
|
||||
Resume node updates after a failure:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_master_usb_then_nodes.py --port /dev/ttyACM0 --no-build --nodes-only --start-from 192.168.178.14
|
||||
```
|
||||
|
||||
Flash only the master with the same safe USB app-flash path:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
./flash_master.sh
|
||||
```
|
||||
|
||||
`flash_master.sh` is now intentionally an app/bootloader/partition update only:
|
||||
no full erase and no filesystem upload. Use a full clean flash only when the
|
||||
partition table or filesystem must be deliberately reset.
|
||||
|
||||
## USB App Flash: Master
|
||||
|
||||
Recommended helper:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
./flash_master.sh
|
||||
```
|
||||
|
||||
Manual flow:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
|
||||
|
||||
PORT=/dev/ttyACM0
|
||||
ENV=rfp_esp32s3_wroom1_n16r8_master
|
||||
|
||||
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
||||
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
||||
@@ -165,154 +168,13 @@ PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
||||
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
||||
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
||||
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio run -e rfp_esp32s3_wroom1_n16r8_3x106_coldboot
|
||||
```
|
||||
.venv/bin/python -m platformio run -e "$ENV"
|
||||
|
||||
Node firmware outputs:
|
||||
|
||||
```text
|
||||
.pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
.pio/build/rfp_esp32s3_wroom1_n16r8_3x106_coldboot/firmware.bin
|
||||
```
|
||||
|
||||
## WLAN Flash: Master
|
||||
|
||||
Flash the master by OTA:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets 192.168.178.10 \
|
||||
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_master/firmware.bin
|
||||
```
|
||||
|
||||
## WLAN Flash: Single Node
|
||||
|
||||
Standard firmware to one node:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets 192.168.178.11 \
|
||||
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
```
|
||||
|
||||
## WLAN Flash: Group
|
||||
|
||||
Flash all six nodes in order:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets 192.168.178.11,192.168.178.12,192.168.178.13,192.168.178.14,192.168.178.15,192.168.178.16 \
|
||||
--start-from 192.168.178.11 \
|
||||
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
```
|
||||
|
||||
Resume a failed OTA run from a specific node:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets 192.168.178.11,192.168.178.12,192.168.178.13,192.168.178.14,192.168.178.15,192.168.178.16 \
|
||||
--start-from 192.168.178.14 \
|
||||
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
```
|
||||
|
||||
## WLAN Flash: Full Installation
|
||||
|
||||
Build standard OTA firmware locally, flash all six nodes sequentially, then flash
|
||||
the master last:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_update_all_ota.py
|
||||
```
|
||||
|
||||
Dry-run without building or flashing:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --dry-run --no-build
|
||||
```
|
||||
|
||||
Resume after an interrupted run:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --start-from 192.168.178.14
|
||||
```
|
||||
|
||||
Useful variants:
|
||||
|
||||
```bash
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --nodes-only
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --master-only
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --no-build
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --subnet 192.168.178.0/24
|
||||
```
|
||||
|
||||
The full-update helper is only for standard OTA builds:
|
||||
|
||||
- Nodes: `rfp_esp32s3_wroom1_n16r8_3x106`
|
||||
- Master: `rfp_esp32s3_wroom1_n16r8_master`
|
||||
|
||||
Cold-boot targets remain USB clean-flash targets because OTA does not rewrite
|
||||
the bootloader/flash-mode layout.
|
||||
|
||||
Notes:
|
||||
|
||||
- OTA only works when the laptop and nodes are already in the same IP network.
|
||||
- The OTA helper flashes sequentially, verifies reboot, and then continues to the next node.
|
||||
- The cold-boot test target should be flashed by USB, not by OTA.
|
||||
- Reason:
|
||||
- it changes flash/boot related build settings (`flash_mode`, `memory_type`)
|
||||
- it also uses a different release name for validation
|
||||
- OTA only updates the application image, not the full USB-style flash layout
|
||||
- If you try the cold-boot target by OTA, the usual symptom is exactly this:
|
||||
- upload looks "uncertain"
|
||||
- device stays reachable
|
||||
- uptime keeps increasing
|
||||
- reboot cannot be proven
|
||||
- Reboot verification is now strict:
|
||||
- it records firmware version and uptime before upload
|
||||
- it waits for the node to disappear from the network
|
||||
- it waits for the node to come back
|
||||
- if no offline transition is seen, it requires a clear uptime reset before declaring success
|
||||
- This avoids false positives where a node stays reachable and the script would previously print `OK` too early.
|
||||
|
||||
## USB Flash: Master
|
||||
|
||||
Recommended clean-flash helper:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
./flash_master.sh
|
||||
```
|
||||
|
||||
Check the serial port:
|
||||
|
||||
```bash
|
||||
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
|
||||
```
|
||||
|
||||
Flash the master via USB:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
sudo .venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
.venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
--chip esp32s3 \
|
||||
--port /dev/ttyACM0 \
|
||||
--port "$PORT" \
|
||||
--baud 460800 \
|
||||
--before no_reset \
|
||||
--before default_reset \
|
||||
--after hard_reset \
|
||||
write_flash -z \
|
||||
--flash_mode qio \
|
||||
@@ -321,88 +183,7 @@ sudo .venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
0x0 .pio/build/rfp_esp32s3_wroom1_n16r8_master/bootloader.bin \
|
||||
0x8000 .pio/build/rfp_esp32s3_wroom1_n16r8_master/partitions.bin \
|
||||
0xe000 .piohome/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
|
||||
0x10000 .pio/build/rfp_esp32s3_wroom1_n16r8_master/firmware.bin
|
||||
```
|
||||
|
||||
Conservative master cold-boot firmware:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
sudo .venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
--chip esp32s3 \
|
||||
--port /dev/ttyACM0 \
|
||||
--baud 460800 \
|
||||
--before no_reset \
|
||||
--after hard_reset \
|
||||
write_flash -z \
|
||||
--flash_mode qio \
|
||||
--flash_freq 80m \
|
||||
--flash_size 16MB \
|
||||
0x0 .pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/bootloader.bin \
|
||||
0x8000 .pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/partitions.bin \
|
||||
0xe000 .piohome/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
|
||||
0x10000 .pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/firmware.bin
|
||||
```
|
||||
|
||||
Use USB for the cold-boot master target. OTA is not sufficient for this test
|
||||
because the fix changes bootloader/flash-mode related build settings.
|
||||
|
||||
## USB Flash: Single Node
|
||||
|
||||
Recommended clean-flash helper:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
./flash_node.sh
|
||||
```
|
||||
|
||||
Check the serial port:
|
||||
|
||||
```bash
|
||||
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
|
||||
```
|
||||
|
||||
Standard firmware:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
sudo .venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
--chip esp32s3 \
|
||||
--port /dev/ttyACM0 \
|
||||
--baud 460800 \
|
||||
--before no_reset \
|
||||
--after hard_reset \
|
||||
write_flash -z \
|
||||
--flash_mode qio \
|
||||
--flash_freq 80m \
|
||||
--flash_size 16MB \
|
||||
0x0 .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/bootloader.bin \
|
||||
0x8000 .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/partitions.bin \
|
||||
0xe000 .piohome/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
|
||||
0x10000 .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
```
|
||||
|
||||
Cold-boot test firmware:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
sudo .venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
--chip esp32s3 \
|
||||
--port /dev/ttyACM0 \
|
||||
--baud 460800 \
|
||||
--before no_reset \
|
||||
--after hard_reset \
|
||||
write_flash -z \
|
||||
--flash_mode dio \
|
||||
--flash_freq 80m \
|
||||
--flash_size 16MB \
|
||||
0x0 .pio/build/rfp_esp32s3_wroom1_n16r8_3x106_coldboot/bootloader.bin \
|
||||
0x8000 .pio/build/rfp_esp32s3_wroom1_n16r8_3x106_coldboot/partitions.bin \
|
||||
0xe000 .piohome/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin \
|
||||
0x10000 .pio/build/rfp_esp32s3_wroom1_n16r8_3x106_coldboot/firmware.bin
|
||||
0x10000 build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_MASTER_V20260511E.bin
|
||||
```
|
||||
|
||||
If upload does not start immediately:
|
||||
@@ -410,94 +191,284 @@ If upload does not start immediately:
|
||||
1. Hold `BOOT`
|
||||
2. Tap `RESET`
|
||||
3. Release `BOOT`
|
||||
4. Run the upload again
|
||||
|
||||
Use USB for the first flash of `rfp_esp32s3_wroom1_n16r8_3x106_coldboot`.
|
||||
After that, if you go back to the normal node firmware, OTA is fine again with the standard node target.
|
||||
## USB Clean Flash: Node
|
||||
|
||||
## USB Flash: Group
|
||||
|
||||
USB flashing always happens physically one board after another unless several boards are connected at the same time.
|
||||
|
||||
Recommended workflow:
|
||||
|
||||
1. Build the desired target once.
|
||||
2. Plug in node 1 and flash it.
|
||||
3. Unplug node 1, plug in node 2, repeat.
|
||||
4. Continue until node 6 is done.
|
||||
|
||||
If the same serial path is reused each time, the single-node USB command above is the repeatable group-flash procedure.
|
||||
|
||||
## Quick Difference: Master vs Node
|
||||
|
||||
- Master:
|
||||
- Target: `rfp_esp32s3_wroom1_n16r8_master`
|
||||
- Typical IP: `192.168.178.10`
|
||||
- Binary: `.pio/build/rfp_esp32s3_wroom1_n16r8_master/firmware.bin`
|
||||
- Node:
|
||||
- Target: `rfp_esp32s3_wroom1_n16r8_3x106`
|
||||
- Typical IPs: `192.168.178.11` to `192.168.178.16`
|
||||
- Binary: `.pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin`
|
||||
- Cold-boot test node:
|
||||
- Target: `rfp_esp32s3_wroom1_n16r8_3x106_coldboot`
|
||||
- Binary: `.pio/build/rfp_esp32s3_wroom1_n16r8_3x106_coldboot/firmware.bin`
|
||||
- Cold-boot test master:
|
||||
- Target: `rfp_esp32s3_wroom1_n16r8_master_coldboot`
|
||||
- Binary: `.pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/firmware.bin`
|
||||
|
||||
## Recommended Order
|
||||
|
||||
1. Test the affected board with its cold-boot target:
|
||||
- master: `rfp_esp32s3_wroom1_n16r8_master_coldboot`
|
||||
- node: `rfp_esp32s3_wroom1_n16r8_3x106_coldboot`
|
||||
2. Remove power for at least 20 to 30 seconds
|
||||
3. Verify whether it now boots without pressing `RESET`
|
||||
4. If it works, roll the same target to the remaining nodes
|
||||
5. If it still fails, inspect the hardware power-up path on `EN`, 3.3V rail, and any external loads
|
||||
|
||||
## Hand-off für andere (teamfähig)
|
||||
|
||||
Use this section when you want to provide the procedure to other people without hard-coding your local paths.
|
||||
|
||||
### Quickstart Template
|
||||
Recommended helper:
|
||||
|
||||
```bash
|
||||
export RFP_REPO="/path/to/WLED-MM/repo"
|
||||
export NODE_BIN="/path/to/node/bin" # optional if node is already in PATH
|
||||
|
||||
cd "$RFP_REPO"
|
||||
|
||||
PATH="$NODE_BIN:$PATH" \
|
||||
NPM_CONFIG_CACHE="$RFP_REPO/.npm-cache" \
|
||||
PLATFORMIO_CORE_DIR="$RFP_REPO/.piohome" \
|
||||
PLATFORMIO_PACKAGES_DIR="$RFP_REPO/.piohome/packages" \
|
||||
PLATFORMIO_PLATFORMS_DIR="$RFP_REPO/.piohome/platforms" \
|
||||
PLATFORMIO_CACHE_DIR="$RFP_REPO/.piohome/.cache" \
|
||||
PLATFORMIO_BUILD_CACHE_DIR="$RFP_REPO/.piohome/buildcache" \
|
||||
.venv/bin/python -m platformio run -e rfp_esp32s3_wroom1_n16r8_3x106
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
./flash_node.sh
|
||||
```
|
||||
|
||||
### OTA group-flash template
|
||||
Manual flow:
|
||||
|
||||
```bash
|
||||
cd "$RFP_REPO"
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
|
||||
|
||||
PORT=/dev/ttyACM0
|
||||
ENV=rfp_esp32s3_wroom1_n16r8_3x106
|
||||
|
||||
.venv/bin/python .piohome/packages/tool-esptoolpy/esptool.py \
|
||||
--chip esp32s3 \
|
||||
--port "$PORT" \
|
||||
erase_flash
|
||||
|
||||
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
||||
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
||||
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
||||
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
||||
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
||||
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
||||
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio run -e "$ENV" -t clean
|
||||
|
||||
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
||||
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
||||
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
||||
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
||||
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
||||
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
||||
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio run -e "$ENV" -t upload --upload-port "$PORT"
|
||||
```
|
||||
|
||||
## OTA Preflight
|
||||
|
||||
Check whether the current devices look OTA-updatable before flashing:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --preflight-only --no-build
|
||||
```
|
||||
|
||||
Single node:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets <ip1>,<ip2>,<ip3>,<ip4>,<ip5>,<ip6> \
|
||||
--start-from <ip1> \
|
||||
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
|
||||
--targets 192.168.178.11 \
|
||||
--firmware .pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin \
|
||||
--expect-release RFP_N16R8_NODE3x106_V20260511E \
|
||||
--preflight-only
|
||||
```
|
||||
|
||||
### Minimal hand-off checklist
|
||||
## OTA Update: Whole Installation From RFP Wi-Fi
|
||||
|
||||
1. Confirm all nodes are reachable in the same network.
|
||||
2. Build once, then flash.
|
||||
3. Validate reboot behavior on each node.
|
||||
4. If one node fails, resume with `--start-from` from that node.
|
||||
5. Document which target was used (`standard` vs `coldboot`).
|
||||
This builds locally and flashes nodes `.11` to `.16` first, then the master `.10`.
|
||||
The master is flashed last so the show controller stays available while the nodes
|
||||
update.
|
||||
|
||||
### Rollback / removal plan for shared instructions
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py
|
||||
```
|
||||
|
||||
1. Revert this doc section in git:
|
||||
- `git checkout -- docs/rfp-node-flashing.md`
|
||||
2. Or remove only the hand-off section manually if the rest should stay.
|
||||
3. If a deployment should be rolled back, flash the previous known-good firmware bin with the same OTA/USB commands.
|
||||
If your PC is not connected to the RFP Wi-Fi and the master is already on the
|
||||
right release, keep the master connected by USB and let the master relay node
|
||||
OTA updates through its own Wi-Fi connection:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --via-master-usb --port /dev/ttyACM0 --no-build
|
||||
```
|
||||
|
||||
This node-only relay is still useful for resumes and tests. For full updates,
|
||||
prefer `tools/rfp_update_master_usb_then_nodes.py` so the master is flashed and
|
||||
verified first. The relay streams the node firmware through the master and does
|
||||
not store the full file on the master filesystem. The default relay baud rate is
|
||||
`921600` for faster node updates; opening `/dev/ttyACM0` can reset the ESP32-S3,
|
||||
so the tool waits briefly before sending commands. If a flaky USB cable or hub
|
||||
causes serial errors, retry with `--relay-baud 115200`.
|
||||
|
||||
The updater prefers the named release binaries from `build_output/release/` when
|
||||
they exist and verifies the expected RFP release name after reboot:
|
||||
|
||||
- Nodes: `RFP_N16R8_NODE3x106_V20260511E`
|
||||
- Master: `RFP_N16R8_MASTER_V20260511E`
|
||||
|
||||
During the controlled migration from older generic WLED-MM builds, the updater
|
||||
sends WLED's `skipValidation=1` upload parameter by default. The update is still
|
||||
accepted only if the target reboots and then reports the expected RFP release
|
||||
name in `/json/info`.
|
||||
|
||||
If you explicitly want WLED's release-name validation to block mismatches before
|
||||
upload, use:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --no-skip-validation
|
||||
```
|
||||
|
||||
Use existing build artifacts without rebuilding:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --no-build
|
||||
```
|
||||
|
||||
Devices that already report the selected RFP release are skipped by default.
|
||||
This avoids reflashing the same binary and then trying to prove an update from
|
||||
an unchanged release string. To force reflashing the same release anyway:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --no-build --force-current-release
|
||||
```
|
||||
|
||||
Resume from a failed device:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_update_all_ota.py --no-build --start-from 192.168.178.14
|
||||
```
|
||||
|
||||
## OTA Update: Single Device
|
||||
|
||||
Master:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets 192.168.178.10 \
|
||||
--firmware build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_MASTER_V20260511E.bin \
|
||||
--expect-release RFP_N16R8_MASTER_V20260511E \
|
||||
--skip-validation
|
||||
```
|
||||
|
||||
Node:
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
.venv/bin/python tools/rfp_network_flash.py flash \
|
||||
--targets 192.168.178.11 \
|
||||
--firmware build_output/release/WLEDMM_14.7.2-mdev_RFP_N16R8_NODE3x106_V20260511E.bin \
|
||||
--expect-release RFP_N16R8_NODE3x106_V20260511E \
|
||||
--skip-validation
|
||||
```
|
||||
|
||||
## Why OTA Can Fail After Build Success
|
||||
|
||||
OTA updates only the application image. It does not reliably replace bootloader,
|
||||
flash mode, or partition table. If a board still has an old partition layout, do
|
||||
one USB clean flash with the production target first. After that, OTA should be
|
||||
usable again.
|
||||
|
||||
The OTA helper is intentionally strict: upload is considered successful if the
|
||||
device reboot is proven by an offline transition, an uptime reset, or a WLED
|
||||
transport reset during upload plus the expected RFP release name in `/json/info`.
|
||||
When flashing the exact same release again, the transport-reset proof is weaker,
|
||||
so the whole-installation updater skips already matching devices by default.
|
||||
|
||||
## Global 2D Timing Check
|
||||
|
||||
The `/infinity` scene controls intentionally expose only one brightness control.
|
||||
It sits next to `Master Speed`, starts at `100%`, and the old per-row dimmers
|
||||
are forced to full output by the controller UI.
|
||||
|
||||
Global 2D animations derive their beat position from Infinity master time, not
|
||||
from frame arrival time on each node. `Master Speed` is BPM, with one beat equal
|
||||
to one visible 2D step. For example, `Checkerd` at `240 BPM` changes pattern
|
||||
`240` times per minute.
|
||||
|
||||
Use `Strobe` in the `/infinity` Global 2D mode selector to check sync visually.
|
||||
Its `Pulse Width` control is the normal `Size` control renamed for this mode.
|
||||
The strobe is rendered from the shared beat phase, so all nodes should flash
|
||||
in parallel at every BPM value from `20` to `240`.
|
||||
|
||||
## Master Crash Capture
|
||||
|
||||
If the master ever restarts unexpectedly, capture the next run with a serial log.
|
||||
This keeps the production partition layout unchanged while still decoding ESP32
|
||||
panic backtraces.
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
mkdir -p /tmp/rfp-master-crash
|
||||
|
||||
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
||||
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
||||
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
||||
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
||||
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
||||
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
||||
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio device monitor \
|
||||
-e rfp_esp32s3_wroom1_n16r8_master \
|
||||
--port /dev/ttyACM0 \
|
||||
-b 115200 \
|
||||
--filter esp32_exception_decoder \
|
||||
--filter log2file
|
||||
```
|
||||
|
||||
After a crash, save:
|
||||
|
||||
- The monitor log from the current directory or PlatformIO log output
|
||||
- The first `rst:` line after reboot
|
||||
- Any `Guru Meditation`, `panic`, or decoded backtrace lines
|
||||
- The current `/json/info` fields `ver`, `release`, `e32code`, and `e32text`
|
||||
|
||||
Do not switch to a coredump partition shortly before the event unless a repeated
|
||||
crash proves that serial logs are not enough.
|
||||
|
||||
## WLED Backup Mode
|
||||
|
||||
The regular WLED UI is intentionally kept available as a fallback.
|
||||
|
||||
- `Show Mode: ON` means Infinity Sync is active.
|
||||
- `WLED Backup: ON` means Infinity Sync is stopped and regular WLED control can be used.
|
||||
|
||||
Stop Infinity on the master by API:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.10/json/infinity \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"enabled":false}'
|
||||
```
|
||||
|
||||
Re-enable later:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.10/json/infinity \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"enabled":true}'
|
||||
```
|
||||
|
||||
## Coldboot Diagnosis
|
||||
|
||||
The firmware side is now consolidated into the normal production targets. If a
|
||||
board still starts only after pressing `RESET`, capture the serial log directly
|
||||
after real power-on.
|
||||
|
||||
```bash
|
||||
cd /home/jan/Documents/RFP/WLED-MM/repo
|
||||
|
||||
PATH=/home/jan/Documents/RFP/Finanz_App/node/current/bin:$PATH \
|
||||
NPM_CONFIG_CACHE=$PWD/.npm-cache \
|
||||
PLATFORMIO_CORE_DIR=$PWD/.piohome \
|
||||
PLATFORMIO_PACKAGES_DIR=$PWD/.piohome/packages \
|
||||
PLATFORMIO_PLATFORMS_DIR=$PWD/.piohome/platforms \
|
||||
PLATFORMIO_CACHE_DIR=$PWD/.piohome/.cache \
|
||||
PLATFORMIO_BUILD_CACHE_DIR=$PWD/.piohome/buildcache \
|
||||
.venv/bin/python -m platformio device monitor \
|
||||
-e rfp_esp32s3_wroom1_n16r8_master \
|
||||
--port /dev/ttyACM0 \
|
||||
-b 115200
|
||||
```
|
||||
|
||||
Expected directly after power-on:
|
||||
|
||||
```text
|
||||
rst:0x1 (POWERON_RESET)
|
||||
SPI_FAST_FLASH_BOOT
|
||||
```
|
||||
|
||||
If there is no clean boot log until the reset button is pressed, inspect hardware:
|
||||
|
||||
- `EN` / `CHIP_PU` must not float.
|
||||
- Use a proper pull-up and reset delay, e.g. `10 kOhm` pull-up plus `1 uF` from `EN` to GND.
|
||||
- If the 3.3 V rail rises slowly or external loads drag it down, use a reset supervisor.
|
||||
- Check strapping pins and external DMX/LED wiring for backfeeding during power-up.
|
||||
|
||||
Reference in New Issue
Block a user