Introduction: GPSDO YT, Disciplined Oscillator 10Mhz Reference Frequency. Low Cost. Accurate.

Picture of GPSDO YT, Disciplined Oscillator 10Mhz Reference Frequency. Low Cost. Accurate.


Instead check the new 2x16 lcd display version available here:

I left the old version here for documentation.


Hi guys,

What is a GPSDO ? GPSDO means: GPS disciplined oscillator. GPS for global positioning system. All GPS satellites are equipped with synchronized atomic clock. GPS module receives these signals from several satellites. And by triangulation, he knows his location. But here, what interests us is the pulse per second that is found on the module. With this precise pulse (from atomic clock), we can do a very very accurate oscillator. What for ? For reference, for calibration of frequency counter or just for fun to have one in his lab.

They are many schematic on the internet. I have tried some. Some are good, one with a tiny2313 was 5 hertz too slow. But mine is the most simple, useful and convenient. And i'm giving you the .hex code. They are no VCO and no divider. Circuit with VCO are doing well. But, it must have a pulse signal of 10khz or more continuously. If antenna goes too weak, missing pulse or no pulse at all, the Oscillator (ocxo) is running by itself and the VFC (Voltage Frequency Control) isn't accurate anymore. The VCO feedback needs reference frequency to stick on. If not, It varies from a 1 to 2 Hertz! Also, the cheaper gps module doesn't work in this configuration. We must have at least 10khz to make a VCO. I tried with 1000 hertz. The gap was too large.The frequency varied. So with a ublox neo-6m you can't do a great vco gpsdo because maximum output frequency is 1000Hz. You must buy a neo-7m or upper.

This is how my GPSDO YT works. The controller found the good adjustment for any OCXO with vfc 0 to 5v. If we loose GPs signal, the frequency doesn't move at all. When the signal reappears, the controller takes his last known good value and continue as before. On scope, with a reference oscillator. We can't tell when the signal is lost or when it came back. The signal is the same.

After calibration, you can use the gpsdo without antenna if you want. A few mounts later you will have a very little drift. But.... how much larger ? It's time for some explanation.

Here is some Math... Easy math, follow me with this it's easy. So far the algorithm has 6 phases. Each phase takes a sample of 1 to 1000 seconds, found the good pwm adjustment and go to most longer samples for more accuracy.

Accuracy = (((Number of second x 10E6) + 1)/number of second) - 10E6

Phase 1, 1 second sample for 10,000,000 counts for +- 1 Hz accuracy

phase 2, 10 seconds sample for 100,000,000 counts for +-0.1Hz accuracy

Phase 3, 60 seconds sample for 600,000,000 counts for +-0.01666 Hz accuracy

Phase 4, 200 seconds Sample for 2,000,000,000 counts for +-0.005 Hz accuracy

Phase 5, 900 seconds sample for 9,000,000,000 counts for +-0.001111 Hz accuracy

Phase 6, 1000 seconds sample for 10 billions counts for +-0.001 Hz accuracy

Worst case . When we get phase 6. This number can change a bit each 1000 seconds or not. some time it will be 10,000,000,001 or 9,999,999,999 So, +or - 0,000,000.001 variation for 1000s. Now we must know the value for 1 second.

10Mhz = 1 second

For 1 second = 10,000,000,001 count/1000s = 10,000,000.001 Hz (worst case for 1 second)

10,000,000.001 - 10,000,000 = 0.001 Hz/s faster or slower

0.001Hz X 60 X 60 X24 X365 = 31536 Hz/years

So remember, 10Mhz is 1 second, 31536Hz X 1 / 10E6 = 0,0031536 second/ year

Another faster method for calculation. one miss fo 10E9Mhz is 1/10E9= 1E-10

1E-10 x 60x60x24x365 = 0,0031536 second/year.

Is that accurate enough for you?

