ACARS decoder
Home Page Up ACARS decoder ADS-B dump1090 AIS receiver Cross-compiling Kernel compile Monitoring NTP RTC Wall Clock Updating GPSD


Installing the multi-channel ACARS decoder

Some brief notes about getting the multi-channel ACARS decoder from Thierry Leconte working on the Raspberry Pi card PC, with an RTL-SDR.

1 - Get rtl-sdr library installed, install and test the dongle

If you don't already have a working RTL-SDR dongle installation working.  

(Please be careful when copying the following commands.  I usually try to double-space the parameters along the line, but when I do that for a Web page the HTML non-break-space character sometimes gets inserted, so the following are all single-spaced.  Using copy and paste should therefore work correctly, at the expense of some readability.)

sudo apt-get update
sudo apt-get install git-core
sudo apt-get install git
sudo apt-get install cmake
sudo apt-get install libusb-1.0-0-dev
git clone git://
cd rtl-sdr
mkdir build
cd build
sudo make install
sudo ldconfig		# Francis Breame reports that this is required
cd ~
sudo cp ./rtl-sdr/rtl-sdr.rules /etc/udev/rules.d/

Now we need to either reboot, or power-down, and plug in the dongle, and restart.

sudo reboot

Run the rtl_test:


But I get an error?

On versions of Raspian Linux later than 3.6.11, you may get an error message at this point:

Found 1 device(s):
0: Generic RTL2832U

Using device 0: Generic RTL2832U

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.

This is because a DVB driver was added to the OS so that, er, TV could be received! This interferes with the operation of the DVB-T stick for ADS-B reception, so you need to take the steps outlined here before continuing. Re-run the test:



2 - Downloading and compiling the multi-channel ACARS decoder

Updated 2017-Mar-24 thanks to Dick from The Netherlands.  The project has moved from SourceForge to github, hence a substantial change in the instructions for downloading is required.

Make a directory for the ACARS stuff, and change to that directory:

cd ~
mkdir acars
cd acars

The current version can be found here  There may be a later version available so it might be worth to check this project on a regular basis.

If you have an older version of acarsdec installed in a directory called “acarsdec” then you first have to remove or (preferably) rename that directory.  To rename the old version to one with (preferably) a version number use a command like this:

mv acarsdec/ acarsdec-3.4

Now copy/clone the project with this command:

git clone

Because the source is cloned to your RPI, a new directory named “acarsdec” will be created at the point where you issue the “git clone” command.  So if you run the “git clone” command after the “cd acars” above, you will get a directory acarsdec in the acars directory which now contains the source of the project.

Now change to that directory, run "make" to compile the program, and see what libraries (if any) are missing:

cd acarsdec
make -f Makefile.rtl

If you get an error like "No such file or directory" referring to a file sndfile.h or alsa/asoundlib.h, you may then need to update your installation with the commands below, and run the make command once again:

sudo apt-get install libsndfile1-dev
sudo apt-get install libasound2-dev
sudo apt-get install librtlsdr

although if you have also made dump1090 earlier on the same Raspberry Pi, it may have triggered all or parts of that requirement.

Francis Breame notes: However, the last one (sudo apt-get install librtlsdr) gave 'unable to locate package'.  It was fixed by the 
"sudo ldconfig" during rtl installation mentioned above.

Dick notes:  You can now make versions for the Airspy, the SDRplay, as well as the original RTL dongle:

make -f Makefile.air        # creates a program called acarsdec.air
make -f Makefile.sdrplay    # creates a program called acarsdec.sdrplay
make -f Makefile.rtl        # creates a program called acarsdec.rtl

PS. If you want to compile for a different device it is necessary to first do a:

make -f Makefile.rtl  clean

PPS: It seems they have changed their mind yet again, so you might get a program named acarsdec for all different devices.  Welcome to the wonderful world of Linux and "open sauce" software!

3 - Running the decoder

You might like to create a simple command to run the decoder, and specify the frequencies you want to use.  Use nano to create a file (e.g. run-acars) containing the one line:

./acarsdec.rtl -p -8 -r 0 131.525 131.550 131.725 131.825

where the three-letter file extension is either air, sdrplay or rtl  depending on the make file that was used.  For the SDRplay (which according to the help) doesn't support -p or -r but does need the -s):

