Open GoogleCodeExporter opened 9 years ago
Cleaned up the patch
Original comment by Michael....@gmail.com
on 16 Jan 2010 at 9:50
Attachments:
This is a duplicate of #55 "Incorrect check for timer 0 overflow in micros()". I
haven't found #55 because of a wrong filter setting in the search dialog.
Original comment by Michael....@gmail.com
on 16 Jan 2010 at 11:54
millis() has similar issues, it doesn't count up when IRQs are disabled. The
attached
patch addresses this also.
Original comment by Michael....@gmail.com
on 16 Jan 2010 at 12:10
Updated test sketch with additional test case for millis().
What is the expected output?
t1=2011128
t2=2011140
t3=2011148
ovl1=0 ovl2=1 ovl3=0
t2-t1=12 t3-t1=20 t3-t2=8
tm1=2019
tm2=2020
tm3=2020
What do you see instead (Arduino-17)?
t1=2021368
t2=2020356
t3=2021388
ovl1=0 ovl2=1 ovl3=1
t2-t1=-1012 t3-t1=20 t3-t2=1032
*** Error: t2 < t1 ==> missed a timer overflow
tm1=2034
tm2=2034
tm3=2035
*** Error: tm2==tm1 ==> missed a timer overflow
What do you see instead (Arduino-18-rc1-2)?
t1=2016248
t2=2016260
t3=2016268
ovl1=0 ovl2=1 ovl3=1
t2-t1=12 t3-t1=20 t3-t2=8
tm1=2024
tm2=2024
tm3=2025
*** Error: tm2==tm1 ==> missed a timer overflow
Original comment by Michael....@gmail.com
on 16 Jan 2010 at 1:30
Attachments:
Can you explain a bit more about the problem with millis() and how your
solution works?
Original comment by dmel...@gmail.com
on 28 Jan 2010 at 1:58
The millis() problem is only a small problem. I don't know how relevant it is
in real
applications. I just added it for completeness and because the fix is the same
as for
the micros() problem which is much more important.
Problem:
millis() is updated on timer0 overflow. When IRQs are disabled, the update is
also
disabled. The result is, that at the time of reading tm2 in the example above
you get
the old (not updated) value of millis() which means the result is inaccurate.
Please
look at the code of the test sketch MicrosTimerOverflowTest.pde for this
scenario.
The second problem is, that the clock loses time when IRQs are disabled for
more than
two timer overflows, so a complete update cycle is missed.
Solution:
What I have done is to check the overflow flag not only via the IRQ but
additionally
directly in the millis() and micros() function. When overflow is set, the time
variables are updated, the overflow flag is cleared (so the IRQ is skipped) and
the
updated value is returned.
This makes it possible to use millis() / micros() in a loop when IRQs are
disabled as
long as it is called regularly (at least once in a ms) to check the overflow
flag
manually.
MikeT
Original comment by Michael....@gmail.com
on 30 Jan 2010 at 8:54
When IRQs are disabled, the delay() function doesn't work, because it relies on
millis():
void delay(unsigned long ms)
{
unsigned long start = millis();
while (millis() - start <= ms)
;
}
Using the patch makes it possible to use delay() while IRQs are disabled
because the
timer overflow is handled additionally in millis() and not only via the ISR.
Original comment by Michael....@gmail.com
on 30 Jan 2010 at 12:06
Original issue reported on code.google.com by
Michael....@gmail.com
on 15 Jan 2010 at 11:00