1

As described here https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

I use timer 0 to get my own timer with a milliseconds resolution.

It is setup like this:

void setup (void)
{
    ...
    cli();
    OCR0A  = 0xAB;
    TIMSK0 |= (1 << OCIE0A);
    sei();
    ...
}

The value 0xAB is chosen randomly and should not affect the behaviour.

The interrupt handler looks like this:

ISR(TIMER0_COMPA_vect)
{
    if (myTimer != 0)
        myTimer--;
    return;
}

This works just OK but having a closer look at the actual timing values using millis() I've found that the timer values given by this ISR are about 2-3% too long.

According to adafruit.com this method should exactly follow the built-in millis() timer of the Arduino. In my program there are no other interrupts active. There are some Serial.print() outputs, maybe they affect the timing? The solution I've found looks like this:

ISR(TIMER0_COMPA_vect)
{
    static unsigned long timeLast;

    unsigned long timeNow = millis();
    uint8_t timeDiff = (uint8_t)(timeNow - timeLast);
    timeLast = timeNow;

    if (myTimer != 0)
        myTimer -= timeDiff;

    return;
}

Instead of simply decrementing the timer, the timer value is decreased by the actual amount of time since the last call of the ISR.

With this my timer follows exactly the millis(). But why doesn't the first approach give an exact timing? Apparently there are some cases where the time between calls of the ISR is not 1ms but 2ms.

1
  • Does that mean that millis() already returns the corrected value i.e. millis() gives the actual number of milliseconds and not the 1.024ms?
    – Sören
    Commented Jun 30, 2019 at 13:17

1 Answer 1

3

The Arduino core configures Timer 0 for a period of 1,024 µs. Your ISR will then be called at very regular intervals, and is a good place to have timing-related code. You just have to keep in mind that the unit of time is not one millisecond, but 1.024 ms.

If this “weird” unit bothers you, then you could do what the Arduino timing ISR does: keep track of how late, relative to a 1 ms period, you are getting. When you notice you are 1 ms late, count one extra millisecond.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.