millis () rollover

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
}

]

unsigned long fakeMillis = 4294967290UL;

...is safer. Acquire the habit.

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.

thanks

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).

What's the difference between ++fakemillis and fakemillis++ ?

++ (increment) / -- (decrement)
Description
Increment or decrement a variable

Syntax
x++; // increment x by one and returns the old value of x
++x; // increment x by one and returns the new value of x

What's the difference between ++fakemillis and fakemillis++ ?

The difference is in what happens if the variable is used during the pre- or post-increment operation.

To illustrate:

char buf[10];
byte index = 0;

buf[0] = '\0';

buf[++index] = 'a';
buf[index++] = 'b';

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;
}

And what was your score?

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...

    ++fakeMillis;                          //increment faketimer

In this situation, the pre or post increment will give the same result. Personally as a matter of style here, I would prefer:

    fakeMillis++;

Notice I omitted the comment. Comments are supposed to elaborate, not describe what things are doing. eg.

foo += 2;  // add 2 to foo

Useless comment.

Don't you mean "WARNING: You should never use pre or post increment statements in an argument list to a macro or function"

Yes, thank you for making it exact :wink:

Unsigned math demo. Values shown in decimal, hex and binary. Substitute your own values as needed.

unsigned long a, b, c;

void setup() {
  Serial.begin( 9600 );
  a = 0xffffff00UL;
  b = 0x10UL;
  Serial.println( "\n unsigned math\n" );
  Serial.print( "a = ");
  Serial.print( a, DEC );
  Serial.print( " = 0x");
  Serial.print( a, HEX );
  Serial.print( " = 0b");
  Serial.println( a, BIN );
  Serial.print( "b = ");
  Serial.print( b, DEC );
  Serial.print( " = 0x");
  Serial.print( b, HEX );
  Serial.print( " = 0b");
  Serial.println( b, BIN );
  if ( b >= a ) Serial.println( "b >= a" );
  else          Serial.println( "a > b" );
  c = a - b;
  Serial.print( "a - b = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
  c = b - a;
  Serial.print( "b - a = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
  c = b - (b + 1);
  Serial.print( "b - (b + 1) = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
}

void loop() {};