Micros() too fast

Hello everyone!

Right now I’m coding a multi-app GUI that performs multiple functions. One of these functions is telling the time. I’m doing this without an RTC module and am instead just using millis() and micros(). I previously ran into some trouble using millis() because I found that it was inaccurate. I then read a post about using micros() instead of millis() and I have seen much better results. However, last night I checked the accuracy of the clock, and found that after three hours or so, the clock was 3 or 4 seconds behind the real time.

I’ll post my code below and would love some feedback on how to make my clock more accurate.

P.S. The reason why I call clockFunction() so many times is because if I don’t, the time doesn’t update.

Smart_Watch_Prototype_2.ino (56.1 KB)

Sorry, but my life expectancy is too short to study 56k of code.

The Arduino 16MHz clock does not run at exactly 16MHz and the error can vary with temperature. If you want clock time then you need a Real Time Clock module.

...R

heydenyo:
I'll post my code below and would love some feedback on how to make my clock more accurate.

Why do you seem to think its a code problem ?

Have you measured the accuracy of the clock your Arduino is getting ?

If so, how accurate was it ?

I agree with Robin2 you will need an RTC if you want to keep an accurate time.

I did however take a look at your code (unfortuantely).

Your use of clockFunction() in your code however means you will never return an accurate time even with an RTC and in many cases it could easily be a minute or hour or day out. The only time you need to call it is before you use the time it generates. There is no point in calling it when you get, for example. the hours as that will update all the fields and if you have read the minutes just before the minute expires the hours will be from one time and the minutes from the previous time. Calling clockFunction() will server no purpose, it won't make things any more accurate and could easily make the data you get less accurate. If you have a section of code that does not use the time don't call clockFunction. You want all the data hours minutes seconds from a single point in time, not all from different points in time no matter that they will be close - they may still be on different days.

I don't know if all those repeated calls to clockFunction leads to the problems you have.

The millis() and micros() functions are exactly as accurate as each other since they are based on the ceramic resonator of the system clock.

You can make an ATmega328P a much more accurate timer by switching the system oscillator to the 8 MHz internal oscillator to free up the XTL1/TOSC1 and XTL2/TOSC2 pins. Then replace the resonator with a precision 32.768 kHz crystal and turn on the AS2 bit in the ASSR to connect the crystal oscillator to Timer2.

I have an Arduino Uno outdoors keeping time. It would be off many seconds in 24 hours except that I have a correction for the typical number of milliseconds in a day using that Uno in that location. I don't need great accuracy so this is good enough. If I needed better accuracy I would get an RTC or get time from the internet (using NTP) or do something like what johnwasser suggested.

Several reasons why you might have to call your clock function so often.

I would also time how long screen updates take; if I understand your code correctly, you want your clock to display in one-hundreds of a second. So 10 milliseconds max for a loop cycle.

I would increase the baud rate; printing the time on serial at 9600 takes just over one millisecond per character; you're printing 13 characters so do the calculations. At the moment that you start printing more than can be done in a required time, Serial.print becomes a blocking function.

So looking at all the replies, it looks like I'll just have to ditch clockFunction() and buy an RTC. The one problem I have with using an RTC is that it takes up arduino pins that I don't have.

Bute thanks for all your help everyone! Any more advice about keeping the time or just my code in general? I'm a beginner, so any feedback would be much appreciated!

Is your project network connected? If so, you could use an adaptive NTP solution instead.

Instead of just picking an interval to update using NTP, track the ‘skew’ - how much the NTP time differs from the current estimated time. If the skew is zero, double the update interval. Skew of 1 second - keep the current update interval. Larger skew - cut the update interval in half.

This will converge on an update interval that is usually within 1 second of the actual time.

The one problem I have with using an RTC is that it takes up arduino pins that I don't have.

By using an RTC with a 1 Hz pulse output you could get away with using only 1 pin on the Arduino

MHotchin:
Is your project network connected? If so, you could use an adaptive NTP solution instead.

Instead of just picking an interval to update using NTP, track the 'skew' - how much the NTP time differs from the current estimated time. If the skew is zero, double the update interval. Skew of 1 second - keep the current update interval. Larger skew - cut the update interval in half.

This will converge on an update interval that is usually within 1 second of the actual time.

I don't think my project will end up being network connected. However, this is an interesting idea, thanks for the feedback!

UKHeliBob:
By using an RTC with a 1 Hz pulse output you could get away with using only 1 pin on the Arduino

Ok, this is good to know, I think I would be able to spare 1 pin. Thanks!

One more problem I have with using an RTC module is that it may be too big for my project. After I'm done with a prototype, I'm going to shrink my project so that it can be worn. Are smaller RTCs just as accurate as bigger ones?

Don't confuse the various modules commonly available with the actual RTC which is a quite small chip. The biggest coponent is likely to b the battery (assuming you need one for just the rtc).

countrypaul:
Don't confuse the various modules commonly available with the actual RTC which is a quite small chip. The biggest coponent is likely to b the battery (assuming you need one for just the rtc).

Ok thanks.

The teensy 3.2 is set up to do its own RTC. All you need to do is add a crystal and a backup battery.

-jim lee