Monitoring an accurate clock

Hi all..the number of replies has caught me out a little. However I have read them now and hope I understood the comments.

First comment is about the Arduinos inbuilt oscillator. It's referred to as a resonator, and somewhere, compared to a crystal. I've now googled and found that a resonator is a low cost ceramic device as apposed to a quartz crystal. What a pity a few pennies/cents were saved there !

In #8 jboyton describes accurately measuring 1 second periods by concurrently measuring the gps 1pps as a control. That sounds like an interesting approach which perhaps I couldd also use as I can extract 1pps from one of the the pendulum optos. But the position of the pulse is different on alternate swings as the sensor is off-centre. perhaps the gps could be divided by 2 and a 2 second period measured ?

I now have an insight into interrupts. Thanks. Absolutely easy to figure in a computer running multiple tasks. Not quite sure about a 1 task micro with only one task in hand. No worries...it will come clear !

In the profile set up I have repeatedly entered my website url and page name. But it never stays, However until I've cracked that, here it is. A DIY Free Pendulum, Hipp Toggle master clock.

Thanks .... Roger

Roger,
the variation of distance between the rod tip and the magnet can be a source of error?
Because I see in the photo that you tied the pendulum to the wood case and I believe that wood can vary it's lenght.

zoomx:
Roger,
the variation of distance between the rod tip and the magnet can be a source of error?
Because I see in the photo that you tied the pendulum to the wood case and I believe that wood can vary it's lenght.

zoomx ..I have replied by PM to avoid the thread going off topic...Roger

cornishlad:
But the position of the pulse is different on alternate swings as the sensor is off-centre. perhaps the gps could be divided by 2 and a 2 second period measured ?

I thought you said you needed to measure a pulse with a 30 second period? One second or two seconds would be less problematic. I have a simple script to measure 1 second pulses (since most RTCs output 1 Hz square wave it's an easy way to measure their accuracies).

By the way, thanks for posting the link to your project, it looks like fun.

to get this high in accuracy you will need a counter higher as 10 000 000 or a simple solution:
lets say the gps is infinit precise, when you get a pulse start counter when you get a clock signal subtract the counter value you have from the pulse counter.
meaning you count the difference in pulses between both counters, the length of measurement is not imoortant is better for resolution.

I started off thinking along those lines because the clock outputs a pulse every 30 seconds..I believe it was your earlier post that made me think that there may be other approaches. I'm not fixed on any particular approach and after all this is the section for project guidance. The pendulum has a feed to the divider board of 1pps. And I have the 1pps from the gps receiver already.

I thought, probably erroneously, that measuring over a 30 second period may be more accurate but that's probably wrong. If you have a scheme based on a 2 second period that you would be prepared to share I'd be pleased to try it.

I don't think I could adapt to actual 1 second pulses for the reason I mentioned. There is no way to get a pulse that's absolutely positioned centrally and be the same on the rightward and leftward swing. But the timing between two rightward or two leftward pulses accurately represent the clock rate !)
@ shooter. you posted while I wrote ! I'll reply asap R
Roger

Roger, I don't know what the best solution is. Maybe a frequency counter is the way to go. How accurate is a typical frequency counter?

I don't have a counter or an oscilloscope, just an Uno and a GPS. I wanted to be able to measure the accuracy of real-time clocks as they varied with temperature so that I could write software to compensate for the error. I wrote a sketch to do this and it appears to be able to measure an interval to an accuracy of better than 1us.

Here's output from the sketch. The first value is the number of Uno processor clocks in one GPS second. The second number is the error in parts per million (or microseconds since it is a 1 second period) for the Uno resonator. The third value is the number of Uno clocks per RTC period. And the last value is the error in the RTC as compared to the GPS time. As you can see, the Uno runs about 0.1% slow. The RTC is much better, using a 32.768kHz crystal and carefully chosen capacitors. It is only about 3ppm slow at 24°C.

Hello

Resonator                  1Hz pulse
cks/GPSsec    error        cks/GPSsec    error

