I recently released OpenPager, a library for Arduino-compatible microcontrollers that handles POCSAG (pager protocol) communication.
It is designed specifically for the TI CC1101 radio transceiver paired with ESP8266 or ESP32 boards. While there are other radio libraries out there, OpenPager focuses specifically on robust POCSAG implementation with features like parallel auto-baud detection and software-based signal synchronization.
It is available now in both the Arduino Library Registry and the PlatformIO Registry.
The Hardware
To use this, you need:
- MCU: ESP8266, ESP32, or similar Arduino-compatible board.
- Radio: TI CC1101 module (SPI interface).
The library is optimized for the ESP architecture, leveraging its speed for the software PLL required for accurate decoding.
Key Features
- Dual Mode: Supports both transmitting and receiving (half-duplex).
- Auto-Baud Detection: The receiver runs parallel decoders to detect and receive 512, 1200, and 2400 baud messages simultaneously.
- Protocol Support: Handles Alphanumeric (ASCII), Numeric (BCD), and Tone-only messages.
- Error Correction: Implements BCH error detection (SECDED).
- Signal Handling: Automatic polarity detection for inverted signals and RSSI monitoring.
Installation
PlatformIO
Add this to your platformio.ini:
lib_deps =
ktauchathuranga/openpager
Arduino IDE
Search for "OpenPager" in the Library Manager.
Usage: Receiving Messages
The most complex part of pager protocols is usually handling different baud rates. OpenPager handles this by spawning three independent decoders internally. You just set it to "0" to enable auto-scanning for all rates.
Here is a callback-based example:
#include <OpenPager.h>
// Initialize with CSN pin (15) and GDO0 pin (5)
OpenPager pager(15, 5);
void onMessage(OpenPagerMessage msg) {
Serial.printf("[RIC: %lu] [Baud: %d] %s\n", msg.ric, msg.baudRate, msg.text);
}
void setup() {
Serial.begin(115200);
// Initialize radio at 433.920 MHz
// 0 = Auto-Baud mode (scans 512, 1200, 2400 simultaneously)
pager.begin(433.920, 0);
pager.setCallback(onMessage);
pager.startReceive(0);
}
void loop() {
// The library handles decoding in the background;
// messages appear via the callback.
}
Usage: Transmitting Messages
Transmission is straightforward. You specify the RIC (Receiver ID), function code, message body, and baud rate.
#include <OpenPager.h>
OpenPager pager(15, 5);
void setup() {
// Initialize at 433.920 MHz with a base rate of 1200
pager.begin(433.920, 1200);
}
void loop() {
// Send a message to RIC 1234567
// Func: 3, Text: "Hello World", Baud: 1200, IsAlpha: true
pager.transmit(1234567, 3, "Hello World", 1200, true);
delay(5000);
}
Under the Hood
The CC1101 operates in asynchronous mode, outputting raw demodulated data on the GDO0 pin. OpenPager processes this stream using a software PLL to maintain bit synchronization.
The interesting part is the RX Architecture:
- Parallel Decoding: The library runs three decoder instances (512, 1200, 2400) in parallel.
- Sync Lock: All decoders process the signal; when a valid sync word is detected, the appropriate decoder locks onto the stream.
- Jitter Handling: On the ESP32, 2400 baud works reliably. On the ESP8266, interrupt jitter (~3-5ยตs) makes 2400 baud more challenging, but lower rates work perfectly.
Links
- GitHub Repo: https://github.com/ktauchathuranga/openpager
If you are working with POCSAG or legacy paging hardware, give it a try and let me know if you run into any issues.
Top comments (0)