./ -s 131.525 131.550 131.725 131.825

Use the ppm correction for your dongle after the "-p" - it's shown as "-8" in this example.  If you are unsure, use "0", but do try to use another program to determine what the value should be. Actually, the output from the program doesn't show a different frequency whatever value for "-p" is used.  Make that file executable:

chmod +x run-acars

and run the command-file:


Dick notes: the command I use for the RTL is a bit more complicated and looks like this:

/home/pi/acarsdec/acarsdec.rtl -l "/home/pi/acarsdec/logs/$(date +"%Y%m%d")-5.log" \
-n -p 70 -r 00000005 131.525 131.725 131.825 \
 >> "/home/pi/acarsdec/logs/process-acarsdec_rtl.log" 2>&1 &

The one for the SDRplay looks like this:

/home/pi/acarsdec/acarsdec.sdrplay -l "/home/pi/acarsdec/logs/$(date +"%Y%m%d")-RSP.log" \
-n -G -100 -s 131.525 131.725 131.825 \
>> "/home/pi/acarsdec/logs/process-acarsdec_RSP.log" 2>&1 &

DJT: I split the lines with "\" to make them fit on the page better.  They should still work!


  • The frequencies are suggested for the UK, in Europe or other parts of the world other frequencies may produce more messages.  Thanks to Jon for those suggestions.
  • The maximum frequency spread is 1 MHz.
  • You can enter the PPM value for your particular dongle using the -p parameter.
  • You can get a very good estimate of the PPM for your dongle using the "kalibrate" program.
  • It would be a help if there were an indication of tuning accuracy, so the the PPM value could be set without needing another program.
  • If your OS is greater than 3.6.11 (uname -a to check), there may be a conflict between the OS installing drivers for the DVB-T stick and the drivers required for operation as an SDR.  If you see a conflict, check here for a solution.
  • Dick notes: The Usage part of the README on Thierry’s website is incomplete.  Not all options are shown and several depend on the <device> you compiled.  So my advice is to compile the version you want and run that program without options and those relevant to this <device> will be shown. 

Using Kalibrate

Francis Breame notes: I'm sure that you're aware of it, but I'd just mention that for frequency offset, I found the kalibrate program very handy, which uses GSM reception to determine the offset.  In case you think it worth referring to, the instructions are:

mkdir ~/kal
cd ~/kal
sudo apt-get install libtool autoconf automake libfftw3-dev
git clone
cd kalibrate-rtl
git checkout arm_memory		# Essential for the Raspberry Pi
sudo make install

Both runs can take some time, so be patient!  You can add -v (verbose) to give an indication that things are happening.

First scan for local channel numbers:

kal -s GSM900 -d 0 -g 40

You should see something like this, but your frequencies and powers will be different, of course:

Using device 0: Generic RTL2832U
Found Elonics E4000 tuner
Exact sample rate is: 270833.002142 Hz
Setting gain: 40.0 dB
kal: Scanning for GSM-900 base stations.
        chan: 29 (940.8MHz + 33.774kHz) power: 866917.42
        chan: 34 (941.8MHz + 33.892kHz) power: 2521756.20
        chan: 45 (944.0MHz + 568Hz)     power: 941020.93
        chan: 88 (952.6MHz + 35.252kHz) power: 2002022.17

Pick two or more with the highest powers, do multiple runs to calculate the frequency offsets, and take the integer average:

kal -c <channel> -d 0 -g 40

You should see:

kal: Calculating clock frequency offset.
Using GSM-900 channel 34 (941.8MHz)
average         [min, max]      (range, stddev)
+ 34.098kHz     [34053, 34141]  (88, 22.927330)
overruns: 0
not found: 55
average absolute error: -36.205 ppm

You need to take the opposite sign of the absolute error when passing it to acarsdec (you are offsetting the error) - I think!  So use "-p 36" in this case.

Kalibrate on Windows

It seems that on Windows you may need to make an initial estimate of the PPM error from the first step, so that the commands become:

C:\Tools\SDR\kalibrate-win-release>kal -g 42 -s 900
Found 1 device(s):
  0:  ezcap USB 2.0 DVB-T/DAB/FM dongle

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Rafael Micro R820T tuner
Exact sample rate is: 270833.002142 Hz
Setting gain: 42.0 dB
meh: Scanning for GSM-900 base stations.
        chan: 19 (938.8MHz + 31.434kHz) power: 133429.06
        chan: 111 (957.2MHz + 29.672kHz)        power: 100942.26

