Παρασκευή 6 Μαΐου 2016

Decoding both AIS channels simultaneously with a single RTL-SDR

With the advent of Software Defined Radio, most hardware problems have become software problems. I knew the hardware was here to support decoding both AIS channels with a single USB RTL-SDR stick, but there is no software (besides gnuradio based software) to support that. Gnuradio is "too much" to fit on an ARM board, and I've started to look for other solutions.
The main obstacle was how to shift frequency from a command line utility in order to provide both channels that have a 50KHz space between them.
Our friend of the openwebrx project, Andras Retzler, HA7ILM, has built a very handy and efficient library for manipulating IQ data, csdr
However I still had to find a way to provide data to csdr, and then demodulate each channel separately, but let's start from the beginning.
AIS transmissions are at 162.025 MHz and at 161.975 MHz. We select the middle frequency 162.000 MHz as center, to avoid also any DC bias interference. Then we shift frequency by 25KHz by using the "csdr shift_addition_cc". A demodulator follows that demodulates Narrowband FM and then data is handled to "aisdecoder" a tool that takes demodulated audio data and decodes AIS messages.
rtl_fm has the ability to provide raw 16 bit integer IQ data by using the -M raw switch, but we need to multiply this data twice and then shift it by 25KHz lower for one channel and upper for the other one.
The idea of using a network streaming server to provide IQ data for all our demodulators comes also from openwebrx project where Andras uses ncat to stream the data and has proven to be very efficient.
On the demodulator part, I've tried the "demod" tool from Andres Vahter that uses the liquid-dsp library. It's a lot more cpu hungry than the original rtl_fm demodulator, but it works. If you are aware of any other more efficient solution just provide it in the comments section.
Each demodulator handles data via a FIFO pipe to aisdecoder, and each aisdecoder connects to aisdispatcher that provides AIS data to both AISHub.net and marinetraffic.com 
So I provide below the commands I've ended up using after many hours of testing!

Aisdispatcher:
aisdispatcher -u -h 0.0.0.0 -p 5000 -H 5.9.207.224:xxxx,data.aishub.net:xxxx -G

AisDecoders:
aisdecoder -h 127.0.0.1 -p 5000 -a file -c mono -d -f /home/sdr/ais.fifo
aisdecoder -h 127.0.0.1 -p 5000 -a file -c mono -d -f /home/sdr/ais1.fifo



of course you will first have to make the FIFO pipe using the mkfifo command.



rtl_fm:
/usr/local/bin/rtl_fm -d AIS -f 162000000 -M raw -s 1008000 | ncat -4l 4952 -k --send-only --allow 127.0.0.1

Demodulators:
ncat -v 127.0.0.1 4952 | csdr convert_i16_f |csdr shift_addition_cc 0.024801587 |csdr convert_f_i16 | demod --samplerate 1008000 --resamplerate 48000 -i i16 -o i16 --bandwidth 4500 fm --deviation 3500 > /home/sdr/ais.fifo
ncat -v 127.0.0.1 4952 | csdr convert_i16_f |csdr shift_addition_cc -0.024801587 |csdr convert_f_i16 | demod --samplerate 1008000 --resamplerate 48000 -i i16 -o i16 --bandwidth 4500 fm --deviation 3500 > /home/sdr/ais1.fifo


The 0.024801587 number comes from dividing the shift frequency with sampling rate ( 25000/1008000)

More experiments have to be done, specially in the sampling rate and down-sampling ratio. I suspect that rtl_fm provides a more efficient down-sampler, but we still have to have enough samples to cover a broader range for both channels

Of course to increase your chances of receiving AIS data with an RTL-SDR you'd better use RTL-SDR.com dongle that has a much much better clock with a TCXO.

You can check the station online at http://www.aishub.net/live-map.php?rrdname=2546&sname=Patras and http://www.marinetraffic.com/en/ais/details/stations/2566
Enjoy your fresh AIS messages!