[time-nuts] First success with very simple, very low cost GPSDO, under $8
Tom Van Baak
tvb at LeapSecond.com
Thu Apr 10 03:05:52 EDT 2014
>> You only need enough bits to cover the worst case OCXO frequency drift or
>> the worst case GPS jitter error, per second. For example, if your OCXO stays
>> accurate to 1 ppm it can't possibly drift more than 1 us per second.
>> Similarly, it's a safe assumption that your GPS 1PPS stays within 1 us of
>> correct time. Therefore, the maximum number of 100 ns ticks you will be off
>> in any second is +/-10. So even a 8-bit counter is enough. Does this make
>> sense now?
> Am I confused or did you forget to add the 2 errors to cover the case when
> they both happen during the same second? 2 us or a count of 20 is still
> tiny, even for an 8 bit counter.
Yes, thanks, for worst case, add them. Also include a +/- 1 count error for the timer/counter. In reality it might be hard to say for certain what the max oscillator or max GPS jitter is. Are the numbers min/max, or 1-sigma, or 3-sigma, etc.? I used 1 us as a very generous example. But as you see, the number of bits you need to hold the time interval error is still very small.
A couple more comments on the Arduino...
1) Have you checked for glitches in your dual-DAC system? The Arduino API is forcing you to make two successive calls to analogWrite(). I wonder if there might be a glitch when the LSB carries/borrows into the MSB, since each PWM is configured separately. You can check this with a test version of your code that linearly sweeps through all possible DAC values and then continuously measure the output voltage with a high-res voltmeter.
2) Once you get rid of the unnecessary timer interrupt and have just the GPS 1PPS interrupt, realize that since all you do is a PID calculation and DAC update once a second, you can simply move that code to the interrupt handler. That further avoids any contention between main and interrupt code, since loop() has nothing to do.
3) Please consider using the ATmega input capture feature rather than a rising edge interrupt. The trouble with doing precise timing with interrupts is that, in AVR chips at least, there is some latency and jitter, depending if a multi-cycle instruction was in progress. You can avoid this by using hardware timer/capture registers. To find examples search for words like: Arduino timer ICR1H ICR1L
4) If you use (ICR1H) ICR1L you don't even need to use interrupts since the value is frozen until the next edge. I mean, you could poll if the code is simpler that way. Then your GPSDO is all in loop() with no interrupts at all. It's hard to get much simpler than that.
More information about the time-nuts