Now make an approximate estimate of the error: -30 kHz at 945 MHz => -0.030/945 => -0.000031 => -31 ppm.  I then did a run against both of the GSM stations which had been discovered:

C:\Tools\SDR\kalibrate-win-release>kal -e -31 -c 19
Found 1 device(s):
  0:  ezcap USB 2.0 DVB-T/DAB/FM dongle

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Rafael Micro R820T tuner
Exact sample rate is: 270833.002142 Hz
meh: Calculating clock frequency offset.
Using GSM-900 channel 19 (938.8MHz)
average         [min, max]      (range, stddev)
-  84Hz         [-98, -68]      (30, 7.318200)
overruns: 0
not found: 0
average absolute error: -30.910 ppm

C:\Tools\SDR\kalibrate-win-release>kal -e -31 -c 111
Found 1 device(s):
  0:  ezcap USB 2.0 DVB-T/DAB/FM dongle

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Rafael Micro R820T tuner
Exact sample rate is: 270833.002142 Hz
meh: Calculating clock frequency offset.
Using GSM-900 channel 111 (957.2MHz)
average         [min, max]      (range, stddev)
- 1.012kHz              [-1029, -993]   (35, 9.529743)
overruns: 0
not found: 0
average absolute error: -29.943 ppm


So the offset value for this dongle is around -30 ppm, and the correction +30 ppm.  Getting one of the more expensive dongles with a TCXO solves the offset and initial drift problems well enough for this use!

The Next Steps

Having the messages decoded is all very well, but it would be great to see these messages in Plane Plotter, and with any position reports plotted.  Here's how to do this:

Feeding Plane Plotter

On the Raspberry Pi

Suppose that your Plane Plotter PC has an IP address of  When building the command-line for the Raspberry Pi program include the string:


This might make the command string like something like:

./acarsdec.<device> -v -n -p 0 -r 0 131.525 131.550 131.725 131.825

where <device> is either air, sdrplay or rtl  depending on the make that was used.  Remember to include your correct Plane Plotter PC's IP address, and the appropriate ppm correction for your own dongle.

On Plane Plotter

Be sure that in the Options, I/O settings, Input data panel, the box UDP/IP from net is checked.

That's all!  The Message View in Plane Plotter will display received ACARS messages - one per line.

The next steps

Ideally, rather than using the UDP protocol, it would be better to use TCP as then the receiving Raspberry Pi does not need to be on the same sub-network, and TCP is more appropriate and reliable message protocol for the relatively infrequent ACARS messages.  TCP support may also allow multiple clients getting data from the one Raspberry Pi.  Two things need to happen to make this work:

  1. The program needs to be modified to provide TCP output for Plane Plotter
  2. Plane Plotter needs to be updated to accept ACARS messages over TCP, just as it can do with VDL2.  It can already accept UDP messages, though, as described below.

Let's hope the folk involved can make these things happen!

The README - the program's Help information

Here is the read-me snapshot from October 2018 - be sure to get the current version here.  Please study the output from the program's Help command to see what parameters are needed for your own particular device.  You can show the help just  by entering the program name alone:

./acarsdec.rtl  or  ./  or  ./acarsdec.air

You can get the help text into a file for later reference by using a Linux redirection such as:

./acarsdec.rtl > help.rtl.txt


  • up to 8 channels decoded simultaneously
  • error detection AND correction
  • input via rtl_sdr, or airspy or sdrplay software defined radios (SDR)
  • logging data over UDP in PlanePlotter or acarsserv formats to store in an sqlite database, or JSON for custom processing.

Multi-channel decoding is particularly useful with broadband devices such as the RTLSDR dongle, the Airspy and the SDRplay device. It allows the user to directly monitor to up to 8 different frequencies simultaneously with very low cost hardware.


acarsdec [-v] [-o lv] [-t time] [-A] [-n|N|j ipaddr:port] [-i stationid] [-l logfile] -r rtldevicenumber f1 [f2] [... fN] | -s f1 [f2] [... fN]

-v : verbose

