The Raspberry Pi single-board computer runs Linux in a small package.

ADS-B Flight Tracking with a Raspberry Pi and USB-Connected Software-Defined Radio

ADS-B Flight Tracking

The Raspberry Pi is an extremely low-cost yet highly capable Linux platform. Let's combine one with a USB-connected Software-Defined Radio to receive and process data broadcast at 1090 MHz by aircraft flying overhead. ADS-B is part of US, Canadian, Australian, and European air traffic control systems. Aircraft broadcast their positions and other flight data. The resulting data collection can replace secondary radar surveillance.

Web view of ADS-B aircraft tracking on a Raspberry Pi, several aircraft around West Lafayette, Indiana.

ADS-B tracking data received with an RTL SDR unit plugged into a Raspberry Pi. RTL SDR means it's based on a RealTek chip set and it's a Software-Defined Radio. It looks like an over-sized USB thumbdrive and costs about US$ 10-20. This system is running the free PiAware software. Light purple aircraft icons indicate tracking by multilateration.

ADS-B or Automatic Dependent Surveillance — Broadcast collects aircraft data including position from a GPS navigational system, elevation, air speed, and bearing. It is "Automatic" in the sense that the system runs on its own with no control input from the pilot, "Dependent" in the sense that it needs position input from other on-board systems, and "Broadcast" in the sense that the data is transmitted as cleartext at 1090 MHz, easily received by simple ground stations. Aircraft at higher altitudes may be easily received at distances of 100 miles or more.

Aircraft registration
database lookup:
Map ICAO hex codes
like aa4c3e
to registration

By 2015, ADS-B was manditory in parts of Australian airspace and it was being used for air traffic control in Canada. It is part of the Single European Sky ATM Research or SESAR, and the U.S. Next Generation Air Transportation System or NextGen. Position and velocity information is broadcast once per second through what is essentially a modified Mode S radar transponder. In most cases the position information is more accurate than what can be obtained by current air surveillance radar systems.

Air Surveillance Radar

Primary Surveillance Radar (or PSR) detects objects by the "skin paint" return, the reflection from the aircraft. The return energy falls off as the fourth power of range, a severe penalty defined by the radar equation for received signal power:

Pr = Pt Gt Ar σ F4
(4π)2 Rt2 Rr2

Pr = signal power returning from the target to the receiving antenna

Pt = transmitter power

Gt = transmitter antenna gain

Ar = effective aperture of receiving antenna, which can be calculated as Grλ2/4π where Gr is receive antenna gain and λ is wavelength

σ = radar cross section of the target

F = propagation factor

Rt and Rr are ranges (that is, distances) from the transmitter to the target and from the receiver to the target, respectively. The receiver and transmitter can be widely separated in bistatic radar systems and these two ranges may be significantly different.

With the transmitter and receiver co-located and so just a single range value R, the return signal power is proportional to 1/R4. If you double the range, the return signal drops by a factor of 16. At ten times the range, the return signal drops to just 1/10,000 or 0.01% of the original level.

This limits the range and accuracy of primary surveillance radar.

Secondary Surveillance Radar (or SSR) is derived from the IFF or Identification Friend or Foe systems designed during World War II. The radar pulse interrogates the aircraft, requesting a data packet from its transponder. The radar transmits at 1030 MHz, the transponder replies at 1090 MHz.

This can work at a much greater range than the primary radar given similar transmit power, antenna gain, and receive sensitivity, as the received signal levels in both directions fall off only at a rate of R2 rather than R4.

A Mode A transponder simply reports the aircraft's identity. Mode C also reports the pressure altitude. Mode S can send 56 to 1,280 bits of information per return.

Multilateration (or MLAT) is used to calculate the location of aircraft with Mode S but not ADS-B transponders. The aircraft are located using the time difference of arrival of their signals at three or more FlightAware receivers. They appear as light purple aircraft icons.

U.S. Military
Callsigns

Military aircraft will appear with their callsign, typically a word indicating the unit and a number for which aircraft. I see INDY and MASH, KC-135R tankers with the 434th Air Refueling Wing out of Grissom Air Reserve Base near Peru, Indiana. REACH is a general callsign used by various Air Mobility Command cargo aircraft. Look up the ICAO hex code at airframes.org to see the aircraft type.

Software-Defined Radio

Build a 1090 MHz
ADS-B antenna

