Show by Label

Friday, July 31, 2020

A high precision 10MHz GPS disciplined oscillator (GPSDO)

Note that I will be changing and adding to this post for a while. Please revisit often!
I have also created a new blog that only deals with the monitoring, measuring and logging of the GPSDO.
This blog can be found here.

For quite some time, I have been intrigued with a project to obtain a very high precision and long term stable 10MHz oscillator. Not that I really, really need one, it just got my interest and I wanted to learn how to build one.

Most of the interest was triggered when I upgraded my FY6600 function generator, and also when building my dividable pulse generator. Both projects can be found on this blog.

I have been following the projects on YouTube by John Sculley (here), and he designed a precise pulse generator by using a GPS module. The first video of a series can be found here : GPS locked 10MHZ reference 

Unfortunately, John has stopped publishing further works which is a real pity. I hope he is OK and has other things to do.

Anyway, this got my attention, and when I started to search the internet for more projects of this kind, I found one that was exactly what I wanted. I looked for a rather simple design, something that I could build and understand, and would not need "time-nut" qualities. The project I decided to learn more about was that of Lars Wallenius. It can be found here: Lars' EEV blog 

Unfortunately, Lars died from cancer shortly after publishing his design.

This was a real loss because he was a very kind and knowledgeable person. Besides, his GPSDO baby got quite some interest, and unfortunately, he did not live long enough to see all the fruits of his work and attention it got.

Even with this deceivingly simple circuit, I knew I had to learn a lot of stuff, because GPS modules, disciplining OCXO's (An OCXO is an Oven Controlled X-tal Oscillator) and measuring the results were all topics I knew little or nothing about. This posed quite a challenge for me, but hey, that's why I like this hobby so much. The good news is that on this particular blog, there were some really helpful and very smart guys that helped me out when I stumbled or fell. I started this project in October from 2019, by ordering the various components. We're now well into the summer of 2020 and this is one of the longest projects I think I ever embarked on.  I'm still far from having satisfied my curiosity or ready to put it aside or to rest.

I will continue to add information here about what I learned and measured so others can benefit from this as well.

First Prototypes

As a first step, I started off by designing a prototype with a first attempt to see if I could actually build this and learn more about it. First I used a protoboard, and that turned out to work OK, but it was quickly apparent that I needed to clean-up that contraption and go to a more permanent setup. By then I already experimented with more OCXO types, which is why I designed two circuits. One with the controller and one with the OCXO circuitry on it. Below is a picture of that prototype using a CTI OCXO.

The seperate OCXO board allowed me to swap various OCXO's. In the top of the picture you can also see a Blileyt and a TempTech OCXO. Initially, I had a lot of troubles getting one, that arrived, and worked. It literally took me a few months to collect a few that I could start to work with. Because I had no knowledge of OCXO's I collected a few initially, worked with them, found some issues and then added a few more. I now have 5 OCXO's that are working and that I have been added to my circuits.

The (second hand) OCXO's I have worked with are:

Oscilloquartz    8663-XS       12V DC    sine wave out
Bliley           NV47M1008      5V DC    square wave out
Trimble          65256          5V DC    sine wave out
IsoTemp          143-141        5V DC    square wave out
CTI              OC5SVC25       5V DC    square wave out

With this setup, I was able to test some changes to the original design, most notably a different method to discharge the TIC capacitor (C1). However, when I was learning more and more, it was time to create a dedicated PCB to implement all the wisdom and features, put it into a good housing and start to work with that.

Designing a PCB

The PCB that I designed using DipTrace, incorporated everything I knew at the time, and was put together to house different OCXO's. Unfortunately, I did not have the Oscilloquartz and the Trimble versions yet, so I made a footprint error with the layout of the Oscilloquartz one (I could not find a datasheet with a footprint), and since I had no plans to order a Trimble initially, I didn't even consider adding that footprint.

Note that the diagrams that I show below are the result of the many little changes I made on the basis of the PCB's. That's why I call the schematics Version 2. These schematics do NO longer reflect the PCB schematic diagrams 100% anymore, although all changes can be made on these PCB's, like I did as well. I will post the original files that went with the GERBERS on my Github as well as the revised ones.

Component side of the PCB:

Bottom side of the PCB with the modifications required for the Oscilloquartz footprint:

Some of the design and layout decisions

Power Supply

The units I have get fed by an external 12V DC power supply. Initially, I used switching wall-warts. Because I wanted to eliminate possible problems, I switched to a battery that would also provide back-up power during a brown-out.

The battery powered supply is made-up of a 5V DC brick that can supply the required warm-up current for the OCXO's. In my case I happened to have a 7A version, but that's not needed. Using 1.5 to 2A per GPSDO should be enough. Remember that I have to feed three versions at this moment. The next step in the chain is a Boost unit that supplies 12.6V DC to a closed lead-acid battery, salvaged from a burglar system. The battery I have is a YUASA NP7-12, 12V 7.0 Ah version.

I used a Boost regulator for safety reasons. The Boost will most likely fail to the lower input voltage, a Buck unit could fail to the higher input voltage, ruining your electronics.

The 12.6V output level of the Boost regulator will charge the battery while the mains is present. If that would drop out, the battery will supply a steady 12V DC.  From the battery, I go through a 1N5822 Schottkey diode to prevent back-powering. From this I directly go to 3 pairs of DC leads with barrel connectors, and they feed the three GPSDO units.

