The millis overflow issue is quite common on the web and on this forum.
I understand that whenever you subtract an older time from a newer one, you get the correct unsigned result.
I just wanted to see it in action.
So i made this simple sketch, and it does not seem to behave correctly:
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
unsigned char start = 253;
unsigned char mil = 253;
unsigned char period = 3;
mil++; // 254
mil++; // 255
mil++; // 0
mil++; // 1
mil++; // 2
Serial.println((unsigned char)mil, DEC); // prints 2
Serial.println(mil, DEC); // prints 2
Serial.println();
Serial.println((unsigned char)(mil - start), DEC); // prints 5
Serial.println(mil - start, DEC); // prints -251
if(mil - start >= period){ // DOES NOT ENTER IF
Serial.println("Time passed"); // NOT PRINTED
}
}
void loop() {
// put your main code here, to run repeatedly:
}
Why does the Serial.println in the if statement does not get executed?
Of course if I change it to if((unsigned char)(mil - start) >= period)
it works. but in all millis overflow questions, the guide says use this if (currentMillis - startMillis >= period) and you will be fine as long as both variables are defined as unsigned numbers
UKHeliBob:
My suspicion is that the calculation is being done using integers but try this
void setup()
{
Serial.begin(115200);
byte start = 253;
byte mil = 253;
byte period = 3;
mil++; // 254
mil++; // 255
mil++; // 0
mil++; // 1
mil++; // 2
Serial.println(mil); // prints 2
Serial.println(mil - start); // prints -251
if ((byte)(mil - start) >= period)
{
Serial.println("Time passed");
}
}
void loop()
{
}
Works..
But if a cast is needed anyway,
A) Can I assume that for checking time elapsed with millis I should always cast the subtraction?
B) Doesn't it imply that in the "Using millis() for timing. A beginners guide" (thank you for this excellent one) a casting is missing in the examples and otherwise it actually won't handle correctly the millis overflow?
B) Doesn't it imply that in the "Using millis() for timing. A beginners guide" (thank you for this excellent one) a casting is missing in the examples and otherwise it actually won't handle correctly the millis overflow?
If all the terms are unsigned long, then no casts are necessary.
yanivps:
Thanks for replay.
Look at my example please
They are all unsigned char:
unsigned char start = 253;
unsigned char mil = 253;
unsigned char period = 3;
and yet, comparison fails
You can't promote an unsigned long to an int, so arithmetic it automatically done as unsigned long.
This is not the case for an unsigned char.
BulldogLowell:
Certainly there is. You can expect that the handling of promotion confirms to the standards, even though your intuition suggests some other handling!
I will grant you that it is expected because it is documented, as I said, but why was it written that way ? It can't have been an accident.