I was unsure of what happened at millis() rollover and despite the competent advice here on the board, I tend to like to see things for myself, especially since it has been 30 years since I did any 2's complement math. I didn't want to wait 50 days and blink when the numbers rolled by so tried this.
attached program counts right on through the rollover, just like the pro's said it would..
Thanks to all here who made programming possible for me...... its fun for a hardware guy.
[
#include <Arduino.h>
/*
what really happens with timer function at millis() rollover?
lets test it.
*/
unsigned long fakeMillis = 4294967290; //set fakeMillis to a number near the rollover point
unsigned long mark = fakeMillis; // set a time marker start of timer
//long mark = fakeMillis; // try other type variables
//int mark = fakeMillis;
void setup()
{ Serial.begin(9600);
}
void loop() {
do
{
++fakeMillis; //increment faketimer Serial.println(fakeMillis); // prints "timer output" through rollover event Serial.println(fakeMillis-mark); //perform typical subtraction for timer does it work through rollover?
delay(1000);
}
while (fakeMillis>1); // whatever keep looping
}
The micros() function acts like the millis() function, only 1000 times faster. Rollover in 1+ hours, instead of 49+ days. Just in case you are the impatient types, and want results Now!.
i had seen that notation ul and f after variables and numbers in code and do not know the exact usage.
please elaborate on the habit i should acquire.
Dean
i had seen that notation ul and f after variables and numbers in code and do not know the exact usage.
UL stands for unsigned long. It tells the compiler to treat the number as an unsigned long, rather than an int.
F stands for float. For systems where float and double are different sizes, a literal is treated as a double. The F tells the compiler to treat it as a float, instead. On the Arduino, floats and doubles are the same, so F is not needed.
Don't worry subtracting two time values will give the right result if the result variable is a signed integer.
(and the time values aren't too far apart - ie less than 2^31 different).
If the result of subtraction is treated as unsigned then it will be exactly the same bit pattern, but the difference will be
conceptually in the range 0.. 2^32-1 (sometimes you always know your difference will be non-negative so this
doubles the range of differences you can handle).
Unlike subtract when you compare two values it matters if they are signed or unsigned - the two comparisons
behave differently (for the same bit-patterns).
At the end of this snippet, index will have been incremented twice, to 2. In the first case, index will be incremented, and then the value of index will be used as the array index. So, index will be incremented to 1, and then 'a' will be stored in buf[1].
In the second case, the value of index will be used, and then index will be incremented. So, 'b' will be stored in buf[1], and then index will be incremented to 2.
In this scenario, clearly the post-increment form is the desired form, but there are situations where the pre-increment form is desired (although they are not as common).
WARNING: You should never use pre or post increment statements in a macro or function.
What output do you expect ? 6 numbers
#define SQR(x) ((x)*(x))
void setup()
{
int a = 2;
Serial.begin(9600);
Serial.println(SQR(a++));
a = 2;
Serial.println(SQR(++a));
a = 2;
int x = add(a++, a);
Serial.println(x);
a = 2;
x = add(a, a++);
Serial.println(x);
a = 2;
x = add(++a, a);
Serial.println(x);
a = 2;
x = add(a, ++a);
Serial.println(x);
}
void loop()
{
}
int add(int x, int y)
{
return x + y;
}
robtillaart:
WARNING: You should never use pre or post increment statements in a macro or function.
Don't you mean "WARNING: You should never use pre or post increment statements in an argument list to a macro or function"
Macros because of the multiple instatiation as illustrated, function because the order of evaluation is arbitrary and
the compiler can re-order operations I believe...