Wavelens

Works anywhere in the world · follow your local laws

Turn a $30 RTL-SDR and a Raspberry Pi into a digital public-safety scanner

31 Oct 2026 · 9 min read · RTL-SDR · Raspberry Pi · P25 · dsd-fme

Rather not? Full Spectrum is a Pi with everything below already installed, plus two pre-configured dongles and a Spotter, for $499. The rest of this page is for building your own.

A modern public-safety radio system doesn't sit on one frequency. It has a control channel — a data carrier that never stops — and a pool of voice channels it hands out call by call. To listen you need something that reads the control channel, hops to each voice channel as it's granted, decodes the digital voice (P25 in most of the US) and comes back. That is all a "trunking scanner" is, and every piece of it exists as open-source software that runs on a Raspberry Pi.

What you need

  • A Raspberry Pi 4 (2 GB is plenty). A Pi 3B+ decodes P25 too but with less headroom; a Zero 2 W is marginal.
  • One RTL-SDR dongle. The plain RTL2832U + R820T type is fine — ours hears the 800 MHz band at +35 dB over the noise floor from inside a car. See which dongle before you buy a fancy one.
  • An antenna for 800 MHz. The telescopic whip in the kit, pulled to about 9 cm, works. A $15 magnetic-mount 800 MHz whip on the roof works a lot better.
  • A 3 A USB-C supply. Brownouts show up as the dongle "disappearing" mid-call.
  • The Wavelens app on an Android phone, which is where you hear it.

Install the software

Start from Raspberry Pi OS Lite (64-bit). The full step-by-step, including flashing the card and pairing, is on the companion page; the short version:

sudo apt update && sudo apt full-upgrade -y
sudo apt install -y git python3-pip python3-dbus python3-gi bluez rtl-sdr rtl-433
sudo pip3 install --break-system-packages bluezero
echo "blacklist dvb_usb_rtl28xxu" | sudo tee /etc/modprobe.d/rtlsdr.conf
sudo reboot

The blacklist line matters: Linux grabs an RTL-SDR as a DVB-T television tuner by default and nothing else can open it. After the reboot, rtl_test -t should list your dongle with its serial.

Then the bridge and the digital voice decoder:

cd ~ && git clone --depth 1 https://github.com/pmcbrien/wavelens.git
cd ~/wavelens/companion/pi
./install-dsd.sh          # builds mbelib + dsd-fme, ~10 min on a Pi 4
sudo ./install-service.sh # bridge runs at boot as wavelens-bridge

dsd-fme is the decoder: it takes the dongle's IQ stream over rtl_tcp, demodulates C4FM or QPSK, follows the trunking grants and emits 8 kHz PCM. mbelib is the IMBE/AMBE vocoder it needs; the install script makes you confirm you've read its patent notice because that's what its authors ask.

What happens when you press SCAN

Open the Scanner tab in the app and tap SCAN. The bridge does, in order:

  1. Hunt. It reads its own rtl_power sweep of 851–869 MHz and looks for carriers that are there in every pass — a control channel never stops transmitting, voice channels do. Three passes is enough to tell them apart.
  2. Rank. The steady carriers are sorted by strength. If you've loaded a RadioReference export, each one is named ("Pinellas County (Countywide Simulcast)") and the decoder is picked for it — P25, DMR, EDACS.
  3. Lock. dsd-fme is pointed at the strongest. It reports Sync: +P25p1 and starts printing TSBK control messages within a couple of seconds. If it sees voice frames but no control traffic, that was a voice channel, and it moves to the next candidate.
  4. Follow. Each grant tunes the dongle to the voice channel; the audio comes back as 40 ms ADPCM frames over BLE and the app names the talkgroup.
  5. Rotate. Five seconds with no call and it hands off to the next strongest system above the signal floor — like a scanner stepping to the next bank. HOLD pins it.

You can watch all of that in the Alerts tab, which shows the bridge's last 100 journal lines live.

Receiving public-safety radio is legal in the US; it's what every scanner sold at a truck stop does. What you will not hear is encrypted traffic. P25 carries an algorithm ID with every call, dsd-fme sees it, and the bridge marks the talkgroup "encrypted" and moves on — there is no setting, key or trick that changes that. Many agencies now encrypt everything; a system that is all-encrypted is skipped automatically so the scanner doesn't sit on silence.

Where to go next

If the voice sounds chopped into syllables on a countywide system, read why simulcast sounds broken. If you want names on the talkgroups, load a RadioReference export. And if you'd like the Pi to also decode TPMS, weather sensors and aircraft while it scans, add a second dongle.

Rather not build it?

Spotter $64 · Full Spectrum $499: the builds on this blog, programmed and tested, set up for where you drive, with free updates for life. The guides stay here, free, if you change your mind.

Shop Join the free Android beta

Open firmware and bridge on GitHub · receive only · every command on this blog is copied from a Pi we run

Next: Which RTL-SDR dongle? What we learned at 800 MHz · all articles