15 KiB
RFP Infinity Flashing
This document covers flashing for both the Infinity master and the ESP32-S3 render nodes.
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
Use a cold-boot target when a board only starts reliably after pressing RESET
following a long power loss.
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:
- 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 settings that were stored through the WLED UI must be re-applied unless they are also encoded as firmware defaults.
Roles
- Master:
- Usually
192.168.178.10 - Runs the
/infinityweb UI - Accepts DMX and web commands
- Sends Infinity Sync packets to the nodes
- Keeps one dummy WLED pixel on
GPIO21so the regular WLED UI remains valid - Keeps the real WLED status pixel exclusively on
GPIO48 - Repairs old master
cfg.jsonLED-bus entries soGPIO48is not reused as a normal LED output
- Usually
- Nodes:
- Usually
192.168.178.11to192.168.178.16 - Render the LED output locally
- Receive Infinity Sync from the master
- Usually
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 onGPIO48. - 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:
-
Preferred: open
/infinityon the master and use the mode button in the top bar:Show Mode: ONmeans Infinity Sync is active.WLED Backup: ONmeans Infinity Sync is stopped and regular WLED control can be used.
-
Or stop Infinity on the master by API:
curl -X POST http://192.168.178.10/json/infinity \
-H 'Content-Type: application/json' \
-d '{"enabled":false}'
- Or disable Infinity on one node for local testing:
curl -X POST http://192.168.178.11/json/infinity \
-H 'Content-Type: application/json' \
-d '{"enabled":false}'
Re-enable later:
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.
Build: Master
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
Master firmware output:
.pio/build/rfp_esp32s3_wroom1_n16r8_master/firmware.bin
Conservative master cold-boot build:
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:
.pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/firmware.bin
Build: Nodes
Standard build:
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_3x106
Cold-boot test build:
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_3x106_coldboot
Node firmware outputs:
.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:
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:
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:
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:
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:
cd /home/jan/Documents/RFP/WLED-MM/repo
.venv/bin/python tools/rfp_update_all_ota.py
Dry-run without building or flashing:
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:
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:
.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
- it changes flash/boot related build settings (
- 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
OKtoo early.
USB Flash: Master
Recommended clean-flash helper:
cd /home/jan/Documents/RFP/WLED-MM/repo
./flash_master.sh
Check the serial port:
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
Flash the master via USB:
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/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:
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:
cd /home/jan/Documents/RFP/WLED-MM/repo
./flash_node.sh
Check the serial port:
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
Standard firmware:
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:
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
If upload does not start immediately:
- Hold
BOOT - Tap
RESET - Release
BOOT
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 Flash: Group
USB flashing always happens physically one board after another unless several boards are connected at the same time.
Recommended workflow:
- Build the desired target once.
- Plug in node 1 and flash it.
- Unplug node 1, plug in node 2, repeat.
- 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
- Target:
- Node:
- Target:
rfp_esp32s3_wroom1_n16r8_3x106 - Typical IPs:
192.168.178.11to192.168.178.16 - Binary:
.pio/build/rfp_esp32s3_wroom1_n16r8_3x106/firmware.bin
- Target:
- Cold-boot test node:
- Target:
rfp_esp32s3_wroom1_n16r8_3x106_coldboot - Binary:
.pio/build/rfp_esp32s3_wroom1_n16r8_3x106_coldboot/firmware.bin
- Target:
- Cold-boot test master:
- Target:
rfp_esp32s3_wroom1_n16r8_master_coldboot - Binary:
.pio/build/rfp_esp32s3_wroom1_n16r8_master_coldboot/firmware.bin
- Target:
Recommended Order
- Test the affected board with its cold-boot target:
- master:
rfp_esp32s3_wroom1_n16r8_master_coldboot - node:
rfp_esp32s3_wroom1_n16r8_3x106_coldboot
- master:
- Remove power for at least 20 to 30 seconds
- Verify whether it now boots without pressing
RESET - If it works, roll the same target to the remaining nodes
- 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
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
OTA group-flash template
cd "$RFP_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
Minimal hand-off checklist
- Confirm all nodes are reachable in the same network.
- Build once, then flash.
- Validate reboot behavior on each node.
- If one node fails, resume with
--start-fromfrom that node. - Document which target was used (
standardvscoldboot).
Rollback / removal plan for shared instructions
- Revert this doc section in git:
git checkout -- docs/rfp-node-flashing.md
- Or remove only the hand-off section manually if the rest should stay.
- If a deployment should be rolled back, flash the previous known-good firmware bin with the same OTA/USB commands.