however, you must have a good OXCO. I prefer Double Oven 12v Sinus output. More stable, quiet and accurate. But i have same result with simple 5V. For exemple, a stp 2187 have a stability short time (allan deviation) of 2x10-12 = 0.000,000,000,02 Hz of stability. In the same time, when gps pulse is available, Avr will always correct pwm (frequency). The uC is always counting... always. This mean that on display you will not see date and time. When uC is sampling 900s, this one is busy for 900 seconds. It must count all clock. Problem is uC is running at 10Mhz. Each clock must be count. It is counting itself. If only one clock is missing the sample will not be good and pwm adjustement will not be right. I can't refresh display each second.

When the sampling is started. Uc start to count timer0. Each 256 clock generates an interruption. X register is incremented. when it's full Y register is incremented and X reseted to 0 and so on. At the end, at he last one gps pulse, the count is stopped. And now and only now i can update display and do some math for pwm calculation.

knowing that, i have only 25,6 us (256 clock before interrupt) to read and display time or other. It's impossible. One interrution can be buffed, not 2. I could refresh the time after 1000s... but it will be not pratical to see time with 15, 16 minutes interval. I have a watch, a clock, a cell phone to know time :) I'm doing a 10Mhz reference. Not a clock.

Another problem i had, some avr instruction have 2 cycles. Including the rjmp instruction. This means if the first or last gps pulse came up at the same time of a 2 cycles instruction, the uC will miss a clock. Because uC will finish the instruction before begin the interrupt. So the counter will start or stop one cycle later. So i can't do a time wait loop... But in fact, i have no other choice. I needed to loop somewhere!! I So i'm using rjmp and nop (this do nothing) instruction. Nop is an one cycle instruction. I have put 400 nop instruction for one rjmp on atmega48. 2000 on atmega88 and atmega328p version. So the chances are less to first or last pulse come at rjmp instruction. But yes it's possible and if this happen, this error will be corrected at the next sampling.

The display is optional. You can do circuit with, uC, OCXO and low-pass filter (resistor capacitor) only, turn on and wait. After 1 hour you will have an acceptable frequency. But to reach phase 6. It takes a couple of hours.

Pwm is 16 bits. 65535 step. 5v/65535 = 76,295 uV

OCXO variation is 2Hz by 1V. 1v/76,295uV = 13107 step for 2 hz. 2/13107 = 152.59uHz by step of pwm

The phase 5, is changing pwm by 3, phase 6 is 2. step... Why 3 ? because 3 is changing frequency by 0.000,000,000,4 at 15 minutes scale. and 4 is my magic number in my algorithm. For exemple, if in phase one, first frequency found is 10.000,003Mhz. I lower down by 0,000,000.4 step.

Too large step can pass from 10.000003 to 10.000001 and after 9,999998Hz. I'm missing the target.

With 0,0000004. It's quicker than 0,1 and i'm more sure of not bypass a number. And so on. I'm doing the same with 10 seconds, 60 seconds and 200s phase and 900s. 1000s is running mode and use a pwm step of 2

Please note that phase 5 is more longer to achieve. The gap between 4 and 5 is larger. But it help to pass from 5 to 6 quicker.

When phase 6 has counted exactly 10 billions, the pwm values is saved in eeprom. Now, it's time for the running mode. This one count 1000 seconds sample but with 2 step pwm only. At running mode, the real frequency is displayed and updated at 1000 seconds interval. If signal is lost in running mode it pass in self running. No change of pwm in this mode. When signal come back, it return to phase 5 to resynchronization.

If circuit is unplug after eeprom is saved. This one will begin at phase 5 at power on with eeprom pwm value.

For erasing eeprom value, just press the button at at start-up. Pwm 50% will be load and calibration will start from phase 1.

I pass many hours to try different thing, configuration of the circuit. I did many tests, with OP amp, buffer and other chip. And at the end... the best result i got doesn't need it. Just a good stable power supply and some filtering capacitor. So I keep this simple.

Step 1: Buy Parts

Picture of Buy Parts

The first thing to do is buy the parts. Because often shipping is very very long.

Gps module: I'm using a ublox neo-6m. I bought this one on ebay. Do a search, it's cost about 7 to 10 us dollars.