Small SDR units marketed primarily for television reception are available for only about US$ 10–20. They include a USB-connected receiver and a small whip antenna on a short coaxial cable. They are intended for markets like Hong Kong and other large coastal Chinese cities, where people commonly use one of these plus a laptop computer in place of a dedicated television set.

1090 MHz means a wavelength of 27.5 cm, so a quarter-wave whip would be just 6.9 cm or 2.7 inches long. The antenna supplied with these units is about twice that length. Click here for how to build a simple ADS-B antenna.

RTL SDR software-defined radio stick and small external antenna provided in the kit.
Close view of RTL SDR software-defined radio stick showing MCX connector and antenna cable.
RTL SDR MCX connector on small diameter coaxial cable.

Most RTL-SDR devices use an MCX antenna connector. Adapters from MCX to SMA or F or pigtails are available from Amazon and eBay.

Realtek RTL2832U units have varying tuning ranges depending on the tuner chip. Not all of them cover 1090 MHz. The E4000 has the highest tuning range, although with a gap around 1100–1250 MHz and no coverage below 52 MHz.

Tuner Chip Frequency Range
Elonics E4000 52 – 1100, 1250 – 2200 (gap varies)
Rafael Micro R820T 24 – 1766 MHz
Rafael Micro R828T 24 – 1766 MHz
Fitipower FC0013 22 – 1100 MHz
Fitipower FC0012 22 – 948.6 MHz
FCI FC2580 146 – 308, 438 – 924 MHz

Use lsusb to find the Vendor ID and Product ID. This shows that mine should have an E4000 tuner, but see the warning further below:

$ lsusb
[... other lines deleted ...]
Bus 001 Device 005: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
[... other lines deleted ...] 

Here is a list of RTL SDR devices known to work with common SDR software, based on a list at osmocom.org.

Vendor:Product Tuner Device
0x0bda0x2832all/anyGeneric RTL2832U (e.g. hama nano)
0x0bda0x2838E4000ezcap USB 2.0 DVB-T/DAB/FM dongle
See following warning
0x0ccd0x00a9FC0012Terratec Cinergy T Stick Black (rev 1)
0x0ccd0x00b3FC0013Terratec NOXON DAB/DAB+ USB dongle (rev 1)
0x0ccd0x00d3E4000Terratec Cinergy T Stick RC (Rev.3)
0x0ccd0x00e0E4000Terratec NOXON DAB/DAB+ USB dongle (rev 2)
0x185b0x0620E4000Compro Videomate U620F
0x185b0x0650E4000Compro Videomate U650F
0x1f4d0xb803FC0012GTek T803
0x1f4d0xc803FC0012Lifeview LV5TDeluxe
0x1b800xd3a4FC0013Twintech UT-40
0x1d190x1101FC2580Dexatek DK DVB-T Dongle (Logilink VG0002A)
0x1d190x1102?Dexatek DK DVB-T Dongle, MSI (DigiVox?) mini II V3.0
0x1d190x1103FC2580Dexatek Technology Ltd. DK 5217 DVB-T Dongle
0x04580x707f?Genius TVGo DVB-T03 USB dongle (Ver. B)
0x1b800xd393FC0012GIGABYTE GT-U7300
0x1b800xd394?DIKOM USB-DVBT HD
0x1b800xd395FC0012Peak 102569AGPK
0x1b800xd39dFC0012SVEON STV20 DVB-T USB & FM

Beware: Some devices are externally labeled "DVB-T+DAB+FM", which identify on the USB bus as 0x0bda:0x2838 (ezcap, expected to have an E4000 tuner). However, they instead have a Fitipower FC0012 tuner and thus are not suitable for ADS-B as they only cover 22-948.6 MHz. You will see:

$ lsusb
Bus 001 Device 004: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
Bus 001 Device 005: ID 0424:7800 Standard Microsystems Corp. 
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ dump1090-mutability 
Wed Jun 13 15:55:43 2018 EDT  dump1090-mutability v1.14 starting up.
Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001 (currently selected)
Found Fitipower FC0012 tuner
Max available gain is: 19.20 dB
Setting gain to: 19.20 dB
[FC0012] no valid PLL combination found for 1090000000 Hz!
Exact sample rate is: 2000000.052982 Hz
Gain reported by device: 19.20 dB
^C
Caught SIGINT, shutting down..
Normal exit. 