Initially, I used a 15VDC supply and an extra LM7812 to feed the Oscilloquartz OCXO. After I switched to the above setup, I now feed the Oscilloquartz directly with the 12V DC supply.

Power Distribution

To avoid cross-talk or otherwise influences between the various components, I went as far as I could separating the power sources. The main power entering the GPSDO is 12V DC. In the case of the Oscilloquartz OCXO, it directly feeds that. In the other versions, the 12V goes to an LM7805 that is mounted on the chassis. It gets hot otherwise. This LM7805 is dedicated to power the 5V DC OCXO's only.

Here is that part of the schematic:
The 12V DC also goes to an LM7808 and this supplies power to all the other circuits, some  powered by their own 78L05 regulators. One is used for the UBLOX NEO carrier. This carrier actually contains a 3V3 regulator that feeds the NEO chip. The trouble with this unit is that the current fluctuates quite a bit, and more importantly, the 1PPS pulse is pretty powerful and it's difficult to keep that "rumbling" away from the other parts.

The Arduino Nano also gets powered by the LM7808, and it also has it's own on-board 5V and 3V3 regulators. I first used this on-board 5V regulator to also power some other parts, but I found that when the controlling loop is unlocked, there is a pretty dramatic power change that influences the ambient temperature by several degrees. I disconnected the parts so there is nothing connected to the Arduino 5V and 3V3 supplies anymore. The Nano 8V and 5V supplies are only buffered by electrolytes.

The next circuit that is powered from the LM7808 is the DAC circuit. This has it's own power supply based on a 5V REF02 Voltage reference. Following a suggestion from EEV blog member miti, this has been done to isolate the (noisy) Arduino PWM signals from the DAC circuit that is feeding the control voltage for the OCXO. More details can be found on the EEEV blog.

The other 5V components are powered by another 78L05 (U13).

All supplies and components are by-passed with Tantalum electrolytes and 100nF capacitors.

Some of the signals coming from the NEO or the OCXO have fast rise times, and to avoid ringing and cross-talk issues, I used small resistor values in series to dampen the transitions. I did the same with the serial Rx/Tx lines from the NEO and the Arduino Nano.

The controller circuit

Below is the controller portion of the GPSDO. It really follows the design that Lars put forward.

There are a few small additions.
U7 is a 10MHz to 1PPS divider circuit based on a PIC, that I didn't use yet. I used my own synchronous frequency divider instead.

To avoid a reset of the Arduino firmware program when you plug in a mini-USB cable to program or monitor it, I added a 10uF capacitor across the reset pin and ground. Note that when you need to reprogram the firmware, you need to remove this capacitor. I mistakenly located it on the bottom of the PCB, while it should have been located on top, together with a jumper. For now I just soldered a small SMD capacitor across the pins on the Nano circuit board itself.

The oscillator circuit

On the bottom of this diagram you can see the PWM/DAC circuit that drives the OCXO frequency adjustment. The components of this circuit are powered by a 5V reference chip. There are provisions on the PCB to replace the trimmer with actual resistors, to reduce the temperature effects on this very, very sensitive circuit. The two inductors are there to stop the 10MHz signals to back-fire into the rest of the circuits. The PCB also has provisions to accomodate sine wave and square wave out OCXO's, as well as 5V and 12V versions. Look at the schematic below for more details.

Trimming the OCXO output

When you power-up the board with an OCXO of your choice, using a 10K trimmer in the position of R106 makes the frequency adjustments very easy. You can start with the 10K resistor values for R104 and R111, and hopefully adjust the OCXO to a precise 10MHz output with the trimmer in the middle of the range. If it's too much towards either end, you can change the values for R104 or R111 so it is roughly in the middle position. I used the running program with the DAC set to mid-range (h 32676) to adjust the trimmer to get the OCXO towards 10MHZ. While adjusting the trimmer, I looked at the diff_ns column and adjusted the trimmer such that I got an average around 0. Initially, I used a frequency counter for this adjustment, but this is actually much more precise.

Trimming the gain setting

With the mid-range adjustment done, you can now calculate the gain and set and store that into the EEPROM as per the instructions. If the gain to too low, you can increase the value of R109 to get a gain of at least 500. I recommend that you now let the OCXO adjust to it's newer life inside your GPSDO for several days if not weeks. They typically went through a very rough handling dismantling the equipment they were in and then to remove them from the PCB, in addition to the handling and shipping process on their way to you. These OCXO's are very delicate devices. I "aged" mine for a month or more before I replaced the trimmer by fixed resistors in the R105 and R110 positions. Using resistors instead of the trimmer will improve the temperature effects on the very sensitive adjustment circuit.

In the table on the schematic diagram, you can see the values of the trimming resistors I used for the various OCXO's. I found that although Lars recommended a gain of around 500, I got much better results with gains around the 1.000 value for my best OCXO's. It all depends on the quality of the OCXO and the difficulty of the controlling loop adjusting them. If you get wild DAC swings, especially over the +/- 50 ns range, you can reduce the gain and or increase the damping factor.

The OCXO circuit

The circuit diagram below can be used to figure out how to power and tune the various OCXO's. For sine-wave out versions, you need the "squarer" circuit that EEV blog contributor miti proposed. With the values shown, I did not need to tune C201, the amplitudes where large enough to get me very close to an ideal 50% duty cycle. If needed you can add a trimmer in parallel to C201. The trick of the squarer is to amplify the sine wave towards or even beyond the ground and VCC levels. Watch out that you don't exceed the maximum input levels for the 74HC14.

