Pages: 1 2 3 [4]   Go Down
Author Topic: Keeping accurate time  (Read 19543 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...
Frankly, creating anything other than the most simpletons of clocks without an RTC is highly questionable, unless its the trip than matters moreso than the destination...

Frankly, building a development board with an irregular heartbeat (resonator) to save a dime is highly questionable to me.
Logged

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3501
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A crystal will be usually ~10 ppm of the mark. So dedicated RTCs are still much better. A resonator will startup faster.

 If you insist on precision timing without giving any details on how much accuracy you really need run your Arduino from an external clock and use a PLL to sync it with something like a Trimble Thunderbolt (can be bought for cheap from *bay). If this will not give enought precision then you have an issue smiley-wink
Logged

Check out my experiments http://blog.blinkenlight.net

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have had great luck / happiness with the DS3231. Great chip, well-documented, easy to interface with, and even a couple of libraries to choose from. In the end though I wrote my own reading / bit-shifting routines since some of the libraries I dealt with didn't do that part perfectly for all the variables that the DS3231 supports. No big deal, there are plenty of examples out there that pointed me in the right direction.

Equally fun was writing a routine that turned these values into a float that reflected the microsoft way of tracking time in Excel.
Logged

Rapa Nui
Offline Offline
Edison Member
*
Karma: 60
Posts: 2086
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Constantin: they claim +/-2ppm/year and 5ppm aging - can you confirm that somehow?? Thnks.
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Constantin: they claim +/-2ppm/year and 5ppm aging - can you confirm that somehow?? Thnks.
Sorry, I hate to be punny but I don't have the time. It's good enough for me...
Logged

0
Offline Offline
Edison Member
*
Karma: 67
Posts: 1675
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I did a number of tests with the DS3231.   2 ppm is reasonable If you power it so the temp compensation is maintained.  I use 5 volts all the time since the rate does vary a bit at different voltages.

I used a gps pps signal to test the chip.  My chips do 1 ppm for short times, a few days.  That's as long as I ran them with the gps clock.

Here is a bit more http://forums.adafruit.com/viewtopic.php?f=19&t=17966&p=92197&hilit=ds3231#p92197
Logged

Rapa Nui
Offline Offline
Edison Member
*
Karma: 60
Posts: 2086
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@fat16lib: thanks! So you may discipline it via gps and Vcc smiley.
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Using a GPS receiver is about as good as you're going to get... hard to beat atomic clocks that operate under close supervision.
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try just using millis() directly instead of delay(). Something like (warning...untested code):

Code:
uint32_t lastTime;

void loop(void)
{
  if ((millis() - lastTime) >= 1000) {
    lastTime += 1000;
    digitalClockDisplay();
  }
  ......
}

This is actually a very smart way of doing it, because you avoid the problems with millisecond rollover.
I wonder why people seem to think that using the built-in millisecond counter inevitably results in problems at rollover.

Alternatively, I would suggest using the microsecond counter.
Code:
uint32_t lastTime = 0;
const int oneSecond = 1000000;

void loop(void)
{
  if ((micros() - lastTime) >= oneSecond) {
    lastTime += oneSecond;
    digitalClockDisplay();
  }
  ......
}
This rolls over every 1.2 hours or so, but that is not a problem in this sort of application. Another advantage -- in this application, quite a great one -- is that a clock that runs too fast or too slow is easily adjusted by changing the value of the constant oneSecond. (sort of like the fast/slow lever on a wind-up alarm clock)
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

"const int oneSecond = 1000000;"

Can this work? I'd like to think you need a long for such a big number. Beyond that, wouldn't one have to use 1000000L?
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"const int oneSecond = 1000000;"

Can this work? I'd like to think you need a long for such a big number. Beyond that, wouldn't one have to use 1000000L?

OOPS! (Well, I told you it was untested code.)

Okay, so try:
Code:
uint32_t lastTime = 0;
const long oneSecond = 1000000L;

void loop(void)
{
  if ((micros() - lastTime) >= oneSecond) {
    lastTime += oneSecond;
    digitalClockDisplay();
  }
  ......
}
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 212
Posts: 13085
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


I suspect the compiler is smart enough to know what you intended but, technically, because you are comparing an unsigned value to a signed value the comparison should be extended to 64 bits; which is rather undesirable.  This is probably a better choice...

const unsigned long oneSecond = 1000000UL;
Logged

Pages: 1 2 3 [4]   Go Up
Jump to: