# Firmware picker Each result now includes **Restore your settings after flashing**. Its commands follow the selected logging mode and the exact image's verified role/hardware controls. Click On, Off, or Check to view and copy the commands; Companion MQTT and GPS show their app/WebConfig steps instead. See [feature switches by role](role_feature_switches.md) for the full reference. The [USB web console](https://flasher.meshcore.io/console) works with the default ASCII terminal on USB Companion and infrastructure roles. Pick the choices in any order. Every selection narrows all the other controls to firmware combinations that were actually built in the current release set. The optional chip-family filter (ESP32, nRF52, RP2040, or STM32) can narrow the hardware list first. You can skip it: picking hardware fills it in automatically. Chip family and hardware are the only dropdowns. All remaining choices use buttons. **Firmware profile** combines OTA support, Full/standard, and sensor or storage differences in one choice. The picker reads public release metadata from GitHub. It does not upload device information. Hardware names, target names, and download links come directly from the published firmware assets.
Loading release information...
For a new installation, choose the exact board and role, prefer a FULL / complete profile when it is available, and select Full install / layout migration (merged .bin). Narrower profiles remain available when their reduced transport or feature set is intentional.
Upgrading an existing ESP32 infrastructure node from a smaller partition
layout? The selected Full result links directly to its exact board and
role partition-expansion ZIP when published. Follow its included README
to check the installed OTA target and source layout for a supported Wi-Fi
or LoRa route. If no unique matching ZIP is available, the picker links
to the utility release to check availability. USB installation uses the matching
merged image instead. An app-only .bin cannot change the partition table.
If the installed firmware supports it, run get storage.layout
to see the live flash size and OTA slots. Firmware version alone does not
prove the installed layout.
Pick in any order. Use Any to clear one choice, or clear everything with the button below. The address bar updates with your choices; copy its URL to reopen or share the same selection.
Exact firmware match
Use this for uncommon board suffixes or expert recovery. A filename match is not a board-identity check.
-merged.bin | Erase/fresh install, recovery, role migration, or partition-profile change on ESP32 over USB |
| Non-merged .bin | Update an existing same-board, same-role, same-partition installation |
| *-migration.zip | Exact ESP32 board and role staged partition migration; follow its included README for Wi-Fi or LoRa steps |
| Other .zip firmware shown by the picker | Native nRF52 Serial DFU update package; it is not an extra archive |
| .uf2 | UF2 bootloader drag-and-drop install or update |
| .hex | Erase/recovery flash with a supported wired programmer |
Never send a merged ESP32 image through browser OTA or LoRa OTA. Back up the
node identity, configuration, keys, and radio settings, and verify every
filename suffix before flashing. A staged migration writes the partition table;
power loss during that write can require cable recovery. The package README
states what each route preserves and which older layouts it accepts.
## LoRa OTA and OTAFIX
A LoRa OTA capable build can receive and stage updates for its role. A later
LoRa update still needs an exact target identity,
compatible partition signature, matching radio settings, and the correct
update package.
Selecting an nRF52 board shows its direct **Bootloader UF2**, **Bootloader DFU
ZIP**, and **Bootloader HEX (SWD)** downloads, when an exact published profile
is available. ESP32 and other chip families do not show this section. The web
picker checks the latest stable OTAFIX release; the downloadable picker
includes the bootloader release named in its saved catalog. If a board has no
verified mapping or a file is missing, the picker explains that instead of
offering another board's bootloader. MeshTower internal and microSD remain
separate; RAK3401 and RAK4631 each use their adaptive storage bootloader.
Ikoka Stick, Nano and Handheld plus SolarXiao use the XIAO bootloader;
Wio Tracker L1 1W and E-Ink use the L1 bootloader. See the
[board coverage audit](https://github.com/mikecarper/Adafruit_nRF52_Bootloader_OTAFIX/blob/feature/ota-delta-apply/docs/meshcore-hardware-coverage.md)
for the source checks and boards still awaiting a dedicated, tested release.
Board mappings and file names, URLs, sizes and SHA-256 hashes come from
`bootloader-manifest.json` in the
[OTAFIX release](https://github.com/mikecarper/Adafruit_nRF52_Bootloader_OTAFIX/releases/latest).
Application UF2 and DFU files do not install a bootloader. Follow the bootloader
release's migration instructions if the installed version needs a recovery bridge.
nRF52 LoRa OTA requires an OTAFIX bootloader built for the exact board and
storage layout. Select the hardware-matched HEX, Serial DFU ZIP, or
bootloader-update UF2 for the application image being installed.
## Hardware and variant names
Hardware families with multiple released targets get **Hardware variant**
buttons. They separate revisions, display type, expansion kit, radio/PA layout,
pin map, and other physical differences without crowding the Hardware dropdown.
**Firmware profile** buttons combine OTA support, Full/standard, and choices
that need a different image or wiring, such as serial port or external storage.
The legacy `no_external_sensors` profile is labeled **Receives LoRa OTA -
Reduced optional sensors** on the same button. On RAK3401 and RAK4631 this
compact profile uses internal storage without an external storage board. The
reduction does not disable generic I2C or unrelated board-integrated peripherals.
Reduced RAK3401 and RAK4631 targets retain INA219/INA226/INA260/INA3221 as
voltage/current entries in the optional sensor table. They are not the only I2C
users: the SSD1306 OLED, supported autodiscovered RTCs, and RAK12500 GPS remain
separate I2C peripherals in compatible recipes. RAK12501/L76K GPS uses Serial1
instead. The explicit RAK4631 Serial1 bridge omits the combined GPS provider
because its bridge owns the RAK12501 UART, so that legacy image does not expose
RAK12500 either. The firmware-configured INA3221 and RAK12500 addresses are both
`0x42`; to install both, keep RAK12500 at `0x42`, strap INA3221 A0 to SCL for
`0x43`, and use a build with `-DTELEM_INA3221_ADDRESS=0x43`. Companion power saving,
controllable FEM receive gain, and radio-chip receive gain are saved settings
rather than separate recommended firmware files. Do not substitute a similarly
named physical target.
The header-wired RAK19007 W25Q16 LoRa-OTA recipes are also exact hardware
variants, labeled **External storage board (W25Q16)** in the picker. W25Q16 is
the flash-memory part on the added storage board; RAK13302 identifies the radio
module, not the storage board. Choose this variant for RAK4631 or for RAK3401 + RAK13302 only
when that core/radio combination, the `EF4015` flash wiring, and its matching
OTAFIX bootloader are all present. The common base-board wiring does not make
the two firmware or bootloader identities interchangeable.
The picker recommends one Full Companion image instead of separate USB, BLE,
ordinary WiFi, and USB-logging images. On ESP32, logging is off by default so
the one USB TTY starts in ASCII and automatically changes to framed Companion
when a complete `<` frame arrives. Enabling logging gives that TTY to the
plaintext CLI/logger and disables framed USB Companion until logging is turned
off and the normal ASCII-to-binary mode switch occurs. nRF52 Full Companion
retains its optional dedicated interface `02`.
Exact filename search finds compatibility images included in the selected
release family. For older releases, open their GitHub release pages.
The 1.17.1.8 public matrix keeps one ESP32 Full image per board and role.
Some richer images, including Station G2 Full, retain an observer-named OTA
identity. Exact older identities needed by a partition migration are packaged
inside that board and role's migration ZIP instead of adding a second ordinary
Full download. A deliberate target-ID override does not make a different
partition layout or physical board compatible.
Some normal ESP32 roles begin in the legacy 1.25 MiB dual-OTA layout but have
a Full image with larger slots. The 1.17.1.8 utility release contains 94 exact
board and role migration ZIPs. Each package checks its source layout and target
identity, contains the bridge and Full application files for its supported
routes, and documents what saved data it preserves. Use the package's own Full
application after the bridge; do not substitute a loose Full image with a
different target ID. If no exact package exists, use the matching merged USB
image. Once migrated, routine app-only updates still need the same target and
partition signature.
## Maintaining the runtime directions
The online picker and downloadable HTML use the same command renderer.
Hardware-specific controls are enabled only when `_data/firmware_controls.json`
matches the selected release family and exact target. If that metadata is
missing or belongs to another release, the picker retains basic role/logging
directions and links the complete guide without inventing hardware support.
For 1.17.1.6, that JSON also records the verified LoRa OTA role of each image
and USB logging modes where the packaged application was checked. Logging
metadata is tied to the source hash of its firmware file. The normal iKoka
30 dBm repeater has USB logging and LoRa OTA; its compact no-external-sensors
image has LoRa OTA without logging.
Capacity directions come from each qualified profile's recorded reductions and
are tied to the source hash of the selected download. The older 1.17.1.5 USB
sleep workaround stays limited to that release.
After qualifying a new release, resolve its PlatformIO configuration with no
other PlatformIO process running, then generate the controls from that source
revision and its staged manifests:
```bash
pio project config --json-output > /tmp/meshcore-picker-pio-config.json
python3 scripts/generate_picker_controls.py \
--stage /path/to/staged-release \
--pio-config /tmp/meshcore-picker-pio-config.json
```
Refresh the `data-controls-url` version query when publishing the generated
metadata so browsers fetch the new release's controls.
The generated `partitionMigrations` lookup comes from `BOARDS` in
`scripts/package_esp32_partition_migration.py`, the same exact board/role table
used to build the migration packages. Expanded ESP32 Full results use this
lookup (including canonical board/role recipes for Observer profiles), then
require one matching published ZIP in the same release family's utility page.
Hardware variants and roles remain distinct. Unlisted targets, missing or
ambiguous assets, and stale metadata never produce a guessed download link.
For the downloadable version, save the release family's public GitHub release
objects as a JSON array, then package the same picker UI and controls:
```bash
python3 scripts/package_firmware_picker.py \
--releases-json /path/to/releases.json \
--output /path/to/FIRMWARE-PICKER.html
```
This HTML embeds its catalog and directions, so selections work without an
internet connection. Firmware downloads and the USB web console still need
network access. When replacing the downloadable picker on release pages,
update its entry in each page's `SHA256SUMS.txt` as well.
## Memory-corrected 1.17.1.5 downloads
Corrected downloads retain the 1.17.1.5 release page and use source suffix
`aa20e927`, with `1e4d1e16` for Wireless Paper Full's 350-contact follow-up.
The picker accepts replacement source hashes within that exact
release version. Its installation directions identify the nRF52 queue-sharing
behavior, Wireless Paper Full's 350 contacts with a shared 256/128-slot queue,
and the 150-contact limit on the other six affected ESP32 Full profiles.
Those notices apply only to the corrected files. See the
[memory correction details](old-releases/1.17.1.5.md#memory-corrections-in-aa20e927)
and each replacement's `.memory.json` report before updating.