If you have a square wave out OCXO, you can add C105 and change the value of R15 to 100 Ohms to dampen the transitions somewhat.

The importance of the GPS module

Knowing nothing about the required GPS modules, I first purchased two U-Blox NEO 6M units and later an M8N version, and started to play with them. In the process, I managed to blow-up one of the 6M units by using the wrong supply voltage for the serial interface. It is 3V3! By then I also learned that the units I had were actually Chinese fakes of the U-Blox versions (they do not have the flash memory) and I also learned more about the timing version. A real M8T is not cheap but I decided to bite the bullet and purchased a genuine M8T chip. I'm very glad I did. I de-soldered the broken 6M chip from the carrier and soldered the M8T in it's place. In the beginning, I did not really know how to select the most optimum settings, but I got a lot of satellites and the results looked good, so I left it at that. Mistake! One other mistake I made was that I didn't save all the settings into the NEO EEPROM and so I lost them after a power cycle. Because I no longer monitored the NEO output, I was unaware of this. These things cost me dearly because I spent a very long time chasing weird events that were actually the result of my not fully understanding the importance of the GPS units.

Because I live in a multi-story apartment building, I only have a partial view of the sky. The active "puck" antenna ( I first used three, one for each GPSDO)  is fixed on the window sill just outside the view of the building itself. This view is only East facing and because there is another apartment above me, also only straight up. After months of struggling with my three GPSDO's, swapping OCXO's in and out, and witnessing strange events that I could not explain, I kept on tweaking and changing the hardware. In the process I found several items that I could have done better and I also replaced some components, but I was never really happy with the results. I was also hampered by my lack of understanding and inexperience. After several months of leaving the project alone, and turning my attention to other projects with an attempt to let the OCXO's "age" in the GPSDO hardware, I picked it up again. However, I quickly became pretty frustrated when it turned out that the aging didn't help at all and that I still witnessed the same weird results and significant instability.

By then a lot of it was no longer rocket science for me and I knew a lot more about the whole process. Exasperated, I finally turned my attention to the GPS section. In my three GPSDO's, I used a NEO 6M, an M8N and a M8T GPS receiver. After making some more detailed measurements and observations with the U-center application, it turned out that my NEO versions were not receiving enough satellites with a strong enough signal.

Because my instability of the GPSDO's showed-up over the course of a day, I tracked the GPS modules for at least a day as well. I then noticed that there were serious glitches and drop-outs in the reception over a 24 hour period and this must have been the reason for the weird hick-ups I witnessed in monitoring my three GPSDO's.  I also learned that I needed to update the firmware for the M8N and M8T in order to get access to the Galileo constellation, in order to add more satellites to the mix. The 6M cannot received the Galileo constellation al all, so that version became unusable for me.

Updating the NEO firmware was not that easy, but I figured it out. (that process is described on the EEV blog) With the now updated M8N and the M8T, I started to try various settings, and compare the results. It turned out that due to my limited view of the sky, only the M8T in the stationary and timing mode settings provided a stable and reliable 1PPS pulse. I used the survey mode for 24 hours to get a solid fix on my geo positions, and programmed them into the NEO's. The results were dramatically different for the GPSDO's. All the strange effects, except for one (the Bliley, see below), went away. As a matter of fact, it also showed that the hardware additions to the original design were working really well, the results were suddenly and finally outstanding I thought.

Because I only have one M8T, I installed that into the GPSDO with the Bliley, because initially, that showed the most stable results. The 1PPS output signal of the Bliley GPSDO was then used as an input to the Trimble GPSDO, by feeding the signal into the empty NEO connector on the PCB. The 1PPS output of the Trimble was then used as the input for the Oscilloquartz GPSDO, in effect linking all three units to the same M8T. This allowed me to verify the three units and really compare the results.

The lesson to be learned here is that if you don't have a good 360 degrees view of the sky, the GPS module is the weakest link and that can really ruin your day. You will have to optimize the NEO settings to get the best and strongest reception, use it in the stationary mode, filter out the weak satellites and maybe upgrade the firmware to get access to the Galileo constellation and switch to use a timing version if you can.

The completed GPSDO

The picture below shows the GPSDO using the PCB with the CTI OCXO. All in all, I build three working GPSDO units with different OCXO's so I could compare them.

In the bottom right of the picture is the GPS module. I use an adapter cable to connect the board the an SMA connector on the back-panel. It allows for a quick and reliable connection to the GPS antenna. The front-panel you see here is just a quick-and-dirty prototype to test things. I also designed a PCB that functions as a front-panel, but when I made this picture it didn't come in yet.

The three colored wires you see on the top-left side of the picture are leads that go from three pins protruding through the front-panel and connect to the serial pins, Rx, Tx and GND of the Arduino Nano. They further connect to a Raspberry Pi that runs a small program that logs all the activity in a separate file on a USB stick connected to one of the USB ports on the RasPi. The RaspPi also contains a little email program that sends me the results by email at the end of each day. It allows me to collect a whole day worth of second-by-second status outputs by the controlling program running on the Arduino. That data can be imported into an Excel spreadsheet and analyzed, or processed to be analyzed by a program call TimeLab. TimeLab is a special program that can be used to analyze the stability of oscillators. Both programs are available from my Github site, details are further down below.

What I learned

