Tuesday, 9 February 2016

Rasperry Pi RTL-SRD AIS tracker for OpenCPN and MarineTraffic.com

Raspberry Pi 2 Model B
RT820T based RTL SDR USB dongle
1/4 wave groundplane antenna / moxon loop

I have a raspberry Pi 2 running with RTL-SDR USB stick successfully feeding AIS to marinetraffic.com  and to my local network. The rough steps (and links to guides are below)

Start with fresh install of raspbian Jessie lite 2016-5-10

Install RTL SDR on Raspberry Pi and add to blacklist of USB devices: http://goo.gl/tXnW13.
sudo apt-get update

Now install the required utils to compile the RTL-2832U USB dongle driver

sudo apt-get install git 
sudo apt-get install cmake
sudo apt-get install libusb-1.0-0.dev
sudo apt-get install build-essential

Now install the RTL-2832U USB dongle driver src and compile

git clone git://git.osmocom.org/rtl-sdr.git
cd rtl-sdr/
mkdir build
cd build
cmake ../
sudo make install
sudo ldconfig

Edit the following file /etc/modprobe.d/raspi-blacklist.conf

use your favourite editor like nano or vi 

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

add the following lines in the file.

blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830

Save and exist.
 (ctrl-X --> y -->enter)

REBOOT then plug in your RTL-SDR stick

Confirm the RTL is working using rtl_test first before proceeding:

sudo rtl_tcp -t

Install gnuradio(dev) http://goo.gl/TVogHw  (takes a long time!) :
sudo apt-get install gnuradio gnuradio-dev
install osmosdr:
sudo apt-get install gr-osmosdr

install Boost
sudo apt-get install libboost1.50-all

install Cppunit:
sudo apt-get install libcppunit-dev

install liblog4cpp5:
sudo apt-get install liblog4cpp5-dev

install socat:
sudo apt-get install socat
install swig:
sudo apt-get install swig

install gr-ais https://goo.gl/QXXzhO.  :

 git clone https://github.com/bistromath/gr-ais.git
 cd gr-ais
 mkdir build
 cd build
 cmake ../
 if you get an error at this point:
CMake Error at CMakeLists.txt:114 (find_package):
  Could not find a configuration file for package "Gnuradio" that is
  compatible with requested version "3.7.6".

then edit cmake to force 3.75 (a bodge, but works!):

cd ~/gr-ais
nano CMakeFiles.txt

find the section #Find gnuradio build dependencies
edit the line:
find_package(Gnuradio "3.7.6" REQUIRED)
change to

find_package(Gnuradio "3.7.5" REQUIRED)

 exit nano(Ctrl-x -->y-->enter)
resume with building:

cd ~/gr-ais/build
cmake ../
 sudo make install
 sudo ldconfig

if you get an error
ImportError: No module named ais_swig
then check you have installed swig, reboot and then re-try the steps to build gr-ais

Install and run "kal" :

mkdir ~/src
cd ~/src
sudo apt-get install libtool autoconf automake libfftw3-dev
git clone https://github.com/asdil12/kalibrate-rtl.git
cd kalibrate-rtl
git checkout arm_memory

sudo make install

" to calibrate the RTL dongle to work out the error value to use in ais_rx
http://goo.gl/wbqOts. MY RTL dongle had an error of around minus 33 ppm, and this is the value passed to ais_rx below. replace with your error value. As the dongle warms up this value may change so check again after some time. don't forget to put an antenna on your SDR stick.
in the UK we have 900MH\ gsm base stations. for the US this is usually 850MHz. Command below is for 900MHz :

sudo kal -s 900

this will give you a channel number of a nearby GSM station

use the channel number to get a calibration value. e.g. below found chan: 114

sudo kal -c 114

this will then give you a ppm value -make note of it below
average absolute error: -33.163

profile your hardware by running the following command: (takes a long time!)

You can then pipe AIS messages to MarineTraffic using "socat" (sudo apt-get install socat) using the command below (where should be changed for your marinetraffic upload IP and port and --error -33 should be changed for your error value obtained from kal

ais_rx --gain 44 --error -33 -s osmocom | socat - UDP4-DATAGRAM:

if you run OpenCPN on a computer on your LAN, you can send the traffic to that at the same time as marinetraffic (assuming your OpenCPN computer is running on LAN and also pipe the raw AIS sentences to the console for confirmation of reception:
ais_rx --gain 44 --error -33 -s osmocom | tee >(socat - UDP4-DATAGRAM: | tee >( socat - UDP4-DATAGRAM:

to keep this running when you disconnect your console session, create a file and save the above commandline into it:
touch ~/ais.sh
sudo nano ~/ais.sh
paste the above commandline into file and save (Ctrl-x Ctrl-y)
make the file executable
sudo chmod +x ais.sh
Then to run as background process on startup, edit /etc/rc.local to have it run on startup)
sudo nano /etc/rc.local
paste the following line into it and save
/home/pi/ais.sh &

It is fairly processor-intensive on the Pi - 100% of two cores and 50-75% of the remaining cores.

I am no raspberry pi expert so optimisations could be made for sure. I'm happy to make my SD card image available to anyone who wants a copy, but I don't have sufficient hosting for the image file.

As the script runs headless on startup, no output is sent to the console by default.
To see it is working you can either
a) open up OpenCPN and see the traffic
b) sniff the network traffic on the destination computer using nc -l -n 9999 (linux)
c) sniff the network traffic using Wireshark (windows)
d) You can use rTail and pipe the output of the AIS parser to stream it to a webpage hosted on your Pi

LoRa bike race tracker

mountain bike tracking system for off-grid out-of-gsm coverage races

Bike Hardware:

Semtech LoRa SX1276?
uBlox GPS
LiPo charger or DC-DC converter for 8.4v bike light battery pack passthrough.
Arduino Pro Mini or Teensy controller for logic - possible soft-mesh LoRa mesh for greater range?
(or module like Dorji HopeRf Motronics etc)

Base Station Hardware

RaspberryPi as AccessPoint, serving locally stored OSM map tiles for relevant area. Wifi Captive Portal serving OSM with markers via HTML5 allows any device to view map and locations.
If base station has 3g/gsm/wifi capability, option to upload positions to internet KML or similar for public viewing.
Possibly remote relay station solar powered with Yagi backhaul
if LoRaWan, then SX1301 receiver board


Support for 100's devices - SODTMA-like self organising or smart-beaconing of position, or base-polled?
AIS-like sentences for identifying devices and position/speed information, possibly battery level too. AIS data format would allow integration with OpenCPN quite easily for mapping and standard libraries.
So would NMEA0183 spat transparently from GPS, with custom NMEA sentence for battery information, panic buttons etc

NMEA max chars in sentence is 82 (inc CRLF)
the maximum packet length is 256 bytes in LoRa mode.
125KHz BW, coding rate=1. 82byte payload, 6 byte preamble +CRC
spreading factor
9 10 11 12
time on air (ms) 545 968 1773 3219
rx sens (dBm) -127 -130 -132.5 -135

SF 10 for 125Khz BW would give ~ 1s transmission which should be fade resistant.
1 minute updates would give 60 clients per channel. 8 channels = 420 clients with no overlapping. 49 channels (SX1301)=2940 clients@1 minute updates. ~300 clients @ 10s resolution. Improved with adaptive packet rate controlled via LoRaWAN
GPS synchronised packet transmission. assuming no mesh.
Alternatively set up LoraWAN and use adaptive data rate determined by basestation.