Amazon
ASIN: B00SXZDUAQ

Amazon
ASIN: B00P2UOU72

Amazon
ASIN: B00CKG6T9I

Amazon
ASIN: B01C6EQNNK

Raspberry Pi

The Raspberry Pi is a small single-board computer available for US$ 30–45. Typical models are based around a Broadcom BCM2835 with a low-power ARM processor running at 700 MHz and a dual-core GPU. Newer models include a quad-core 900 MHz CPU with 1 GB of RAM. There is onboard 10/100 MHz Ethernet and two or four USB 2.0 ports. The board is 86 × 54 mm, just a little too large to fit into an Altoids tin. Audio and video output is through an HDMI port, See some other pages of mine for details on the Raspberry Pi hardware and networking.

Raspberry Pi small single-board Linux computer, showing Ethernet and USB connectors.

Raspberry Pi with one 10/100 Mbps Ethernet port and two USB ports.

Two Raspberry Pi Linux systems in a small case, both with Ethernet network connections and one with an 802.11 WLAN wireless network interface.

Two Raspberry Pi systems in a small surplus case.

Installing PiAware

FlightRadar24
FR24 Software
FlightAware
PiAware

PiAware is an ADS-B software package. It's free to download and easy to install, see the FlightAware PiAware page for details. If you already have a Raspberry Pi running, all you need to do is download and install PiAware.

Another alternative is the FlightRadar24 FR24 software. You can run both FR24 and PiAware at the same time, and have premium access to both FlightAware.com and FlightRadar24.com.

Linux package
management

The obvious PiAware download is a Debian .deb package. Most people use a Debian-derived Linux distribution on their Raspberry Pi, like the Raspbian distro. But if you are using Pidora or another RPM-based Linux distro, or something like FreeBSD, you can download and build PiAware from the source code.

Starting piaware at Boot

Once you install PiAware it will be configured to automatically start every time the system boots:

