The curious case of the orphan APRS code

A project log for Simple Universal Modem

Can it save audio? It can save data too!

anders-nielsenAnders Nielsen 10/17/2022 at 09:200 Comments

Even though I finally implemented the final piece of the Kansas City Standard code with the start and stop bits, I have to admit I have left in some orphan code in the modem driver. 

A while back I had to see if there was any way this could be used for the ham operator on a budget’s dream – APRS decoding.
APRS is a global packet radio service that let’s radio amateurs send small messages, often with location information, and have them relayed to the intended recipient, and as luck would have it the protocol isn’t that far off from KCS at 1200 baud – except that the encoding is NRZ and it uses the improved frequencies of 1200 and 2200, meaning less problems with harmonics. 
Though the frequencies are different, they’re still close enough that we don’t need new filters for transmission/modulation – and currently the Simple Universal Modem doesn’t rely on any filters on the demodulation side. 

But that’s awesome, right?
Well yes, but.. Those filters are missing on the demodulation side because the modem expects a clean audio signal – and certainly not the pile of RF noise goo that comes out of a Baofeng. 
The issue here is that the modem works by detecting every zero crossing with a certain margin provided by the hysteresis and that amount of margin is easily overcome by only a tiny amount of static noise. 
Any noise strong enough to cause a zero crossing + hysteresis will garble up the data with no real way of recovery. As far as I can tell this problem is hard to overcome without a signal to noise ration that is far far better than what’s plausible on the RF bands. 

But what about transmission? That’s not a problem, right?
Well… It kinda is too. If we open an APRS packet in Audacity you might notice something rather peculiar. To me at least..

The frequencies change at different phases of the waveform! Remember those “improved” frequencies? Well, it turns out that when your baud rate isn’t a multiple of your frequency, you run into situations like this. There’s simply not enough room in one 1200 baud bit length for two waves of 2200Hz, so the wave changes its frequency at random places. 
Since we’re using T1 and PB7 to generate the initial square wave, which means we can only change the frequency at a zero crossing, there’s simply no way to replicate this behavior. 
Maybe the receiving station could still decode the packet if we rounded to the nearest zero crossing but that would, sadly, still be out of spec. On the demodulation side this is also a bit of a problem since the time between zero crossings vary depending on how much of the wave was snipped off – and this propagates until the NRZ encoding does it’s job and limits the amount of marks allowed in a row… But well after the damage has been done to our attempts at frequency detection. I did manage to get around this – rather ungracefully – by compensating, based on the previous bit. Not great, not terrible. 

So.. I decided to spend my time elsewhere and postpone the pursuit of a super cheap packet radio for another day.
I might pick it up again but I’m almost hoping someone will pick up the torch and submit a pull request. 

And that was the story of the orphan APRS code in the Simple Universal Modem repo.