15982844 cks, -1072.3 ppm, 15982894 cks, -3.1 ppm
15982839 cks, -1072.6 ppm, 15982890 cks, -3.2 ppm
15982839 cks, -1072.6 ppm, 15982891 cks, -3.3 ppm
15982839 cks, -1072.6 ppm, 15982890 cks, -3.2 ppm
15982838 cks, -1072.6 ppm, 15982891 cks, -3.3 ppm
15982839 cks, -1072.6 ppm, 15982890 cks, -3.2 ppm
15982837 cks, -1072.7 ppm, 15982888 cks, -3.2 ppm
15982837 cks, -1072.7 ppm, 15982890 cks, -3.3 ppm
15982838 cks, -1072.6 ppm, 15982888 cks, -3.1 ppm
15982838 cks, -1072.6 ppm, 15982890 cks, -3.3 ppm
15982838 cks, -1072.6 ppm, 15982888 cks, -3.1 ppm
15982837 cks, -1072.7 ppm, 15982890 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982887 cks, -3.1 ppm
15982837 cks, -1072.7 ppm, 15982890 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982888 cks, -3.2 ppm
15982838 cks, -1072.6 ppm, 15982892 cks, -3.4 ppm
15982838 cks, -1072.6 ppm, 15982887 cks, -3.1 ppm
15982837 cks, -1072.7 ppm, 15982890 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982887 cks, -3.1 ppm
15982837 cks, -1072.7 ppm, 15982891 cks, -3.4 ppm
15982837 cks, -1072.7 ppm, 15982887 cks, -3.1 ppm
15982836 cks, -1072.8 ppm, 15982889 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982887 cks, -3.1 ppm
15982837 cks, -1072.7 ppm, 15982890 cks, -3.3 ppm
15982836 cks, -1072.8 ppm, 15982887 cks, -3.2 ppm
15982837 cks, -1072.7 ppm, 15982888 cks, -3.2 ppm
15982836 cks, -1072.8 ppm, 15982887 cks, -3.2 ppm
15982836 cks, -1072.8 ppm, 15982888 cks, -3.3 ppm
15982836 cks, -1072.8 ppm, 15982887 cks, -3.2 ppm
15982837 cks, -1072.7 ppm, 15982889 cks, -3.3 ppm
15982836 cks, -1072.8 ppm, 15982890 cks, -3.4 ppm
15982836 cks, -1072.8 ppm, 15982885 cks, -3.1 ppm
15982835 cks, -1072.8 ppm, 15982889 cks, -3.4 ppm
15982836 cks, -1072.8 ppm, 15982888 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982887 cks, -3.1 ppm
15982836 cks, -1072.8 ppm, 15982888 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982888 cks, -3.2 ppm
15982837 cks, -1072.7 ppm, 15982890 cks, -3.3 ppm
15982836 cks, -1072.8 ppm, 15982887 cks, -3.2 ppm
15982838 cks, -1072.6 ppm, 15982891 cks, -3.3 ppm
15982838 cks, -1072.6 ppm, 15982889 cks, -3.2 ppm
15982839 cks, -1072.6 ppm, 15982890 cks, -3.2 ppm
15982838 cks, -1072.6 ppm, 15982893 cks, -3.4 ppm
15982839 cks, -1072.6 ppm, 15982888 cks, -3.1 ppm
15982838 cks, -1072.6 ppm, 15982891 cks, -3.3 ppm
15982838 cks, -1072.6 ppm, 15982890 cks, -3.3 ppm
15982837 cks, -1072.7 ppm, 15982888 cks, -3.2 ppm
15982838 cks, -1072.6 ppm, 15982890 cks, -3.3 ppm
15982836 cks, -1072.8 ppm, 15982887 cks, -3.2 ppm
15982835 cks, -1072.8 ppm, 15982887 cks, -3.3 ppm
15982836 cks, -1072.8 ppm, 15982885 cks, -3.1 ppm

The sketch isn't perfect. Because it doesn't deal with timer overflows in a robust manner there is an occasional misreport. But since I use it to manually monitor/measure the error I don't care. It could be made more robust. It could also be made to measure over 2 seconds. Here it is, for what it's worth:

// Check processor clock and 1Hz pulse (from any source) accuracy against GPS
//
// Connect the GPS shield via 5V, GND.
// Connect the PPS signal to the input capture pin as defined below.
// Connect the 1Hz pulse output (don't forget a ground wire) to the pin defined below.


#define PPS_INPUT_PIN         8	  // 328 pin 14 (input capture)
#define SQW_INPUT_PIN         2

