Uno millis() falls behind over long periods (hours/days)

Just for fun I am running this comparison of millis() time with a Timer1 interrupt that adds 1000 every second. So far the difference is holding steady at '1' (or a 2 every 16 seconds when the millis() count twice to catch up). It will be interesting to see if the difference ever goes above 2. Just passed 500,000 milliseconds and the difference has not changed for they are tracking within 2 ppm.

@cotestatnt Update at 12:42 EDT. The timer just passed 5,000,000 milliseconds and the time difference has not changed. That means millis() is tracking the Timer1 interrupt within 0.2 ppm.

@cotestatnt Update at 14:03 EDT. The timer just passed 10,000,000 milliseconds and the time difference has not changed. That means millis() is tracking the Timer1 interrupt within 0.1 ppm.

@cotestatnt Update at 16:24 EDT. The timer is well past 18 million milliseconds and still tracking.

@cotestatnt Update at 8:37 EDT the next day. The timer is well past 76.8 million milliseconds and still tracking. I think this is enough to show that millis() is no less accurate than an interrupt on Timer1.

volatile uint32_t TimerTime, TimeDifference; // current epoch time

void setupTimer1()
{
  noInterrupts();
  TCCR1A = 0;  // Clear registers
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 15624;                        // 1 Hz (16000000/((15624+1)*1024))
  TCCR1B |= (1 << WGM12);               // CTC
  TCCR1B |= (1 << CS12) | (1 << CS10);  // Prescaler 1024
  TIMSK1 |= (1 << OCIE1A);              // Output Compare Match A Interrupt Enable
  TimerTime = millis();
  interrupts();
}

void setup()
{
  Serial.begin(115200);
  setupTimer1();
}

void loop()
{
  static uint32_t lastTT = 0;

  noInterrupts();
  uint32_t tt = TimerTime;
  uint32_t td = TimeDifference;
  interrupts();

  if (tt != lastTT)
  {
    lastTT = tt;
    Serial.print(tt);
    Serial.print('\t');
    Serial.println(td);
  }
}

// Timer1 interrupt service routine
ISR(TIMER1_COMPA_vect)
{
  TimerTime += 1000; // Add 1000 milliseconds
  TimeDifference = TimerTime - millis();
}
3 Likes