$ ls -l /etc/rc*/*pidora /etc/init.d/pidora
-rwxr-xr-x 1 root root 1486 Jul  9 07:41 /etc/init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc0.d/K01piaware -> ../init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc1.d/K01piaware -> ../init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc2.d/S02piaware -> ../init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc3.d/S02piaware -> ../init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc4.d/S02piaware -> ../init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc5.d/S02piaware -> ../init.d/piaware
lrwxrwxrwx 1 root root   17 Aug 13 11:28 /etc/rc6.d/K01piaware -> ../init.d/piaware 

It seems at first that it works:

$ sudo bash
# /etc/init.d/piaware status
piaware is running 

But let's ask the running process for details:

# piaware-status
dump1090 is not running.
faup1090 is not running.
piaware is running.
no program appears to be listening for connections on port 30005.
faup1090 is NOT connected to port 30005.
piaware is connected to FlightAware.
got 'couldn't open socket: connection refused'
maybe dump1090 is NOT producing data on port 30005. 

The piaware service did not get dump1090 running, a process that decodes ADS-B data and makes it available on a TCP port. We can try to start it:

# dump1090 --quiet --net
Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000091 (currently selected)

Kernel driver is active, or device is claimed by second instance of librtlsdr.
In the first case, please either detach or blacklist the kernel module
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time.

usb_claim_interface error -6
Error opening the RTLSDR device: Device or resource busy 

Let's investigate further by listing the RTL kernel modules:

# lsmod | grep rtl
dvb_usb_rtl28xxu       17133  0 
rtl2830                 8206  1 dvb_usb_rtl28xxu
rtl2832                 9990  2 dvb_usb_rtl28xxu
i2c_mux                 2471  1 rtl2832
dvb_usb_v2             15893  1 dvb_usb_rtl28xxu
dvb_core              100357  3 rtl2830,rtl2832,dvb_usb_v2
rc_core                23526  14 ir_sharp_decoder,ir_xmp_decoder,lirc_dev,ir_lirc_codec,dvb_usb_rtl28xxu,ir_rc5_decoder,ir_nec_decoder,ir_sony_decoder,ir_mce_kbd_decoder,ir_jvc_decoder,dvb_usb_v2,ir_rc6_decoder,ir_sanyo_decoder 

One way to fix this would be to add a block to /etc/rc.local:

# cat /etc/rc.local
[... other lines deleted ...]
### PiAware ADS-B flight tracking
echo "Restarting dump1090 and piaware ADS-B flight tracking"
/etc/init.d/piaware stop
while [ "$(pgrep dump1090)" ]
do
        echo " killing $(pgrep dump1090)"
        pkill dump1090
done
for MODULE in $( lsmod | awk '{print $1}' | grep rtl28 )
do
	echo " removing module $MODULE"
	rmmod -s $MODULE
done
dump1090 --quiet --net &
/etc/init.d/piaware start
/etc/init.d/piaware status
piaware-status

# /etc/rc.local
Restarting dump1090 and piaware ADS-B flight tracking
Stopping piaware server: piaware.
Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000091 (currently selected)
Starting piaware server: piaware.
Found Elonics E4000 tuner
Max available gain is: 42.00
Setting gain to: 42.00
Exact sample rate is: 2000000.052982 Hz
Gain reported by device: 42.00
piaware is running
dump1090 is running.
faup1090 is running.
piaware is running.
dump1090 is listening for connections on port 30005.
faup1090 is connected to port 30005.
piaware is connected to FlightAware.
dump1090 is producing data on port 30005. 

A simpler fix is to blacklist the kernel module. Put this in the appropriate file and reboot:

# cat /etc/modprobe.d/piaware-blacklist.conf
blacklist dvb-usb-rtl28xxu 

The dump1090 process is listening on TCP ports 10001, 30001, 30002, 30003, 30004, and 30005, plus TCP port 8080 ("http-alt") which provides a web service.

# lsof -p $( pgrep dump1090 )
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
dump1090 2833 root  cwd    DIR  179,2    12288 132781 /
dump1090 2833 root  rtd    DIR  179,2     4096      2 /
dump1090 2833 root  txt    REG  179,2   122140   4160 /usr/bin/dump1090
dump1090 2833 root  mem    REG  179,2    26632   6102 /lib/arm-linux-gnueabihf/librt-2.13.so
dump1090 2833 root  mem    REG  179,2  1200240   6099 /lib/arm-linux-gnueabihf/libc-2.13.so
dump1090 2833 root  mem    REG  179,2   130448  15082 /lib/arm-linux-gnueabihf/libgcc_s.so.1
dump1090 2833 root  mem    REG  179,2   427628   4559 /lib/arm-linux-gnueabihf/libm-2.13.so
dump1090 2833 root  mem    REG  179,2   116462   5425 /lib/arm-linux-gnueabihf/libpthread-2.13.so
dump1090 2833 root  mem    REG  179,2    50856  30702 /lib/arm-linux-gnueabihf/libusb-1.0.so.0.1.0
dump1090 2833 root  mem    REG  179,2    10170   1777 /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
dump1090 2833 root  mem    REG  179,2   126236   4569 /lib/arm-linux-gnueabihf/ld-2.13.so
dump1090 2833 root    0r   CHR    1,3      0t0   3261 /dev/null
dump1090 2833 root    1u   CHR  136,0      0t0      3 /dev/pts/0
dump1090 2833 root    2u   CHR  136,0      0t0      3 /dev/pts/0
dump1090 2833 root    3r  FIFO    0,8      0t0   7679 pipe
dump1090 2833 root    4w  FIFO    0,8      0t0   7679 pipe
dump1090 2833 root    5u  0000    0,9        0   3258 anon_inode
dump1090 2833 root    6u   CHR  189,4      0t0   3610 /dev/bus/usb/001/005
dump1090 2833 root    7u  IPv4   7687      0t0    TCP *:30002 (LISTEN)
dump1090 2833 root    8u  IPv4   7688      0t0    TCP *:30001 (LISTEN)
dump1090 2833 root    9u  IPv4   7689      0t0    TCP *:30005 (LISTEN)
dump1090 2833 root   10u  IPv4   7690      0t0    TCP *:30004 (LISTEN)
dump1090 2833 root   11u  IPv4   7691      0t0    TCP *:http-alt (LISTEN)
dump1090 2833 root   12u  IPv4   7692      0t0    TCP *:30003 (LISTEN)
dump1090 2833 root   13u  IPv4   7693      0t0    TCP *:10001 (LISTEN)
dump1090 2833 root   14u  IPv4   8161      0t0    TCP localhost:30005->localhost:35501 (ESTABLISHED)
dump1090 2833 root   15u  IPv4   8621      0t0    TCP localhost:30005->localhost:35503 (ESTABLISHED)
dump1090 2833 root   16u  IPv4   8704      0t0    TCP localhost:30004->localhost:45242 (ESTABLISHED) 

Use a web browser to connect to TCP port 8080 on your Raspberry Pi:

Web view of ADS-B aircraft tracking on a Raspberry Pi, several aircraft around West Lafayette, Indiana.

The piaware process will be connected to a FlightAware server, uploading the data you are receiving. This automatically upgrades you to a free Enterprise membership at FlightAware:

# lsof -p $( pgrep piaware )
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
piaware 2842 root  cwd    DIR  179,2     4096     2 /
piaware 2842 root  rtd    DIR  179,2     4096     2 /
piaware 2842 root  txt    REG  179,2     3896  7814 /usr/bin/piaware
piaware 2842 root  mem    REG  179,2    71528 13346 /lib/arm-linux-gnueabihf/libresolv-2.13.so
piaware 2842 root  mem    REG  179,2    18040  4554 /lib/arm-linux-gnueabihf/libnss_dns-2.13.so
piaware 2842 root  mem    REG  179,2    95324 47276 /usr/lib/libitcl3.4.so.1
piaware 2842 root  mem    REG  179,2    87792  5150 /lib/arm-linux-gnueabihf/libz.so.1.2.7
piaware 2842 root  mem    REG  179,2  1410384  3952 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.0.0
piaware 2842 root  mem    REG  179,2   297452  3953 /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0
piaware 2842 root  mem    REG  179,2    32424 47269 /usr/lib/libtls1.6.so
piaware 2842 root  mem    REG  179,2   130800 10799 /usr/lib/libtclx8.4.so.0
piaware 2842 root  mem    REG  179,2    42692  6007 /lib/arm-linux-gnueabihf/libnss_files-2.13.so
piaware 2842 root  mem    REG  179,2    38608  4573 /lib/arm-linux-gnueabihf/libnss_nis-2.13.so
piaware 2842 root  mem    REG  179,2    71624 13291 /lib/arm-linux-gnueabihf/libnsl-2.13.so
piaware 2842 root  mem    REG  179,2    26484 13347 /lib/arm-linux-gnueabihf/libnss_compat-2.13.so
piaware 2842 root  mem    REG  179,2  2025648 10547 /usr/lib/locale/locale-archive
piaware 2842 root  mem    REG  179,2   130448 15082 /lib/arm-linux-gnueabihf/libgcc_s.so.1
piaware 2842 root  mem    REG  179,2   427628  4559 /lib/arm-linux-gnueabihf/libm-2.13.so
piaware 2842 root  mem    REG  179,2     9812 13289 /lib/arm-linux-gnueabihf/libdl-2.13.so
piaware 2842 root  mem    REG  179,2  1200240  6099 /lib/arm-linux-gnueabihf/libc-2.13.so
piaware 2842 root  mem    REG  179,2   116462  5425 /lib/arm-linux-gnueabihf/libpthread-2.13.so
piaware 2842 root  mem    REG  179,2   975580 58942 /usr/lib/libtcl8.5.so.0
piaware 2842 root  mem    REG  179,2    10170  1777 /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
piaware 2842 root  mem    REG  179,2   126236  4569 /lib/arm-linux-gnueabihf/ld-2.13.so
piaware 2842 root    0u   CHR    1,3      0t0  3261 /dev/null
piaware 2842 root    1w   REG  179,2     5575   269 /tmp/piaware.out
piaware 2842 root    2w   REG  179,2     5575   269 /tmp/piaware.out
piaware 2842 root    3r  FIFO    0,8      0t0  7680 pipe
piaware 2842 root    4w  FIFO    0,8      0t0  7680 pipe
piaware 2842 root    5u  IPv4   7910      0t0   TCP raspberrypi.kc9rg.org:46232->eyes.flightaware.com:1200 (ESTABLISHED)
piaware 2842 root    6r  FIFO    0,8      0t0  8146 pipe
piaware 2842 root    7r  FIFO    0,8      0t0  8308 pipe
piaware 2842 root    8u   REG  179,2        0   866 /tmp/tcl1uXddV (deleted)
piaware 2842 root   11w  FIFO    0,8      0t0  8309 pipe
piaware 2842 root   12r  FIFO    0,8      0t0  8310 pipe