By default, this receiver have the 1 pulse by second enabled. We don't need to do anything.

You can use any gps module with a 1 Hertz pulse output. You have one. Use that!

OCXO: I tried 2 oscillators. A double oven stp2187 12v sine wave output. And a ISOTEMP 131-100 5V, square wave output. Both come from radioparts16 on ebay. I had a very good service from them and the price was cheaper.

AVR: Code fit on a little atmega48. But i suggest to buy an atmega88 or atmega328p. It's almost the same price. Buy this on digikey or ebay. I'm using the dip version. You can buy surface mount version, but pay attention, pins aren't the same to the schematic.

Lcd display: Any 4x20 HD44780 compatible display will work. Guess where i bought mine :) Yes on ebay a couple years ago. Now it's more expensive than before. But available under $20 US.

Maybe in the near future, i'll do a code for a 2x16 display. Those displays are only 4$. And between you and me, a 2 lines display would be sufficient.

You must have an AVR ISP Programmer. Programming an AVR isn't like an Arduino. Arduino has already be programmed to communicate on serial port. A brand new avr must be programmed with ISP or Parallel High Voltage Programmer. We are using isp here.

A 74hc04 or 74ac0, volt regulator 7812 and 7805, resistors, capacitor.... digikey, ebay

Step 2: Here Is Schematic and Gpsdo_YT_v1_0.hex

Picture of Here Is Schematic and Gpsdo_YT_v1_0.hex

I think that the schematic is all you need to realise this project. You can use a copper clad board with etching method or just perforated board if you like.

You can use any box you want, but i suggest a metal box. Or just on a breadboard for fun like mine :)

I'm waiting for antenna extension and bnc connector to put my project in a box.

You must choose the right fuse bit. Be sure that external oscillator is selected. If you have trouble with External Oscillator, try External Crystal. And the low.ckdiv8 clock is unchecked. See picture. Pay attention, when the external clock fuses bit, you must provide an external clock to program or run the code. In other words, connect the Oscillator in xtal1 pin.

By the way... you can use the same code to do a frequency counter with 1 second gate. Just enter clock to be measured in xtal1 pin and you will have a +-1 Hz frequency counter.

I will be updating the project as soon as i have new stuff.

In the meantime, if the project interests you, you have enough material to start and even finish it before me

I uploaded 2 videos, you can see phase one and the last one.

I'm available for any questions or comments. Thank you.

February 26 2017.... Version 1.1 available.

-atmega48 isn't supported anymore. Not enough space.

-Added number of satellite locked.

-Support 2x16 lcd. If you have a 4x20, will be working too. But 2 last line will display nothing.

Step 3: Logs in Eeprom

Picture of Logs in Eeprom

Here is the dump of eeprom after a couple hours uf running time. I'll explain how to read this. Again, it's easy :)

At address 00,01 is stored pwm value. As soon phase 5 count 9 billion, pwm value is updated every time the counter reaches exactly 10 billion.

As soon we are at phase 5. All counts are stored in eeprom after pwm value. Start at address 02, after 03 and so on.

This exemple came from my 5 volts ocxo. We can read pwm value of 0x9A73 = 39539 decimal on 65536. = 60,33% or 3.0165 Volt.

So address 00:01 is 0x9A73

Next, you can read 03. For 9,000,000,003 Pwm is lowered by 3 because we are yet in phase 5

00 for 10,000,000.000 pwm stay is untouch and we pass to running mode (phase 6)

02 for 10,000,000.002 In that case, pwm value is lowered from 2

01 for 10,000,000.001 pwm value is lowered from 2

01 for 10,000,000.001 pwm value is lowered from 2 again

00 for 10,000,000.000 pwm stay is untouch

00 for 10,000,000.000 pwm stay is untouch

00 for 10,000,000.000 pwm stay is untouch

Now you know how to read the eeprom. Each 1000 seconds new value is written in eeprom. When eeprom is full, it restarts from address 2.

FF value mean 9,999,999.999

You can with this dump track the accuracy, without any LCD display.

