Trifecta bridge — beta 7
Pre-releaseTrifecta repeater firmware (real LoRa + ESP-NOW bridge + IP bridge, all at once) — beta 7.
Built from commit a4e94a33 on the espnow-ip-bridge branch. Covers the companion, room server, Heltec V3, Heltec V4, and Xiao S3 WIO.
Two builds per repeater board, same code, different tradeoff:
_debugfiles —BRIDGE_DEBUG,MESH_DEBUG,MESH_PACKET_LOGGING,WIFI_DEBUG_LOGGINGall on. Noisier serial output, and debug logging has a real (small) timing/CPU cost on a busy repeater, but gives full visibility into bridge/routing decisions. Use this for testing, troubleshooting, or pairing withwatch_boards.pybelow.- Plain files (no
_debugsuffix) — functionally identical, debug logging stripped out. Quieter and slightly leaner/faster. Use this once you're done actively debugging and just want the repeater running.
What's new since beta 6
- New: room server can now join a Trifecta repeater's mesh with zero LoRa hardware, same no-LoRa ESP-NOW bridge pattern the companion already uses (Waveshare S3-Zero). New env:
ESP32_S3_Zero_room_server_bridge_espnow. - New: that room server can passively listen on one public group channel (
#hashtag-style) and feed its text messages straight into the room's post feed — CLI:room.channel <name> <psk>(accepts either hex or base64, whichever your app shows you),get room.channelto read it back. Deliberately one channel per board, not several — keeps the full post-length budget available and needs no channel-name prefix. Seeget bridge.channel/set bridge.channel/set bridge.secretto join the ESP-NOW side first, same as the companion. - Fixed: a genuinely unconfigured
ESPNOW_BRIDGE_RADIOboard (companion, repeater, or room server) boot-looped. The mesh auto-sends a self-advert on boot regardless of whether the ESP-NOW radio has been configured yet; the send path reached an XOR-keying step that divides by the configured secret's length, which is zero pre-configuration — instant crash, every boot, on any board that hadn't been set up yet. - Fixed: a companion/room-server-role board joined to a repeater's ESP-NOW bridge could never receive anything relayed back out that same bridge. A shared dedup table meant a packet that arrived over ESP-NOW was already marked "seen" by the time the repeater tried to mirror it back out over ESP-NOW to reach a different peer on the same bridge — silently dropped, every time, regardless of RF conditions. Real-world symptom: an ESP-NOW-joined room server never receiving channel messages sent by an ESP-NOW-joined companion through the same repeater, while the identical message from a real LoRa companion worked fine.
- Fixed: once a repeater's ESP-NOW bridge had learned even one peer, it stopped broadcasting entirely — every subsequent send became unicast-only to already-known peers, permanently excluding any peer that never transmits unprompted (a passive room server, by design). FLOOD-route traffic (channel messages, self-adverts) now gets one broadcast after the normal known-peer unicast fan-out, so a passive listener is reachable too; DIRECT traffic's existing unicast-with-retry behavior is unchanged.
- New, untested (no hardware yet): an ESP32-C3 "Super Mini" variant spec. Companion/repeater/room-server envs all compile clean against the same chip-agnostic radio code the S3-Zero uses — nothing hardware-specific has been verified yet (onboard LED pin deliberately left unset rather than guessed).
Repeaters (Xiao S3 WIO, Heltec V3, Heltec V4)
Which file to flash:
-merged.bin— for a blank/fresh board. Flash at offset0x0:
esptool.py --chip esp32s3 write_flash 0x0 <file>-merged.bin- plain
.bin(no-mergedsuffix) — app-only, for upgrading a board that's already running MeshCore. Preserves identity, WiFi credentials, and BLE bonds. Flash at offset0x10000:
esptool.py --chip esp32s3 write_flash 0x10000 <file>.bin
After flashing, configure over the standard MeshCore serial CLI (set bridge.channel, set bridge.secret, set wifi.ssid, set wifi.pwd, set ip.host, etc.) — no custom tooling needed.
Room server, no LoRa (Waveshare ESP32-S3-Zero)
Same flashing pattern as above (-merged.bin at 0x0 for blank, plain .bin at 0x10000 to upgrade). If changing an existing board's role (e.g. this same physical board was previously a companion), erase flash fully first — esptool.py erase_flash — before flashing the merged image. A role change doesn't touch the separate SPIFFS partition otherwise, so stale config from the old role can survive and cause boot issues.
Configure the ESP-NOW join the same as a repeater (set bridge.channel/set bridge.secret, matching whatever real repeater it should join), then optionally room.channel <name> <psk> for the public-channel bridge.
Monitoring multiple boards at once
python3 watch_boards.py
Auto-detects every connected board, connects to all of them, and streams their debug output live in one terminal. Press n to dump neighbors.all, b to dump bridge status, c to toggle watching companion boards, from every connected board at once. See the script's own --help for details.
Full writeup, use cases, and setup details: https://smellyspice.github.io/MeshCore/
A personal MeshCore fork, unmerged upstream, developer release only — do not run on a mesh you depend on.