Skip to main content
Colorado Mesh · Bot Firmware

An on-device botfor the Colorado mesh.

Companion-radio firmware built on top of MeshCore — pair the radio with the MeshCore app once, then the on-device bot answers ping, path, trace, status, neighbors, magic8, and more without the phone in the loop. No app bridge, no internet, no cloud.

133
Boards built per release
On-device
No internet, no cloud
Open
MIT licensed
What it adds

A focused patch queue on top of upstream MeshCore.

The release-built firmware applies an ordered patch queue on top of a pinned MeshCore commit, so reviewers can see exactly what deviates from upstream. The patches stay small and behavioral — they don't fork the radio stack.

Bot command registry

Adds ping, hello, path, trace, status, channels, version, stats, magic8, prefix, time, lora, id, neighbors, and more — all answered on-device.

Channel-aware response policy

Replies only on #bot and #testing for normal commands. #emergency messages are forwarded to Public. All other channels are silent.

Multi-bot response coordinator

Hop-aware delay (~3 s per hop, capped at 15 s) on top of a ~1.5 s base + 2.2 s jitter, bounded by a 75 s TTL. Each reply carries a 4-hex request token so peer bots can correlate and suppress duplicates — even when reply text differs (hop count, SNR, recv time).

Prefixless commands everywhere

No `!` or `bot ` prefix needed — send the command name on its own, whether you're on #bot, #testing, or DMing the bot directly. Two-byte path hash by default for compact trace results.

Plug-and-play discovery

Sends its first flood advert ~5 s after boot so the rest of the mesh learns the bot is up almost immediately, and auto-overwrites the oldest contact when the table fills. Channel-side coordination is token-based, so dropping a second bot in the area needs no peer config.

Tunable host-side prefs

CLI-tunable channels, response delay, advert intervals, and known-bot list. Private-key import/export is disabled in release builds.

Command reference

Send these on #bot, or DM the bot directly.

Prefixless on both channels and DMs — just send the command name, no ! or bot prefix. In any channel besides #bot, #testing, and #emergency, the bot stays silent.

CommandResponse
pingPong
helloHello @[<your-name>], from <bot-name>
pathCompact route summary back to you, e.g. Path 3h@2B SNR -6.25 | 2751 → ea4d → 430d
traceActive trace request along your reverse path
statusBot uptime, battery, storage, send counters
neighborsNodes heard directly within the last hour
versionFirmware version + build date
magic8 <question>Classic 8-ball answer
helpList all commands
Multi-bot etiquette

Why nearby bots don't spam the channel

When several Colorado bots hear the same command, the response coordinator adds a hop-aware delay (~3 s per hop, capped at 15 s) on top of a ~1.5 s base + ~2.2 s jitter, bounded by a 75 s pending TTL. Each queued reply is prefixed with a 4-hex request token derived from the request fingerprint. Peer bots see the token go by, mark that request handled, and drop their pending reply. The closest bot wins the race; everyone else stays quiet — so #bot stays readable even with dense bot coverage.

Latest release

Firmware releases

Published builds from the meshcore-bot-firmware repo.

Checking GitHub for the latest release…

Release information
Supported boards

133 board variants build on every release

ESP32: 57 · nRF52: 68 · RP2040: 4 · STM32: 4. Each board ships in USB and BLE variants where supported.

133 of 133 shown

