← Projects
raspberry-pi intermediate 43 min ago ◯ 6 min read

Decoding POCSAG and FLEX Pager Traffic with RTL-SDR and multimon-ng on a Raspberry Pi

Build time: 2-3 hours
Tools needed: Raspberry Pi with Raspberry Pi OS installed, soldering iron (optional, for antenna connector work), basic Linux command line familiarity
Parts List
rtl-sdrpocsagflexpagermultimon-ngraspberry piradiosdrsoftware defined radio

Our Raspberry Pi and RTL-SDR coverage already spans flight tracking with ADS-B, marine traffic with AIS, aircraft datalink messages with ACARS/VDL2, weather satellite imagery from NOAA and GOES, and a full remote SDR server setup — but one of the most approachable and genuinely interesting RTL-SDR decoding projects hasn't made it onto the site yet: pulling POCSAG and FLEX pager traffic out of the air and decoding it into readable text. Paging networks look obsolete from a consumer standpoint, but they're still in heavy active use by hospitals, fire and EMS dispatch, utility SCADA systems, and industrial alerting — which makes them a genuinely useful signal to understand, and a great practical exercise in RF decoding that's simpler to get working than ADS-B or AIS.

A note on what you'll receive: Pager traffic in many areas includes messages that are not encrypted and were never designed with privacy in mind at the protocol level, similar to how unencrypted analog radio traffic works. Treat anything you decode the way you'd treat any radio scanner traffic: understand your local laws regarding interception and further distribution or publication of message content (this varies significantly by country and even by message type), and this is best approached as a technical decoding exercise rather than a way to monitor anyone's private communications. Our Flipper Zero and the law guide covers the same general principle in more depth and is worth reading regardless of which piece of hardware you're using.

How POCSAG and FLEX Work, Briefly

Both are digital paging protocols transmitted as FSK (frequency-shift keying) signals, typically in the VHF (around 138-174 MHz in the US, varies by region) or UHF (around 400-470 MHz) bands depending on the specific paging network. POCSAG is the older and simpler of the two, transmitting at a fixed baud rate (512, 1200, or 2400 bps) with messages addressed to specific pager "cap codes." FLEX is Motorola's newer, more complex protocol supporting higher data rates and more sophisticated framing, widely used by larger commercial paging carriers. Both carry either simple numeric pages (a callback number, commonly used for basic alerting) or full alphanumeric text messages, depending on how the sending system and receiving pager are configured.

Hardware Setup

This project uses the same RTL-SDR dongle as the rest of this site's SDR projects, so if you've already built the ADS-B tracker or remote SDR server, you likely have everything needed already. A wideband discone antenna gives the broadest frequency coverage across VHF and UHF paging bands without needing to swap antennas for different frequency ranges, though a simple telescopic antenna cut or extended for your local paging frequencies works for initial testing.

  1. Flash Raspberry Pi OS (Lite is sufficient, since this runs headless) to a microSD card following our standard headless Pi setup process.
  2. Plug the RTL-SDR into a powered USB hub rather than directly into the Pi's USB ports — RTL-SDR dongles can draw more current than a Pi's USB port reliably supplies alongside other peripherals, and a powered hub avoids intermittent dropouts during long decode sessions.
  3. Install the RTL-SDR driver package (rtl-sdr) and blacklist the kernel's default DVB-T TV tuner driver, which otherwise claims the device before your SDR tools can use it — the same first step covered in our other RTL-SDR project guides.
  4. Verify the dongle is detected and working with rtl_test before moving on to decoding software.

Installing and Configuring multimon-ng

multimon-ng is the standard open-source tool for decoding a wide range of digital radio protocols from an audio stream, including POCSAG and (with more limited support) FLEX. It doesn't talk to the RTL-SDR directly — instead, rtl_fm demodulates the raw RF into an FM audio stream, which is piped into multimon-ng for protocol decoding.

  1. Install build dependencies and compile multimon-ng from source (it's not in the default Raspberry Pi OS repositories): git clone the multimon-ng repository, then build with CMake following the project's standard build instructions.
  2. Identify an active paging frequency for your area — local radio reference databases and SDR community frequency listings are the usual sources, since paging frequencies are licensed and vary significantly by region and carrier.
  3. Run the demodulation and decode pipeline, piping rtl_fm tuned to your target frequency directly into multimon-ng with the POCSAG decoder flags enabled: rtl_fm -f 152.XXXM -s 22050 -g 40 - | multimon-ng -t raw -a POCSAG512 -a POCSAG1200 -a POCSAG2400 -f alpha - Running all three POCSAG baud rate decoders simultaneously is reasonable since they're computationally cheap and you often don't know in advance which rate a given frequency uses.
  4. Watch the output for decoded cap codes and message text. A properly tuned frequency and reasonable signal strength will show a steady trickle of decoded pages; no output at all usually means either no active traffic on that frequency right now, or the gain (-g) setting needs adjustment — too low misses weak signals, too high introduces overload distortion that breaks decoding on strong nearby signals.

FLEX Decoding: More Involved

multimon-ng's FLEX support is more limited than its POCSAG support, and reliably decoding FLEX traffic (particularly at its higher data rates) often benefits from a more specialized tool chain built around GNU Radio and a dedicated FLEX decoder flowgraph rather than the simpler rtl_fm-to-multimon-ng pipeline used for POCSAG. If FLEX is the dominant protocol on your local paging frequencies, treat getting POCSAG working first as the right starting point to confirm your RF chain and frequency are correct, then look at GNU Radio Companion-based FLEX decoder projects as a follow-on once the basics are proven out.

Logging and Making Sense of the Output

Raw multimon-ng output scrolling in a terminal is fine for initial testing but not practical for ongoing monitoring. Pipe the output into a simple logging script that timestamps each decoded message and writes it to a file or a lightweight database — a short Python script reading multimon-ng's stdout line by line and appending structured entries (timestamp, cap code, protocol, message text) to a SQLite database or CSV file is enough for most use. From there, our Grafana and InfluxDB monitoring guide covers turning a stream of logged events like this into a browsable dashboard if you want to track paging activity over time rather than just tailing a log file.

Where to Go From Here

Of all the RTL-SDR decoding projects on this site, POCSAG is one of the most approachable — the protocol is simple, the tooling is lightweight enough to run comfortably on any Raspberry Pi model, and watching real decoded text messages scroll by from a protocol most people assume died with the 1990s is a genuinely satisfying first RF decoding project for anyone who hasn't done one before.