Purpose: Define the software choices for the VHF Radio Pi (DOT-VHF): own ADSB tracking/logging (with optional sharing), VHF record/clean/transcribe, local weather → Meshtastic, and use of the Flycatcher’s second antenna.
Hardware context: Raspberry Pi 5 Model B; Nooelec Flycatcher (dual-channel: 1090 + 978); 3× RTL2838 (RTL-SDR) dongles; ROKland Meshtastic nodes; 2 TB NVMe for logging. Optional: Hailo-8 via Pi 5 AI HAT+ (currently disabled).
| # | Want | Notes |
|---|---|---|
| 1 | Own ADSB tracking and logging | Local capture and storage on 2 TB NVMe; full control of our data. |
| 2 | Option to share ADSB to online services | If we choose: feed to FlightAware, FlightRadar24, ADSBexchange, etc. (e.g. Beast/MLAT); opt-in, not required. |
| 3 | VHF audio: recorded, cleaned up, transcribed | Capture aviation VHF (118–137 MHz); clean/denoise; run STT (CPU or Hailo when enabled); transcripts to mesh + NVMe. |
| 4 | Local weather on Meshtastic stream | Weather system at install location; get API for that weather; add weather data into the Meshtastic stream. (API TBD.) |
| 5 | Flycatcher 2nd channel | Same radio as ch1 (SAW filter); can’t do analogue. Use for 978 UAT (see below). |
| Item | Status |
|---|---|
| Hailo-8 AI HAT+ | Disabled — not in use at the moment; can be re-enabled later for accelerated STT. |
| Storage | 2 TB NVMe — used for logging (ADSB, SDR/OpenWebRX, transcript logs, etc.). Plenty of space for long-term capture and replay. |
Until the Hailo HAT is re-enabled, STT can run on CPU Whisper (slower but works) or the pipeline can focus on logging VHF audio to NVMe and transcribe later (or when Hailo is on). The 2 TB NVMe is well-suited for that.
What it is: Web-based SDR receiver; one or more RTL-SDRs; waterfall, demodulation (NFM, WFM, etc.), optional digital decoders. Access via browser — no desktop needed.
Why here: Gives operators a single “web terminal” to tune VHF (and optionally other bands), see activity, and listen. Fits SkyBridge ground-station “optional VHF SDR” role.
Relevant details:
/etc/openwebrx, web UI under “Settings”; devices and profiles for each dongle.Install options:
Suggested use on DOT-VHF:
Goal: VHF RF → demodulated audio → on-device STT → text → Meshtastic (historical transcript messages). Audio and transcripts can be logged to the 2 TB NVMe.
Flow:
RTL-SDR (VHF) → rtl_fm (or similar) → demod audio → [optional VAD] → Whisper (CPU or Hailo-8) → text → Meshtastic
→ log to NVMe (raw + transcripts)
Components:
| Layer | Role | Options |
|---|---|---|
| SDR capture | Dedicated dongle, VHF band | rtl_fm (narrow FM, 118–137 MHz), or csdr-based pipeline; fixed device by serial/bus. |
| Audio | Demodulated audio to STT | Pipe (stdin) or ringbuffer; 16 kHz mono typical for Whisper. Optionally write to NVMe for replay. |
| STT | Speech → text | Whisper (tiny/small): CPU for now (Hailo disabled), or Hailo-8 when Hailo HAT is re-enabled (hailocs/hailo-whisper). |
| Delivery | Text onto mesh | Meshtastic (serial or network API) — send transcript lines as mesh messages. |
| Logging | Persistent storage | 2 TB NVMe — ADSB logs, VHF audio segments, transcripts, OpenWebRX recordings. |
Hailo-8 (when re-enabled):
Current mode (Hailo disabled): Run Whisper on CPU, and/or log VHF audio to NVMe and transcribe in batches or when Hailo is re-enabled. The 2 TB NVMe makes “record now, transcribe later” practical.
VHF “cleaned up”: Denoise/clean the demodulated audio before STT (e.g. high-pass filter, noise gate, or light spectral subtraction) so transcripts are better; keep raw and cleaned copies on NVMe if desired.
Why separate SDR for STT:
OpenWebRX doesn’t provide a local audio stream. Using a dedicated RTL-SDR + rtl_fm (or equivalent) keeps the STT pipeline simple and independent of the web UI.
What we want: Weather from the install-location weather system added to the Meshtastic stream so the mesh carries local conditions (temp, wind, pressure, etc.) for pilots and other nodes.
Status: API for the on-site weather system is TBD. Once we have the API:
Next step: Get the weather system’s API (vendor, endpoint, auth, units). Then we can wire a small service (e.g. Python or Node) that fetches → formats → sends to Meshtastic.
What we want:
Hardware: Flycatcher handles ADSB only. Both channels are tied to the same radio hardware (SAW filter) — they can’t do analogue VHF. That’s why we added a separate RTL-SDR (or more) for analogue VHF (118–137 MHz). So: Flycatcher = 1090 + 978; standalone dongle(s) = VHF.
Verified (Nooelec): The Nooelec Flycatcher is specified only for ADS-B (1090 MHz) and UAT (978 MHz) — “Designed to receive both ADS-B (1090 MHz) signals and UAT (978 MHz).” No mention of 118–137 MHz or voice; the product is for airplane tracking, flight tracking, and weather monitoring (FIS-B over UAT). The 118–137 MHz aviation voice band is a different frequency range and would require different front-end hardware. The Flycatcher cannot do voice traffic; analogue VHF requires a separate SDR.
Flycatcher 2nd channel: 978 MHz UAT (only option)
The Flycatcher is built for 1090 MHz (ADS-B ES) + 978 MHz (UAT). Both channels are SAW-filtered for those bands — no analogue, so the 2nd channel isn’t “extra” to repurpose; it’s the 978 UAT channel. Use it for that:
| Channel | Use | Why |
|---|---|---|
| Channel 1 | 1090 MHz ADS-B ES | Commercial + international; primary traffic. |
| Channel 2 | 978 MHz UAT | US general aviation; FIS-B weather over UAT; same radio type as ch1, can’t do analogue. |
That gives you full ADSB (1090 + 978) on the Flycatcher; analogue VHF is on the additional SDR(s) we added because the Flycatcher can’t read it.
VHF SDR on DOT-VHF: RTL-SDR.com Blog V4 (R828D, RTL2832U)
lsusb shows iManufacturer: RTLSDRBlog, iProduct: Blog V4 (one of the three RTL2838 devices; the other two are FlyCatcher_ADS_B and FlyCatcher_UAT).Flycatcher (HAT, 2 channels): | Channel | Antenna / use | Software / role | |———|—————–|————————————-| | 1 | 1090 MHz ADSB | readsb / dump1090-fa — tracking, logging, optional feed | | 2 | 978 MHz UAT | 978 decoder (e.g. dump978, or readsb with 978) — same logging/sharing pipeline |
Standalone RTL-SDR dongles:
| Dongle | Role | Software |
|——–|——————-|—————————–|
| RTL-SDR.com Blog V4 (RTLSDRBlog / Blog V4) | Web SDR terminal and/or VHF → STT | OpenWebRX (VHF 118–137 MHz) and/or rtl_fm → clean → Whisper → Meshtastic + NVMe |
(Other USB RTL-SDRs if present can be spare or second VHF instance; pin by udev using manufacturer/product.)
Use udev rules (e.g. by idVendor/idProduct and USB port/serial) so each device gets a stable name and the right service uses the right dongle.
| Component | Purpose | Status |
|---|---|---|
| OpenWebRX | Web SDR terminal (VHF waterfall/tuning) | Running on port 8073; 3 aviation band profiles |
| rtl_connector + rtltcp_compat | Shared IQ access for Blog V4 | Port 127.0.0.1:1235 active; pipeline + OpenWebRX share one dongle |
| vhf-pipeline.py | VHF AM capture -> archive -> STT -> Meshtastic | /home/blastly/scripts/vhf-pipeline.py; systemd service enabled |
| faster-whisper 1.2.1 | CPU STT for voice segments | tiny.en model; venv /home/blastly/vhf-pipeline-venv/ |
| sox + ffmpeg | Audio conversion (PCM->FLAC, 24k->16k resample) | System packages installed |
| meshtastic 2.7.8 | Mesh delivery of transcripts | In pipeline venv; MESH_HOST env var – node connection pending onsite |
| readsb + tar1090 | ADSB 1090 MHz tracking + web map | Pinned to device 2 (FlyCatcher_ADS_B); tar1090 at /tar1090 |
| rclone 1.73.1 | NVMe -> central server backup | Script + systemd timer (6h); remote skybridge-central pending config |
| 1.8 TB NVMe | Primary data storage | Mounted /mnt/nvme; {vhf-audio,transcripts,adsb,logs,backup-staging} |
MESH_HOST=<node-ip> in /etc/systemd/system/vhf-pipeline.service. Pipeline logs transcripts to NVMe now; mesh delivery activates when node is connected.rclone config -> create remote named skybridge-central (SFTP/S3/B2). Timer picks it up automatically.--vad-threshold in service ExecStart or run manually first to test.sudo readsb-set-location <lat> <lon> once onsite.dump978 when UAT reception wanted.device="cpu" to "hailo" in WhisperModel() call in vhf-pipeline.py.Pipeline is built and services are enabled. Remaining items are all “connect hardware onsite” or “configure credentials” – no more software to write for core VHF -> STT -> Meshtastic flow.