BoardPlatformVariant
Ebyte EoRa-S3ESP32BLE
Ebyte EoRa-S3ESP32USB
GAT562 30S Mesh KitnRF52BLE
GAT562 30S Mesh KitnRF52USB
GAT562 Mesh Tracker PronRF52BLE
GAT562 Mesh Tracker PronRF52USB
GAT562 Mesh Watch13nRF52BLE
Heltec E213ESP32BLE
Heltec E213ESP32USB
Heltec WSL3ESP32BLE
Heltec WSL3ESP32USB
Heltec Wireless PaperESP32BLE
Heltec Wireless PaperESP32USB
Heltec Wireless TrackerESP32BLE
Heltec Wireless TrackerESP32USB
Heltec ct62ESP32BLE
Heltec ct62ESP32USB
Heltec mesh solarnRF52BLE
Heltec mesh solarnRF52USB
Heltec t096nRF52BLE
Heltec t096nRF52USB
Heltec t114nRF52BLE
Heltec t114nRF52USB
Heltec t114 without displaynRF52BLE
Heltec t114 without displaynRF52USB
Heltec v2ESP32BLE
Heltec v2ESP32USB
Heltec v3ESP32BLE
Heltec v3ESP32USB
KeepteenLT1nRF52BLE
KeepteenLT1nRF52USB
LilyGo T-Echo-LitenRF52BLE
LilyGo T-EchonRF52BLE
LilyGo T-EchonRF52USB
LilyGo T3S3 sx1262ESP32BLE
LilyGo T3S3 sx1262ESP32USB
LilyGo T3S3 sx1276ESP32BLE
LilyGo T3S3 sx1276ESP32USB
LilyGo TBeam 1WESP32BLE
LilyGo TBeam 1WESP32USB
LilyGo TDeckESP32BLE
LilyGo TDeckESP32USB
LilyGo TETH Elite sx1262ESP32BLE
LilyGo TETH Elite sx1262ESP32USB
LilyGo TLora V2 1 1 6ESP32BLE
LilyGo TLora V2 1 1 6ESP32USB
M5Stack Unit C6LESP32BLE
M5Stack Unit C6LESP32USB
Mesh pocketnRF52BLE
Mesh pocketnRF52USB
Meshadventurer sx1262ESP32BLE
Meshadventurer sx1262ESP32USB
Meshadventurer sx1268ESP32BLE
Meshadventurer sx1268ESP32USB
MeshtinynRF52BLE
MeshtinynRF52USB
Minewsemi me25ls01nRF52BLE
Minewsemi me25ls01nRF52USB
Nano G2 UltranRF52BLE
Nano G2 UltranRF52USB
PicoWRP2040USB
ProMicronRF52BLE
ProMicronRF52USB
R1NeonRF52BLE
R1NeonRF52USB
RAK 11310RP2040USB
RAK 3112ESP32BLE
RAK 3112ESP32USB
RAK 3401nRF52BLE
RAK 3401nRF52USB
RAK 3x72STM32USB
RAK 4631nRF52BLE
RAK 4631nRF52USB
RAK WisMesh TagnRF52BLE
RAK WisMesh TagnRF52USB
SenseCap SolarnRF52BLE
SenseCap SolarnRF52USB
Station G2ESP32BLE
Station G2ESP32USB
T Beam S3 Supreme SX1262ESP32BLE
Tbeam SX1262ESP32BLE
Tbeam SX1276ESP32BLE
ThinkNode M1nRF52BLE
ThinkNode M1nRF52USB
ThinkNode M2ESP32BLE
ThinkNode M2ESP32USB
ThinkNode M3nRF52BLE
ThinkNode M3nRF52USB
ThinkNode M5ESP32BLE
ThinkNode M5ESP32USB
ThinkNode M6nRF52BLE
ThinkNode M6nRF52USB
Tiny RelaySTM32USB
WioTrackerL1EinknRF52BLE
WioTrackerL1nRF52BLE
WioTrackerL1nRF52USB
Xiao C3ESP32BLE
Xiao C3ESP32USB
Xiao S3 WIOESP32BLE
Xiao S3 WIOESP32USB
Xiao nrf52nRF52BLE
Xiao nrf52nRF52USB
Xiao rp2040RP2040USB
heltec tracker v2ESP32BLE
heltec tracker v2ESP32USB
heltec v4ESP32BLE
heltec v4ESP32USB
heltec v4 tftESP32BLE
heltec v4 tftESP32USB
ikoka handheld nrf e22 30dbm 096nRF52BLE
ikoka handheld nrf e22 30dbm 096nRF52USB
ikoka handheld nrf e22 30dbm 096 rotatednRF52BLE
ikoka handheld nrf e22 30dbm 096 rotatednRF52USB
ikoka nano nrf 22dbmnRF52BLE
ikoka nano nrf 22dbmnRF52USB
ikoka nano nrf 30dbmnRF52BLE
ikoka nano nrf 30dbmnRF52USB
ikoka nano nrf 33dbmnRF52BLE
ikoka nano nrf 33dbmnRF52USB
ikoka stick nrf 22dbmnRF52BLE
ikoka stick nrf 22dbmnRF52USB
ikoka stick nrf 30dbmnRF52BLE
ikoka stick nrf 30dbmnRF52USB
ikoka stick nrf 33dbmnRF52BLE
ikoka stick nrf 33dbmnRF52USB
nibble screen connectESP32BLE
nibble screen connectESP32USB
t1000enRF52BLE
t1000enRF52USB
waveshare rp2040 loraRP2040USB
wio-e5-miniSTM32USB
wio-e5STM32USB
wio wm1110nRF52BLE
How to flash

