Oscillator sync to GPS module

I am trying to figure out the best way to adjust the arduino count from input capture 16bit to make sure I capture 16 million ticks per second. I am using the 16bit timer capture to measure a signal every 10sec. So I was thinking, using the PPS output to create an accurate 1 sec time base. Theoretically 1sec pulse should give me 16 million ticks. If the micro crystal drifts I want to adjust the count to align with the GPS PPS.

If I want to automate the sync I would have to electronically switch the GPS PPS signal to the 16bit capture pin, run some sync code, then switch it back out to the signal I am interested in accurately measuring? Is there a better way where I can still measure the PPS and keep the 16bit capture pin dedicated to measuring the signal of interest? I am using a Leonardo arduino board.

What do you have? A GPS PPS? A 16MHz signal attached to T1?

What do you want? A 10s output? A 16MHz output?

You need more than a 16 bit timer to count 16 million ticks.

You can use a Bresenham algorithm scheme to track the phase drift between the PPS an Uno's crystal: set the timer to count up fast, and on overflow, you add a value to a register, while with every PPS, you subtract a second's-worth of counts from the register and record the value. That will track the drift. You can't adjust the crystal with the drift, but if you know what the drift is, you can schedule events in sync with the PPS at disciplined, higher or lower frequencies.

You don't need to put the PPS on the ICP pin, you can put it on a normal interrupt pin and read the timers during the interrupt.

It sounds to me as: you want to deal with "asynchronous clocks".
You want to align a local clock (e.g. in MCU) with a master clock (GPS). And at the end - the MCU clock should adapt itself to run with the same clock.

In HW people call it "PLL" (phase lock loop).

I know this topic from audio applications: a sender (PC) sends audio frames but paying out results in a tiny drift (too fast or too slow).

Here, what I think do you need to check:

  • can you "trim" a clock, a PLL, inside MCU, to adjust the clock (make it a bit faster or slower)?
  • how fine granular can you do?
  • is this just an INT clock divider or do you have option to use a factional setting?
  • can you do a clock modification "on the fly", or do you have to reconfigure the PLL by stopping it, change it, start it again - this would be vary "bad" (but OK for second range to adjust)

As I know, GPS modules provide often a clock (from the atomic GPS clock), as 10 MHz or as 1 Hz.
Can you feed this clock, via external wires, as an clock input to a MCU, or a device on MCU (e.g. a TIM, INT, clock source, e.g. SAI external).

If you cannot "hard couple" the clock, e.g. not as a clock input. you have to do an "adaptive clock recovery": your local, free running clock tries to get in "sync" with the external (free running) clock. You have to adjust your own (local) clock.

This is a "control loop" (feedback): You need a PID algorithm (Parallel, Integrated, Differentiated), which will check for the difference in clock (a drift) and decide how to adjust your own clock.

I would check if you can bring the "GPS clock" as input to MCU. It could act immediately as source clock. If not possible:
Find if you can measure this input clock, find the relation with local MCU clock, based on difference and drift direction (also how fast it is drifting = acceleration) - derive aa parameter how to trim your local clock.

BTW: the "control loop", this "PID controller" sets how much your local clock is "breathing":
how much jitter, how are min. and max. to jitter in between, how fast a change happens ...
A complex topic, possible, but you have to think about how your "feedback loop" would behave.

Instead of "adaptive clock recovery" it might be better to check your HW if you can feed MCU with a GPS clock (and all derived from there). Than it is "hard locked", very accurate.

BTW: maybe you know Shannon Theorem or Nyqyist Criteria: it says: in order to sample an input waveform, to know its frequency - I need to sample with twice the speed of frequency I want to get.

When it comes to clocks, esp. for the clock edges (a digital clock): when does the rising edge happen of my external clock in relation to my own clock? - you need a much faster sampling clock (at least measuring/sampling the clock with 10x of the input clock frequency).

Synchronizing two clocks (with SW) is possible, but might be challenging, esp. in terms of speed/performance you need.
But at the end, all is wasted intelligence if you cannot adjust your MCU, e.g. to set a slightly different config on PLL (system_clock config). If you have to stop a PLL - and all stalls - or you can just in increments of integers (not floating point values) - not fine granular to let follow the clock.

on a 4g femtocell we used gps to adjust the TCXO by pulling an adjustment voltage to in/decrease it's speed slightly. don't see that as an option

would suggest using micros/millis() and occasionally in/decreasing the # of tics waited for to maintain sync with the 1PPS

1 Like

Timer 1 and Timer 3 on the ATmega32U4 are both 16 bit counters with input capture so it's not immediately apparent why one could not be able to capture both your "signal" and the "1 PPS" from the GPS to pretty high resolution.

Thanks MrMark. I didn't know it had another 16bit input capture. I can generate code that will count roll over to time seconds. For both timers. Use the pps on one timer to tell me if I'm still getting 16 million ticks. If it deviates I can alter the math dealing with timer 1 counting of the signal of interest. Works for me!

I appreciate all the feedback. I'm going to try the dual 16bit timers approach. See where that takes me.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.