M3 step 4: the LoRa Scanner App, Sniffer and Captures

The Sniffer lists packets newest first (time, RSSI, SNR, and for
Meshtastic the sender, receiver and hops), with the clear header and a
hex dump on Enter (Q96); `p` picks an EU868 preset, kept in Settings
(Q95). `c` starts a Capture: pcap with LoRaTap in /captures/lora, its own
Clean-up category, recorded by a small Service so it carries on with the
App closed (Q97, Q100). The Status Bar shows L while listening, bright on
each packet, and CAP while capturing (Q101). StorageService gains raw
appends for binary files. Debug Builds get `lora inject` to test all of
this with no transmitter in range: a Capture made on the device reads
back in TShark field for field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-05 20:14:58 +02:00
co-authored by Claude Opus 5.5
parent 594748e99a
commit 2fce79aebd
23 changed files with 723 additions and 13 deletions
+4 -1
View File
@@ -1,6 +1,6 @@
# M3 — Radio bring-up: the LoRa Scanner
**Status:** in progress (branch `m3`): steps 1 and 2 done.
**Status:** in progress (branch `m3`): steps 1 to 4 done.
**Goal:** the LoRa radio on the Cap works, receive only: a Radio Service owns it and shares the SPI bus with the SD card safely, and a LoRa Scanner App shows what's on the air, either packets (Sniffer) or energy across the band (Sweep). Nothing in M3 can transmit. The mesh comes on top of this in M4 (receive) and M5 (transmit).
@@ -16,6 +16,9 @@
- **DIO2 doesn't change reception** (within ±2 dB over three runs, P0 high). It likely selects TX versus RX in the FM8625H; it stays the RF switch, as in Meshtastic.
- **The noise floor at the desk is high** (-87 to -94 dBm, varying run to run), about 25 dB above thermal noise for 250 kHz. Something nearby is loud, possibly the Cardputer itself or the PC; Sweep (step 5) should show where it sits.
- **Step 2:** presets, frequencies and the channel hash are checked against Meshtastic's source (`MeshRadio.h`, `RadioInterface.cpp`): LongFast and the default key give hash 8, MediumFast 31, as Meshtastic shows. Captures were checked with TShark 4.2.5: every LoRaTap field reads back. Wireshark ignores the spec's quarter-dB packet RSSI below 0 dB SNR, so packet RSSI is plain dBm.
- **Step 3:** the DIO1 interrupt works (a 100 ms receive timeout wakes the task after 105 ms). While listening: four 1.7 MB uploads and Gemini pages to the card, no radio or card errors (the card refuses a write about once in five uploads with the radio asleep too; `put` now catches it). The ring takes 9.8 KB while listening; the radio task's stack peaks at 2.0 KB.
- **No packets yet, and a loud desk.** Twenty minutes on LongFast and on LoRaWAN's three uplink frequencies (SF7, SF9, SF12): no packet and no header, valid or not. The noise floor reads -83 to -94 dBm, against -112 dBm with the antenna switched off: 20 to 30 dB lost to something nearby, not the screen and not the GNSS receiver. Preamble detections are false alarms at this noise level (more on an empty frequency, 869.0 MHz, than on LongFast).
- **Step 4:** a Capture made on the device reads back in TShark field for field (time, frequency, SF, RSSI, SNR, payload). A Capture keeps the radio listening with the App closed; stopping it puts the radio back to sleep.
- **Cost:** RadioLib 7.8.1 and the probe add 23.6 KB of flash and 656 bytes of static RAM to the release firmware (1,679,843 bytes of 3,342,336).
## Decisions (design round 2026-10-05)