In the process of trying different OCXO's and learning about the controlling software, the GPS module and the overall performance, I noticed that OCXO's with a thick housing (double enclosure?) such as the Bliley, the Oscilloquartz and the Trimble have, were a lot less sensitive to the ambient temperature changes measured within the enclosure, and also the temperatures in my office.

To further take advantage of that knowledge, I created foam boxes around all 6 sides of the OCXO's to further isolate them from outside temperature effects. I tracked the OCXO temperatures, and found them to be a lot less stable than you would anticipate from a device that has a dedicated oven to heat-up the X-tal parts to a temperature significantly higher than the ambient temperature. I measured OCXO temperatures between 40 and 55 degrees C, with an ambient temperature in the enclosure of between 25 and 35 degrees, in an office with temperatures between 18-28 degrees.

Below is a photo of the Bliley where you can see the (10-15mm) bottom isolation between the PCB and the Bliley itself. I extended the leads of the Bliley so it would protrude through the isolation to the PCB. The LM35 temperature sensor that measures the temperature of the OCXO is clearly visible on the right of the OCXO. It is located within the isolation box, and I also stuff some foam between the leads and the TO92 plastic of the LM35 to add some more isolation from the PCB temperatures. On top of this base, I add the rest of the insulation walls and cover. When you add the walls and the top cover, make sure the connections are without heat leaks.  I used special glue and double sided sticky foam to build the box, but left the top cover free so I could dismantle if needed. I used some bubble-wrap between the insulation box and the top cover, so it all fits snugly.

Just to the left of the Arduino Nano, you can see the other TO-92 package of the ambient  LM35 sensor. This sensor is actually too close to the OCXO, especially with the larger sizes of the Oscilloquartz and the Trimble, so I took it out and extended the leads with 5-8 cm long wires, isolated the connections with some shrink-wrap, while leaving the TO-92 plastic free, and positioned the sensor on top of the D1/C1/R1 circuit, located just to the right of the orange filter capacitor. These components are the most sensitive to temperature changes and will effect the controlling loop of the firmware.

Below is a picture of the Bliley OCXO in it's completed isolation chamber. It still has the ambient LM35 in it's original location, it shows why I wanted to move it out of the way. On the bottom right of the picture you can see the three serial monitor pins:

Temperature effects

Several components, in particular the TIC circuit around R1, D1 and C1 will influence the controlling loop based on temperature. The other components are that of the DAC, controlling the frequency adjustment of the OCXO. The voltage difference between DAC steps can be in the order of microVolts, especially with higher gains. No wonder that temperature has an effect. The last one is obviously the OCXO itself, with the oven that puts the X-tal inside to temperatures as high as 50-60 degrees or more. The sole purpose of this oven is to create a large differential with the ambient temperature so the ambient temperature will have little effect on the X-tal itself. In theory...

During my own observations, I found that the temperature of the OCXO oven is influencing the ambient temperature a lot more than the room temperature does. This is why I decided to add an insulation box around the OCXO's. Even then, the oven temperature is dominant for the ambient temperatures. The room temperature only lowers or raises these "linked" temperatures somewhat.

Here is what I mean.

This shows that over a 24 hour period, the room temperature (in red) only varies by 0,5 degrees Celsius (Max - Min) and is fairly flat otherwise.

Here are the graphs following the Oscilloquartz oven and ambient temperatures. Note that these graphs go from mid-night to mid-night.

I think that this proves that the ambient temperature inside the enclosure is heavily influenced by the OCXO oven temperature. This is why I decided to add the insulation in the first place. Note that these graphs were made with the insulation already in place! The effects were much, much larger without the insulation.

This effect was very different with the OCXO's that have the thin casing, such as the IsoTemp and CTI OCXO's. They were much more influenced by the room temperature changes, even when isolated, which prevented me using them in my environment, where the room temperatures change several degrees, especially in winter.

DAC temperature compensation

Although the effect of the room temperature was negligible at first, but when the room temperature increased during our vacation and the following heat-wave, I could see that the DAC curve started to follow the ambient and OCXO temperature curves. tou counter this effect, I implemented the compensation for the Trimble and the Oscilloquartz. The calculated values for the Oscilloquartz were sufficient, but the Trimble needed a few tweaks by hand before the DAC curve flattened out. 
The Bliley does not need any temperature compensation. The DAC curve shows no sign of a temperature effect.

Note the very minimal DAC adjustments that are needed to keep the frequency aligned, and this is with a gain of 902!
However, after a few days of monitoring, I noticed a strange phenomenon that started to show up on both the compensated OCXO's , theTrimble and the Oscilloquartz. (I found the root cause, described below)

Here are the graphs for the Trimble, after I set the temperature compensation:

Note the Ambient and OCXO oven temperature graphs on the bottom first and compare that to the Oscilloquartz OCXO graph a little higher up. When the temperature drops a bit around 30.000 seconds, there is a sudden and steep rise in the temperature, until about 64.000 seconds when there is a sudden steep drop. This is unrelated to the room temperature! These transitions can also be observed in the ns and DAC graphs. So despite the fact that the DAC graph is much flatter due to the compensation, there are some pretty serious side effects. The Oscilloquartz has exactly the same behavior.

As a first step, to hunt down the issue, I disabled the temperature compensation again.

