A multi-transport companion firmware built on top of MeshCore for Heltec and Seeed LoRa devices (OLED / e-ink / headless). One build serves USB + Bluetooth + TCP at the same time, so you can drive the radio from a phone app, the web client, or Home Assistant — together.
Upstream: github.com/meshcore-dev/MeshCore (MeshCore is a lightweight multi-hop LoRa mesh; see their repo for the protocol, mobile clients, and the canonical flasher).
🖐️ Looking for the touch UI? The standalone on-device LVGL interface for the Heltec V4 TFT and LilyGo T-Deck now lives in its own project: ALLFATHER-BV/wadamesh. This repo is the OLED/e-ink companion firmware (the MeshCore core it builds on) only.
Experimental — use at your own risk. This firmware is not officially supported. Flashing custom firmware may have unexpected effects; you are responsible for your use of it. No warranty is provided.
A single firmware image supports USB, Bluetooth, and TCP companion connections at the same time (e.g. Home Assistant on USB, the MeshCore app on BLE, the web client on TCP). Use one, two, or all three; BLE and TCP can be toggled from the device UI.
- USB — always on when the device is powered.
- Bluetooth — the pairing PIN is shown on the device's Bluetooth tab (state + pairing info). Long-press the tab to enable/disable BLE; the footer reads "ON: long press" / "OFF: long press".
- TCP — server on port 5000, multiple clients. The Network (TCP) tab shows status, IP, port, and SSID. Long-press to enable/disable TCP. Wi-Fi credentials are not stored in the repo — set them at build time (
WIFI_SSID/WIFI_PWD) or at runtime (see Configure Wi-Fi). The plain WebSocket port is 8765 (ws://only).
Other niceties:
- Push to all clients — RX log, new messages, contact adverts, and path updates are sent to every connected client, so each app sees live updates.
- No duplicate RX log on sync — when one client syncs history, only that client gets the sync frames; the others don't see them re-echoed.
Otherwise this is the same codebase as MeshCore; we sync from upstream and add our addon customizations on top.
| Device | MCU | Display | Build env |
|---|---|---|---|
| Heltec WiFi LoRa 32 V4 | ESP32-S3 | 128×64 OLED | heltec_v4_companion_radio_usb_tcp |
| Heltec WiFi LoRa 32 V3 | ESP32-S3 | 128×64 OLED | Heltec_v3_companion_radio_usb_tcp |
| Heltec Wireless Paper | ESP32-S3 | 213×104 e-ink | Heltec_Wireless_Paper_companion_radio_usb_tcp |
| Seeed Xiao S3 WIO | ESP32-S3 | optional 128×64 OLED | Xiao_S3_WIO_companion_radio_usb_tcp |
Env-name casing matters when building: V4 uses lowercase heltec_v4_…; V3 uses a capital H Heltec_v3_…. Use the exact name (see Build it yourself).
Touch boards (Heltec V4 TFT, LilyGo T-Deck) are built and released from wadamesh, not here.
Run the full meshcomod web client as a tab inside Home Assistant. Connect the device over TCP (Wi-Fi) or USB to the machine running HA, then add the meshcomod client as an iframe/panel for a dedicated MESHCOMOD sidebar tab: voltage, state of charge, temperature, uptime, and realtime/trend graphs alongside your other dashboards.
Use TCP for stability in Home Assistant. The web console and the companion protocol share the USB serial port, so a USB-connected HA can be affected by console handling. Connect HA over TCP (Wi-Fi) for a separate, unaffected path.
Three ways, no CLI recovery mode needed. Wi-Fi is 2.4 GHz only (not 5 GHz-only SSIDs); credentials are stored in NVS and survive reboots.
1. Flasher Wi-Fi GUI (easiest) — the Wi-Fi panel on flasher.meshcomod.com.
2. Web/USB console — console.meshcomod.com (or the Console tab on the flasher), device on USB:
set wifi.ssid YourSSID
set wifi.pwd YourPassword # open network: set wifi.pwd
wifi.apply
wifi.status
3. Meshcomod chat — open the built-in Meshcomod contact (favourited by default, near the bottom of the contact list) and send commands. These are handled locally on the device and are not sent over the LoRa mesh. Note your client may keep the password in local chat history.
| Command | What it does |
|---|---|
help |
List all Meshcomod commands |
status |
USB/BLE/TCP and Wi-Fi state |
wifi set ssid "<v>" |
Set SSID (quote if it has spaces) |
wifi set pwd "<v>" |
Set password ("" for open) |
wifi scan / wifi use <n> |
List nearby SSIDs, then pick one |
wifi status |
SSID, runtime vs compile-time creds, link state |
wifi apply |
Reconnect with stored credentials |
wifi clear |
Clear runtime creds (fall back to compile-time on next boot) |
tcp on / tcp off / tcp status |
Control/query the TCP server |
ble on / ble off / ble status |
Control/query Bluetooth |
Disabling wireless access is guarded:
tcp offandble offask you to confirm withok(orcancel) first, since you could lock yourself out.
No local build needed. Builds are published as GitHub Releases (tag companion-*); the latest is also mirrored to the web flasher.
- Open flasher.meshcomod.com.
- Easy mode (recommended): pick your device + version; the flasher downloads it for you.
- Manual mode: choose Custom firmware and upload a
.binfrom the latest release. - Connect via USB, BLE (PIN on the display), and/or TCP.
If unsure which binary to flash, use merged (it includes the bootloader + partition table and writes from
0x0).
Pinned older versions for rollback: see the Release log (RELEASES.md) and the GitHub Releases list.
For custom code or build flags.
Dependencies: git, python3 + pip, and platformio (pio in PATH, or python3 -m platformio). build.sh falls back to python3 -m platformio when pio isn't on PATH.
- macOS:
xcode-select --install, thenpython3 -m pip install --user -U platformio - Linux:
sudo apt update && sudo apt install -y git python3 python3-pip, then the pip install - Windows: use WSL (Ubuntu) and follow the Linux steps
Clone the repo and build with the exact env name. Wi-Fi credentials are baked in at build time (override at runtime later).
export WIFI_SSID="YourNetworkName"
export WIFI_PWD="YourPassword" # open network: export WIFI_PWD=""
export FIRMWARE_VERSION=v1.16.0.2
sh build.sh build-firmware heltec_v4_companion_radio_usb_tcpexport WIFI_SSID="YourNetworkName"
export WIFI_PWD="YourPassword"
export FIRMWARE_VERSION=v1.16.0.2
sh build.sh build-firmware Heltec_v3_companion_radio_usb_tcpOther targets use the same flow with their env name (Heltec_Wireless_Paper_companion_radio_usb_tcp, Xiao_S3_WIO_companion_radio_usb_tcp). Build all shipped companions at once with sh build.sh build-meshcomod-companion-firmwares.
Outputs (every target): app-only out/<env>-<version>-<sha>.bin and merged out/<env>-<version>-<sha>-merged.bin (flash from 0x0). The merged image is also at .pio/build/<env>/firmware-merged.bin.
If the display stays black after flashing and resetting:
- Flash the merged image — it includes the bootloader + partition table. Generate with
pio run -t mergebin -e <env>→.pio/build/<env>/firmware-merged.bin. (Defaultout/copies are app-only.) - Use the web flasher — on flasher.meshcomod.com, Custom firmware → upload the merged file (writes from
0x0). - Still black? — upload the merged file again; if the flasher offers erase, erase first then upload (this wipes contacts and other data).
- Heltec V4 only: if a merged image still gives a black screen (while V3 is fine), try the non-merged
.binat offset0x10000(the device must already have a valid bootloader + partition table). Newer firmware also adds a longer pre-display delay and watchdog feeds on first boot to improve merged-boot reliability.
Companion / repeater / room-server firmware is built by GitHub Actions and published as GitHub Releases; push a track tag (e.g. companion-v1.16.0.2) and the pipeline builds the shipped boards, publishes the release with the bins attached, and prunes to the newest 5. See docs/CI_RELEASES.md.
- Companion protocol · CLI commands · QR codes
- Packet format · Payloads · Stats binary frames
- Device WebSocket / Wi-Fi · FAQ
- CI releases · Release process · Release log
git remote add upstream https://github.com/meshcore-dev/MeshCore.git # if not already added
git fetch upstream
git merge upstream/main
# resolve any conflicts, then:
git push origin mainContributing to upstream MeshCore? Use their dev branch for PRs; open an Issue first for larger changes — see meshcore-dev/MeshCore.
- Legacy/no-channel clients — a client that doesn't implement channel chat should ignore channel message frames (
0x08,0x11). - Debug over USB — serial terminals show binary companion frames on the USB transport; use BLE/TCP for app traffic if you need clean USB logs.
- BLE first connect — on the first BLE connection you may need to disconnect and reconnect once.
- First Meshcomod
help— the firsthelpin a fresh Meshcomod chat may not reply; send it again. - Web console retry — a
get/set wifi.*command may not show a reply on the first try; run it again.
Same as MeshCore (see license.txt). MeshCore is MIT.