You can dump the eeprom file with an isp programmer.

I hope that i gave you enough information. If not, let me know. Advice, error, anything.



mike_99 made it! (author)2017-09-26

Hi Yannik

I made it and it works well! One question: What expect you on the "From GPS TX" input? I left it open and it works.

Best regards and thanks for software


Yannick99 (author)mike_992017-09-26

Hi, glad to hear that. For your question. Gps input is optional. Each second gps send information on the gps tx pin.

If you put a wire from gps tx pin to gps input pin on atmega, you will see the number of satellite you are locked with.

Your gps need to send data at 9600 bps. Ublox is already at 9600 by default. Just put the wire and see. Let me know

cuita (author)2017-02-27

Hi, Yannick, it doesn´t seem to be working. The LCD display just shows a line of blocks and the PWM stays stuck on 0.5. I´ve checked and rechecked every connection and everything seems to work, but unfortunately I can´t debug it.

The problem happens with both versions, not just the new one.

Yannick99 (author)cuita2017-02-27

I don't change the old version. So if the old version was working before and not now. Problem is on your side. Also i downloaded and program an atmega328p with Gpsdo YT 1_1 2x16_mega328p.hex and for me it's working fine. Maybe you have a programming problem ?

cuita (author)Yannick992017-02-27

Fun thing: reading is important. Especially the part about the button.

So, a long collection of issues, some related to you, some not:

1. I got it to work by setting it to external CRYSTAL (!), but not with external OSCILLATOR, even after filtering the signal to send a square wave clock.

2. Once that part was fixed, I finally read the part where you mentioned that the pwm remained fixed for 15 minutes. Hitting the reset button on the freshly-programmed IC did the thing and it started running correctly.

3. Related to 2, the circuit I built earlier seemed frozen because it was in phase 6. I did a hard reset by holding down the button when booting and then it worked correctly... however, just pressing reset during run time did nothing. Is this because the phase needs to end before doing the reset? If so, this would be a good thing to change.

4. I get nothing on my LCD screen; just a series of blocks, meaning the LCD is not being initialized. But that's not the only thing: when the LCD is connected, nothing works. I've checked and double-checked and every wire is in the correct location. I'll attach a picture afterwards, maybe you can see any issues.


Yannick99 (author)cuita2017-03-02

Cuita, after some other test i changed the schematic. I'm using the output of the 12V OCXO in the 5V in buffer before enter in uC. The modification is very easy to do... re-download schematic please. And excuse me for all of this. Thank you

Yannick99 (author)cuita2017-02-28

Hi Cuita,

Yes i told you :) 15 min to wait. It's a pre-heat waiting time to put Oscillator accurate before to start counting. Push button to pass.

You will see this soon on your display:)

Between you me, we are using oscillator. It's why i suggest to put fusebit in this mode. But now, thanks to you, i know that this can be a trouble. I'll add a note about this.

When you do a hard reset. Uc reset... no choice, it reset. But if you was in run mode, uc will restart at same pwm value as before.

Now for the LCD, i double checked my wire with my schematic. All fit but i saw something confusing. On the schematic, do you notice that pin 5 and 6 are reversed. Number and name are good. But position is reversed between 5 and 6. Check on your side it's maybe the trouble. And me i'll try to find another draw for this.

Let me know, you can write me by email will be more quick

cuita (author)Yannick992017-02-28

Hi, Yannick! I fixed it, but it´s not exactly what you say: You left pin 5 unconnected in your diagram, instead it has to be grounded. I saw this in the photo of your protoboard above!

Yannick99 (author)cuita2017-02-28

Great... i'll fix my schematic thank you :)

On version 1.1 i changed something. Pwm value is saved only when run mode is acheved. So if you turn off the thing before that you must restart the whole process.

But after, when pwm is saved, it start directly on run mode.

I'm trying a new algorythm. Right now the frequency change very very sloly from 9,999,999.999 to 10,000,000.001. When frequency hit top or bottom, pwm is raised ou lowered. So most of the time we have the right frequency but we can have this more accurate.

