Friday, September 06, 2019

Aircraft, ADS-B and the Raspberry Pi



So, did you know that Aircraft, nearly all aircraft broadcast their position, name, altitude and other metrics whenever they fly on a 1090 Mhz signal.


It is called Automatic Dependent Surveillance Broadcast  ADS-B

And so, if you say had such a Radio receiver you can listening to this information and know what planes are flying around you.

That is the subject of this post.

And we will do this in 2 ways, both using a Raspberry Pi 3B+.  Of course you are going to read carefully both ways before diving in regardless


Standing on the Shoulders of Giants
I hope at all times to produce excellent and clear documentation.   But it's not my policy to steal somebody else's work and claim it.  And when in this case their documentation is so top notch, I've have nothing really to add.  So I'll point to their great work and add some pointers


Hardware Required
- Raspberry Pi 3B+, I use PiHut
- 32GB microSD card to hold the Operating System and apps
- My Pi is in a nice case. I recommend FLIRC
- A Software Defined Radio.  Mine was 11 GBP from Amazon UK
- I did not need a powered USB hub, I simply plugged the USB radio into a PI USB slot

By the end of this post I expect you will be running to order these parts!


Method 1 Manual 

- You will install a Pi with Raspbian
- You will then download any compiler tools required, the dump1090 code, compile it and start the built program

First read this Blogpost

This refers to the detail build guide PDF

Since the build guide is not cut and paste-able you can use my command line notes here

apt-get update
apt-get upgrade
apt-get install git-core
apt-get install git
apt-get -y install cmake

# id
uid=0(root) gid=0(root) groups=0(root)
# cd
# pwd
/root

git clone git://git.osmocom.org/rtl-sdr.git
Cloning into 'rtl-sdr'...
remote: Counting objects: 1768, done.
remote: Compressing objects: 100% (559/559), done.
remote: Total 1768 (delta 1269), reused 1622 (delta 1190)
Receiving objects: 100% (1768/1768), 388.97 KiB | 0 bytes/s, done.
Resolving deltas: 100% (1269/1269), done.

cd rtl-sdr/
mkdir build
cd build

apt-get -y install libUSB-1.0

cmake ../ -DINSTLL_UDEV_RULES=ON
-- Build type not specified: defaulting to release.
-- Extracting version information from git describe...
-- Checking for module 'libusb-1.0'
--   Found libusb-1.0, version 1.0.21
-- Found libusb-1.0: /usr/include/libusb-1.0, /usr/lib/arm-linux-gnueabihf/libusb-1.0.so
-- Udev rules not being installed, install them with -DINSTALL_UDEV_RULES=ON
-- Building with kernel driver detaching disabled, use -DDETACH_KERNEL_DRIVER=ON to enable
-- Building with usbfs zero-copy support disabled, use -DENABLE_ZEROCOPY=ON to enable
-- Building for version: 0.6.0-5-g8183 / 0.6git
-- Using install prefix: /usr/local
-- Configuring done
-- Generating done
-- Build files have been written to: /root/rtl-sdr/build