Three paths from download to flashed bot.

The web flasher is the fastest path for most operators. PlatformIO is for anyone building from source or running a custom patch. Manual esptool / nrfutil is the fallback when the browser-based path isn't an option.

EASIEST

MeshCore web flasher

Open flasher.meshcore.io in Chrome or Edge, pick "Custom firmware," drag in the right file for your board (merged.bin / uf2 / zip), and click Connect → Flash.

Open flasher.meshcore.io
SOURCE BUILD

PlatformIO from source

Clone the repo with --recurse-submodules, apply patches, then pio run -e <board>_companion_radio_usb -t upload. Swap the env for your specific board.

Open guide
MANUAL

esptool / nrfutil

ESP32: esptool.py write_flash 0x0 <board>-merged.bin. nRF52: drag the .uf2 onto the bootloader drive, or use adafruit-nrfutil with the .zip.

Open guide
After you flash

First-time setup — four things, in order.

Because this is a companion-radio firmware, the radio still needs a one-time hand-off from a phone before the bot can do its job. Skipping this is the most common reason a freshly-flashed bot looks dead — the firmware is fine; it just has no clock and no channels yet.

  1. STEP 1

    Pair the radio with the MeshCore app

    This is a companion-radio firmware — the bot lives on the radio, but the radio still needs a one-time setup from a phone. After flashing, open the MeshCore companion app, pair over BLE (or USB if your board is USB-only), and complete the welcome flow.

  2. STEP 2

    Sync the clock

    The app pushes the phone's time to the radio on connect. Without this, timestamps in `time`, received-at fields, and the coordinator's TTL window all drift. Re-pair after any long power-off so the clock catches up.

  3. STEP 3

    Add #bot, #testing, and #emergency

    In the app's Channels screen, add the three community channels by name (the bot defaults to listening on these plus Public). Without the channels present in the radio's table, the bot has nothing to answer on — even though the firmware is configured to use them.

  4. STEP 4

    Wait for the advert

    The bot self-adverts ~5 s after boot and again on its scheduled interval. Once your other contacts see the advert, the bot will appear in their contact list and any nearby bot will auto-add it. From there, send `ping` on `#bot` to confirm it's alive.

Heads up

The bot listens on #bot, #testing, #emergency, and Public

Those four are the bot's entire universe. #bot and #testing are where normal commands work. #emergency messages get re-broadcast on Public. Every other channel is silent — even DMs work, but the channel set is what the bot uses to scope replies.

Get the bot on the mesh

Flash, drop into #bot, and say ping.

Found a bug, want a new command, or curious how the patch queue works? File an issue or jump in the Discord — both are open.