The device now transmits a NodeInfo (User protobuf: id/long_name/short_name) on the LongFast primary channel every 60s, so it appears in other Meshtastic clients as 'Reticutasticore' / 'RTC'. NodeNum derived from the MAC (!4359d2d0). No public key advertised, so DMs to us fall back to channel encryption — which the existing RX path already decodes and displays. Confirmed on hardware: announce tx=0 (success) on the first T-window. Also spec the planned message-received animation (upside-down spinning smiley + lightning bolts -> Meshtastic-style modal) in the README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
73 lines
3.5 KiB
Markdown
73 lines
3.5 KiB
Markdown
# 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: RTC scanner + acid display + Meshtastic decode
|
||
|
||
`src/main.cpp` rotates the single SX1262 through each network's PHY preset
|
||
(**R**eticulum / mesh**T**astic / mesh**C**ore = **RTC**), listens per dwell
|
||
window, logs every raw packet, and **decodes Meshtastic on-chip** (AES-128-CTR
|
||
via mbedtls + protobuf → text / node names). The 128×64 OLED shows an animated
|
||
acid-house UI: a smiley (that periodically freaks out — spins, stripes, eyes +
|
||
mouth open), a punk `RTC` header, three live network rows (packet counts + RX
|
||
blips), and the last decoded event.
|
||
|
||
Device identity `Reticutasticore` / `RTC` is baked in (`DEVICE_NAME`) as the
|
||
name this device will present on all three networks once the TX/participation
|
||
layer lands — so a message addressed to it will be routable.
|
||
|
||
**Validated on hardware (2026-07-01):**
|
||
- radio inits clean, all three presets cycle, display renders.
|
||
- **Meshtastic**: live broadcast packets at −34 to −44 dBm; on-chip decode
|
||
matches the offline reference (`tools/meshtastic_decode.py`, verified against
|
||
real captures — decoded node "Arch Optiplex"/"ARCH").
|
||
- **MeshCore**: received real packets too — so the `0x12` sync-word guess is
|
||
**correct** (was an open item).
|
||
- **Reticulum**: silent — placeholder PHY config + likely no RNode nodes near.
|
||
|
||
Still RX-only: no bridging or transmit yet.
|
||
|
||
## Open items baked into the config table
|
||
|
||
- **MeshCore sync word** (`src/main.cpp`, `CONFIGS[]`) is a guess (`0x12`,
|
||
RadioLib's private default). Confirm against MeshCore `src/` — 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.
|
||
|
||
```bash
|
||
pio run # compile
|
||
pio run -t upload --upload-port /dev/cu.usbserial-0001 # flash (adjust port)
|
||
pio device monitor -b 115200 # watch the scan
|
||
```
|
||
|
||
## Planned: message-received animation
|
||
|
||
When a text message arrives, play a short intro before showing it: the striped
|
||
smiley spins **upside-down / rotated**, little lightning bolts flash, then a
|
||
Meshtastic-style **message modal** slides in with the sender + text. (Spec'd,
|
||
not yet built.)
|
||
|
||
## Roadmap from here
|
||
|
||
1. **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.
|
||
2. **On-device bridge/dedup** — port the Phase 0 `bridge_core` relay+dedup
|
||
logic to C++.
|
||
3. **TX** — re-originate a decoded message onto the other two networks within
|
||
their dwell windows (queue between windows).
|
||
4. Revisit dwell timing / RAM budget with real per-protocol state (§3).
|