# make
Scanning dependencies of target rtlsdr_shared
[  3%] Building C object src/CMakeFiles/rtlsdr_shared.dir/librtlsdr.c.o
[  6%] Building C object src/CMakeFiles/rtlsdr_shared.dir/tuner_e4k.c.o
[ 10%] Building C object src/CMakeFiles/rtlsdr_shared.dir/tuner_fc0012.c.o
[ 13%] Building C object src/CMakeFiles/rtlsdr_shared.dir/tuner_fc0013.c.o
[ 16%] Building C object src/CMakeFiles/rtlsdr_shared.dir/tuner_fc2580.c.o
[ 20%] Building C object src/CMakeFiles/rtlsdr_shared.dir/tuner_r82xx.c.o
[ 23%] Linking C shared library librtlsdr.so
[ 23%] Built target rtlsdr_shared
Scanning dependencies of target convenience_static
[ 26%] Building C object src/CMakeFiles/convenience_static.dir/convenience/convenience.c.o
[ 30%] Linking C static library libconvenience_static.a
[ 30%] Built target convenience_static
Scanning dependencies of target rtl_sdr
[ 33%] Building C object src/CMakeFiles/rtl_sdr.dir/rtl_sdr.c.o
[ 36%] Linking C executable rtl_sdr
[ 36%] Built target rtl_sdr
Scanning dependencies of target rtl_fm
[ 40%] Building C object src/CMakeFiles/rtl_fm.dir/rtl_fm.c.o
[ 43%] Linking C executable rtl_fm
[ 43%] Built target rtl_fm
Scanning dependencies of target rtlsdr_static
[ 46%] Building C object src/CMakeFiles/rtlsdr_static.dir/librtlsdr.c.o
[ 50%] Building C object src/CMakeFiles/rtlsdr_static.dir/tuner_e4k.c.o
[ 53%] Building C object src/CMakeFiles/rtlsdr_static.dir/tuner_fc0012.c.o
[ 56%] Building C object src/CMakeFiles/rtlsdr_static.dir/tuner_fc0013.c.o
[ 60%] Building C object src/CMakeFiles/rtlsdr_static.dir/tuner_fc2580.c.o
[ 63%] Building C object src/CMakeFiles/rtlsdr_static.dir/tuner_r82xx.c.o
[ 66%] Linking C static library librtlsdr.a
[ 66%] Built target rtlsdr_static
Scanning dependencies of target rtl_tcp
[ 70%] Building C object src/CMakeFiles/rtl_tcp.dir/rtl_tcp.c.o
[ 73%] Linking C executable rtl_tcp
[ 73%] Built target rtl_tcp
Scanning dependencies of target rtl_test
[ 76%] Building C object src/CMakeFiles/rtl_test.dir/rtl_test.c.o
[ 80%] Linking C executable rtl_test
[ 80%] Built target rtl_test
Scanning dependencies of target rtl_adsb
[ 83%] Building C object src/CMakeFiles/rtl_adsb.dir/rtl_adsb.c.o
[ 86%] Linking C executable rtl_adsb
[ 86%] Built target rtl_adsb
Scanning dependencies of target rtl_eeprom
[ 90%] Building C object src/CMakeFiles/rtl_eeprom.dir/rtl_eeprom.c.o
[ 93%] Linking C executable rtl_eeprom
[ 93%] Built target rtl_eeprom
Scanning dependencies of target rtl_power
[ 96%] Building C object src/CMakeFiles/rtl_power.dir/rtl_power.c.o
[100%] Linking C executable rtl_power

 make install
[ 23%] Built target rtlsdr_shared
[ 30%] Built target convenience_static
[ 36%] Built target rtl_sdr
[ 43%] Built target rtl_fm
[ 66%] Built target rtlsdr_static
[ 73%] Built target rtl_tcp
[ 80%] Built target rtl_test
[ 86%] Built target rtl_adsb
[ 93%] Built target rtl_eeprom
[100%] Built target rtl_power
Install the project...
-- Install configuration: "Release"
-- Installing: /usr/local/lib/pkgconfig/librtlsdr.pc
-- Installing: /usr/local/include/rtl-sdr.h
-- Installing: /usr/local/include/rtl-sdr_export.h
-- Installing: /usr/local/lib/librtlsdr.so.0.6git
-- Installing: /usr/local/lib/librtlsdr.so.0
-- Installing: /usr/local/lib/librtlsdr.so
-- Installing: /usr/local/lib/librtlsdr.a
-- Installing: /usr/local/bin/rtl_sdr
-- Set runtime path of "/usr/local/bin/rtl_sdr" to ""
-- Installing: /usr/local/bin/rtl_tcp
-- Set runtime path of "/usr/local/bin/rtl_tcp" to ""
-- Installing: /usr/local/bin/rtl_test
-- Set runtime path of "/usr/local/bin/rtl_test" to ""
-- Installing: /usr/local/bin/rtl_fm
-- Set runtime path of "/usr/local/bin/rtl_fm" to ""
-- Installing: /usr/local/bin/rtl_eeprom
-- Set runtime path of "/usr/local/bin/rtl_eeprom" to ""
-- Installing: /usr/local/bin/rtl_adsb
-- Set runtime path of "/usr/local/bin/rtl_adsb" to ""
-- Installing: /usr/local/bin/rtl_power
-- Set runtime path of "/usr/local/bin/rtl_power" to ""

sudo ldconfig   # did nothing here

 pwd
/root/rtl-sdr/build
# cd -
/root/rtl-sdr

ls -l /etc/udev/rules.d
total 4
-rw-r--r-- 1 root root 1028 Nov 27  2017 99-com.rules

cp ./rtl-sdr.rules /etc/udev/rules.d/
ls -l /etc/udev/rules.d
total 12
-rw-r--r-- 1 root root 1028 Nov 27  2017 99-com.rules
-rw-r--r-- 1 root root 5794 Sep  3 16:53 rtl-sdr.rules

shutdown -r now

rtl_test -t
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM

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
Failed to open rtlsdr device #0.

cd /etc/modprobe.d
# ls -l raspi-blacklist*
-rw-r--r-- 1 root root 0 Nov 13  2018 raspi-blacklist.conf
cp raspi-blacklist.conf raspi-blacklist.conf.org
vi raspi-blacklist.conf

