I'm currently working on a project, where I have an external device (POCSAG pager - POCSAG protocol) that is giving out a digital (5V - 0V) square-wave signal. I have an ATmega2560 (Arduino) microcontroller and I want to read the signal so I can decode it to text.

I already finished this project where the external device works in perfect "lab conditions", which means that one bit is transmitted in exactly 833 microseconds (1200 Hz). I read all the bits correctly with a simple timer and decode them afterwards.

The problem is, when I try it on a real-world pager, the bit-rate varies a lot! From 750 microseconds to 870 microseconds, and each bit is somewhere in between this which means that I get a lot of errors when reading the signal since one message is up to 5000 bits long. Let's not forget that there is always noise on the data line when the real signal is not present, when there are no messages being transmitted.

I managed to make it work in "lab conditions" by measuring 3 bits, and if all bits match 833 microseconds I attached an interrupt that would trigger a timer with a period of 833 microseconds that samples the signal and saves it into a character array (yes, I know, bad solution). As I said, this works perfectly as long as the frequency is stable.

I tried measuring 10 - 20 bits which were between 750 - 860 microseconds and calculating the average bit-rate and sampling the signal with that rate afterwards... Didn't work either.

The digital signal always has a preamble of 576 alternating bits (0101010101...) so you can detect when an actual message is being transmitted.

Any ideas on how I should tackle this?

I'm sorry if I didn't explain it thoroughly enough... If you have any further questions, let me know!

EDIT: This is how the signal is encoded. In short, one bit is transmitted in 833 microseconds (supposedly) and the message starts bits 576 alternating bits, called the preamble (010101010101...). After that a 32-bit long Frame Sync codeword is transmitted (the FS codeword is always the same) that signals the beginning of the first batch of data. There are 8 frames (each frame holds 2 codewords, 2 x 32 bits) which hold 16 codewords of data. After those 8 frames, if the message continues, another FS codeword is transmitted and so on and on...

  • \$\begingroup\$ This isn't really answerable without an explanation of how the data is encoded. Typically, to decode a signal you need to start from an understanding of what is and isn't a safe assumption. The pre-amble makes it look like you might be able to synchronize a receive clock to that and assume the bit timing within the message won't wander much from that, but it's also possible that the encoding of the data itself permits clock recovery. Because you haven't specified, the question in unanswerable. It's likely your problem is not original; research how the signal is usually interpreted. \$\endgroup\$ – Chris Stratton Jun 12 '18 at 17:40
  • \$\begingroup\$ Are you saying that within a single message the bit timing varies this much? Or are you saying that different sources have different frequencies but the frequency remains fixed for a given message? \$\endgroup\$ – Elliot Alderson Jun 12 '18 at 17:52
  • \$\begingroup\$ @ChrisStratton I'll add a picture of how the signal is structured to the original question. And yes, my problem is original. There's nobody that actually made something like this for this protocol that works on real-world applications. There is one example but it only works on lab conditions and follows a similar procedure as I do for sampling the signal. \$\endgroup\$ – 0xd4v3 Jun 12 '18 at 17:54
  • 1
    \$\begingroup\$ The easy solution is oversampling; sample at a much higher rate, then use the preamble to work out how many sampled bits corresponds to one real bit. \$\endgroup\$ – pjc50 Jun 12 '18 at 17:56
  • 1
    \$\begingroup\$ You can't be giving us the complete picture. What happens if a frame consists of 64 consecutive zeros or 64 consecutive ones? If the timing varies as much as you say it does within a frame it would be impossible to recover the data. \$\endgroup\$ – Elliot Alderson Jun 12 '18 at 18:05

The preamble in POCSAG is designed exactly for receiver to synchronize itself to the transmission data rate. At this point you can use well-known DPLL techniques to synchronize your internal clock with transmitted data.

The following blocks always begin with standard sync codeword, which means you can fine-tune the clock at the beginning of every payload.

Even though the data rate might drift between the blocks it is highly unlikely it will change within the block. You should be able to keep in sync by correcting the clock using sync codeword - that's what it is there for.

After receiving each block you can use hamming distance and parity bits to detect errors and use error-correcting codes if necessary.

As a side note, oversampling with sufficient frequency is too heavy for this MCU, considering required additional processing. Tasks like DPLL are better done using IRQ on data line. This would also separate synchronization from error processing, making code more efficient.



  • Basic Data separator design, 1200 baud NRZ synchronous but noisy from FM radio.
  • data has low transition frequency relative to data rate (1/32=3%).
  • Tx clock frequency error = TBD, assume 100ppm for now.
  • Rx data asymmetry =TBD vs data content and RSSI signal strength , = TBD
  • Rx data jitter from inter-symbol-interference(ISI) =TBD
  • Rx data jitter from low RSSI = TBD ( random and adjacent channel interference(((ACI)
  • Rx clock range > Tx clock error (VCXO) = TBD
  • dual bandwidth mode PLL design suggested to capture frequency error and lock phase error to 0 +/- TBD %
  • desired Message Error rate = 1e-6 or TBD at worst case yet acceptable signal level = TBD Rf RSSI level or Rx power level resulting in worst case random jitter of preamble of TBD or 33% target.
  • store messages in a database with ID addresses and data Baltimore police had these long ago So now we see a lot of TBD’s that once you learn what they are and make an error budget , you can make a design target budget and then see what factors affect this.

I have successfully done this using a spare video interlace line to receive 256 bits at 4MBps NRZ in a 4.5MHz video luma NTSC channel including 8 bits for clock sync and the rest for address ID , data and CRC. It could tolerate a 200 bit stretch with random or no transitions easily and +/-40% random jitter.

How you do it depends on your TBD’s.

I created a 4MHz PLL that sync’ to preamble very fast then using a CMOS switch changed loop bandwidth to correct the VCXO error much slower. You won’t have to, but , I used a sawtooth to sample and hold the phase error of any data transitions. Because ISI jitter is common , the phase errors from this cause an alternating phase error noise that can be attenuated by the feedback filter design. Rx skew due to Discriminator threshold error error is also measureable mainly at 1/2 bit rate and can be attenuated. Loop filter lead/lag compensation is just choose the RC ratios around 10:1 near the unity loop gain breakpoint so it is stable and clock jitter should not contribute more than 5% error but in poor designs such as this your timing window has too many ToBeDetermined’s.

In the end the design result could be some phase error tracking code in a SDR that integrates and dumps the result after each interval to simulate a 4046 type PLL to recover the data or a PLL IC itself with I&D data desciminator to use the entire bit interval for “optimal receiver” performance.

The challenge is to identify all unknowns in a spec then expected results the solve the design is much easier with reading similar examples.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.