[time-nuts] How to properly characterize 32kHz oscillators manually and with a microcontroller?

Pete Stephenson pete at heypete.com
Mon Jun 27 15:22:49 UTC 2016


Hi all,

I have a few Maxim DS3231 temperature-compensated real-time clock
chips I use for various embedded hobby projects. They're specced to
have an accuracy +/-2ppm between 0 Celsius and 40 Celsius. One is from
a standard, reputable vendor, while a few are from somewhat more
dubious internet sellers. While all the chips work and seem to
maintain reasonable time over a period of a few weeks, it's possible
that some don't meet spec and I'd like to test them and make sure they
do what they're supposed to.

Here's what I've been doing manually, and what I hope to accomplish
using a microcontroller. Any tips are very welcome.

===== Manual Approach =====

I've manually tested a few of the chips using a digital storage
oscilloscope and a Trimble Thunderbolt's PPS output. Here's how I've
set things up:

1. Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)

2. Set the oscilloscope to trigger on the Thunderbolt's PPS output. As
expected, the DS3231's 32kHz output drifts slowly relative to the PPS,
so the pulse train seems to move slowly to the left or right
(depending on the chip) on the scope.

3. Wait until the rising edge of one of the 32kHz pulses is (visually)
lined up with an arbitrary line on the scope's graticule, then start a
timer.

4. Wait until the rising edge of the next pulse drifts to the same
line on the graticule -- that is, it has drifted by one cycle -- and
then stop the timer.

If I'm particularly motivated, I'll watch the scope for longer and
count the time it takes for the clock to drift two or three cycles.

As an example, one of the clocks drifts by one cycle in 120 seconds.

I then calculate the stability as follows:

Stability = (1 cycle / 120 seconds) / (32768 Hz)
= (1 cycle / 120 seconds) / (1 second / 32768 cycles)
= 2.54*10^(-7)
= 0.254 ppm.

Is this right so far? If so, that clock seems to be well-outperforming
the specs.

I've tested a few chips at a few different temperatures (e.g in the
freezer, in direct sunlight, etc.) and they seem to drift faster for a
minute until the chip measures and corrects for the temperature
change, at which case the drift returns to the normal value.

===== Automated Approach =====

The manual approach is handy, but only measures short-term drift and
is subject to errors. I'd like to automate the measurements using a
microcontroller (I'm familiar with AVRs, mainly the ATmega328 and
ATtiny85 using the Arduino IDE, for what it's worth).

My plan was to have the microcontroller count the number of cycles of
the 32kHz clock over a period of time, say 1000 seconds. If all was
perfect, it'd count exactly 32768000 cycles during this time.

I'm a little concerned about the speed at which the pulses need to be
counted. The 32kHz pulses come in every ~30.5 microseconds, and
handling an interrupt on an ATmega328 running at 16MHz takes about
5.125 microseconds[1] plus whatever's done in the interrupt routine
(e.g. incrementing the PPS counter). Would it make sense to use
interrupts for both the PPS counter and the 32kHz counter? Even if the
CPU is doing something, it knows an interrupt is pending so it
wouldn't miss any counts (assuming it could handle the interrupt
before the next one comes in). Alternatively, I could use a tight loop
to see if the pin for the 32kHz signal goes high and just use
interrupts for the PPS pulse. Time-sensitive code on microcontrollers
straddles the edge of my knowledge, so any advice would be
appreciated.

Seem reasonable? Any tips on doing this better?

Cheers!
-Pete

[1] http://www.gammon.com.au/interrupts
-- 
Pete Stephenson



More information about the Time-nuts_lists.febo.com mailing list