First of all, let me second Majenko in suggesting the use of an RTC. The Arduino Uno is clocked from a ceramic resonator, and these are nowhere accurate enough for proper timekeeping. C.f. the answers to How do I get an accurate time? How do I get an accurate time?.
Next, instead of counting seconds, I suggest you instead count
milliseconds. I know it sounds like overkill, but it's actually
simpler because you already have millis()
returning a millisecond
count:
void loop()
{
uint32_t now = millis();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000) {
last_minute += 60000;
if (++minutes >= 60) {
minutes = 0;
if (++hours >= 24)
hours = 0;
}
}
// Do not advance the seconds when the user sets the time.
if (time_is_being_set_by_the_user()) {
last_minute = now;
}
}
Oh, wait! No! Do not count milliseconds, instead count microseconds:
void loop()
{
uint32_t now = micros();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000000) {
last_minute += 60000000;
// The rest does not change...
}
}
Why? Because, as I said before, the ceramic resonator of your Arduino is
not very accurate. You will eventually find out that it drifts
significantly. However, if you compare to a good reference, you will be
able to calibrate the drift. If, for example, you find that it drifts
forward by 0.0025% (about 15 seconds per week, quite optimistic), you
will be able to fix it simply by replacing 60000000 by 60001500. The
same would work if counting milliseconds, except that you would only be
able to do a coarse tuning. Oh, and do not worry about micros()
overflowing not worry about micros()
overflowing.
First of all, let me second Majenko in suggesting the use of an RTC. The Arduino Uno is clocked from a ceramic resonator, and these are nowhere accurate enough for proper timekeeping. C.f. the answers to How do I get an accurate time?.
Next, instead of counting seconds, I suggest you instead count
milliseconds. I know it sounds like overkill, but it's actually
simpler because you already have millis()
returning a millisecond
count:
void loop()
{
uint32_t now = millis();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000) {
last_minute += 60000;
if (++minutes >= 60) {
minutes = 0;
if (++hours >= 24)
hours = 0;
}
}
// Do not advance the seconds when the user sets the time.
if (time_is_being_set_by_the_user()) {
last_minute = now;
}
}
Oh, wait! No! Do not count milliseconds, instead count microseconds:
void loop()
{
uint32_t now = micros();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000000) {
last_minute += 60000000;
// The rest does not change...
}
}
Why? Because, as I said before, the ceramic resonator of your Arduino is
not very accurate. You will eventually find out that it drifts
significantly. However, if you compare to a good reference, you will be
able to calibrate the drift. If, for example, you find that it drifts
forward by 0.0025% (about 15 seconds per week, quite optimistic), you
will be able to fix it simply by replacing 60000000 by 60001500. The
same would work if counting milliseconds, except that you would only be
able to do a coarse tuning. Oh, and do not worry about micros()
overflowing.
First of all, let me second Majenko in suggesting the use of an RTC. The Arduino Uno is clocked from a ceramic resonator, and these are nowhere accurate enough for proper timekeeping. C.f. the answers to How do I get an accurate time?.
Next, instead of counting seconds, I suggest you instead count
milliseconds. I know it sounds like overkill, but it's actually
simpler because you already have millis()
returning a millisecond
count:
void loop()
{
uint32_t now = millis();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000) {
last_minute += 60000;
if (++minutes >= 60) {
minutes = 0;
if (++hours >= 24)
hours = 0;
}
}
// Do not advance the seconds when the user sets the time.
if (time_is_being_set_by_the_user()) {
last_minute = now;
}
}
Oh, wait! No! Do not count milliseconds, instead count microseconds:
void loop()
{
uint32_t now = micros();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000000) {
last_minute += 60000000;
// The rest does not change...
}
}
Why? Because, as I said before, the ceramic resonator of your Arduino is
not very accurate. You will eventually find out that it drifts
significantly. However, if you compare to a good reference, you will be
able to calibrate the drift. If, for example, you find that it drifts
forward by 0.0025% (about 15 seconds per week, quite optimistic), you
will be able to fix it simply by replacing 60000000 by 60001500. The
same would work if counting milliseconds, except that you would only be
able to do a coarse tuning. Oh, and do not worry about micros()
overflowing.
First of all, let me second Majenko in suggesting the use of an RTC. The Arduino Uno is clocked from a ceramic resonator, and these are nowhere accurate enough for proper timekeeping. C.f. the answers to How do I get an accurate time?.
Next, instead of counting seconds, I suggest you instead count
milliseconds. I know it sounds like overkill, but it's actually
simpler because you already have millis()
returning a millisecond
count:
void loop()
{
uint32_t now = millis();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000) {
last_minute += 60000;
if (++minutes >= 60) {
minutes = 0;
if (++hours >= 24)
hours = 0;
}
}
// Do not advance the seconds when the user sets the time.
if (time_is_being_set_by_the_user()) {
last_minute = now;
}
}
Oh, wait! No! Do not count milliseconds, instead count microseconds:
void loop()
{
uint32_t now = micros();
static uint32_t last_minute;
// Increment the time every minute.
if (now - last_minute >= 60000000) {
last_minute += 60000000;
// The rest does not change...
}
}
Why? Because, as I said before, the ceramic resonator of your Arduino is
not very accurate. You will eventually find out that it drifts
significantly. However, if you compare to a good reference, you will be
able to calibrate the drift. If, for example, you find that it drifts
forward by 0.0025% (about 15 seconds per week, quite optimistic), you
will be able to fix it simply by replacing 60000000 by 60001500. The
same would work if counting milliseconds, except that you would only be
able to do a coarse tuning. Oh, and do not worry about micros()
overflowing.