The above effect was only showing-up during the current heatwave we have. However, this effect also caused me to reconsider boxing in the OCXO's with insulation. It looks as if the OCXO cannot get rid of their generated heat, or they try to maintain a certain delta with the ambient temperature.  Whatever the cause, the stepping-up by 0.5-2.0 degrees is influencing the loop regulation, and therefore the DAC settings, which is not good, see the next topic. 

I have now taken the isolation for the three OCXO's away as much as possible, so only the bottom part remains, or in the case of the Trimble, I could only remove the top. I'm running a new set of tests since I had to restart the systems after the power-down.
After running for a few days without the OCXO's in their isolation boxes, I started to loose the lock frequently. This was the major reason why I implemented the extra insulation in the first place. Since the hick-ups only showed-up during the heatwave, with office temperatures around 30 degree C,   I decided to go back to the insulated OCXO's and take the hick-ups for granted. We only have these very high temperatures during a few weeks of the year.

Since then, the room temperatures dropped a little bit, and I saw less of the hick-ups. 

Temperature compensation results

Consequently, I applied the temperature compensation again. Here are the before and after results:
First is the before, you can clearly see that the DAC follows the OCXO oven temperature.

And above is the after. There is much less of a temperature effect now.

And here are the Oscilloquartz results, first before then after:


Why is the temperature compensation for the DAC so important?

When you don't have the luxury of an atomic clock to your disposal to measure (compare) the accuracy and stability of your DIY GPSDO, you can use TimeLab to characterize your tool. Lars has several examples in his documents, go read them if this is new to you.

The way to use TimeLab to characterize your GPSDO is to collect the DAC values and import them into the tool, while converting them back to a 10 MHz frequency representation. However, this only works when the DAC values have a 1:1 relation to the differences measured against the 1PPS coming from the GPS.

When the DAC values are influenced by things like temperature, this will skew and distort the TIC relationship and hence the TimeLab representation is of less value because it no longer shows the true disciplined OCXO performance and stability.

The OCXO oven temperature can be monitored by Lars' program to get a handle on the temperature based deviations on the DAC, and his firmware can compensate the DAC settings by taking the OCXO temperatures into account.
The idea behind this is to get a DAC curve that is as much as possible devoid from temperature based deviations.

Below is an example of one of my GPSDO's, with the Trimble OCXO. The graphs show the DAC values, the OCXO temperature, the ambient temperature within the enclosure and the ns value coming from the TIC over a 24 hr period. All temperatures show a dip of several degrees Celsius, and you can clearly see that the DAC follows this curve, which will compromise a TimeLab measurement. Note that the ns graph does not follow the temperature curve, and this is a better representation of what the disciplined OCXO does, and what we would like to see represented in the TimeLab graphs.

This shows that it is very important to monitor the OCXO temperature and also find the source of deviations in order to properly compensate the DAC.

Temperature effect when the GPS lock is lost

I noticed a rather strange temperature effect between the locked and unlocked states of the GPSDO controlling loop. When the controlling loop looses lock, The ambient temperature, that I measure close to R1/D1/C1 and the Nano, drops a few degrees. There could be two reasons for this. One is that the lock LED is off, requiring less current. To minimize this effect, I replaced the LED with a high-efficiency version, and increased the series resistor from 200 Ohm to 10K. The other reason can be the Nano itself, because there is less filtering going on when the lock is lost, and therefore the Nano spends less time crunching and more time idling. I have used post #466 on the EEV blog to show this effect. EEV blog post

Bliley OCXO DAC jumps

Although the Bliley only needs a soft feathery touch to the DAC to keep the frequency aligned with the GPS, it's not perfect.
I have noticed very strange "jumps" over the course of several weeks. At first I though that this was a warming-up issue, but even after two weeks, these events still happened. They are different in nature though. Here is a "warming-up" glitch. The DAC values drop and then stay flat.

Here is an event where the DAC values drop or rise, and then come back to the original value. Note that an aberration of about 70 DAC points is only marginally larger than the very common and daily gyrations the other OCXO's need to stay locked. Also note that the ns values stay within the lock margin. It's all very relative, but still. In other words, excellent performance, but not perfect.

The slight aberrations on the DAC after the dip settled and went away after a few days. After monitoring the Bliley for two months after powering-up, the glitches went away and the OCXO was very stable. These jumps from the Bliley are still visible after a cold power-up for a few days though.


I found the root cause of the OCXO temperature jumps!

For several months I have been hunting for the cause of the strange temperature jumps of the three different OCXO ovens I have. For far too long, I suspected the temperature jumps to come from the room or ambient temperatures, or the OCXO oven and this would influence the ns/DAC jumps and so I was hunting in that direction.

I have finally found the root cause.
Below is an example of what happens with my Oscilloquartz version. It is no longer using the full OCXO isolation, to avoid "over-heating" but the whole GPSDO unit is now in an extra enclosure with isolation to avoid sudden room temperature drifts.

These graphs run from midnight to midnight and are sampled every second as they are coming from the Lars firmware. I collect the output by a Raspberry Pi connected to the Txd/Rxd pins of the Arduino Nano. These daily log files are emailed to me.
To see what is going on during the day, I also use a USB-mini cable connected between the Arduino and my PC. I use the Arduino serial monitor to show the second by second Lars' report on my screen.

The cause of the temperature jumps, that literally changes from one second to the next, is due to my PC waking-up from sleep in the morning or going to sleep in the evening. This going to sleep or waking-up will activate or deactivate the power on the USB port of the PC, and hence will apply 5V to the Arduino through the USB serial link, or not.

