Measuring time error in 24 hours

For my next project I do not want to use a RTC for time keeping.

My plan is to use just the Time library to get current minutes, hours and seconds and display them on a Neopixel display (60 leds total).

I need a way to calculate the error in seconds that an UNO (actually a 328 with 16Mhz xtal) runs fast, or slow in a 24 hour period.
Once I know this error, my plan is to add or subtract that many seconds at midnight in a sketch function.
Hopefully this can make my planned project have a more accurate clock display.
If the power fails I will set the time using an IR remote.

I could run the sketch for a 24 hour period and note the number of seconds difference between my watch and the Arduino.
I was wondering if there might be other suggestions to get this error.


Perhaps you could (temporarily) put on an Ethernet shield and use File->Examples->Ethernet->UdpNtpClient to get the time from a Network Time Protocol server. Then you could compare the system time with the network time to get the average rate error.

Thanks John.
That maybe an option.

I just thought about using 60hz interrupts for the process.
I could "temporarily" feed power line 60hz to the Arduino.
Count the number of interrupts in 24 hours.
The count should be 5,184,000 for zero error.
I could make correction accordingly


Have you looked at this...

It includes trimming...


Thank you CB
I had not seen that!

For what it's worth, the basic technique in that library is very effective. With a similar technique, I have been able to get a clock (think "kitchen timer") with about 0.5% accuracy (about three second error in 10 minutes) using the internal watchdog. With a calibrated internal oscillator the accuracy is typically better than 0.1%. I suspect crystal+capacitors with "software trimming" will give you great results.

You may be able to come up with a way to trim a little each day. Using the remote you would tell the clock something like "you're fast" / "you're slow". The clock would adjust the trim then reduce the trim amount for next time. If you can work out the details, each day the clock would be more accurate until you would rarely have to make adjustments. I suspect the hard part would be avoiding overshoot.

I believe I posted how to modify the Arduino core to include trimming; something to do with 20 MHz. If you can find that post it may have something of value.

I have run this code and compared it against US time
and find it tracks very well.

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes;
byte oldSecondsOnes;
byte secondsTens;
byte minutesOnes = 0;
byte minutesTens = 4;
byte hoursOnes = 1;
byte hoursTens = 1;

void setup(){

  Serial.begin(115200); // make serial monitor match
  currentMicros = micros();
  previousMicros = currentMicros;
  Serial.println ("Setup Done");

void loop(){

  currentMicros = micros();

  // how long's it been?
  elapsedTime = currentMicros - previousMicros;
  Serial.print ("Elapsed: ");  
  Serial.println (elapsedTime);
  if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
    elapsedTime = 0;
    previousMicros  = previousMicros + 10000UL;
    hundredths = hundredths+1;
    if (hundredths == 10){
      hundredths = 0;
      tenths = tenths +1;
      if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
          secondsOnes = 0;
          secondsTens = secondsTens +1;
          if (secondsTens == 6){ 
            secondsTens = 0;
            minutesOnes =  minutesOnes + 1;
            if (minutesOnes == 10){
              minutesOnes = 0;
              minutesTens = minutesTens +1;
              if (minutesTens == 6){
                minutesTens = 0;
                hoursOnes = hoursOnes +1;
                if (hoursOnes == 10){
                  hoursOnes = 0;
                  hoursTens = hoursTens =1;
                  if (hoursOnes == 4 && hoursTens ==2){
                    hoursOnes = 0;
                    hoursTens = 0;
              } // minutesTens rollover check
            } // minutesOnes rollover check
          } // secondsTens rollover check
        } // secondsOnes rollover check
      } // tenths rollover check
    } // hundredths rollover check
  } // hundredths passing check

  if (oldSecondsOnes != secondsOnes){  // show the elapsed time
    oldSecondsOnes = secondsOnes;
    Serial.print ("Time: ");
    Serial.print (hoursTens);

  } // end one second check

} // end loop

You may be able to come up with a way to trim a little each day. Using the remote you would tell the clock something like "you're fast" / "you're slow".

Great idea.

I could do this with my remote quite nicely.

Thanks Bob.

You're up late but, I guess it's almost the longest day of the year.


1AM on a Friday, not too late for me.