Sunday, September 20, 2015

FE-5680A Breakout board users guide

This is the permanent home for the user's guide for the FE-5680A breakout board.

The FE-5680A is a Rubidium frequency standard widely available used on eBay. It has a DB-9M receptacle as its interface to the outside world and requires +15 VDC @ 1A and +5 VDC at ~100 mA to operate. This breakout board supplies both of those from a 20+ watt 16-24 VDC input - easily obtainable from a surplus laptop power adapter.

In addition to the 2.1mm barrel connector for input power, there is a two pin SIP header footprint on the bottom of the board which can be used as an alternative. There's also a 2 pin SIP header on the top of the board with the RF output, and a 4 pin SIP header that carries the PPS and RS-232 signals. Lastly, there is an LED in the corner of the board that indicates that the module has obtained a physics lock.

The 2 pin and 4 pin SIP headers bring the respective interface pins from the module directly out with no conditioning or other circuitry. The LOCK LED is buffered by a transistor so as to not unduly load the respective module pin (doing so can prevent the PPS signal from working). The pinouts of the various models of FE-5680A vary quite significantly, and the pin labels are nominal ones for the most frequent case.

Some 5680As do not require an external 5 volt power supply. If yours is one, then take an Xacto knife and cut the trace running between the two pads of the solder jumper immediately adjacent to the interface connector. Be careful to not cut any adjacent traces on the board. Keep the knife blade only between the jumper's pads.  If you need to re-enable the +5 supply you can solder the jumper closed again.

Note that both the 5680A and portions of the breakout board (particularly around the +5 LDO) will get quite hot during operation. This is normal. In particular, the module is internally heated to insure stability of its internal oscillator. Attempting to dissipate this heat will simply make more work for the oven.

DB-9 pinout

  1. +15 V supply
  2. ground
  3. !LOCK (low means lock achieved)
  4. +5 V supply
  5. ground
  6. 1 PPS
  7. RF out
  8. RS-232 serial in
  9. RS-232 serial out


Sunday, July 26, 2015

GPS Disciplined Oscillator User Guide

This is the permanent home for the GPS Disciplined Oscillator User Guide.

  • v1.0 - original prototype design
  • v1.1 - Change from an ATMega328p controller to an ATTiny4313
  • v1.2.1 - Add a buck converter to replace the LDO regulator
  • v1.4 - Numerous power bus cleanup and stabilization fixes, the return of the LDO, and change the buffer amp to an inverting compression amp to increase DAC granularity.
The GPS Disciplined Oscillator board is an extremely accurate source of a 10 MHz LVCMOS square wave. This can be used as a calibration source or an external reference for any number of different pieces of lab equipment, or can even be used as a master clock for microcontroller projects that require extreme clock precision.

At the heart of the board is a VCTCXO that has an inherent short-term stability of ±1 ppb. However, the fixed frequency variant of this oscillator only has an initial accuracy of ±1000 ppb. For applications where both the accuracy and stability are important, using a "steerable" oscillator with feedback from an external reference is preferable. GPS offers an extremely accurate and cost effective synchronization source, however typically only a 1 PPS signal is available (though that 1 PPS signal is within ±10 ppb). This board uses a microcontroller to observe both the oscillator output and the PPS signal and tune the oscillator so that it emits as closely to an exact 10 MHz as can be measured. When a full lock is achieved, the output will be within ±1 ppb in both accuracy and stability.

The power supply should be 6-9 volts DC and capable of supplying at least 350 mW. There are three LEDs on the bottom right corner of the board. They are labeled FIX, 0 and 1 (0 and 1 may be labeled GPS and LOCK, respectively, on the board but they have been renamed). The FIX LED comes straight from the GPS receiver. At startup, or if the fix is lost, it will blink once per second. When a fix is (re)acquired, it will begin to blink once every 10 seconds. The 0 and 1 LEDs will blink back and forth when the GPS fix is lost. If they're not blinking, then they form a binary number 0-3, which correspond to fix quality indications of "bad," "good," "better," and "best." Over the previous 1000 second timespan, "bad" is > 50ppb of error, "good" is 5-50 ppb, "better" is 1-5 ppb and "best" is <=1 ppb.

