Skip to content

Trifecta bridge — beta 7

Pre-release
Pre-release

Choose a tag to compare

@smellyspice smellyspice released this 30 Aug 03:17
· 14 commits to espnow-ip-bridge since this release

Trifecta 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:

  • _debug filesBRIDGE_DEBUG, MESH_DEBUG, MESH_PACKET_LOGGING, WIFI_DEBUG_LOGGING all 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 with watch_boards.py below.
  • Plain files (no _debug suffix) — 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.channel to read it back. Deliberately one channel per board, not several — keeps the full post-length budget available and needs no channel-name prefix. See get bridge.channel/set bridge.channel/set bridge.secret to join the ESP-NOW side first, same as the companion.
  • Fixed: a genuinely unconfigured ESPNOW_BRIDGE_RADIO board (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 offset 0x0:
    esptool.py --chip esp32s3 write_flash 0x0 <file>-merged.bin
  • plain .bin (no -merged suffix) — app-only, for upgrading a board that's already running MeshCore. Preserves identity, WiFi credentials, and BLE bonds. Flash at offset 0x10000:
    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.