GPS-Disciplined 10Mhz frequency reference

Since WWV has been slated for defunding, my current 10Mhz precision reference will be useless soon. So I'm converting it to be GPS-disciplined. It won't be AS accurate anymore, as what was originally a phase-locked loop will now be a frequency-locked loop, but it's still going to be accurate enough for what I need.

So far, I've been doodling in EAGLE, picking parts out of the bins here and re-using parts from the current 10Mhz reference.

The TXCO I have needs 12V to power it, and uses a 0-8 volt error correction voltage to steer it back on frequency. (OFC-Mcoy GSM surplus unit.) A MAX5217 I2c 16-bit DAC will generate the steering voltage on a 0-4v level, then an op-amp setup as a noninverting gain of 2 will convert to 0-8V.

The ATmega32u4 is going to be set up as a Pro Micro, although since I want to put it all on one board I've just copied the pro-micro circuitry and pin-numbering scheme. This should help with getting the code done.

The ATmega32u4's 16 bit timer1 can't handle more than Fosc/2.5, so can't count an external timer faster that 6.4Mhz. I'm going to divide the 10mhz oscillator signal down to 5Mhz, and square it up to a TTL compatible signal.

The GPS module I have is the Skytraq S1315F, of which I can find very little information, other than the datasheet from Mouser Electronics. It appears that while this module is very inexpensive from some sources, it's an older part that's been superceded. I don't have to do much interfacing with it, and it's pre-configured. Just apply power, and the 1pps output and the NMEA data will start.

Here are my current "notes" and some questions pertinent to each task the ATmega will have to do.

1pps capture:

GPS generates 1pps signal, rising edge signals the new second.
Atmega32u4 uses INT6/arduino D7 as input, hardware interrupt.
On the rising edge, interrupt and check Timer1's 16 bit count of the 5Mhz clock.
Compare Timer1 to the ideal count.
Do I need to separately generate the interrupt on INT6/ arduino D7, AND do the input capture on ICP1/arduino D4?

LCD:
HD44780 40 char x 2 line thing, Optrex PWB40267-CEM.
plan to use PortF, the analog pins.
A0, A1, A2, A3 to LCD D4, LCD D5, LCD D6, LCD D7
A4 to RS, A5 to E
Write GPS data to LCD: Current time and date, satellites locked, number of satellites used, number of satellites in view, Is TXCO ready yes/no.

5Mhz Input:

5Mhz input to Timer 1 on PD6/arduino D12
16 bit timer, continuous count. We'll check the count every time Int6 catches the 1pps interrupt.

Serial Data from GPS:

Receive serial data at 9600 baud on RXD1/arduino D0 from GPS
Parse serial data and extract current time and date, satellite lock, and number of satellites in view/in use.

I2C interface:

Interface to the 16 bit DAC to control the error voltage. Want to generate a 0-4 volt output voltage.

TXCO

Divide 10Mhz by 2 to get 5Mhz squared up to feed timer1
oven ready signal needs to be converted from <1v not ready to >3V ready to 0-5v digital.
Oven ready is tied to PD7/arduino D6, and will display on LCD.

Lots of code examples exist to do pretty much all of what I'm going to be doing, just gotta chop and swap what I need. Some people have done the timing control differently, some have good documentation, some have very little to none. Most used an I2C controlled LCD, which I don't have.

I'm still very green with C and arduino programming, I do not get much time lately to play with it, and it's often separated by long periods of time...so I forget some of what I learn each time.

Can anyone here help me get organized pin-wise, and make sure before I etch the PCB's and solder the bits down, that I've made good choices for what inputs and outputs I plan to use? I'll work on the code after I have a complete board, probably starting with things like does the arduino talk over USB, then can I get the GPS data, is the 1PPS coming in, does the DAC work, etc.

Your idea will work, but the frequency accuracy derived will be no better than the frequency accuracy of the ATmega clock.

You don't want to introduce any other oscillators into the hardware.

The usual way to control a TXCO from GPS is to divide the 10Mhz down to 1 hz using a hardware frequency divider and to then input the divided down 1hz and the 1hz from the GPS into a hardware PLL, the output of which controls the TXCO.

This way , the txco has the same accuracy as the 1hz GPS reference.

I have built a GPS disciplined 10 MHz reference using a stand alone ATMega328P. I use a VCXO/TCXO/OCXO 10MHz crystal oscillator as the external clock for the ATMega328p.

I count the 10 MHz clock continuously using Timer1 and apply the 1s GPS tick to the ICP1 pin. In the ICP1 interrupt I record the Timer1 count and compute (modulus 65536) the number of 10 MHz ticks since the last interrupt. This I then use as the basic error in two PID loops to control the VCXO/TCXO/OCXO .

One only needs the modulus 65536 result since it is the count error from the ideal one needs and not the actual 10 MHz count.

Using ICP1 in this way removes the Fosc/2.5 problem. It is always within 1 count.

My control is a 2 stage process. I have an initial PID frequency control to bring the error count down to close to zero and then I swap to a PID control to control the cumulative count error towards zero.

The initial frequency control uses Timer0 to generate PWM using a 10 second analogue lag filter. The second cumulative error control uses Timer1 PWM with a 30 second two stage analogue filter. One can use Timer1 for PWM as well as counting the 10 MHz since one never resets the timer.

I use Timer2 as a frequency divider controlled by a Gray switch. This way I can get 10 MHz/N (where N is in the range 2 to 256) as a secondary output frequency.

A simple 20x4 LCD is used to show detailed control information with a 3 colour LED showing whether the output is stable. Red - Initial frequency control, blue cumulative control but not yet within a count of 1 and Green for accurate cumulative control.

I don't process the GPS serial output within the ATMega. Currently I just pass that to a serial terminal in my PC. I may in the future try to process this within the ATMega328p but I'm currently at about 85% usage so things are tight. Maybe in the future I will move to an ATMega2560 but not at the moment.

To my mind the results are pretty good though I don't have test equipment to allow me to compute the Allan variance so my results are subjective only. Using a TCXO I obtain an output such that the cumulative count error is normally zero for 10 or more consecutive seconds and then no more than 1 for more than a second. Using an OCXO the cumulative error count is normally zero for 30 or more consecutive seconds. For TCXO and OCXO and VCXO the cumulative error over a day is never more than 1.

I have run the system with 25MHz, 24MHz and 20 MHz VCXO. All work pretty good even with the overclocking.

I have a basic 10MHz frequency standard based on MSF but I'm not happy with it. Currently I'm working on a frequency standard using BBC Radio 5 on 198 KHz.