I'm logging 20 pwm last value = to 10 Mhz exactly. I do an average and i set the pwm with that and i'm restarting from there. And so on. Over time i think that will be more accurate.. I'll let you know if this is better.

I also buy a metal box today. And i'm waithing for an brand new blue 2x16 lcd display. A day, i hope, i'll be able to finish this project :)

I'll do the 2x16 version. 4x20 is too large for nothing.

What you think, 2x16 is good enough ? I'd like to have one more space between HZ and frequency... 10,000,000.000HZ isn't pretty.Maybe i could use 10000000.000 HZ i dont know.

cuita (author)Yannick992017-02-28

An update: It´s not quite working: When I start it, I get the "GPSDO YT 1.1" message, then "No config, setting PWM to 50%...", then the "Warming..." message, the "Push button to skip", then "Waiting...". And no matter how much I press the button after that, it stays in the "Waiting..." phase, and it never updates the PWM.

Pressing the button to clear the memory does work.

I haven´t tried disconnecting the LCD again, but it was calibrating fine before I put it in.

I think "10,000,000.000Hz" is fine but I haven´t been able to see that message yet!

cuita (author)cuita2017-02-28

Extra update: After removing the LCD, it starts adjusting the PWM again.

Yannick99 made it! (author)cuita2017-03-02

Hi Cuita, I rebuild the whole gpsdo from scratch in a box. version 12v. And i'd like you to check something... What 7404 are you using ? Do you install a socket ? Can you try the circuit without the 7404 ?

Yannick99 (author)cuita2017-02-28

So you are telling me it's working when lcd isn't connected but dont if it is ? Hummm... lcd is only a dummy in this circuit. Did you tried to add the TX cable from your gps module to RX pin 2 on atmega328 ? Probably not if you are seeing only Waiting.... Satellite locked is suppose to be at bottom of this line but it is optional naturally.

I have double checked my code and i'm not understand why you don't come out of this waiting time. If you are able to load default setting, so the button works!!!

Is your LCD needs a lot of power ?

At waiting time, uC count 15 mins itself. No need of gps pulse. it's only a loop. So after 15 minutes it's done... So if you wait and nothing happen, uc is frozen! Why ? I dont know. Maybe a oscillator problem when lcd is connected ? Voltage ? But no you are seeing something on the display!

I don't know i'll think about that.

cuita (author)Yannick992017-02-27

It's very odd, my circuit was working fine, I unplugged it and plugged it back in, and it stopped working. I tried reprogramming it in several different ways with no change. What's strange is that I can program the bootloader on it and other programs do work. I've even tried several clock settings with no success.

cuita (author)2017-02-20

Hi, Yannick, would it be possible for you to release the code for the program? I'd like to alter it to work on a 2x16 LCD Display.

Yannick99 (author)cuita2017-02-26

Done and tested... Hex is now available. Try it and please, tell me what you think :)

Yannick99 (author)cuita2017-02-23

I almost finish. I did it. And i added number of locked satellite. Just add a wire between Tx from gps reciever and RX pin2 of atmega. .Hex soon

Yannick99 (author)cuita2017-02-20

Hi Cuita, instead i'll do that for you. In a meantime i'll maybe add number of locked satellites. It's working with neo 6m but not with neo 8m... i must found why!! Probably 2x16 and 2x20 will be compatible. But code for 4x20 isn't the same memory adresses.

After you could try the code and tell me what you thing about that. Change to make etc..,

cuita (author)2017-02-07

Hi Yannick,

Finally worked, the software was loaded again by another method, it is working VERY WELL !!

Yannick99 (author)cuita2017-02-07

i'm very glad to hear that :)

Dont forget, at startup, you have a 15 min waiting time. PWM doesn't move at all. You can bypass this by pressing pushbutton. But it was not your ptoblem here.... Take care!

cuita made it! (author)2017-02-07

Frequency meter disciplined by Rubidium

cuita (author)2017-02-07

Hello Yannick, we reloaded the uC, this time using another method and now it works correctly!!.
Thank you very much

