What is the purpose of the millis() timer?
What, exactly, is it good for that micros() isn't?
Besides, does millis() still skip numbers? If so, why?
If support for millis() were gutted from the Arduino source code, what else would it affect?
What is the purpose of the millis() timer?
What, exactly, is it good for that micros() isn't?
Besides, does millis() still skip numbers? If so, why?
If support for millis() were gutted from the Arduino source code, what else would it affect?
It reports how many milliseconds have elapsed since the Arduino was last started or reset, but I suspect that you already knew that.
It's rollover period is much, much longer than micros(). Approximately 50 days as opposed to approximately 70 minutes. Of course, neither is a problem as long as code is written correctly.
Have you a reference to it skipping numbers and the effect(s) that it has ?
Removing millis() from the Arduino source code might not affect any Arduino functionality directly but it would certainly screw up the many programs that use it.
odometer:
What is the purpose of the millis() timer?
What, exactly, is it good for that micros() isn't?
Besides, does millis() still skip numbers? If so, why?If support for millis() were gutted from the Arduino source code, what else would it affect?
Yes millis() skips numbers, you refer to this passage
Therefore, this overflow handler increments the value of timer0_millis every 1.024ms and then adds another increment to timer0_millis (catches up, if you will) every time timer0_fract is greater than 125. Hence, timer0_millis accounts for the missing 0.024ms from every “timer overflow” at intervals of 125/3 = 41.67ms. Which means timer0_millis accumulates an error of 0.024ms each time it executes (every overflow), until the error approaches 1ms. At which time, timer0_millis jumps by 2 and corrects itself.
What is more important even if millis() did not skip numbers, you cannot be sure that when you call millis() that it had incremented only by 1. That depends on the time the other code of your application takes to execute. That is why you have always have to use an inequality when comparing millis() like in the sample below.
if (millis() -lastTimeSomeThingWasDone >= interval)
{
lastTimeSomeThingWasDone += interval;
doSomeThing();
}
But why does millis() pretend to be something it's not?
Why can't it just admit its true nature and go up by exactly 1 unit every 1024 us? That would save some overhead.
Does delay() still depend on millis()? If it does, then that is one reason for millis() to admit its true nature.
I really don't like millis() because its rollover time is long enough to lure people into a false sense of security. At least with micros() you don't get to bury your head in the sand for a month and a half. This makes code easier to debug.
Does delay() still depend on millis()?
No it doesn't (why not take a look?)
AWOL:
Does delay() still depend on millis()?
No it doesn't
Good.
(why not take a look?)
Where?
Why can't it just admit its true nature and go up by exactly 1 unit every 1024 us?
Then it wouldn't be a millis counter, would it ? How would you use it to measure say a 10 second period ? One way would be to adjust for the odd 24 us every now and again. Wait a minute. We just invented the millis() function !
I really don't like millis() because its rollover time is long enough to lure people into a false sense of security. At least with micros() you don't get to bury your head in the sand for a month and a half. This makes code easier to debug.
Most people who use millis() for timing will have picked up the idea from example code, such as BlinkWithoutDelay or from a forum like this so will use the subtraction method of determining the elapsed time which does not have a problem with rollover.
It sounds like you are very bitter about millis() and have some bad experiences with it. Would you care to share them ?
UKHeliBob:
Then it wouldn't be a millis counter, would it ? How would you use it to measure say a 10 second period ?
(10000000 >> 10) (this works out to 9765)
I really don't like millis() because its rollover time is long enough to lure people into a false sense of security. At least with micros() you don't get to bury your head in the sand for a month and a half. This makes code easier to debug.
Most people who use millis() for timing will have picked up the idea from example code, such as BlinkWithoutDelay or from a forum like this so will use the subtraction method of determining the elapsed time which does not have a problem with rollover.
It sounds like you are very bitter about millis() and have some bad experiences with it. Would you care to share them ?
I have read of many people using millis() for exactly the sort of head-in-the-sand code I describe.
The problem is, as I said, that the long rollover time encourages this.
If you want to know where this personally affected me, it was in reprogramming a do-it-yourself alarm clock kit. The code was originally written by someone quite aware of the rollover problem, yet he used millis() the "wrong" way, and tried to patch it with code designed to zero out certain time-related variables immediately after millis() rollover. He commented this patch with a remark that "this will not dominate the inaccuracy".
This kludge in a kit selling for well over US$100.
When I was reprogramming the clock to do things the "right" way, I missed one instance of his "wrong" use of millis(), and ended up with an alarm clock in which the alarm had a darn good change of not sounding when it was time for it to sound.
If you're worried about rollover issues affecting your code, you write a "myMillis" function that counts at 10, 100 or 1000 times the real one, or only starts near to the rollover, and you use that, with macros to revert the code back when you're happy with it.
If you don't like "millis" as it is, write your own (you have all the source), and do your own 1.024ms based conversions.
That's what open source is all about.
(I personally think the blink without delay example is wrong - at least it was last time I looked, but nothing has been done to correct it. Same for the servo sweep examples)
BlinkWithoutDelay seems to be OK if(currentMillis - previousMillis > interval) {
millis() is not used in the servo sweep example.
millis() is not used in the servo sweep example.
Did I ever say it was?
BlinkWithoutDelay seems to be OK
As I said, last time I looked, it wasn't.
The comparison was incorrect.
Edit: < fires up PC > yup, version 1.0.5 is still wrong.
I use micros() for timing things instead of millis(), seemed like clocks written that way tracked official US time better.
http://www.time.gov/
I write my code to count seconds every 1000000 micros (one second), and rollover/increment the next digit as needed:
void loop(){
currentMicros = micros();
elapsedMicros = currentMicros - nextMicros; // have seen odd results doing this in the 'if'
if (elapsedMicros >=duration){ // 1 second gone by?
nextMicros = nextMicros + duration;
onesSeconds = onesSeconds +1;
if (onesSeconds == 10){ // rollover & increment next digit
onesSeconds = 0;
tensSeconds = tensSeconds +1;
updateDisplay = 1; // see below
if (tensSeconds == 6){
tensSeconds = 0;
onesMinutes = onesMinutes +1;
if (onesMinutes == 10){
onesMinutes = 0;
tensMinutes = tensMinutes+1;
if (tensMinutes == 6){
tensMinutes = 0;
onesHours = oneHours +1;
if (onesHours == 10){
onesHours = 0;
tensHours = tensHours +1;
if ( (tensHours == 1) && (onesHours == 3){ // check for 13 'clock - or 25 o'clock for 24 hr time
tensHours = 0;
onesHours = 0;
}
}
}
}
}
}
} // however many are needed, hard to check in this little 5-line reply box
if (updateDisplay == 1){ // put the new time up!
updateDisplay = 0; // clear the flag
// do whatever is needed to output the time
// send via SPI to MAX7219, discrete shift registers, whatever
// units are all nicely broken out, no messing with Modulo math
// tensHours, onesHours, tensMinutes, onesMinute, tensSeconds, onesSeconds
// can go farther down even = tenths, hundreths, thousandths,
// just make the rollover checking smaller:
// duration = 1,000,000 micros (don't use commas for real) = 1 second
// = 100,000 tenths
// = 10,000 hundreths
// = 1,000 thousandths (milliSeconds)
}
// do other stuff while time is passing
} // end loop
AWOL:
millis() is not used in the servo sweep example.
Did I ever say it was?
As this thread is about millis() I took it that was what you meant.
BlinkWithoutDelay seems to be OK
As I said, last time I looked, it wasn't.
The comparison was incorrect.Edit: < fires up PC > yup, version 1.0.5 is still wrong.
Wrong in what way ?
Wrong in that the comparison says ">" when it should say ">=".
Thanks
I was under the impression that most Arduinos used a ceramic resonator and are not suitable for use as a clock anyway?
The ceramic oscillator keeps time about as well as a mechanical watch.
I don't know about you, but I prefer a mechanical watch to no watch.
odometer:
What is the purpose of the millis() timer?
To measure millimeteres ... or was it milliliteres ...? ]
What, exactly, is it good for that micros() isn't?
The biggest millis()
-interval you can measure is approximatly, calculated as [b]10^-3/10^-6[/b]
, 1000 times bigger than the biggest micros()
interval you can measure. Of course, you could do your own "count the number of rollovers". Sometimes I miss that there is no seconds()
with a rollover after 126 years.
If support for millis() were gutted from the Arduino source code, what else would it affect?
For any code that is not calling millis()
- not a thing. Maybe, just maybe the compile time would be 0.00045% faster. The executable would be identical.
On the forum however - I shudder at all the questions with "[i]why does micros(1000000) not wait one second?[/i]
". Maybe even "[i]I tried micros(1000)*1000, but that didn't work either.[/i]
". Can you take another "[i]How do I reset the Arduino but without calling setup() to avoid rollover, as my Arduino will be timing the aquarium light and needs to be on for more than 70 hours.[/i]
"?
Msquare:
Can you take another "[i]How do I reset the Arduino but without calling setup() to avoid rollover, as my Arduino will be timing the aquarium light and needs to be on for more than 70 hours.[/i]
[/quote]
A [font=Courier]seconds() [/font]function would be useful. (Like [font=Courier]millis()[/font], only the hardware would very likely crap out before the first rollover.)