Electronics > Projects, Designs, and Technical Stuff

More GPSDO designs

(1/2) > >>

S57UUU:
Hello!

For about a year now, I have been working on a time/frequency reference for my SIDI interferometer. It is still not a finished project, much a work in progress, but I accumulated a lot of material, and decided to publish it. I was writing this as I went along. Later I tried to organized it into sections, etc, but it is still quite bloggy.

Marko Cebokli

MIS42N:
I just read through GPSy Dances, epic story. There are parallels with my own journey, but I haven't gone quite as far.

The development of disciplining algorithms is interesting. My GPSDO is self tuning, it does a calibration run by initially trying the maximum and minimum control voltages and noting the frequency errors. If they were for instance +16Hz at 3V and -8Hz at 0V, it then computes a nominal zero frequency error (in this case 1V) and slope (8Hz/V) then tries to halve the larger error (the +16Hz to +8Hz) by applying 1V+8*1V/8 [the calculated sensitivity] = 2V. Now there is a new pair of values (maybe +9Hz and -8Hz because the slope is not 100% linear) and do it again. The process is repeated (halve the largest) until both are in the region of +0.25Hz and -0.25Hz. This is close enough to the actual frequency to derive a pretty accurate sensitivity and a nominal start voltage. These are stored in non-volatile memory and used on all subsequent starts. The advantage of this approach is it works with any OCXO and caters for +ve or -ve control slopes. (I haven't tried it with a ceramic oscillator with +-50ppm tuning range, but it should handle it - the measuring loop cuts off as soon as the deviation is larger than 256 cycles, or has run for 256 seconds.)

The second thing is the corrections are applied periodically based on accumulated GPS arrival times. The sweet spot with the OSC5A2B02 seems to be 512 seconds (the period has to be 2^n). My best GPSDO is applying corrections of maximum 4*10^-11 (0.4mHz), which is probably as good as one could expect from a cheap OCXO. The algorithm is somewhat complex in that readings are cascaded through a series of accumulators. First, 2 readings a second apart are compared. Then 2 values that are each the accumulation of 2 readings. Then 2 values that are each the accumulation of 4 readings, and so on until comparing 2 values that are each the accumulation of 256 readings. At each comparison there are guard values that, if exceeded, initiate a premature correction. This ensure a lock within 3 minutes of applying power, settle to better than 1 ppb after 15 minutes, usually stops hitting guard values within a day. There is no reason why the logic can't handle much longer periods if the OCXO was stable enough. I have some evidence that a good DOXCO will flywheel for 4096 or even 8192 seconds. Yet to try that.

It looks like you will be buying a u-blox zed-ft9 or similar if you want the timing accuracy you are looking for. I think any single frequency (L1 band) GPS is going to have ionospheric problems. The dual frequency receivers can compensate.

If you think reflections are causing any problems, the quadrafiliar antenna is better than the patch antenna at rejecting them.

S57UUU:
Yeah, it's a bit of TLDR, but I wanted to record all of the blind alleys and dead ends I encountered, so that other people might avoid them.

Characterizing the OCXO on startup is a good way to save the user from loop tuning, especially if many people build it and experiment with various OCXOs. Currently, I am also testing a bunch of different OCXOs and rubidiums, will make another TLDR web page, maybe in a month or two. The CTI OSCA5A2... are in fact not that bad, provided you put them in a benign environment (no air drafts and fast temperature changes). They also have quite low phase noise.

I did not completely understand the second part, the two by two thing (I guess I'll have to take the time and dive into your code someday). If I understood right, you make a binary "tree" of comparisons. But what do you do after each comparison?

In the future, I will probably end up with one of those expensive dual freq receivers (which also need a dual freq capable antenna, etc).  Before that, I'll try the older "T" types, like LEA-6T or NEO-8T, etc - whatever I can get cheaply off the web :-)

Some time ago, I bought a couple of Chinese QFH kits. They contain a PCB,  a SMA connector, and some uncut wire, but no instructions. The length of the arms is very important in the QFH, so I'll have to look in the textbooks.

MIS42N:
I am writing up how the program works, here is a cut and paste about the tree:

The logic for the accumulation is relatively straightforward. It is guided by a count of the seconds over which accumulation occurs, starting at second zero as the second after the last correction. This count is inspected as a binary number: e.g. second 27 is inspected as 11011.
Each second:
1. Place the phase error for the current second in E (for Error), set the level counter L to zero.
2. Counting from the rightmost digit of the counter inspect binary digit number L.
3. If the inspected digit and all digits in the counter to the left (i.e. for more significant levels) of the inspected digit are zero then this is the first value received at this level. Set the “previous accumulated value” (A) = E and go to instruction 6.
4. Otherwise there is a previous accumulated value at this level. Calculate the errors using the previous accumulated value (A) and E as the two values. Test the calculated errors against predefined limits. If either limit is exceeded, initiate a correction. Otherwise, swap values A and E.
5. If the inspected digit is 1, add A to E, increase the level L by 1, return to instruction 2.
6. If the level is for the chosen maximum period (e.g. if applying corrections every 1024 seconds, the chosen level is 10) then initiate a correction, otherwise finish.

With the two values, A and E, the frequency error is proportional to E-A (if the phase hasn't changed between them, then the frequency is right but not necessarily in phase with the reference (the 1pps))

The phase error at the end of the measurement period is proportional to 3E-A [derived from double the average - A+E giving a value proportional to the phase error in the middle of the measuring period and adding the change due to frequency error (doubled) 2(E-A)]

Knowing those values and the sensitivity, a correction is computed.

The 'predefined limits' is a bit arbitrary. I aim to keep the phase error below 1 cycle (quite large), and the frequency error below 10^-9 (1ppb). The large phase error limit is because badly positioned antenna can cause the 1pps to wander quite a bit, and I don't want to trigger a correction unnecessarily. The values are not that important, as long as they cause rapid corrections during warmup but no (or minimal) corrections once warmed up.

I record the phase error (to the nearest 25ns). Over a period of 3 days the 'good' GPSDO did not go outside +-50ns, which may be wandering OCXO or may be wandering 1pps. One person is using an earlier version of the GPSDO to test and adjust a rubidium. Because it is locked, measurement over long periods are still valid. He is still working on it, I'm looking forward to the outcome.

S57UUU:
I tried to write code accordng to your textual description, would the folloing be a good approximation?
When I feed it an error of one on each tenth measurement, it does a correction every five steps.

step0:
do_correction(accumulator); sleep(1);
start:
count=-1;
step1:
error=measure();
level=0;
count++;
step2:
if (count < (1<<level))
{
accumulator=error;    //step3
if (level == maxlevel) goto step0;
goto step1;
}
if (fabsf(error-accumulator) > predefined)  goto step0;  //step4
swap(&accumulator,&error);
if (count & (1<<level))   //step5
{
error += accumulator;
level++;
goto step2;
}
if (level == maxlevel) goto step0;    //step6
goto step1;

The "step" labels correspond to the steps in your description.
I attached the whole program below.