icon fullempty.sh

Building an OP25 setup for decoding P25 Digital Radio with a Raspberry Pi

2019-07-05

A photograph of a Raspberry Pi with an RTL-SDR dongle attached.

Recently I've been working on a cheap, compact, portable setup for listening to P25 radio. At least in Minnesota, nearly every single state, county, and city agency has migrated to using P25, with the only remaining services on UHF or VHF patched in from digital, specifically fire dispatch.

I largely followed this guide, but there are extra details I stumbled on that were necessary to actually make it work for me.

You'll need a functioning rtl-sdr, Raspberry Pi, and some kind of speaker to plug into the audio-out. I just use a JBL bluetooth speaker with aux-in I had laying around.

Secondly, check out current versions of the rtl-sdr driver, and the max branch of op25. On Raspbian, you'll need to install libusb-1.0-0-dev and cmake to compile the rtl-sdr driver and op25. For rtl-sdr, just mkdir build, icd there, type cmake .., then make, then make install.

The guide above mentions a different git repo for op25. I use the max branch because the curses interface wouldn't work for me without switching branches, plus it's newer.

Where my instructions differ from the post above is on the subject of tuning. If you have a cheap (non-TCXO) rtl-sdr, it's going to be inaccurate. This might be fine for just tuning manually and listening, but trunked systems need tuning accuracy. op25 can compensate to some degree, but I had a great deal of trouble making my setup work until I had the ppm setting nearly perfect (within 1-2 ppm). If this paragraph doesn't make sense, you need to mess with your rtl-sdr some more before trying this setup.

Even if it still doesn't make sense, run rtl_test -s 960000 -p. Wait about a minute for the ppm to average out, then use that with the -q switch for rx.py. This would be the same ppm setting you'd use with rtl_fm.

Other than that, the above guide is what you should follow. On my setup, I have a 3.5" touchscreen LCD attached to my Raspberry Pi, and a link to a shell script on the desktop with the following contents:

#!/bin/bash

cd ~/scanner
./rx.py -q 62.5 -S 960000 --args="rtl" -N 'LNA:40' -f "852.3625e6" -o 25000 -T trunk.tsv -V -U -w -2 -l http:0.0.0.0:8765 &
sleep 4
chromium-browser "http://0.0.0.0:8765"

I mentioned the curses interface above, but I honestly prefer the web interface. I still could not make keyboard commands work in the curses interface, so operating talk group holds/lockouts/skips via the web interface is more convenient. I also have a command to launch a web browser with this interface for display on the LCD, which is useful because I'd prefer to not have a keyboard attached while taking this around on a battery.

My next possible to-do items:

« Back
© 2022 Derek Arnold · mastodon · twitter · github
This page modified on Fri Jul 5 19:40:16 CDT 2019