-A : don't display uplink messages (ie : only aircraft messages)

-o lv : output format : 0: no log, 1 one line by msg., 2 full (default), 3 monitor mode, 4 JSON

-t time : set forget time (TTL) in seconds in monitor mode(default=600s)

-l logfile : Append log messages to logfile (Default : stdout)

-n ipaddr:port : send acars messages to addr:port via UDP in PlanePlotter compatible format

-N ipaddr:port : send acars messages to addr:port via UDP in acarsdec format

-j ipaddr:port : send acars messages to addr:port via UDP in JSON format

-i station id: id use in acarsdec network format.

for the RTLSDR device -r rtldevice f1 [f2] ... [fN] : decode from rtl dongle number or S/N "rtldevice" receiving at VHF frequencies "f1" and optionally "f2" to "fN" in Mhz (ie : -r 0 131.525 131.725 131.825 ). Frequencies must be within the same 2MHz.

-g gain : set rtl preamp gain in tenth of db (ie -g 90 for +9db). By default use maximum gain

-p ppm : set rtl ppm frequency correction

for the AIRspy device -s f1 [f2] ... [fN] : decode from airspy receiving at VHF frequencies "f1" and optionally "f2" to "fN" in Mhz (ie : -s 131.525 131.725 131.825 ). Frequencies must be within the same 2MHz.

for the SDRplay device -s f1 [f2] ... [fN] : decode from SDRplay receiving at VHF frequencies "f1" and optionally "f2" to "fN" in Mhz (ie : -s 131.525 131.725 131.825 ). Frequencies must be within the same 2MHz.

-L lnaState: set the lnaState (depends on the selected SDRPlay hardware)

-G GRdB: set the Gain Reduction in dB's. -100 is used for agc.


Decoding from rtl dongle number 0 on 3 frequencies , sending aircraft messages only to on port 5555 and no other loging :

acarsdec -A -N -o0 -r 0 131.525 131.725 131.825

Decoding from airspy on 3 frequencies with verbose logging

acarsdec -s 131.525 131.725 131.825

Output formats examples

One line by mesg format (-o 1)
#2 (L:  -5 E:0) 25/12/2016 16:26:40 .EC-JBA IB3166 X B9 J80A /EGLL.TI2/000EGLLAABB2
#3 (L:   8 E:0) 25/12/2016 16:26:44 .G-OZBF ZB494B 2 Q0 S12A 
#3 (L:   0 E:0) 25/12/2016 16:26:44 .F-HZDP XK773C 2 16 M38A LAT N 47.176/LON E  2.943
Full message format (-o 2)
[#1 (F:131.825 L:   4 E:0) 25/12/2016 16:27:45 --------------------------------
Aircraft reg: .A6-EDY Flight id: EK0205
Mode : 2 Label : SA Id : 4 Ack : !
Message no: S31A :

[#3 (F:131.825 L:   3 E:0) 25/12/2016 16:28:08 --------------------------------
Aircraft reg: .F-GSPZ Flight id: AF0940
Mode : 2 Label : B2 Id : 1 Ack : !
Message no: L07A :
/PIKCLYA.OC1/CLA 1627 161225 EGGX CLRNCE 606
46N020W 45N027W 44N030W 40N040W 36N050W
34N055W 32N060W 27N070W
FM ETIKI/1720 MNTN F340 M083
Monitoring mode (-o 3)
             Acarsdec monitor
 Aircraft Flight  Nb Channels   Last     First
 .CN-RNV  AT852X   9 .x.      16:25:58 16:21:05
 .F-HBMI  ZI0321   1 .x.      16:25:52 16:25:52
 .F-GSPZ  AF0940   6 ..x      16:25:21 16:22:30
 .D-ABUF  DE0252   1 .x.      16:25:20 16:25:20
 .EC-MGS  V72422   1 .x.      16:25:07 16:25:07
 .G-EUUU  BA733C   2 .x.      16:24:38 16:24:33
JSON mode (-o 4)

See the read-me on the Web - the lines are too long for this page!

Good luck!

Using other operating systems

It may be possible to run this code on other variants of Linux.  Please note:

- a USB 2.0 hi-speed port is required.  USB 1.1 is not fast enough.

Copyright © David Taylor, Edinburgh   Last modified: 2018 Oct 31 at 16:04