cuita (author)2017-02-06

Hi Yannick, I
did another verification, I do not have the 4x20 display (I only have
one of 2x20) but with the oscilloscope you do not see any activity on
the pins 23,24,25,26,27,28, there are only 5v on pin 28 , The others are at zero v

cuita made it! (author)2017-02-02

Hello dr om,

I am doing the
gpsdo with atmega 328, I do not know if it is working correctly, at pin
15 of the atmega there is a square wave of 152,4Hz 49,39% duty cycle, is
it right ?, the oscillator is a Morion MV89, 12v sine.

I await an answer

Thank you very much

Thank you very much

Yannick99 (author)cuita2017-02-02

Hi, yes your right.... it's normal. Working fine. The duty cycle will change to set the right frequency.

If you probe pin 15 after resistor. (between resistor and capacitor, pwm out) you are suppose to have a dc voltage.

This one will correct the frequency of the OCXO

Let me know

cuita (author)Yannick992017-02-05

Hi Yannick,
thanks for the reply, I say: I do not know how the uC was loaded, I did
not do it, I do not know how to do it, I have no experience with uC, I
just know it was placed on an Arduino UNO board and there it was loaded.
Should the uC be placed on the GPSDO board with the 10MHz OCXO clock during programming?
For programming is it necessary that the pulse of 1pps of the GPS is present?
I apologize for the inconvenience.
Thank you very much

Yannick99 (author)cuita2017-02-05

No need 1hz to program.

Ok so you have programmed via arduino, and as per what i saw, it's working fine. It's running. 10Mhz/65536 = 152.59 Hz and that's what you have. This prove that you oscillator works well. Prove too that uC run with the OCXO clock. So far so good. The frequency will never change. Duty can change.

Now... i'm seeing 2 possibilities.

1- You do not have 1 Hertz pluse in uC


2- The frequency of your OCXO is 10,000,000,000 at 2.467v

On start, pwm is at 50%... but if uC run already at 10 mhz, uC pass to next phase and pwm duty doesn't move.

after phase 5, 6... duty varie very very slow. It a 16bits pwm. at phase 6, pwm change is 2... 2/65536.

5v / 65536 = 76,29uV

76,29uV x 2 = 152,58 uV

152,58 uV it's hard to measure with multimeter.

Just put the proble on this pin, change the OCXO speed. Very sensible. Your project is probably working fine.

Maybe i could add a LED to monitor 1 HZ input. Red led = no hertz something like that.

cuita (author)Yannick992017-02-06

Yannick, I did the following, I replaced the OCXO with an HP8656B
signal generator, injected rf into pin 9 of the uC and connected the
oscilloscope to pin 15 of the uC, by varying the frequency in more and
in less than 10mhz, the pulse train In pin 15 varies the frequency but does not vary the duty cycle, the voltage VCO is always 4,66v. 1pps from GPS is ok on uC pin 4.

Thank you very much

cuita made it! (author)2017-02-04

Hello Yannick,
this does not work, when the gpsdo on the VCO is 2,467v, 10 hours later
VCO = 2,467v, I think the software was not loaded correctly, it was not
loaded by ISP, my experience with microcontrollers is zero, if you do
not Can you help me the project will be unfinished

Thank you very much

Yannick99 (author)cuita2017-02-04

Sure i can help you... How did you program the uC ?

Also, check for good gps antenna. And be sure 1 Hz is working. If 1hz is missing. PWM doesn't change at all.

DIY Hacks and How Tos (author)2016-12-18

That is pretty impressive. You should think about entering this into the First time Author's contest.

Thank you Jason, A contest :) Yes why not. I'll think about that thanks again

About This Instructable




Bio: Hi, i'm electronic technician but it's my hobby too. I like to do and try many projects just for fun :)
More by Yannick99:GPSDO YT 10 Mhz Lcd 2x16 With LED, UTC Time and GPS Localisation.GPSDO YT, Disciplined Oscillator 10Mhz Reference Frequency. Low Cost. Accurate.
Add instructable to: