[time-nuts] arduino solar clock

Tom Van Baak tvb at LeapSecond.com
Mon Jan 20 02:27:42 EST 2014


> We are probably saying the same thing, but I didn't think of it this way when 
> reading your description...

Correct, to maintain timekeeping accuracy the goal is not so much to avoid division, but to pay attention to the remainder when division is used. You may have noticed that many time scale algorithms (e.g., leap years, Julian dates, day of week, etc.) use an abundance of integer division or modulus operations.

> You can get a lot closer by keeping track of the remainder.
>  seconds += ticks/ticksPerSecond;
>  rem += ticks % ticksPerSecond;
>  if (rem > ticksPerSecond) {
>  seconds += 1;
>  rem -= ticksPerSecond;

That's right. However, note that only works when ticksPerSecond is a pure integer. Often when using microprocessors, and especially with binary prescalers, ticks-per-second is of the form N/M instead of integer. For example if the clock is 3.57954545 MHz (colorburst), or a computer claims 102 Hz interrupt rate, but it's actually 102.4 Hz. Another example is a 10 MHz clock with a 1024 prescaler; your ticksPerSecond comes to 9765.625.

The solution in that case is to use period constants rather than frequency constants. That is, when ticksPerSecond is not an integer see if MillisecondsPerTick or NanosecondsPerTick is an integer. In this 9765.625 Hz example we get a NanosecondsPerTick value of 102400. Then your code can look like:

Nanoseconds += NanosecondsPerTick;
if (Nanoseconds >= 1000000000) {
    Seconds += 1;
    Nanoseconds -= 1000000000;
}

Sometimes neither TicksPerSecond or NanosecondsPerTick is a pure integer. In that case use the more general I+N/M fractional arithmetic method. If done right you can maintain perfect timekeeping, not losing a single nanosecond.

/tvb



More information about the time-nuts mailing list