automatically calibrate ppm for rtl-sdr

Note: I found this post sitting in my draft posts folder, it is over two years old but I figured I'd publish it anyway.

I recently discovered an rtl-sdr project of mine had stopped receiving data. After a bit of investigation it turned out the ppm error value I had previously calculated seems to have drifted over time.

PPM is a unit used to measure the variance in a crystal oscillator between the frequency it is meant to operate at and the frequency it actually operates at. When using an rtl-sdr you need to calculate this variance and account for it in your tuning software, eg. rtl_fm -p <ppm goes here>.

Apparently temperature is a factor and it has been chilly lately so I'm guessing that's the culprit.

The first time around I had followed these instructions and computed the PPM for my tuner manually. Since the project I'm operating doesn't need to operate at night (because the boats aren't running) I started thinking that with some scripty goodness I could just recalibrate the tuner nightly to avoid future downtime.

So I hacked something up to do just that, again using the kalibrate-rtl program which computes PPM by checking known base frequencies of cell phone channels. My script checks the three strongest nearby cellular channels three times each and then compute the average.

The problem is it doesn't work. Each cellular channel it checks corresponding to a separate cell tower was producing a wildly different PPM value from the others. It turns out I'm not the first person to notice this. Basically the reason you can't use these supposedly "known good" base signals to calculate error from is that they also contain a small amount of error and the errors are different from tower to tower.

I found references in various HAM radio forums about using NOAA weather signals to manually compute PPM as they're known to be reliably well tuned, however it wasn't something I could easily script so I abandoned that approach.

As it turns out with some further reading I discovered that the RTL-SDR library itself ships with a program to compute the PPM error using a completely different approach. rtl_test computes the PPM error by comparing the the oscillator in the radio to the oscillator in your computers clock simply by checking the time repeatedly. Much simpler, faster, and reliable!

For this valuable contribution the author received only a paltry six upvotes on his post in the RTL-SDR subreddit. Turns out the same guy also wrote the rtl_fm program I'm using to tune my project as well as a program called rtl_power which, among other things, can be used to do passive radar tracking.

Bad ass!

So for helping me fix my project and for all your awesome contribution to the RTL-SDR community thank you Kyle Keen!