Very cheap and simple RX-only APRS IGate

This is a quick post describing my recent efforts to establish a very minimal receive-only IGate at IO91lk. I’m hoping that this post will make it very easy for anyone to replicate the entire setup – so I’ll include hardware purchase and software download links later on.

tl;dr Raspberry Pi 2, RTL TV stick, 5/8 whip on a SO239, Direwolf.

First off, here’s a terrible photo.

You’re looking at MB7UUU – maybe the only RTL dongle with a callsign?


Grab a Raspberry Pi – I used a Pi 2, but you could you a zero for this to keep costs really low, assuming my SD card image works on the zero – not tried. (£6)

Grab a USB Wi-Fi dongle – mine is just a very cheap one off eBay. Hopefully this image will boot and work on the Pis with Wi-Fi built in – will test soon. (£2)

Grab a 4GB SD card. (£2)

Grab an RTL2832U USB TV dongle, I use this one. (£10)

Build or buy an antenna – I made a 5/8 whip on an SO239 socket, didn’t bother with the loading coil, hung from the rafters by the top, works great. (£2 tops for socket, £1 tops for wire, could be done for free)

Devise a way to connect your RTL dongle to your antenna – I had a pigtail floating around, so I did it properly, but you could probably do fine just bodging the antenna element on to the coax from the antenna the dongle came with.

I make that approx. £20 all-in, £25 if you need a USB power supply as well.


You have two options here, easy mode or hard mode.

Easy mode:

  1. grab this SD card image*
  2. unzip it
  3. burn it on to a micro-sd card using Win32diskimager or dd as appropriate
  4. Eject the SD card, stick it in the Pi, boot the Pi
  5. Run rtl_test as per this page, and get the PPM value for your stick (may take some time to warm up / get stable)
  6. Shut down the Pi, put the SD card in your PC, edit aprsconfig.json on the drive mounted from the SD card (or you can do this directly on the Pi if you want – /boot/aprsconfig.json)
  7. Minimally, fill in Mycall, Lat, Lon, Wifis (SSID/key, and only if you aren’t using wired Ethernet), RTLPPM from rtl_test
  8. Boot the Pi with the SD card, give it a minute and you should see your callsign appear on as soon as it hears traffic – example for my case

*full disclosure, I just realised I left my ssh key in authorized_keys- remove if you’re bothered- can’t do anything with it unless I’m on your LAN

That’s it. There’s a utility I wrote on the SD card which runs at every boot, takes whatever is configured in /boot/aprsconfig.json and sets everything up. Should be pretty flexible. If you need to reconfigure the IGate, just pull the SD card, edit that file, then boot it again. Likewise if your SD card fails, just burn it again from the link above and drop your aprsconfig.json file on to the card.

The login credentials for the image are: hostname rtlpi, user root, password raspberry.

Here in Tilehurst / Calcot with a 5/8 whip at ~70m ASL / ~5m AGL in an attic, I routinely receive several packets per minute, mainly from the local digipeaters.

The Pi image is theoretically set up with an Icecast server so you can listen to what Direwolf hears on 144.800 through a web browser, to get an indication that things are working, however I think I broke this somehow just before I took the image, while minimising filesystem writes to maximise SD card lifetime. I might do an updated image shortly.

If you’re using Wi-Fi, and your dongle doesn’t register as wlan0, you might have to do some fiddling.

Hard mode

Not going to write this up fully right now, but the secret sauce is the following command line:

ppm=37 # your PPM value here

rtl_fm -f 144800000 -p $ppm - | direwolf -t 0 -c direwolf.conf -r 24000 -D 1 -q d > dw.log

or if you want to include streaming to Icecast:

rtl_fm -f 144800000 -p $ppm - | tee >(direwolf -t 0 -c direwolf.conf -r 24000 -D 1 -q d > dw.log 2>&1) | ices2 /tmp/ices-conf.xml

where direwolf.conf is:

ADEVICE stdin null
MYCALL [your callsign here]
MODEM 1200
IGLOGIN [your callsign here] [your APRS passcode here]
PBEACON sendto=IG delay=0:30 every=60:00 symbol="igate" overlay=R lat=50^12.34N long=1^1.23W [update with your own position]

and ices-conf.xml is:

<?xml version="1.0"?>
 <name>APRS frequency audio stream</name>
 <param name="rate">24000</param>
 <param name="channels">1</param>
 <param name="metadatafilename">test</param>-->
 <yp>1</yp> <!-- allow stream to be advertised on YP, default 0 -->

I’ve bundled some software into the SD card image which automates the configuration stuff – source code to go up on Github soon.


In the UK, a pedantic reading of the licence terms suggests, in my opinion, that an APRS IGate falls under Unattended and/or Remote Operation (section 2 part 10(3)), and the licence (section 1) also pedantically defines Radio Equipment as transmitting and receiving equipment. So while the regulator is highly likely to not give a damn, filing for an NoV (Notice of Variation) was straightforward and came back extremely quickly – about 40 hours from initial application with RSGB ETCC to having the NoV returned from Ofcom. Superb service, and my thanks to Steve G8SFR at ETCC in particular – so now by any possible reading I’m covered. Steve advised that closedown operators are not required to be named for a receive-only application, and a max transmit power of -60dBW (1 μW) was specified on the application – way above the -80dBm (10pW) local oscillator leakage measured at the RF input connector by G8JNJ – technically required since the LO will leak out of the antenna, even if to an indetectably small degree. If you choose not to go down the NoV route, and clearly this won’t be possible for all, I’m not about to judge, but it’s not on me.