This is interesting, because I feed a regulated 8V DC to the VIN power input of the Arduino, and I do not have any other logic connected to the 5V and 3V3 power outputs from the Arduino board. I only have a 100uF cap attached to the 5V output, and nothing to the 3V3 output. You would think that the 8V supply and the on-board voltage regulator would sufficiently power the Arduino, regardless of the presence of 5V coming from the USB connection. The Arduino circuit uses a Schottkey diode (D1) to "OR" the on-board regulated 5V supply with the 5V coming from the USB input.

For a reason I cannot explain yet, the Arduino ADC1 and ADC2 inputs that are used to sample the temperatures are influenced when you apply the USB cable with power. You can also see in the graphs that ADC0, used for the TIC input, gets the same treatment, and this influences the TIC measurement (ns graph) and hence the DAC.

Because of the DAC jumps, we have a "falsifying" event in the TimeLab reports.

The solution would be to use a USB cable with the 5V power removed, or remove D1 on the Arduino board. Unfortunately, this diode is located on the bottom of the PCB and is not easy to get to when you already soldered the Arduino on a main PCB, like I did. I could not easily modify the Arduino board so I connected a male and female USB connector together and did not connect the power pin between them.

Contrary to what I first believed the root cause for the OCXO temperature jumps was, it is not caused by the USB power connections (+5, GND or shield), but the data lines (D- and D+). I figured this out by using a break-out board contraption after I isolated the +5V line earlier.

If either one or both of the data lines are connected, both LM35 temperature measurements in the Lars report jump by about 0.5 degrees up when connected and down when not.

It may be related to the Arduino Nano internal reference, but I can't explain that yet, can anybody?  :-//

Using an additional enclosure to reduce room temperature effects

To reduce the room temperature effects on the GPSDO, I have put the Oscilloquartz GPSDO inside a sturdy plastic enclosure. To improve on the insulation, I de-soldered the BNC connectors from the PCB and replaced them by short shielded wires going to front-panel mounted BNC connectors. The aluminum enclosure of the GPSDO was further insulated from the plastic enclosure by bubble wrap and foam. This enclosure also houses the Raspberry Pi that monitors the Lars' program status outputs. To regulate the temperature inside the  plastic enclosure, I installed a small 30 mm 5V DC fan. This fan is controlled by the RPi through a proportional PWM signal that is calculated based on the value of a DS18B20 temperature sensor that is located inside the plastic enclosure. There are a few small ventilation holes in the top front, and the fan is located high-up in the back, creating an air flow just at the top of the enclosure, and not more below where the GPSDO is located. The regulated fan speed will create an inside temperature range that will be small and stable. Right now, after some tuning, the inside temperature is ranging between 32.5 and 33.1 degrees Celsius, several degrees above room temperature, creating a small buffer.


Here are the first results:
The first graph of the temperature inside the plastic enclosure is only a snap-shot to show the temperature swings. Note that the other two temperatures have a low-pass filter applied to the Lars program. The inside temperature is now regulated within 0.6 degrees and therefore the temperature within the aluminum GPSDO enclosure is also stable. The temperature swings inside the plastic enclosure come from the fact that the fan is stopped when the temperature is below the set-point. It was too difficult to regulate the fan speed to keep the temperature constant. That will require a PID type regulation. For now, this method seems to be sufficient. The temperature inside the GPSDO enclosure is now no longer influenced by the room temperature and hence the DAC will finally show the "real" representation of the GPSDO. This is still with a TC of 500 and a gain of 987. Next step is to remove the DAC temperature compensation from the Lars program.

I have tuned the fan controller such that the inside temperature is 33 degrees Celsius, and stays within 0.2 degrees. The GPSDO ambient temperature is very stable at 52 degrees, and the OCXO oven stays at 65 degrees, both within a 0.5 degree window. The inside temperature oscillates within a .2 degrees window due to the proportional fan regulation, with an almost constant room temperature. Higher or fluctuating room temperatures will not be handled well enough, that needs an improved controller.
I need to monitor this behavior for a longer period. Next week we'll get higher outside temperatures again, which will be a good test. The next test will be in the winter-time when the room temperature will drop significantly during the night when we don't heat the room.
I have now implemented a PID algorithm to better control the fan. This is actually the first time I put together a PID, so be aware. The first results are actually very good. I'm now running some long-term tests to see how well it works with larger room temperature swings. Luckily, we have unusually high temperatures at the moment. The latest version (run_fanV2_0) with the tweaked PID parameters is located on my Github site.
I have also ordered two more 30mm 5V fans that I'm going to install in the aluminum enclosures of the Bliley and Trimble GPSDO's. I have high hopes that I can control the ambient temperature within the enclosure better, largely eliminating room temperature effects on the DAC.
UPDATE: when the room temperature changed more significantly, the fan could not keep the Oscilloquartz OCXO temperature flat. There is too much of a delay due to the double separation between the OCXO and the fan. But, it showed me the right way to go forward.  

Temperature controlling the GPSDO enclosure

