[HOWTO] Decoding pager transmissions with a Pi and rtl-sdr

41 posts   Page 1 of 2   1, 2
by Sonny_Jim » Sun May 26, 2013 10:26 pm

Please note, if you are based in the UK please read and understand Section 48 of the UK Wireless Telegraphy Act 2006:

After purchasing an USB RTL2832 based dongle for use with my RPi to receive ADS-B messages from aircraft I was annoyed that I had purchased one that was unable to tune to the higher frequencies needed, so I looked for something to do with it whilst a E4000 based one turned up.

You can find a list of compatible devices and places to buy them on the rtl-sdr wiki:

From Wikipedia:
POCSAG is an asynchronous protocol used to transmit data to pagers. The name comes from Post Office Code Standardization Advisory Group, this being the British Post Office which used to run nearly all telecommunications in Britain before privatization.


On the RPI, download and install the rtl-sdr and multimonNG sources. rtl-sdr provides the drivers and narrow band FM demodulator for the USB dongle, whilst multimonNG will be used to decode the resulting POCSAG data.
Code: Select all
# Install dependencies
sudo apt-get update
sudo apt-get -y install git cmake build-essential libusb-1.0 qt4-qmake libpulse-dev libx11-dev

# Fetch and compile rtl-sdr source
mkdir -p ~/src/
cd ~/src/
git clone git://git.osmocom.org/rtl-sdr.git
cd rtl-sdr
mkdir build
cd build
sudo make install
sudo ldconfig

# Fetch and compile multimonNG
cd ~/src/
git clone https://github.com/EliasOenal/multimonNG.git
cd multimonNG
mkdir build
cd build
qmake ../multimon-ng.pro
sudo make install

If you left the USB dongle in the RPi whilst installing rtl-sdr, you will need to unplug it and plug it back in again for non-root access to work. Also it's important to note that unless I am using a powered USB hub, it's not uncommon for my RPi to reset whilst plugging in a dongle. If in doubt, power down the RPi before plugging in the USB dongle.

Finding and listening to POCSAG signals

It turns out that where I live there is quite a lot of pager traffic still around, which is found around 137-154MHz, according to a search for POCSAG at the Global Frequencies Database:

It's used for all sorts of interesting stuff like railway management,
2/2 running: ================= Main Lines amber, reception and arrival roads Double amber Time reported and ETA for response:

Fire service & medical despatching:
INC ALERT No: 7119994 TRAUMA, AT: HOTEL CENTRAL, XX MAIDEN ST, Time of Call: 27/05/2013 Tel: 08456 XXXXXX

Refrigeration system monitoring:
26/05/2013 07:32:42 B3AHS1AH1DaMc Status : Discharge Air Moisture Content

Alarm management:
ProcessVue Communications WatchDog Message- Comms are working between ProcessVue Server and BMS System

HVAC monitoring:

It's also very easy to receive, even with a crappy aerial.

It's a lot easier to find POCSAG frequencies using a waterfall display app and a laptop/desktop PC, I used a Windows laptop with SDRSharp. For Linux desktops, multimode from gnu-radio is also good;

Set your chosen waterfall app to to 'WFM' mode and have a hunt around until you find something that sounds like POCSAG. A lot of digital signals sound similar, there's a few example audio files here:

It's *possible* to run rtl_tcp on the rpi to transfer the data over a network connection and use the rtl_tcp input on SDRSharp/multimode but I found my wireless card caused pops and dropouts. It's much easier to just plug the dongle into the desktop but if you have a better network situation than me you might want to try:
Code: Select all
rtl_tcp -a $IP_ADDRESS_OF_RPI

And then use the rtl_tcp input option in SDRSharp/Multimode.

Decoding on the RPi

Once you've found a POCSAG channel, you can then plug your RTL dongle back into the Pi and use the following command to send output to the headphone jack. In the following example I'm tuning to 153.350MHz. This also has the side benefit of turning your RPi into an FM radio :-)
Code: Select all
rtl_fm -f 153.350M | aplay -r 24k -f S16_LE -t raw -c 1

and finally to decode them using multimon-ng and output to stdin, you can use
Code: Select all
rtl_fm -N -o 4 -A lut -s 22050 -C -f 153.350M - | multimon-ng -t raw -a POCSAG512 -a POCSAG1200 -a POCSAG2400 -f alpha /dev/stdin