# rtl28xuu for aircraft scanning
blacklist dvb_usb_rtl28xxu

shutdown -r now

rtl_test -t
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
[R82XX] PLL not locked!
Sampling at 2048000 S/s.
No E4000 tuner found, aborting.

# pwd
/home/pi
# cd
# pwd
/root
# ls
rtl-sdr

git clone git://github.com/MalcolmRobb/dump1090.git
Cloning into 'dump1090'...
remote: Enumerating objects: 1401, done.
remote: Total 1401 (delta 0), reused 0 (delta 0), pack-reused 1401
Receiving objects: 100% (1401/1401), 4.15 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (850/850), done.

ls -l
total 8
drwxr-xr-x  8 root root 4096 Sep  3 17:05 dump1090
drwxr-xr-x 10 root root 4096 Sep  3 16:41 rtl-sdr


 cd dump1090
# pwd
/root/dump1090

 make
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c dump1090.c
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c anet.c
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c interactive.c
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c mode_ac.c
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c mode_s.c
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c net_io.c
gcc -g -o dump1090 dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o `pkg-config --libs librtlsdr` -lpthread -lm
gcc -O2 -g -Wall -W `pkg-config --cflags librtlsdr`  -c view1090.c
gcc -g -o view1090 view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o `pkg-config --libs librtlsdr` -lpthread -lm

./dump1090 --interactive

./dump1090 --quiet --net &
[1]     1004
# Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001 (currently selected)
Found Rafael Micro R820T tuner
Max available gain is: 49.60
Setting gain to: 49.60
Exact sample rate is: 2000000.052982 Hz

Gain reported by device: 49.60


Method1, Webserver

Once you have started dump1090 a webserver is running on port 8080, so from a browser surf into it.  Example our pi has IP 192.168.1.150  so it was http://192.168.1.150:8080


I noticed that Google Maps did not display the maps correctly.   In order to get this to work it was involved as I had to join  Google Cloud


then generate a project and request an API Key

Go back to Pi and in the dump1090 code and edit  the gmap.html file and add the last line shown below below the 2 that I show

<script type="text/javascript" src="coolclock/coolclock.js"></script>
<script type="text/javascript" src="coolclock/moreskins.js"></script>
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?key=KEY_THAT_I_GOT_FROM_GOOGLE&libraries=geometry"></script>

Now restart dump1090  and the maps should display.   As you signed up for the cloud it looks like the free tier comes with 300 USD worth of services, and each time a map page is loaded it has a cost which I presume is deducted from the 300 USD credit.




Method 2, FlightAware


After trotting through method 1, I then realised that I can instead take a pre packaged Raspberry Pi image from FlightAware.  You are building a piaware computer.

This works in the following way

- Make a flightaware userid and password on flightaware by joining

- Download the Flightaware image for Raspberry Pi and  write it to your microSD using Etcher or similar

- Start up Pi

- For me I needed to give it a predictable DHCP address given out by by Mikrotik DHCP server

- I added a console screen to the Pi and got a command line

- Using the  pi default password of flightaware you login

- Use raspi-config to setup ssh daemon, and now for any further command line config I can ssh in from another system using user pi and the password just chosen

- change the pi user password to something inscrutable

- Okay enough talk,  here are the build instructions



- Once you have built your piaware device  you can goto the webserver running on your build device.  Obviously this is data coming from your aerial and decoded by your Pi


- Now click on 'View you site statistics online'
Here you can customise your photograph, and click on the gear wheel to set accurately your GPS position and altitude.

- One you have signed on and your piaware is transmitting its data to the flightaware servers it means you qualify for a free Enterprise account

- Download the FlightAware application for your phone.  Any codes are stored on the online statistics page you click from your webserver.



- You are not alone.  The above map represents other piaware users helping flightaware to maintain an accurate map of aircraft flying and their exact position


What I learnt

- Nearly all planes transmit an ADS-B signal on 1090 MHz giving their plane speed, name, altitude etc

- You can buy a cheap  (12 GBP) Software Defined radio and connect this up to a small inexpensive Raspberry Pi

- Then either using the dump1090 software you installed, or a predesigned FlightAware image you can see what planes are flying around you by decoding their ADS-B transmissions

Personally I find this frikkin incredible!

- If you use the FlightAware image for your Pi computer then it sends this data to FlightAware central where your data and the data from other piAware computers is aggregated to provide a comprehensive realtime map of aircraft around you.

- From not really knowing that ADS-B existed just a few weeks back, I've come a long way.




Links
Wikipedia ADS-B