As a logical next step, I wanted to see if I could control the temperature inside the GPSDO enclosure, and not having to use another, much larger, box surrounding it. The temperature control would be more direct instead of indirect, which would also benefit the temperature critical components of the GPSDO itself.
The whole idea behind this approach is as follows. The OCXO oven, despite sitting in an insulating box, will heat the inside of the enclosure. That heat will eventually leak away through the metal enclosure to the room. This transfer is highly depending on the room temperature itself. If that changes, so will the inside temperature, and so will the OCXO temperature. If we can control the inside temperature, and keep it constant, the OCXO will be presented by en even "outside the insulation box" temperature, and stay constant too. Because the OCXO will always generate heat, we could simply blow-off the excess heat, and keep the temperature stable. To only blow the right amount of excess heat, we can use a temperature controlled fan. The trick is to set the maximum inside temperature level such that there is always a temperature buffer between the inside temperature and the room temperature. If the room temperature drops in the winter when the room is no longer heated, there will be a much larger temperature transfer due to the leakage. The trick is to set the temperature such that it will still run, or very slowly, when this happens. In the summer, when the room temperature can get pretty high, the maximum fan speed should be enough to still keep the inside temperature constant. This may need some tweaking, which is why I modified the firmware to set the controlling parameters for the fan during run-time.
To test that approach, I first modified my Trimble GPSDO. I concocted a simple fan driver circuit, and modified Lars' code to incorporate just the fan controller. Here is a portion of the schematic with the very simple fan driver circuit:

A few things. You cannot use the D9 output from the Arduino, it interferes with the loop, and the result is a stream of "No PPS" messages. Why, I don't know. It took me quite some time to figure out that using D9 was the reason. In any case, D6 works perfectly. I used a small coil and two caps to try to stop PWM pulses from the fan circuit to find it's way back into the OCXO circuits. I used a simple transistor instead of a MOSFET for the same reason. The switching transitions of a transistor are more gradual.
Here is a picture of the fan and the controller board. It only takes a few components.

The 30mm 5VDC fan is installed on the back-panel, and I used two of the mounting screws to also mount the little perf. board with the driver components on it as well. To let fresh air in, I drilled six 6mm holes in the front panel, trying to force the air-flow away from the OCXO. The OCXO itself is still encased in a hard-foam box with about six 10-15mm thick sides. Keep note that the number and size of the input holes are depending on the temperature the OCXO generates. My Bliley has that, so I probably need less, or smaller holes.
The code to extend the Lars' program with this fan drivers is quite simple. I use the ambient temperature sensor as the input, use a low-pass filter to get rid of the notorious jitter of the LM35's and use a text-book PID controller to drive the fan with a PWM signal.

The first results:

The PWM values center around 120 out of a maximum of 255. The amount of air it moves seems sufficient with the intakes that I added. This should give me enough room for higher and lower room temperatures, which are now just shy of 30 degrees during our unusually warm fall temperatures.

The ambient temperature is moving up and down within a 0.6 Celsius window, due to the inertia of the heat transfer system. The OCXO heats-up the inside (ambient) temperature, and the fan tries to regulate it back down to 35 degrees by blowing off the excess. I selected this temperature because it is a few degrees higher than my maximum room temperature together with the surrounding equipment next the the GPSDO's. The regulation takes a bit of time, and so the fan is always a little bit behind, or overshoots. I think this is normal behavior and can be expected of an indirect system. As a result of the now very stable inside ambient temperature, the OCXO temperature is very stable as well. It only varies for 0.3 degrees. 
Because I don't have any experience tuning a PID loop, I tried a few gain values, and after I was somewhat satisfied I gave it a try with the above results. My conclusion is that it's good enough for this purpose, so unless any of you can come-up with better gain values, I'll leave it at that. (I'm still continuing to learn more about PID controllers)
It's safe to assume that with this ambient temperature control, the DAC is now mostly devoid of room temperature changes, and therefore shows a direct relationship to the GPS based time difference (TIC) with that of the OCXO. I will be monitoring the results to see if it also works when we have larger room temperature changes during the winter season. 
When we now analyze the performance with TimeLab using the DAC settings, we have a true representation of the GPSDO performance.
My version of the Lars' program that incorporates this, Version 3.52, is on my Github, the link is below.

After a few days looking at the results, I decided to now also convert my Bliley GPSDO, although it hardly shows any room temperature effects. And I will also modify my Oscilloquartz version again, and take the GPSDO out of the plastic container. The regulation inside this container is even more indirect, so I think I can get better performance with regulating the inside temperature like I do now with the Trimble. It will also remove the requirement of needing a Raspberry Pi and a third sensor, although I'll keep using the RPi for logging purposes.

I have modified my Bliley and Trimble GPSDO's with the fan and the controller. In the meantime, I also sold my Oscilloquartz GPSDO to an interested user. This allowed me to recoup some of my out-of-pocket investments in this project.

New version for the Lars code, V3.60.

While continuing to tune the fan controller, I needed to recompile and restart the units when I changed values. That is very tiresome, and extremely lengthy process because of the restart, so I extended the already existing method that Lars used to now also set the fan controller parameters at run-time. The "info and help" display (f1) incorporates these changes, and so does the display of variables (f2). 
What you can now change on the fly is the minimum PWM setting (u) with an integer value between 0 and 255.
You can also set the maximum ambient temperature (cool_baseline) with the "v" command and use an integer value of degrees in Celsius.
The PID gain settings can bet set with: x for Kp, add an integer that is 10x of what you want, to get one decimal. So use x6 to get 0.6. Use y for Ki and z for Kd with the same x10 values.
Note that these new values are not set in the Nano EEPROM, there is no space left and I didn't want to rearrange the current storage of values that Lars intended. As a consequence, after a reset or reboot, these values will revert back to what is programmed in the code.