If everything is working, you should see output like this:
POCSAG2400-: Alpha: 23:09-92 24/05/2013 14:33:05 AR02EH_2 High Alarm 70 AR02 AHU-20 Ext Air Humidity out of Limits Alarm Item Description Ext Air RH Details Status : Ext Air RH<NUL>

Ideas & fun things to do

It's fairly trivial to setup a webserver to view the decoded data using a webbrowser:
Code: Select all
sudo apt-get -y install lighttpd
sudo mkdir -p /var/www/pager/
sudo chmod 777 /var/www/pager/
rtl_fm -f 153.350M -s 22050 | multimon-ng -t raw -a POCSAG512 -a POCSAG1200 -a POCSAG2400 -f alpha /dev/stdin >> /var/www/pager/153-350M.txt

You should be able to open http://address_of_pi/pager/153-350M.txt in a browser.

A very cool idea would be to control the Pi via the pager network, but unfortunately I do not have a pager :-(

I would be very interested to hear from anybody using multimonNG to decode something other than POCSAG and ADS-B!

Useful links:
Script to fetch and build rtlsdr and MultimonNG
(322 Bytes) Downloaded 258 times
Last edited by Sonny_Jim on Fri Sep 20, 2013 12:47 pm, edited 12 times in total.
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by Ozpi » Mon May 27, 2013 9:50 am
Thanks for this, I tried for about 4 hours on the weekend to compile and kept running into issues - right off to reimage my SD card and off i go ! Appreciate your post.
Posts: 3
Joined: Mon May 27, 2013 9:44 am
by Ozpi » Mon May 27, 2013 12:46 pm
I've run into an issue, any ideas ??

pi@raspberrypi ~/src/multimonNG/build $ qmake ../multimon-ng.pro
pi@raspberrypi ~/src/multimonNG/build $ make
gcc -c -pipe -O2 -Wall -W -DMAX_VERBOSE_LEVEL=1 -DPULSE_AUDIO -DCHARSET_UTF8 -I/usr/share/qt4/mkspecs/linux-g++ -I../../multimonNG -I../../multimonNG -I. -o unixinput.o ../unixinput.c
../unixinput.c:45:26: fatal error: pulse/simple.h: No such file or directory
compilation terminated.
make: *** [unixinput.o] Error 1
pi@raspberrypi ~/src/multimonNG/build $
Posts: 3
Joined: Mon May 27, 2013 9:44 am
by Sonny_Jim » Mon May 27, 2013 1:32 pm
Looks to me like some of the pulseaudio libs are missing. Because I've been using my Pi for RetroArch I probably had them already installed and missed them off the dependencies. For now you can try:
Code: Select all
sudo apt-get install libpulse-dev

I'll have a look to see if there isn't a compile switch to turn off the pulseaudio dependency in MultimonNG
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by Ozpi » Mon May 27, 2013 2:15 pm
Ahh huh! Looks like you were on the right track, other dependencies are libpulse-dev and libx11-dev.

Thanks for your help!!
Posts: 3
Joined: Mon May 27, 2013 9:44 am
by Sonny_Jim » Mon May 27, 2013 2:23 pm
Great, thanks for letting me know, I've updated my original post with the new dependencies.
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by matt.b » Thu Jul 11, 2013 8:43 pm
Dear all,

thanks for the tutorial!
I tried to run my Noxon DAB USB dongle on the Pi. It is connected via one powered usb hub. But when i start the sdr server by using the command
Code: Select all
rtl_tcp -a 192.168.X.X

i get the message
Code: Select all
usb_claim_interface error -6
Failed to open rtlsdr device #0.

Does someone has any idea what the problem? Because obiviously i don't!


Posts: 93
Joined: Fri Oct 19, 2012 7:23 am
by bouni » Thu Jul 11, 2013 10:26 pm

I had the same problem on my arch system.
I fixied that by creating a file (If it not already exists)


adding these lines:
blacklist dvb_usb_rtl28xxu
blacklist rtl2830
blacklist dvb_usb_v2
blacklist dvb_core

the problem is that these modules use the device alredy.
Blacklisting them disables them and you are able to use the device.
Posts: 2
Joined: Thu Jun 27, 2013 1:37 pm
by matt.b » Fri Jul 12, 2013 7:17 am
Hi bouni,

thanks. That solves my problem.
I tried to decode some transmissions. To find the correct frequency i checked the spectrum with SDR# on my windows pc. Then plugged the stick on the raspberry and started the programm using the code
Code: Select all
rtl_fm -f [my frequenc] -s 22050 | multimon-ng -t raw -a POCSAG1200 -f alpha /dev/stdin

But multimon decodes nothing.
Posts: 93
Joined: Fri Oct 19, 2012 7:23 am
by bouni » Sun Jul 14, 2013 12:11 pm
Hi Matt,

i have the same problem.
If i listen to the audio like this:
Code: Select all
rtl_fm -f 173181601 -o 4 | aplay -r 24k -f S16_LE -t raw -c 1

i hear sound similar to this here in the video:

but multimon-ng does not decode anything :|
I'm also not sure if i have to use a special antrenna!?
Posts: 2
Joined: Thu Jun 27, 2013 1:37 pm
by matt.b » Tue Jul 16, 2013 5:35 pm
Dear all,

since i have tested the same combination of Noxon DAB USB stick and antenna on my windows computer i don't think that i have to change something on the hardware side.

Has anyone already decoded some pocsag messages with this components?

Posts: 93
Joined: Fri Oct 19, 2012 7:23 am
by smstext » Tue Jul 30, 2013 1:13 pm
what distro did you use for this or does it not matter?
Posts: 101
Joined: Sun Oct 21, 2012 1:28 pm
by smstext » Tue Jul 30, 2013 6:42 pm
I think I have it running on raspbian. I have it showing over sampling input and output, buffer size, tuned to, sampling, output, exact sample rate and tuner gain.

How do I know when it's found a message?
Posts: 101
Joined: Sun Oct 21, 2012 1:28 pm
by Sonny_Jim » Thu Aug 15, 2013 4:16 pm
I just had to reimage my RPi again after the dreaded filesystem corruption and came here to grab my script and just noticed all the replies, sorry it's taken me a while:

I used the default Raspbian image for mine and that is what my script is based around, although it should work on any distro, it's just grabbing and compiling software.

For those who aren't getting decodes, there's a few reasons why:

1. It's not POCSAG1200
I think in my example multimon is only set to listen to the higher speed version of POCSAG, if you have a look at the help for multimon you can set up other decoders to run at the same time, such as POCSAG512 or POCSAG2400. Also a lot of digital signals sound similar, so double check it *is* actually POCSAG you are receiving. To make multimon decode all speeds of POCSAG use:
Code: Select all
multimon-ng -a POCSAG512 -a POCSAG1200 -a POCSAG2400 -f alpha

2. The signal is too weak/strong
I have no trouble picking them up (even without an antenna sometimes!), but one trap to watch out for is that you don't over saturate the input of the stick, try different gain settings in rtl_fm.

3. You haven't set up the squelch correctly
The decoder works best when it only receives clean POCSAG signals without any static. Try different squelch values so you only hear the signal and not the background noise. This is the -l option of rtl_fm, try increasingly higher values until only the POCSAG signal comes through.

You'll know when it's receiving properly when you start seeing messages be printed to the console, like the examples I gave in my first post.

EDIT: I can't seem to get it to work now either, I'm suspecting that something has changed in multimon-ng
EDIT2: Nope, I just had to follow my own advice and tune my setup better, it still compiles and works fine on the latest Raspian.
EDIT3: Also just to note it's possible to run rtl_fm, multimon-ng and dump1090 all on the same Pi if you have two rtl-sdr devices and a reworked PSU :-)
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by dnk » Sat Aug 17, 2013 3:54 pm
Sonny Jim:

I'm building a cloud-based system that might really benefit from your know-how, designed to save lives. If you'd like to help in this endeavor, saving lives through software and hardware, please drop me a line.

Dave (david@kabal.org)
User avatar
Posts: 2
Joined: Sat Aug 17, 2013 3:28 pm
Location: Boulder, CO, USA
by Sonny_Jim » Mon Aug 19, 2013 5:36 pm
How on earth you can 'save lives' with receiving pager messages I don't know. A standard pager uses way less power and is way more hardy than a Pi or laptop. Plus the emergency services will *already* have receiving equipment. So I have no idea what you are on about.

But anyway, here's a cheap and simple script that will automatically scan and decode all the frequencies that are active for where I am.
(407 Bytes) Downloaded 233 times
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by dnk » Mon Aug 19, 2013 6:19 pm
It's a forwarding and aggregation system. Drop me a line and I'll tell you all about it.

User avatar
Posts: 2
Joined: Sat Aug 17, 2013 3:28 pm
Location: Boulder, CO, USA
by Sonny_Jim » Mon Aug 19, 2013 6:50 pm
I still don't understand. My setup has nothing to do with retransmission, so it'll be useless for you. May I suggest you join the gnu-radio/rtl-sdr mailing lists and post your suggestions there.
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by Sonny_Jim » Tue Sep 03, 2013 4:18 am
Ok, so I patched multimon-ng to have very basic sqlite support, which means it'll generate a database containing address, function, message and a timestamp to pocsag.db.


Using the database you can throw various sql statements at the data, for example if you wanted to see all the messages containing the word test:
select address from messages where message like % TEST %;

And other things like that. It still needs a lot of work but it's a start and sql is a very useful skill to have :-)
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by smstext » Sun Sep 15, 2013 1:01 pm
thanks i will give it a go soon.
Posts: 101
Joined: Sun Oct 21, 2012 1:28 pm
by Sonny_Jim » Mon Sep 16, 2013 6:00 am
I've just updated it to be a little more robust, I left it running for all of last week and came home to a 14MB database so it all appears to be ticketdy boo.

To fetch and build (assuming you have the rest of the dependencies installed):
Code: Select all
sudo apt-get install libsqlite3-dev
cd ~/src
git clone https://github.com/SonnyJim/multimon-ng
cd multimon-ng
mkdir build
cd build
qmake ../
sudo make install

Then an example usage would be:
rtl_fm -f 153.350M -r 22050 - | multimon-ng -t raw -a POCSAG512 -a POCSAG1200 -a POCSAG2400 -f alpha -D pocsag.db -

The new option -D sets the database location.

The database schema is:
Code: Select all
address INTEGER, function INTEGER, message TEXT, baud TEXT, timestamp INTEGER

Timestamp is in Unix Time, the number of seconds since 01/01/1970.

Some example sqlite queries:

Count all messages
Code: Select all
SELECT COUNT(message) FROM messages;

search messages for a particular string and show the address they were sent to
Code: Select all
SELECT address FROM messages WHERE message LIKE %string%;

Something broke rtl_fm working with multimon-ng, for now you can roll back to an earlier commit with changing into the rtl_sdr directory and entering the following:
Code: Select all
cd ~/src/rtl-sdr
git checkout 8c3a99c8f7a88d7d2a05845d4b20cfcdacac4054 .
cd build/
sudo make install
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by tony_g8wbi » Mon Sep 16, 2013 6:27 pm

I've been looking for a POCSAG decoder and this is just the ticket. Eventually I'll migrate it to the Pi to make a standalone box, but in the meantime I thought I'd try it on a Linux laptop. Seems to work, but...

#rtl_fm -f 153.350M | aplay -r 24k -f S16_LE -t raw -c 1
Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Rafael Micro R820T tuner
Oversampling input by: 42x.
Oversampling output by: 1x.
Buffer size: 8.13ms
Tuned to 153602000 Hz.
Sampling at 1008000 Hz.
Output at 24000 Hz.
Exact sample rate is: 1008000.009613 Hz
Tuner gain set to automatic.
Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 24000 Hz, Mono

Although I entered 153.350M on the command line, the output reads Tuned to 153602000 Hz.. Is it really tuning off frequency? There are faint POCSAG burblings in the background noise, even with an external aerial connected.

Does anyone have any thoughts?
Posts: 1
Joined: Mon Sep 16, 2013 6:16 pm
by Sonny_Jim » Tue Sep 17, 2013 1:06 am
You are best using a waterfall program like gqrx or sdr# to find the exact POCSAG frequencies in use in your area.

Although I entered 153.350M on the command line, the output reads Tuned to 153602000 Hz.

I believe it offsets the tuner to avoid the large DC spike at the centre frequency
Posts: 32
Joined: Tue Oct 23, 2012 4:15 pm
by matt.b » Fri Oct 25, 2013 4:25 pm

i tried again to get rtl and multimon working. Finally both is running. But multimon doesn't show any decoded message...
To confirm that rtl is working, i ran rtl_tcp and connected SDR# from my Windows machine. In this configuration everything works.

To run rtl and multimon i'm using the following command:

rtl_fm -N -E -f 123.45M -s 22050 -o 4 -g 11.5 | multimon-ng -t raw -a POCSAG1200 -f alpha /dev/stdin

Has somebody any ideas why i don't get decoded messages?

Posts: 93
Joined: Fri Oct 19, 2012 7:23 am
by matt.b » Fri Nov 01, 2013 4:21 pm
No ideas about my problem described in the last post?
Posts: 93
Joined: Fri Oct 19, 2012 7:23 am