There are three independent output ports. Each outputs a separate copy of the same signal. The output is an LVCMOS (3.3v) 50% duty cycle square wave. This output can be fed, if desired, into 50 ohm coax. If you wish to have an approximately 1v p-p sine wave instead, then a Pi network can be constructed with a 15 MHz roll-off to eliminate all of the harmonics in the square wave output. Each output is identical, and separately buffered. When fed into a 50 ohm termination, the square wave should have a high-to-low range of around 1.5v.

The GPS module has an internal patch antenna, but if you need to connect an external antenna, then there is a U.FL connector on the board that can be connected to a pigtail for whatever connector your antenna presents. The antenna will be fed 3.3 volts at up to 25 mA. In order for the external antenna to be recognized, it must present a DC load of at least 200 ohms.

The operating temperature range of the board is 0-70°C. Rapid temperature swings should be avoided for best frequency stability.

If you need to upgrade the firmware, there is a pogo pin AVR ISP connector on the right side of the board. Your programmer must be able to program at 3.3 volts. DO NOT APPLY 5 VOLTS TO THE PROGRAMMING PORT OR PROGRAM WITH 5V LEVELS! You will likely irreparably damage either the oscillator or the GPS module (the two most expensive components).

There is a 4 pin diagnostic header on the board. It has a ground pin, two 3.3v async serial lines and a PPS output. One of the serial lines is the transmit data pin from the GPS module, the other is the transmit data pin from the controller. The controller transmit pin is tied to the GPS module receive pin (and vice-versa) as well as the diagnostic port. With normal firmware, the controller will not transmit anything. The GPS data will be at 9600 bps and can be tapped for other purposes, if desired. The PPS output is buffered. The rising edge will, in principle, be synchronized to the GPS second, but the output buffer will introduce a few ns of latency. It's recommended, therefore, that this be only used as a frequency standard, rather than a timing output (the latency should be fixed length given a fixed load).

When the "best" lock indication is present on the LEDs, you can expect the Allan deviation for all tau to be 1e-9 or better. Typical performance levels are between 1e-10 and 4e-10 for tau 6e-1 through 1e3, and then (with the PLL firmware) proceeding downwards from there. No representation or assertion is made about the phase of the output relative to GPS, only the frequency.

After power is applied, it may take the GPS receiver up to a minute (assuming good GPS reception) to obtain a 3D fix (as indicated by the change from once-per-second blinking of the FIX LED to once every 10 seconds, plus the 0 and 1 LEDs changing from blinking back and forth to extinguishing). If you put a backup battery in the holder on the board, this should be reduced to only a few seconds after power-up. Once a GPS lock is indicated, it will take 1000 seconds (16 minutes, 40 seconds) to sample the clock relative to the GPS PPS signal enough times to indicate lock quality with confidence. If the system had obtained a previous lock, then it should be able to quickly stabilize and show indications of a lock right away. If not, then a lock may take upwards of 60 minutes to achieve and hold, depending on the initial calibration of your particular oscillator and GPS reception. If the GPS fix is lost, then this procedure must take place before the 0 and 1 LEDs will light. In general, the lock indicator is a pessimistic view. The oscillator will likely be more accurate than is indicated.

Note that the oscillator is sensitive to movement. If you move it while it's operating, you can expect the next sample to show some drift and the LOCK light potentially to back down to poorer lock indications.

The actual feedback loop of the oscillator operates over 100 second periods. The error granularity over that time is 1 ppb. Most of the time, the train of samples will show 1 unit fluctuations centered around zero. That causes single unit fluctuations of the trim value, which cause adjustments of approximately 200 ppt.

Theory of operation

At the heart of the system is a voltage controlled, temperature compensated crystal oscillator running at 10 MHz. The voltage control pin has a range of 0.3-3.0 volts and swings the output frequency ±10 ppm. This voltage must be kept as linear, stable, and noise-free as possible. The output of the DAC is fed into an OP amp configured as a compression amp - an inverting, less-than-unity amplifier with a 1.65 volt virtual ground. The resulting transfer equation is Vout = -0.5*(Vin-1.65) + 1.65. This results in a range of 2.476 volts (DAC value 0) to 0.825 volts (DAC value 0xffff), for a tuning range of roughly ±6 ppm in 200 ppt steps. The input impedance of the oscillator is 100k, so there is a 10k resistor to act as an added load for the amp. Between the amp and the DAC is a simple RC low-pass filter to try and further limit noise. The DAC is a 16 bit serial DAC. Its default power-up state is to output a mid-range voltage. To insure that the DAC is not accessed while the controller is being programmed, there is a pull-up resistor on the !SYNC line (which is effectively a chip-select line). This is necessary because during programming the output from the controller will be floating.

