Building an APRS iGate using a Raspberry Pi and a TV tuner dongle

I’ve been messing around with APRS – the Automatic Packet Reporting System – for some time now and had noticed an absence of coverage in my local area. The end goal of APRS is to feed packets (which might be position data, weather reports, messages or other information) to the APRS-IS (which can be viewed at aprs.fi), and this is done via digipeaters and iGates. A digipeater merely re-transmits packets, until they reach an iGate, which feeds them to the Internet.

My local RAYNET group frequently uses APRS for position tracking at events, but often position reports fail to reach control due to a lack of APRS coverage. I therefore deemed it would be a good project to make a portable, lightweight iGate that could be deployed quickly.

This was done using a Raspberry Pi and RTL-SDR USB dongle – while it is easier to feed the audio output of a radio into the Pi, this does increase the price of the setup; an RTL-SDR dongle can be purchased for as little as £10.

Parts:

  • Raspberry Pi running Raspbian / Debian
  • RTL-SDR dongle
  • Powered USB hub (the Pi cannot provide enough current to run the RTL-SDR)
  • A network connection – this could be via ethernet, WiFi or 3G
  • Power – either a 5V mains power supply, or a battery. The fact that the Pi runs from 5V means one could use a high-capacity mobile phone ‘power bank’ to run this in a remote location temporarily

Preparation

Download a Raspbian image from http://www.raspberrypi.org/ – I used the NOOBS images as these are slightly easier. Extract the image to your Pi’s SD card.

Upon booting the Pi for the first time, ensure you go into advanced settings and enable SSH, as well as changing the hostname to something memorable and descriptive. Then, set up your network link. It is also advisable to force audio output via the 3.5mm socket rather than HDMI, as this will make troubleshooting easier later.

Once an Internet link has been established, update the Pi from the Terminal:

sudo apt-get update
sudo apt-get upgrade
sudo reboot

Setting up the RTL-SDR dongle

By default, the Pi will attempt to load its own drivers to use with the RTL-SDR dongle. However, these assume it is being used for its original purpose (watching Freeview TV), and so we must blacklist them.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Then add the following lines to the file:

blacklist dvb_usb_rtl28xxu
blacklist rtl_2832
blacklist rtl_2830
blacklist dvb_usb_v2
blacklist r820t

To save the file, press Ctrl+X, press Y and then hit enter. Then, reboot:

sudo reboot

Following this, create a folder for the software needed to run the RTL-SDR:

mkdir ~/rtl
cd ~/rtl
sudo apt-get install git build-essential cmake libusb-1.0-0-dev
sudo git clone git://git.osmocom.org/rtl-sdr.git
cd rtl-sdr
mkdir build
cd build
cmake .. -DINSTALL_UDEV_RULES=ON
make
sudo make install
sudo ldconfig

You may see error messages at some points – play close attention to the terminal when entering these commands. If  you get an error, this may be because the command needs to be run as ‘root’ – re-enter the command, but prefixed by ‘sudo’.

We will then install ‘sox’ – a utility that converts audio formats to others – so that we may test the RTL-SDR later.

Check the RTL-SDR dongle is working with the Pi

rtl_test

You should (hopefully) get no packet loss, however when I ran this on my Raspberry Pi Model B (2011), I got loss of around 50 bytes – the iGate still worked, however. The more powerful Raspberry Pi 2 does not suffer from this issue.

We will then test the dongle itself by listening to broadcast radio – I chose to use BBC Radio 1 on 98.5MHz:

rtl_fm -M wbfm -f 98.5M | play -r 32k -t raw -e s -b 16 -c 1 -V1 -

Plug in a pair of headphones to the Pi and you should be able to hear your selected radio station.

Then, try 144.800 MHz, transmitting (on low power) on a HT to check you can hear narrow-band FM signals:

rtl_fm -M fm -f 144.800M | play -r 24k -t raw -e s -b 16 -c 1 -V1 -

Calibrating the SDR

Many of these cheap dongles are not particularly accurate. I therefore plugged mine into a laptop running SDRSharp and transmitted on 144.800 MHz to calculate the necessary offset. With my particular RTL-SDR, one needs to set its frequency to 144.791 MHz when listening to 144.800 MHz.

Decoding the APRS packets

APRS packets are transmitted as AFSK1200 – that is, audio-frequency shift keying at 1200 baud. multimonNG is a piece of software that is capable of decoding this data.

cd ~/rtl
sudo apt-get install qt4-make libpulse-dev libx11-dev
git clone https://github.com/EliasOenal/multimonNG.git
cd multimonNG
mkdir build
cd build
qmake ../multimon-ng.pro
make
sudo make install

Having done so, we then want to test that the Pi is decoding packets. Note that the frequency here should be set so that the RTL-SDR is actually listening to 144.800 MHz…

rtl_fm -f 144.791M -s 22050 | multimon-ng -a AFSK1200 -A -t raw -

Then, transmit an APRS packet on 144.800 (if you do not have an APRS capable radio you can use the APRSDroid app,  holding your phone up to the microphone). You should see multimonNG output the content of the packet.

Feeding the packets through to APRS-IS

pymultimonaprs is a script that interfaces with the RTL-SDR to send APRS packets to the Internet.

cd ~/rtl
sudo apt-get install python-pkg-resources
git clone https://github.com/asdil12/pymultimonaprs.git
cd pymultimonaprs
sudo python setup.py build
sudo python setup.py install

You then need to generate your APRS passcode, which is needed to send traffic to APRS-IS (replace T3ST with your callsign):

./keygen.py T3ST
Key for T3ST: xxxxx

Note down this passcode, as you will need it later.

We will then edit /etc/pymultimonaprs.json – setting the proper frequency and gain*, as well as our callsign, SSID (-10 for iGates), passcode, gateway, comment and location.

sudo nano /etc/pymultimonaprs.json

*a setting of 42.1 worked well for me. Run rtl_test to get a list of possible gain values.

We will then test that the script is working:

sudo pymultimonaprs

Go to aprs.fi, search for your callsign and hopefully see your iGate on the map.

Making the script run at startup

sudo nano /etc/init.d/pymultimonaprs

Then paste in:

#!/bin/sh
### BEGIN INIT INFO
# Provides: pymultimonaprs
# Required-Start: $all
# Required-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start/stop of pymultimonaprs
### END INIT INFO

case "$1" in
 start)
   sudo pymultimonaprs --syslog &
   ;;
 stop)
   sudo killall pymultimonaprs
   ;;
 *)
   echo "Usage: /etc/init.d/pymultimonaprs {start|stop}"
   exit 1
   ;;
esac

exit 0

Make the script executable and start it:

sudo chmod +x /etc/init.d/pymultimonaprs
sudo update-rc.d pymultimonaprs defaults
sudo /etc/init.d/pymultimonaprs start

 

And that’s it – you’re finished!

 

Cover image: Russ Sanderlin – https://www.flickr.com/photos/tearstone/8498072730. CC 2.0 BY-SA 

Comments

Antonis Papatsaras says:

small correction,

line
sudo git clone git://gitosmocom.org/rtl-sdr.git
should be
sudo git clone git://git.osmocom.org/rtl-sdr.git
missing one dot.

Leave a Reply