[time-nuts] getting accurate timing on RTL-SDR output

jimlux jimlux at earthlink.net
Fri Apr 13 18:08:30 EDT 2018

On 4/13/18 1:47 PM, Magnus Danielson wrote:
> Hi Jim,
> On 04/13/2018 06:52 PM, Jim Lux wrote:
>> I'm building a phased array receiver (actually, an interferometer) using
>> RTL-SDR pods, where the elements are isolated from each other - there's
>> a common WiFi network connection, and each node has a BeagleBone Green,
>> a uBlox OEM-7M-C, and the RTL-SDR V3 (which works down to HF, since it
>> has an internal bypass around the RF front end).
>> In general, I have the RTL-SDR set up to capture at 1 Megasample/second.
>> I fire off a capture, record it to a file in the BeagleBone's flash,
>> then retrieve it from my host computer using scp over the network.
>> What I'm trying to do is capture data from all the nodes at
>> (approximately) the same time, then be able to line it all up in post
>> processing. The GPS (or NTP) is good enough to get them all to start
>> recording within a few tenths of a second.
>> So now the challenge is to "line em up".  An obvious approach is to
>> transmit an inband pilot tone with some sync pattern, received by all,
>> and I'm working on that too.
>> But right now, I have the idea of capacitively coupling the 1pps pulse
>> from the GPS to the antenna input - the fast rising and falling edge are
>> broad band and show up in the sampled data.
>> The attached pulses1.png shows the integrated power in 1 ms chunks (i.e.
>> I sum the power from 1000 samples for each chunk) and it's easy to see
>> the GPS edges.  And it's easy to create a estimate of the coarse timing
>> (to 1 millisecond) - shown as the red trace.
>> But then, I want to get better.  So for the 20 edges in my 10 second
>> example, I plotted  (drift1.png) the raw I/Q output of the RTL.  The
>> pulse isn't too huge (maybe 10 DN out of the ADC's -128 to +128 range),
>> but is visible. Bottom trace is the first, and they're stacked up
>> 0, 0.1, 1.0, 1.1, 2.0, 2.1, etc.
>> And you can see, no surprise, that the sample clock in the RTL isn't
>> dead on - over the 10 seconds, it looks like it drifts about 30- 50
>> microseconds - that is, the RTL clock is slow by 3-5 ppm.
>> SO here's the question for the time-nuts hive-mind...
>> What's a good (or not so good) way to develop an estimator of the
>> timing/frequency error. Post processing minutes of data is just fine..
>> I'm not sure what the actual "waveform" that is being sampled is (and it
>> will be perturbed by the quantization of the ADC, and probably not be
>> the same depending on where the RTL is tuned).  That is there's some
>> sort of LPF in the front of the RTL, the edge is AC coupled, and then it
>> goes into some sort of digital down converter in the RTL running at 28.8
>> MHz sample rate.
>> But it seems that there might be some way to "stack" a series of samples
>> and optimize some parameters to estimate the instantaneous time error-
>> given that the frequency vs time varies fairly slowly (over a minute or
>> so).  It's fairly obvious from the plot that if one looked at the
>> "single" sample when the edge comes in, not only does the time shift
>> with each pulse, but the phase rotates as well (totally expected)
>> this is one of those things where you could probably lay a ruler on it
>> and estimate it by eye pretty well, but I'd like an automated algorithm.
>> It would be nice to be able to estimate the timing to, say, a few
>> nanoseconds over a minute or so ( - that would allow a phase estimation
>> of 1/10th of a wavelength of a 20 MHz signal (e.g. Jupiter's RF noise,
>> or WWVH's transmissions)
>> Ideas???
> Cross-correlate. Hug your Fourier transform as you do it.
> Assume that you have a rough idea where the pulse occurs for each SDR.
> FFT with a suitable window function each record.
> Using one as reference, you then multiply the complex response with the
> reference conjugated response.
> Ether compare in the frequency domain or do inverse FFT and search the > time-domain for peak response.

That's the sort of strategy I'm looking at.. find a set of samples where 
the transient occurs, zero pad it out (so that when I do peak picking 
later, I've effectively got interpolation), then run the correlation

ifft(fft(a).*conj(fft(b))) in matlab

> This is how modern GPS receivers to quick lockup of phase, and it works
> very well. Using an FFT library i could code it in relative little C
> code and setup my classic channel decoder this way.
> Now, use this to compare your SDR clocks compared to the reference. As
> they drift over time the windown need to shift, but you can keep track
> of the number of samples shifts to keep full track of it. This should
> give you enough phase and frequency information. Toss in a least square
> or Kalman if you think it would help.
> Cheers,
> Magnus
> _______________________________________________
> time-nuts mailing list -- time-nuts at febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.

More information about the time-nuts mailing list