// Pin operation macros
#define INPUT_PORT(pin)       (pin < 8 ? PIND : (pin < 14 ? PINB : PINC))
#define OUTPUT_PORT(pin)      (pin < 8 ? PORTD : (pin < 14 ? PORTB : PORTC))
#define PIN_MASK(pin)         (pin < 8 ? 1<<pin : (pin < 14 ? 1<<pin-8 : 1<<pin-14))
#define SET_PIN(pin, level)   (level == LOW ? (OUTPUT_PORT(pin) &= ~PIN_MASK(pin)) : (OUTPUT_PORT(pin) |= PIN_MASK(pin)))
#define PIN_IS_LOW(pin)       ((INPUT_PORT(pin) & PIN_MASK(pin)) == 0)
#define PIN_IS_HIGH(pin)      ((INPUT_PORT(pin) & PIN_MASK(pin)) != 0)

volatile uint16_t captureTicks = 0;
volatile uint16_t captureRolls = 0;
volatile uint16_t rollovers = 0;
volatile bool captureFlag = false;

uint32_t prevCaptureTime = 0;
bool first = true;

// =======================================================================================
ISR (TIMER1_CAPT_vect)
{
  captureTicks = ICR1;
  captureRolls = rollovers;
  captureFlag = true;
}

ISR (TIMER1_OVF_vect)
{
  rollovers++;
}
// =========================================================================================

void setup()
{
  Serial.begin(115200);
  Serial.println("\nHello\n");
  Serial.println("Resonator                  1Hz pulse");
  Serial.println("cks/GPSsec    error        cks/GPSsec    error\n");
  
  pinMode(SQW_INPUT_PIN, INPUT_PULLUP);    // requires a pull-up for DS1307
  pinMode(PPS_INPUT_PIN, INPUT);

  
  // Set up timer 1 for input capture of PPS signal
  TCCR1A = 0;            // reset timer1
  TCCR1B = 0;             
  TCNT1 = 0;
  TCCR1B = bit(ICES1) | bit(CS10);       // prescale=1; capture on rising edge
  TIMSK1 = bit(ICIE1) | bit(TOIE1);      // enable capture interrupt; enable overflow interrupt
}
// =========================================================================================
uint8_t cnt = 0;
uint16_t prevRtcT0, prevRtcRolls;
void loop()
{
  uint16_t mvTemp;
  float vcc;
  uint16_t rtcT0, rtcRolls;
  uint32_t rtcElapsed;

  if (PIN_IS_HIGH(SQW_INPUT_PIN)) {                  // if pulse output is high
    while (PIN_IS_HIGH(SQW_INPUT_PIN)) {}            // wait for it to go low
  }
  TIMSK0 = 0;                                        // disable timer 0 overflow interrupts
  while (PIN_IS_LOW(SQW_INPUT_PIN)) {}               // now wait for it to go high
  rtcT0 = TCNT1;                                     // get a timestamp
  rtcRolls = rollovers;
  TIMSK0 = 1;                                        // reenable timer 0 interrupts
 
  rtcElapsed = uint32_t(int32_t(rtcT0) - int32_t(prevRtcT0) + (uint32_t(rtcRolls - prevRtcRolls) << 16));
  prevRtcT0 = rtcT0;
  prevRtcRolls = rtcRolls;

  if (captureFlag) {
    uint16_t t = captureTicks;
    uint16_t r = captureRolls;
    captureFlag = false;
    
    uint32_t captureTime = (uint32_t(r) << 16) + uint32_t(t);
    uint32_t elapsed = captureTime - prevCaptureTime;
    prevCaptureTime = captureTime;
    if (first) {
      first = false;    // discard first calculation since previous values were invalid
    } else {
      Serial.print(elapsed);
      Serial.print(" cks, ");
      Serial.print(float(elapsed)/16.0 - 1000000.0, 1);
      Serial.print(" ppm, ");
        Serial.print(rtcElapsed);
      Serial.print(" cks, ");
      Serial.print(float(int32_t(elapsed) - int32_t(rtcElapsed))/(float(elapsed)/1000000.0), 1);
      Serial.print(" ppm");
  
      Serial.println();
    }
  }
}
// =========================================================================================

I made the same measurement for various RTC and found that some of them have a drift of 30sec a day.
I believe that the crystal is not exactly 32.768kHz. So the best cheap RTC seems to be the ones that has the crystal inside the chip and thermal compensated like the ones that use DS3234 or similar chips.

I matched the time with a NTP synchronised PC over long time. The next step will be to add temperatute measurement.
Since I don't expect fast temperature variation, I will take a measurement every minute.

So I believe that taking a measure every 30 s for a pendulum it's sufficient, you can match againt a NTP clock or a GPS clock easily and you do not worry about transmission lags or computational lags. But this make sense if you don't expect that there are some error sources that can vary very fast.

