An implementation to detect and decode Mode-S messages modulated on 1090MHz. The implementation is implemented fully in Python (2.7.9), tested on raspberry pi 2 model B hardware using an RTL-SDR USB dongle.
Focus is on using Python idioms and readability, not optimizations. Other implementations in C are likely more efficient.
The implementation is multi-threaded:
- Tuner: sample the signal
- Squitter: decoded messages
- Radar: main application that displays messages
- Basic: fundamentals
It tries to be as complete and accurate as possible but with no guarantees of being correct.
The following message will be decoded:
- Short air-to-air surveillance (Downlink format: 0)
- Surveillance altitude reply (Downlink format: 4)
- Surveillande identity reply (Downlink format: 5)
- Long air-to-air surveillance (Downlink format: 16)
- ADS-B (Downlink format:17)
- Extended Squitter (Downlink format: 17)
- Comm BDS altitude reply (Downlink format: 20)
- Comm BDS identity reply (Downlink format: 21)
Messages decoded are displayed either in a serialised format on standard output or in a tabular format depending on preference. An inbuilt server is listening on port 5051 (configurable) and enables a client to access decoded messages in json format.
Some statistics is collected, this data is also accessible through the server
Spots uses pyrtlsdr v0.2.0 to read samples. Use the installation description to install this.
pyrtlsdr is wrapper for rtlsdr library, so this needs to be installed.
See the following references:
- https://sdr.osmocom.org/trac/wiki/rtl-sdr
- https://zr6aic.blogspot.se/2013/02/setting-up-my-raspberry-pi-as-sdr-server.html
The following worked for me
$ sudo apt-get update
$ sudo apt-get install cmake
$ sudo apt-get install libusb-1.0-0.dev
$ git clone git:https://git.osmocom.org/rtl-sdr.git
$ cd rtl-sdr/
$ mkdir build
$ cd build
$ cmake ../
$ make
$ sudo make install
$ sudo ldconfig
Edit the blacklist
$ sudo nano /etc/modprobe.d/raspi-blacklist.conf
Add these lines
blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830
Finally
$ sudo cp ../rtl-sdr.rules /etc/udev/rules.d/
$ sudo shutdown -r 0
As the implementation have no access to specifications the following implementations serves as references for spots
- dump1090 by antirez, the original
- dump1090 by Malcolm Robb, a fork of antirez
- dump1090 by flighaware, another fork
- java adsb at OpenSky, a java implementation
- ADS-B decoding guide
Simply try
$ python radar.py
Configuration for spots is in spots_config.json
. Follows json syntax with no error checks so be careful.
- verbose logging (true/false): writes messages to spots logfile
- check crc (true/false): whether to check crc (recommended) or not
- check phase (true/false): simple check if there is a phase shift and correction
- use metric (true/false): show values in metric system or not (altitude and velocity)
- apply bit error correction (true/false): whether to try to correct bit errors or not (CPU demanding if true)
- read from file (true/false): if true, read samples from a file rather than from the USB dongle
- file name (string): if "read from file" is true, this is the file to read from
- use text display (true/false): if true, show data in table format, if false show in serialised way
- max blip ttl (integer or float): how many seconds to keep an identified aircraft in the table display
- user latitude (float): your latitude position
- user longitude (float): and your longitude
- log file (string): The name of the log file
- log max bytes (integer): How many bytes to log before the log file is rotated
- log backup count (integer): How many roted log files to keep
- spots server address (localhost or ip-address): the address for the server
- spots server port (5051): the server port
Use nginx as proxy server with the following added to the nginx conf file
location /spots {
try_files $uri $uri/ $uri/index.html $uri.html @spots;
}
location @spots {
proxy_pass https://rpi2.local:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
So, nginx will forward any http requests to spots (e.g. https://www.viltstigen.se/spots
) to
https://rpi2.local:8080
(spots runs on rpi2-node).
Flask is running using Gunicorn, listening on port 8080, see emitter.py
and spots_emitter.conf
for details.
Use supervisor
to control processes running as daemons.
The flask application communicates with the radar application (that listen on port 5051) through a simple text
protocol, see files emitter.py
and server.py
Using some html, bootstrap css and javascripts (jQuery and Highcharts), see files spots.html and spots.js, it is possible to get this view in a web browser.
There is probably inconsistencies, bugs, optimizations, documentation etc etc to make. If you find something, let me know but be aware that this is a leisure thing for me.