The output of the oscillator goes into a 1:4 fan-out buffer (with a loading capacitor to bring the load on the oscillator to its rated requirement of 15 pF). One of the outputs of the buffer goes into the clock input line of the ATTiny4313. The other three are presented as outputs, after going through an impedance resistor (to absorb reflected power from impedance mismatches).

The ATTiny4313 is directly clocked from one of the fanout buffer's outputs. Its internal timers are therefore clocked at this frequency. The ATTiny4313 has an input capture capability, where the present value of the 16 bit timer can be "captured" on a rising edge of its ICP pin. This also causes a capture interrupt. The ICP pin is fed from the GPS module's PPS pin. The firmware will effectively count how many cycles of the 10 MHz clock occur between each PPS rising edge. Adjustments in the oscillator frequency will be made in response by writing differing values to the DAC, resulting in changes to the feedback voltage.

The serial port of the GPS module is also connected to the controller. The controller watches for NEMA $GPGSA sentences and looks for an indication of a proper 3D fix. If the GPS is not 3D locked, then it will be ignored and the system will hold-over until it comes back.

The entire system is powered by a LT1117 LDO. The system requires a maximum of approximately 50 mA @ 3.3v (not counting any power required by an external GPS antenna). A 100 mA @ 6VDC power supply is recommended. Higher voltages will simply cause the regulator to dissipate more power as heat. In order to insure that the power to the oscillator and analog sections of the board are as stable and constant as possible, there are separate branches with very wide traces taken directly from the LDO output terminal to both the oscillator (and it's bypass / filter network) and the analog section. From the oscillator branch, a fork splits off to feed the digital section, but only after going through a 47 ┬ÁH inductor, intended to prevent current fluctuations in the digital section from affecting the analog and oscillator supplies.


Thursday, July 23, 2015

A GPS disciplined oscillator

I've started a new project over on Hackaday... It's for a GPS disciplined OCXO. What it does is make a 20 MHz LVCMOS square wave that you can use as a reference for other projects or devices in your lab. Although I went with 20 MHz, a lot of lab test equipment works better on 10 MHz, so I plan on building at least a variant (if not the only version) that outputs 10 MHz.

Check out the work in progress over on!

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.

Wednesday, June 24, 2015

Crazy Clock accuracy problems

I've discovered a design flaw in the Crazy Clock. The result of this flaw is that the clock fairly consistently gains time at a rate of ~120 ppm. That's around ten seconds fast per day. The clock is supposed to stay within 10 ppm - more than an order of magnitude better than that.

Fortunately, the error is consistent in the samples I've taken, and can be corrected in software.

If you've got an affected clock, there are two ways to fix it:

1. If you're very confident in your surface mount soldering skills, you can add a 12 pF capacitor between each lead of the crystal and ground. I do not recommend attempting this, as there's very little room on the board, and almost no margin for error. If you ruin your board attempting this, I won't replace it.

2. The new SW_TRIM facility can be used to trim the clock frequency to compensate for the error. To do this yourself, fetch the firmware from github, compile it with -DSW_TRIM and reflash the controller. After doing that, you'll also want to set the trim factor in EEPROM. It's located at address 4 and is a two byte, two's compliment, little endian integer representing the amount of adjustment in tenths-of-a-ppm. Positive values slow the clock. The standard correction factor for this error is 0x490, or 116.8 ppm slower. The avrdude argument to achieve this is "-U eeprom:w:0xff,0xff,0xff,0xff,0x90,0x04:m". If you do this, you'll wipe out the PRNG seed at locations 0-4, so if your clock has random behavior, you should replace each of the '0xff' in that command with four random numbers from 0-255. There's no harm in not doing this, really, but your random number generator will wind up starting from a "standard" state, resulting in repeated behavior the first time you power the clock up. Don't forget that the system clock speed is 32.768 kHz, so your programming SPI clock must be no faster than 4 kHz. Achieve this by adding either -i 125 or -B 250, depending on your programmer.

If you have an affected clock, you may ship it back to me and I will apply the fix and return the clock to you for free (including shipping to get the clock back to you). If you bought a complete movement, return just the movement - keep the hands and face and stuff. If you bought a controller only, then please return just the controller. In both cases, you'll get a replacement, not necessarily the same one you send. Please be sure to indicate which firmware style you wish. To proceed, contact me with the contact form and I'll send you the address to ship your movement or controller.

Friday, June 19, 2015

Sidereal clock movements

The Crazy Clock has been out there for a while, and one of the firmware options for it for almost as long has been the Sidereal clock. In looking around the Internet, I've found sort of a background rumble of interest in Sidereal movements for astronomers.

For those who aren't aware, the 86,400 second long "day" we know is more precisely a "tropical" day. It's the amount of time (roughly) it takes for the sun to go from the local meridian (the north-south line passing through the zenith - the highest point it reaches) on one day to return to the meridian on the next day. A sidereal day, on the other hand, is the amount of time it takes a star to go from the meridian on one day to the meridian the next day. The two are not the same amount of time, because at the same time that the earth is rotating on its axis, it is revolving around the sun. Over the course of a tropical year (the time it takes for the Earth to return to the same point in its orbit), the revolution adds an extra rotation. So a sidereal day is 1/365.2425(ish) shorter than a tropical day. That works out to 3 minutes, 56 seconds (that's not exact, but it gets us to inside of the 10ppm tolerance of the clock movement, which is enough).

If you combine a 24 hour clock movement with a sidereal controller, you wind up with a very special clock for astronomers. If you superimpose a star chart for your hemisphere, centered on the pole, the hour hand will always point to the star or constellation passing through the meridian (as long as you set the clock to local apparent sidereal time). It's this property that makes 24 hour sidereal movements valuable for building things like automatic astrolabes.

So for those looking, pre-built, ready-to-use 24 hour sidereal clock movements are available from my Tindie store. Just select the pre-built 24 hour movement with the sidereal firmware. They're in stock now!

Wednesday, June 10, 2015

AVRDUDE with linuxgpio and least privilege: don't sudo

The principle of "least privilege" is a valuable practice. Far too many people just put "sudo" in front of everything when they're using *nix - particularly on the Raspberry Pi, which is often thought of as a sort of throw-away computer.

Fortunately, the Raspberry Pi folks were thinking ahead a bit and created the "gpio" group and rules in devd to set the ownership of the GPIO nodes in /sys so that you don't have to be root to use them - you just have to belong to the correct group.

There is one "gotcha" to this, however. To understand it, we need to look at how GPIO functions on the Raspberry Pi.

In /sys, there is a GPIO class - that is, a directory - at /sys/class/gpio (that's not actually where it is, but there's a symlink there, so for our purposes, we'll just say it's there). Inside that directory, there are two nodes "export" and "unexport". To take control of a GPIO pin, you open "export" and write the pin number there. When you do, a new directory will show up named "/sys/class/gpio/gpioX/" where X is the GPIO number. Inside that directory will appear a bunch of nodes that will allow you to take control of the pin.

The gotcha, however, is that the kernel driver doesn't know anything about the "gpio" group. It sets the ownership of all GPIO nodes to "root:root" and "rw-r--r--" (0644). devd comes along at some time after the nodes are created and resets the permissions so that the nodes are writable by the gpio group. Normally this isn't a big deal because most of the nodes in /sys are created when the driver is probed, usually at boot. But in this case, avrdude attempts to export the GPIO pins, and then immediately set their direction. If it does so too quickly, it will get EACCESS attempting to open /sys/class/gpio/gpioX/direction.

People have so far worked around this by simply running avrdude as root - either by prefacing it with "sudo" every time or by making the binary suid as root. These are bad ideas. If for no other reason, if you ask avrdude to read from the chip and write to a new file, that file will be owned by root, rather than by the user running avrdude.

One quick and dirty solution to the problem is to introduce a short delay between the export operation and the rest of the initialization. But more to the point, the delay must also yield the CPU so that devd gets a chance to run. To that effect, my patch just uses "sleep(1)". It's probably too long a delay, but it works consistently.

Another way to go is to remove the export and unexport operations from avrdude and instead leave the pins permanently exported, exporting them from some sort of script possibly run at boot. This is safe to do, since the linuxgpio driver in avrdude is careful to set all the pins as input before exiting, which will return them to high impedance state. I haven't implemented this change, but it would allow avrdude to run faster since there would not be a 1 second delay every time.

To proceed, download AVRDUDE 6.1 and apply this patch. Then build as usual. Having done so, you can now either make avrdude sgid and set its group to gpio, or - probably better - add yourself to the gpio group. No more sudo!