jboyton:
Roger, I don't know what the best solution is. Maybe a frequency counter is the way to go. How accurate is a typical frequency counter?

I don't have a counter or an oscilloscope, just an Uno and a GPS. I wanted to be able to measure the accuracy of real-time clocks as they varied with temperature so that I could write software to compensate for the error. I wrote a sketch to do this and it appears to be able to measure an interval to an accuracy of better than 1us.

Hi..I have been looking at Racal counter/timers on eBay with time measurement to 6 places decimal. Nearly got one last eve. But the problem with hardware devices they don't log results..

Thank you for sharing you sketch.. Now I have two to try thanks also to Robillant in #6. I will knuckle down and start experimenting and hopefully learn about the code as I do so. I will report back when I get something going...Thank you to all who contributed..I got more help than I expected..

Roger

zoomx:
I made the same measurement for various RTC and found that some of them have a drift of 30sec a day.
I believe that the crystal is not exactly 32.768kHz. So the best cheap RTC seems to be the ones that has the crystal inside the chip and thermal compensated like the ones that use DS3234 or similar chips.

I matched the time with a NTP synchronised PC over long time. The next step will be to add temperatute measurement.
Since I don't expect fast temperature variation, I will take a measurement every minute.

So I believe that taking a measure every 30 s for a pendulum it's sufficient, you can match againt a NTP clock or a GPS clock easily and you do not worry about transmission lags or computational lags. But this make sense if you don't expect that there are some error sources that can vary very fast.

OK on your info about RTC's. One thing I find quite interesting is that 32K crystals in wrist watches mostly keep exceptional time especially when temp controlled on the wrist.

One point about pendulum clocks is that it's not so easy to get them exactly synchronised with RT. The last error small is the phase of the pendulum. The temptation is to manually interfere but that can upset timekeeping for quite a while. That's why all my efforts are directed to measuing the "rate" . From #1 you will know that I'm a complete Arduino novice and basically wanted to skip some of the early learning.

All the comments have helped and I will soon be making a start with the either of the two sketches I've got.

Thanks..Roger

There are cheap RTC boards that have very poor accuracy, worse than an Uno's clock. This could be due to an inaccurate crystal, poor matching of the crystal characteristics with the RTC oscillator, poor board layout or maybe even a counterfeit RTC chip. But as you note this is not an indictment of watch crystals. The DS3234 mentioned contains a crystal, calibrated and compensated. The output I posted above was from a $0.60 watch crystal connected to an Atmega328. With software correction it will have an accuracy on par with a DS3234 over a wide temperature range. At least that's my goal.

An interesting read on watch accuracy: http://tf.nist.gov/general/pdf/2276.pdf

I would imagine synchronizing your pendulum with a time reference would be difficult and unnecessary for keeping time to the nearest second. For measuring the error you don't need synchronization.

cornishlad:
Hi..I have been looking at Racal counter/timers on eBay with time measurement to 6 places decimal. Nearly got one last eve. But the problem with hardware devices they don't log results..

How accurate is the time base in the counter?

Sorry if I'm being dense. I've never used a frequency counter.

That's a very good question and I don't know the answer to it ! I've only had mine a couple of months and just assumed it was ok for the purpose I bought it for. Most models are frequency counters with a time measuring facility. Originally these were high quailty bits of kit and only time has made them affordable. Mine was £50 ad I'm well pleased. They should have their calibration checked at regular intervals lol.

Mine appears to have the standard un-ovened 5 mhz crystal reference. A optional version had a precision ovened crystal. After googling a little before replying, I see you can feed a 5Mhz reference into input B. I might look into that.
There are many variants of different ages - and prices.eBay has tons of them.

See here: Universal Counter-Timer 9904 Equipment Racal Engineering / | Radiomuseum

or here for specs on the pdfs: Bama Manual Archive

Overhall I'll say my clock is a success ! It keeps good time but as with all pendulum clocks (except the Shortt clocks of the 1930's) it is affected by changes in barometric pressure. It is this that has made me want to make ongoing, recorded, measurements of the "rate"

Roger

Very interesting stuff. I had to go and read about Shortt clocks, something I'd never even heard of. I was impressed to learn they were accurate to something on the order of 10 parts per billion. And of course I also discovered that I lacked imagination on how one might synchronize pendulums. Thanks for this thread and good luck with your clock.