An Arduino based GPS Disciplined Oscillator. This uses the precise 1 pulse per second signal generated by a GPS receiver to adjust a voltage controlled crystal oscillator, so that the oscillator is phase-locked to the 1 pps signal.
The design is based on hardware and code originally developed by Lars Walenius and posted on the time-nuts list.
This should work with any GPS that produces a 1 PPS output. My implementation uses the Adafruit GPS Shield, which is based on the Globaltop 3339 chip. This is not a specialized timing receiver but its 1 PPS output is specified at a stability of 100 ns RMS. This stability is not difficult to achieve if the antenna has a reasonably unobstructed view of the sky. I was able to fit the phase comparator onto the prototyping space of the GPS Shield card.
My oscillator is a surplus 10MHz OCXO made by FOQ Piezo, which cost $25.00 on eBay. Drift after several weeks of operation is about 6x10^-11 per day.
In place of Lars' PWM-based DAC I am using a 12 bit MCP4725, with an I2C interface to the Arduino.
The oscillator, DAC, and HC393 divider are packaged separately from the GPS and phase comparator, with a 6 inch jumper between them. One advantage of this arrangement is that you can use the oscillator stand-alone. The DAC has non-volatile memory which I load with the latest 3-hour average value, so it will remember its calibration.
Observations:
-- Because the oscillator has only one ground pin, it is important to make sure the VCO circuitry does share a current path with the oscillator, to avoid frequency shifts when the oven current changes. .
-- With the oscillator and phase detector on separate cards, I got a lot of ringing on the 1 and 5 MHZ clock lines. This added noise to the ADC readings and may have also caused occasional spurious interrupts on the Arduino. Adding 100 ohm resistors in series with these lines helped a lot.
-- Covering the oscillator, Arduino and GPS shield to protect them from air currents improves the short-term stability considerably.
-- In place of the DIP switches Lars uses to set the operating mode and time constant, I added simple commands from the PC keyboard to hold at a specified DAC value or run with the loop closed.
-- I have been using an enhanced serial monitor for the Arduino, which is very useful because it allows real-time performance monitoring and plotting. It is described here http://forum.arduino.cc/index.php?topic=185740.60 The monitor software is new and not generally released yet, but is available on request by contacting its author via the Arduino forum. This helps greatly in testing the GPSDO without an external reference. You can for example produce a histogram of the 5-minute average TIC values, send messages to an "Alert" window, and plot the TIC and DAC values over time with a scope-like display.
-- I modified the original code to use the processor's Input Capture Capture register and interrupt for the PPS signal. This reduces both the latency and the uncertainty in the PPS interrupt timing. The PPS signal from the GPS should be connected to Arduino pin D8 and not D2 as in the original design. On the Adafruit GPS Shield, you must cut the trace between the GPS serial TX output and D8 to prevent a conflict. I moved the TX connection to D6.
-- The original code used long integers for the filter variables. This caused some roundoff and truncation errors. Resolved these by converting to float
-- Normally the processor will reset when you connect the USB for computer communication. To prevent this and allow the logging to continue, connect a 4.7 uf 10V capacitor between the Reset pin and Ground. Make sure the + side of the cap goes to the Reset pin.
** Watch this space fo more information and schematics.