The quoted phrase is not a warning, it is merely a statement about how things work.
There's nothing intrinsically wrong with using millis()
or micros()
within a properly-written interrupt routine.
On the other hand, doing anything at all within an improperly-written interrupt routine is by definition wrong.
An interrupt routine that takes more than a few microseconds to do its job is, in all likelihood, improperly written.
In short: A properly-written interrupt routine will not cause or encounter issues with millis()
or micros()
.
Edit: Regarding “why micros() "starts behaving erratically"”, as explained in an “examination of the Arduino micros function ” webpage, micros()
code on an ordinary Uno is functionally equivalent to
unsigned long micros() {
return((timer0_overflow_count << 8) + TCNT0)*(64/16);
}
This returns a four-byte unsigned long comprised of the three lowest bytes from timer0_overflow_count
and one byte from the timer-0 count register.
The timer0_overflow_count
is incremented about once per millisecond by the TIMER0_OVF_vect
interrupt handler, as explained in an examination of the arduino millis function webpage.
Before an interrupt handler begins, AVR hardware disables interrupts. If (for example) an interrupt handler were to run for five milliseconds with interrupts still disabled, at least four timer 0 overflows would be missed. [Interrupts written in C code in the Arduino system are not reentrant (capable of correctly handling multiple overlapping executions within the same handler) but one could write a reentrant assembly language handler that reenables interrupts before it begins a time-consuming process.]
In other words, timer overflows don't “stack up”; whenever an overflow occurs before the interrupt from the previous overflow has been handled, the millis()
counter loses a millisecond, and the discrepancy in timer0_overflow_count
in turn makes micros()
wrong by a millisecond too.
Regarding “shorter than 500 μs” as an upper time limit for interrupt processing, “to prevent blocking the timer interrupt for too long”, you could go up to just under 1024 μs (eg 1020 μs) and millis()
still would work, most of the time. However, I regard an interrupt handler that takes more than 5 μs as a sluggard, more than 10 μs as slothful, more than 20 μs as snail-like.