Below are the cold startup graphs of the Bliley using the version 3.6 of the software with the standard PID parameters, PWM and temperature settings.

After the PID regulation has stabilized, the Ambient temperature within the enclosure stays at 36.0 degrees, even during the next 24 hours. This is a function of the room temperature regulation, as you can see from the PWM graph, but also of the OCXO temperature stability. After the regulation stabilized, the OCXO now only varied 0.3 degrees initially and after almost 7 hours is now very stable at 50.2 +/- 0.1 degrees during the next 24 hours after this graph. BTW, my Bliley still has the DAC values jumping down a few 100 DAC points every now and then for a few days while warming up.
And here are the results of the Trimble after a cold startup:

Note the snap-shot of the more detailed PWM temperature regulation after the initial startup of about 2 hrs. The resulting ambient temperature stays at 36 +/- 0.1 degrees. The OCXO temperature stabilizes at 48.1 degrees +/- 0.1 degrees. A day later, it centered at 48 +/- .2 degrees. Not as good as the Bliley but still very satisfactory.


I think I've solved this DAC temperature problem, although it remains to be seen what the regulation will be when the room temperature changes a lot more during the winter season.
All the above measurements where made with a TC of 500. My GPSDO's are capable of a lot more as I've seen earlier.
Now that I have the temperature effects eliminated from the DAC values, I can go back and re-do the TimeLab measurements and establish the optimum TC and then do the ADEV/MDEV measurements again and also look at the frequency difference in Hz.. 

Now that everything is very stable, I'm going through the process of revisiting the optimum TC for both GPSDO's and make some more TimeLab measurements.

Finding the optimum TC setting

Here are the TimeLab results of running both GPSDO's with a TC of 4, using method #2 from Lars to determine the optimum TC (page 12 in his document). 

The optimum or what Lars calls a "reasonable" TC can be found at the intersecting slopes from the PPS jitter (down going slope) and the oscillator drift and noise (the part of the slope going back up). 
Note that the slopes of  both curves are just about identical up to 200 seconds. I suspect this is because the Trimble gets its 1PPS from the same NEO M8T located in the Bliley GPSDO and so the PPS jitter is the same. With the TC of 4 seconds, both DAC's follow the GPS and the OCXO deviations precisely, because there is no filtering. 
In any case the optimum TC is approx. 4,000 seconds for the Bliley and approx. 2,500 seconds for the Trimble. I selected a TC of 2,000 for both which should allow me to better compare them.

After running the GPSDO's with a TC of 2,000, here are the results of the second day. It took about 6 hours to get a lock, and even after that, the loop needed some more time to get really stable again.

This seems to suggest that a TC of 2,000 for the Bliley is only a little too high, because you can see small drifting patterns in the ns figures. It is otherwise very stable, and this is with a gain of 902!  For the Trimble the TC is definitely too high. The ns numbers start to oscillate and the DAC needs to follow suit. 
I'm now going to set the TC to 1,500 for both. 
Update, a TC of 1,500 was still too high for the Trimble, I gradually brought it down to 800.
Here is the result of optimizing the TC's for both GPSDO's.

The ns curve for the Trimble is no longer "oscillating" because of the OCXO drift anymore, and so the DAC has less swings to correct it.
So despite the fact that the optimum TC in the TimeLab chart shows a value of around 2,500, the reality is different.
The Bliley based GPSDO is now tuned with a TC of 1,500 and is very stable, apart from some anomalies (outliers) as you can see in the middle of the graph.

Stay tuned, there will be more updates...

Additional developments

To keep this blog is clean and focused as much as possible on the GPSDO, I have created another blog post that deals with the monitoring, measuring and logging of the GPSDO.
This blog, with it's own Github project can be found here.

Using my PCB

If you are interested in obtaining this PCB, I added the required files on my Github site, together with my version of the controlling firmware for the Arduino. Please note that I made some errors with the PCB layout and could have done a few things better when I designed the PCB. The pitfall's are described in the readme file on the Github site.

The Github for this project can be found here :


  1. Hi Paul, great work on the Lars GPSDO. I have built the original circuit and although it works I'd like to try some of your improvements. I don't suppose you still have a PCB available?


  2. Hi Mike, yes I do have one more PCB available for you. The price will be 7 Euro's excluding shipping. Send me a PM with your email and address info, so I can send you a PayPal request.

  3. Thanks Paul. How do I send you a PM please?

  4. Send an email to pw.versteeg at

  5. Hi Paul, you mentioned using TimeLab to characterise the GPSDO. How do you get the frequency from the serial data? In his notes, Lars appears to import the DAC value with a multiplier of 2E-12 as Frequency Difference. I'm not sure I understand that.

  6. You indeed need to import the DAC values into TimeLab using the "import ASCII phase or frequency data". To manipulate the DAC value back to frequency, you need to use a factor. The factor is calculated by dividing 1E-9 by the gain. That number must be entered into the import dialog box in the Numeric Fields. As an example, my Trimble has a gain of 1013. The factor is then 1e-9/1013 = 9.87167E-13.

  7. Excellent, thank you! I've started capturing the data to a Raspberry Pi so now I know how to analyse it. I have ordered a Trimble from eBay but in the meantime I'm testing the circuit with an NDK OCXO that came from an IFR signal generator. I used your circuit for trimming the frequency but can't get the gain above 100. It seems to work well though.

  8. This comment has been removed by a blog administrator.

  9. This comment has been removed by a blog administrator.