Saturday, July 4, 2015

Accurately measuring low frequencies

When I discovered the Crazy Clock accuracy problem, one thing I needed to come to grips with in a hurry was exactly how to characterize the accuracy of the clocks.

The fundamental nature of all measurement is that it's relative. If your universe is confined to two points, you have no way to describe the distance between them. It requires a third before you can say that the distance between A and B is a certain fraction of the distance from B to C. Our definition of time is the best we can do - it's effectively defined as the frequency of the photons emitted by a particular atomic transition. Meaning that our "yardstick" for time is a basic property of the universe. But even so, we can only measure time by comparing the frequency of occurrences against each other, just as we use a yardstick to measure the length of a span by comparison.

So the first task when setting out to characterize the accuracy of a clock is to obtain a standard to which one can make comparisons. For that, the best bang for the buck available for the hobbyist is GPS. GPS receiver modules have PPS outputs whose rising edges are accurate to within 0.01 ppm (that is, ±10 ns). Moreover, they are constantly disciplined by the USAF to insure that whatever drift - however minuscule - they might show is eliminated. The downside is that the PPS output is the only accurate time signal available. The serial timecodes typically are not transmitted with any particular synchronization mark (and for the purposes of accurate time measurement they take a substantial amount of time to transmit), and even if that weren't the case, the typical serial I/O libraries don't do a good job of recording synchronization of incoming characters. And while the PPS signal is very accurate, the fact that it's only 1 Hz also raises some issues.

There are two ways to accurately measure the frequency of a square wave (we'll assume for the moment that the frequency being measured is stable, that we're only interested in the rising edge, so the duty cycle is not relevant, and that the combination of the rise time and our hysteresis of measurement places any jitter well inside our measurement tolerance). You can either accurately count the amount of time between adjacent rising edges, or you can count the number of rising edges that occur over an accurately measured time span.

If the GPS module output was, say, a hyper accurate 10 MHz signal, then we could conceivably count the number of rising edges of the 10 MHz clock between adjacent rising edges of the frequency being measured. If you're measuring a 32.768 kHz square wave, you'd expect to get 10,000,000 rising edges of the timing signal after measuring 32768 rising edges of the sampled signal. Any deviation from that 10 million would be a tenth of a ppm error in the frequency being measured, and you could take that measurement (and average it) every second.

Alas, the output of the GPS module is only one accurate pulse every second. Given that, it's much easier to count the other way - count the number of rising edges of the sampled signal between a certain number of rising edges of the timing signal. The two methods are, in fact, almost the same - you're using one signal as a stopwatch and counting occurrences of the other. Unfortunately, to be able to obtain an accuracy of 0.1 ppm, it takes a great deal longer when counting such a low frequency signal.

In fact, although the original crystal frequency is 32.768 kHz, we can't measure it directly for fear that the measuring apparatus would alter the circuit enough to skew the results. We must use the actual microcontroller in the circuit - running under exactly the same conditions we expect in normal operation - to output a proxy waveform. And the best option we have for that is to have it toggle a pin with every clock pulse. The result of that is a 16.384 kHz square wave. It takes 10:11 (611 seconds) to do enough counting to obtain a confidence level of 0.1 ppm.

But there's a problem there. On the actual clock board, the 32.768 kHz crystal not only supplies the timekeeping synchronization, but it also supplies the microcontroller's execution clock. That means that the program that's measuring the accuracy of the clock actually causes errors, because every instruction takes at least one cycle to process. The ATTiny45 processor can't separate the two, so we have no choice but to attempt to remove the error by using the timer prescaler to desensitize our measurements from the slop introduced by the code execution. In introducing a divide-by-8 prescaler, the measurement now takes more than 40 minutes. This also assumes that the code slop caused in our timing is within 8 instructions on the two paths - one that starts the timing and one that stops it. In practice, I compared the results on the same board between dividing by 8 and the next option of dividing by 64 (which took a bit more than 5 hours and 20 minutes), and the results were within my desired margin of error (0.5 ppm).

So that works, but 40 minutes isn't very efficient. It'd be much better to get back up to the 10 minute measurement theoretically possible. This, however, requires using a faster controller so that the code slop doesn't cause timing problems. A 16 MHz part would be able to run nearly 1000 single-cycle instructions between rising edges of a 16.384 kHz signal. So using a separate processor is clearly the way to go. And because we're using an external reference (the GPS PPS signal), the clock frequency of the controlling processor isn't at all critical. It merely needs to be fast enough to insure that an interrupt service routine has enough time to accurately count both sources without missing any.

The downside of using an external jig is that it won't be able to record the result directly in the target device (in actual fact, it's conceivable that the jig could perform an AVR ISP operation to write the result directly to EEPROM once it's done. A future jig might include this). So we need to output it in some way. A 2x16 LCD will do nicely. The completed jig will have an LCD display, a "start" button, a 2.1mm barrel connector for 6-12 volt power, the GPS module, along with an LED for the "FIX" line so you can see at a glance that the GPS is locked, a u.FL jack for an external GPS antenna, and a 3 pin test clock terminal with 1.8 volt power (to simulate a AA battery), the sampling pin and ground. You connect the clock up to it, press start, and 10 minutes later, the display will show the error in ppm and as a two byte correction factor ready to be programmed into EEPROM. Just to hedge my bets, I'm going to connect the serial lines of the GPS module up to the serial port of the ATMega. This way, if there's any programming that becomes necessary for the GPS module, I could upload a sketch to perform it.

No comments:

Post a Comment