PS
Pete Stephenson
Mon, Jun 27, 2016 3:22 PM
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:
-
Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)
-
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.
-
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.
-
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
Pete Stephenson
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
V
Vlad
Mon, Jun 27, 2016 7:26 PM
For very long time, may be Main Frequency (60 Hz) could be utilised.
Say, MCU could count and compare Zero-Crossings and impulses from DS32xx
chips. After several days, you'll see where it goes.
On 2016-06-27 11:22, Pete Stephenson wrote:
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:
-
Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)
-
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.
-
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.
-
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
For very long time, may be Main Frequency (60 Hz) could be utilised.
Say, MCU could count and compare Zero-Crossings and impulses from DS32xx
chips. After several days, you'll see where it goes.
On 2016-06-27 11:22, Pete Stephenson wrote:
> 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
--
WBW,
V.P.
NV
Nigel Vander Houwen
Mon, Jun 27, 2016 7:46 PM
Pete,
Instead of doing this in an ISR, feed the 32KHz into one of the timer/counter inputs, and clock the timer off of that (probably TIMER2), then just have an ISR for the overflow vector. So, when your X bit timer overflows, you can just add that to your total, when you reach your 1000s (or whatever interval you prefer, simply grab the current timer/counter value, add it to what you’ve stored from the overflows, and you have your counts without all the CPU load of an ISR for every cycle of 32KHz.
Nigel
On Jun 27, 2016, at 08:22, Pete Stephenson pete@heypete.com wrote:
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:
-
Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)
-
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.
-
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.
-
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
Pete Stephenson
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.
Pete,
Instead of doing this in an ISR, feed the 32KHz into one of the timer/counter inputs, and clock the timer off of that (probably TIMER2), then just have an ISR for the overflow vector. So, when your X bit timer overflows, you can just add that to your total, when you reach your 1000s (or whatever interval you prefer, simply grab the current timer/counter value, add it to what you’ve stored from the overflows, and you have your counts without all the CPU load of an ISR for every cycle of 32KHz.
Nigel
> On Jun 27, 2016, at 08:22, Pete Stephenson <pete@heypete.com> wrote:
>
> 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
> _______________________________________________
> time-nuts mailing list -- time-nuts@febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.
NS
Nick Sayer
Mon, Jun 27, 2016 8:34 PM
I went through this exercise some time ago with my Crazy Clock.
The Crazy Clock is itself an ATTiny45 clocked with a 32 kHz crystal. I desired to determine the accuracy of the oscillator. I wound up making a purpose-built frequency counter.
First, the device under test gets special firmware that copies the system clock to a pin. The best I could do there is set up a timer to toggle an output on overflow and have it overflow constantly. The result is 16.384 kHz nominal.
The counter is a “backpack” on a 2x16 LCD display (I make a lot of those). The controller is an ATTiny84. 6 of its pins go to the LCD (some shared with the programming interface). The system clock is derived from an external input, which for me is supplied by a GPSDO. The board has a self-biased inverter and DC blocking cap on the input.
The crazy clock interface is a 1.8v LDO to supply power and an input line that goes to the 16.384 kHz output from the DUT. That sample line goes to the ICP pin on the controller.
In the firmware, the timer that has the input capture ability is set to free-run at the system clock frequency. The ICP interrupt reports back the timer delta from the last interrupt. Nominally, you’d expect 16,384 counts. I calculate the delta and accumulate that for 10 seconds before reporting the result on the LCD.
The LCD shows the actual delta, what that means in ppm and the two byte calibration value I write into the DUT’s EEPROM. The DUT’s normal flash code has the ability to trim the system clock by the factor stored in the EERPOM (signed value in 100 ppb units).
I never made this whole thing public, because it seemed to me at the time to be a very specialized item useful to nobody else. But I can cobble together my schematics and firmware. The way I wrote the code, it ought to be easy to have it work for other frequencies (both reference and DUT).
On Jun 27, 2016, at 8:22 AM, Pete Stephenson pete@heypete.com wrote:
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:
-
Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)
-
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.
-
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.
-
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
Pete Stephenson
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.
I went through this exercise some time ago with my Crazy Clock.
The Crazy Clock is itself an ATTiny45 clocked with a 32 kHz crystal. I desired to determine the accuracy of the oscillator. I wound up making a purpose-built frequency counter.
First, the device under test gets special firmware that copies the system clock to a pin. The best I could do there is set up a timer to toggle an output on overflow and have it overflow constantly. The result is 16.384 kHz nominal.
The counter is a “backpack” on a 2x16 LCD display (I make a lot of those). The controller is an ATTiny84. 6 of its pins go to the LCD (some shared with the programming interface). The system clock is derived from an external input, which for me is supplied by a GPSDO. The board has a self-biased inverter and DC blocking cap on the input.
The crazy clock interface is a 1.8v LDO to supply power and an input line that goes to the 16.384 kHz output from the DUT. That sample line goes to the ICP pin on the controller.
In the firmware, the timer that has the input capture ability is set to free-run at the system clock frequency. The ICP interrupt reports back the timer delta from the last interrupt. Nominally, you’d expect 16,384 counts. I calculate the delta and accumulate that for 10 seconds before reporting the result on the LCD.
The LCD shows the actual delta, what that means in ppm and the two byte calibration value I write into the DUT’s EEPROM. The DUT’s *normal* flash code has the ability to trim the system clock by the factor stored in the EERPOM (signed value in 100 ppb units).
I never made this whole thing public, because it seemed to me at the time to be a very specialized item useful to nobody else. But I can cobble together my schematics and firmware. The way I wrote the code, it ought to be easy to have it work for other frequencies (both reference and DUT).
> On Jun 27, 2016, at 8:22 AM, Pete Stephenson <pete@heypete.com> wrote:
>
> 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
> _______________________________________________
> time-nuts mailing list -- time-nuts@febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.
NS
Nick Sayer
Mon, Jun 27, 2016 8:40 PM
On Jun 27, 2016, at 1:34 PM, Nick Sayer nsayer@kfu.com wrote:
In the firmware, the timer that has the input capture ability is set to free-run at the system clock frequency. The ICP interrupt reports back the timer delta from the last interrupt. Nominally, you’d expect 16,384 counts. I calculate the delta and accumulate that for 10 seconds before reporting the result on the LCD.
Correction…
Nominally, you’d expect 10,000,000 / 16,384 counts.
> On Jun 27, 2016, at 1:34 PM, Nick Sayer <nsayer@kfu.com> wrote:
>
>
> In the firmware, the timer that has the input capture ability is set to free-run at the system clock frequency. The ICP interrupt reports back the timer delta from the last interrupt. Nominally, you’d expect 16,384 counts. I calculate the delta and accumulate that for 10 seconds before reporting the result on the LCD.
Correction…
Nominally, you’d expect 10,000,000 / 16,384 counts.
PS
Pete Stephenson
Tue, Jun 28, 2016 8:47 AM
Hi Nigel,
Using the internal timer as a divide-by-256 counter is a clever way of
doing things. Thanks!
I'm not familiar with using the timers as an input, so it looks like I
need to do some light, relaxing reading of the datasheet. From what I
can tell, using timer2 as an input ("asynchronously clocked") requires
that the microcontroller run on its internal RC oscillator rather than
the standard crystal/ceramic resonator since it shares the pins for
the timer input with the crystal.
I think I have some divide-by-n counters in discrete logic lying
around somewhere. As a quick test, I might just use those to divide
down the 32kHz signal by 10 and use a pin interrupt to count the
number of overflows. At the end of 1000 seconds (or whatever), I could
read the counter state. It's likely not as precise as using the
internal timer on the ATmega, and I'd need to make sure I read the
counter state quickly before any pins change, but it should get me
close.
Cheers!
-Pete
On Mon, Jun 27, 2016 at 9:46 PM, Nigel Vander Houwen
timenuts-nigelvh@nigelvh.com wrote:
Pete,
Instead of doing this in an ISR, feed the 32KHz into one of the timer/counter inputs, and clock the timer off of that (probably TIMER2), then just have an ISR for the overflow vector. So, when your X bit timer overflows, you can just add that to your total, when you reach your 1000s (or whatever interval you prefer, simply grab the current timer/counter value, add it to what you’ve stored from the overflows, and you have your counts without all the CPU load of an ISR for every cycle of 32KHz.
Nigel
On Jun 27, 2016, at 08:22, Pete Stephenson pete@heypete.com wrote:
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:
-
Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)
-
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.
-
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.
-
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
Pete Stephenson
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.
Hi Nigel,
Using the internal timer as a divide-by-256 counter is a clever way of
doing things. Thanks!
I'm not familiar with using the timers as an input, so it looks like I
need to do some light, relaxing reading of the datasheet. From what I
can tell, using timer2 as an input ("asynchronously clocked") requires
that the microcontroller run on its internal RC oscillator rather than
the standard crystal/ceramic resonator since it shares the pins for
the timer input with the crystal.
I think I have some divide-by-n counters in discrete logic lying
around somewhere. As a quick test, I might just use those to divide
down the 32kHz signal by 10 and use a pin interrupt to count the
number of overflows. At the end of 1000 seconds (or whatever), I could
read the counter state. It's likely not as precise as using the
internal timer on the ATmega, and I'd need to make sure I read the
counter state quickly before any pins change, but it should get me
close.
Cheers!
-Pete
On Mon, Jun 27, 2016 at 9:46 PM, Nigel Vander Houwen
<timenuts-nigelvh@nigelvh.com> wrote:
> Pete,
>
> Instead of doing this in an ISR, feed the 32KHz into one of the timer/counter inputs, and clock the timer off of that (probably TIMER2), then just have an ISR for the overflow vector. So, when your X bit timer overflows, you can just add that to your total, when you reach your 1000s (or whatever interval you prefer, simply grab the current timer/counter value, add it to what you’ve stored from the overflows, and you have your counts without all the CPU load of an ISR for every cycle of 32KHz.
>
> Nigel
>
>> On Jun 27, 2016, at 08:22, Pete Stephenson <pete@heypete.com> wrote:
>>
>> 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
>> _______________________________________________
>> time-nuts mailing list -- time-nuts@febo.com
>> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
>> and follow the instructions there.
>
> _______________________________________________
> time-nuts mailing list -- time-nuts@febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.
--
Pete Stephenson
TV
Tom Van Baak
Tue, Jun 28, 2016 12:33 PM
Instead of using a timer and ISR, consider clocking the MCU directly from the external 32 kHz signal.
Sample code: http://leapsecond.com/pic/src/pd33.asm
It's a $1 solution; acts like a 4-pin, stand-alone, divide-by-32768 counter; works extremely well.
/tvb
----- Original Message -----
From: "Pete Stephenson" pete@heypete.com
To: "Discussion of precise time and frequency measurement" time-nuts@febo.com
Sent: Tuesday, June 28, 2016 1:47 AM
Subject: Re: [time-nuts] How to properly characterize 32kHz oscillators manually and with a microcontroller?
Hi Nigel,
Using the internal timer as a divide-by-256 counter is a clever way of
doing things. Thanks!
I'm not familiar with using the timers as an input, so it looks like I
need to do some light, relaxing reading of the datasheet. From what I
can tell, using timer2 as an input ("asynchronously clocked") requires
that the microcontroller run on its internal RC oscillator rather than
the standard crystal/ceramic resonator since it shares the pins for
the timer input with the crystal.
I think I have some divide-by-n counters in discrete logic lying
around somewhere. As a quick test, I might just use those to divide
down the 32kHz signal by 10 and use a pin interrupt to count the
number of overflows. At the end of 1000 seconds (or whatever), I could
read the counter state. It's likely not as precise as using the
internal timer on the ATmega, and I'd need to make sure I read the
counter state quickly before any pins change, but it should get me
close.
Cheers!
-Pete
On Mon, Jun 27, 2016 at 9:46 PM, Nigel Vander Houwen
timenuts-nigelvh@nigelvh.com wrote:
Pete,
Instead of doing this in an ISR, feed the 32KHz into one of the timer/counter inputs, and clock the timer off of that (probably TIMER2), then just have an ISR for the overflow vector. So, when your X bit timer overflows, you can just add that to your total, when you reach your 1000s (or whatever interval you prefer, simply grab the current timer/counter value, add it to what you’ve stored from the overflows, and you have your counts without all the CPU load of an ISR for every cycle of 32KHz.
Nigel
On Jun 27, 2016, at 08:22, Pete Stephenson pete@heypete.com wrote:
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:
-
Enable the 32kHz output on the DS3231 and wire it appropriately.
(The 32kHz output shows up on the oscilloscope.)
-
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.
-
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.
-
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
Pete Stephenson
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.
Instead of using a timer and ISR, consider clocking the MCU directly from the external 32 kHz signal.
Sample code: http://leapsecond.com/pic/src/pd33.asm
It's a $1 solution; acts like a 4-pin, stand-alone, divide-by-32768 counter; works extremely well.
/tvb
----- Original Message -----
From: "Pete Stephenson" <pete@heypete.com>
To: "Discussion of precise time and frequency measurement" <time-nuts@febo.com>
Sent: Tuesday, June 28, 2016 1:47 AM
Subject: Re: [time-nuts] How to properly characterize 32kHz oscillators manually and with a microcontroller?
Hi Nigel,
Using the internal timer as a divide-by-256 counter is a clever way of
doing things. Thanks!
I'm not familiar with using the timers as an input, so it looks like I
need to do some light, relaxing reading of the datasheet. From what I
can tell, using timer2 as an input ("asynchronously clocked") requires
that the microcontroller run on its internal RC oscillator rather than
the standard crystal/ceramic resonator since it shares the pins for
the timer input with the crystal.
I think I have some divide-by-n counters in discrete logic lying
around somewhere. As a quick test, I might just use those to divide
down the 32kHz signal by 10 and use a pin interrupt to count the
number of overflows. At the end of 1000 seconds (or whatever), I could
read the counter state. It's likely not as precise as using the
internal timer on the ATmega, and I'd need to make sure I read the
counter state quickly before any pins change, but it should get me
close.
Cheers!
-Pete
On Mon, Jun 27, 2016 at 9:46 PM, Nigel Vander Houwen
<timenuts-nigelvh@nigelvh.com> wrote:
> Pete,
>
> Instead of doing this in an ISR, feed the 32KHz into one of the timer/counter inputs, and clock the timer off of that (probably TIMER2), then just have an ISR for the overflow vector. So, when your X bit timer overflows, you can just add that to your total, when you reach your 1000s (or whatever interval you prefer, simply grab the current timer/counter value, add it to what you’ve stored from the overflows, and you have your counts without all the CPU load of an ISR for every cycle of 32KHz.
>
> Nigel
>
>> On Jun 27, 2016, at 08:22, Pete Stephenson <pete@heypete.com> wrote:
>>
>> 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
>> _______________________________________________
>> time-nuts mailing list -- time-nuts@febo.com
>> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
>> and follow the instructions there.
>
> _______________________________________________
> time-nuts mailing list -- time-nuts@febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.
--
Pete Stephenson
_______________________________________________
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.