Add SSD1306 UI to the Phase 1 scanner: an animated acid smiley inside expanding psychedelic rings, an 'RMC' (Reticulum/Meshtastic/meshCore) strobe header, and three live network rows with per-network packet counts and RX activity blips. Scan loop made non-blocking (millis-based dwell) so the display animates smoothly (~20fps) while the radio rotates. Honest note in-code: the single SX1262 is time-sliced across the three PHYs (ARCHITECTURE.md §2); the UI shows all three armed but true concurrent RX needs added radios (Phase 2). Pins U8g2 2.36.18. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
firmware (Phase 1)
Embedded firmware for the single-device 3-in-1: one Heltec WiFi LoRa 32 V3
(ESP32-S3 + one SX1262) time-multiplexing its single radio across the
Meshtastic / MeshCore / Reticulum PHY configs. See ../docs/ARCHITECTURE.md
§2-§3 for why Phase 1 is a time-multiplexed single radio (Option A).
Current increment: tri-protocol RX scanner
src/main.cpp is the first Phase 1 step. It does not bridge, decode, or
transmit yet — it rotates the SX1262 through each network's PHY preset, listens
for a fixed dwell window, and logs every raw LoRa packet it demodulates
(length, RSSI, SNR, hex). The point is to answer the project's central open
question before building any protocol stacks: can one re-tuned radio actually
hear all three networks?
Validated on hardware (2026-07-01): flashed to a Heltec V3, the scanner
radio.begin()'d cleanly, cycled all three presets, and received live
Meshtastic broadcast packets (payloads prefixed ffffffff) at −36 to
−41 dBm during the Meshtastic dwell. The single-radio time-multiplex premise
holds. MeshCore/Reticulum windows were silent — expected, see open items below.
Open items baked into the config table
- MeshCore sync word (
src/main.cpp,CONFIGS[]) is a guess (0x12, RadioLib's private default). Confirm against MeshCoresrc/— this is the same open item as../docs/ARCHITECTURE.md§1/§5. - Reticulum PHY has no protocol-mandated preset; it's operator-configured. The entry is a placeholder — set it to your actual RNS RNode interface config or that window hears nothing.
- Meshtastic frequency is set to the documented 869.525 MHz, but Meshtastic hashes the channel name to a slot within the region plan, so real deployments may sit on a different slot.
Build / flash / monitor
Requires PlatformIO (pip install platformio). Versions are pinned in
platformio.ini (espressif32 7.0.1, RadioLib 7.7.1) — do not float them.
pio run # compile
pio run -t upload --upload-port /dev/cu.usbserial-0001 # flash (adjust port)
pio device monitor -b 115200 # watch the scan
Roadmap from here
- RX decode per protocol — turn logged raw packets into
{sender, text}(Meshtastic 16-byte header + AES-CTR; MeshCore framing; Reticulum via microReticulum). Start with Meshtastic since we already receive it. - On-device bridge/dedup — port the Phase 0
bridge_corerelay+dedup logic to C++. - TX — re-originate a decoded message onto the other two networks within their dwell windows (queue between windows).
- Revisit dwell timing / RAM budget with real per-protocol state (§3).