Go Down

Topic: millis () rollover (Read 1 time) previous topic - next topic

dmacfarland

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.

[
Quote

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




]

AWOL

Code: [Select]
unsigned long fakeMillis = 4294967290UL;
...is safer. Acquire the habit.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

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

dmacfarland

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

PaulS

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


MarkT

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).
[ I won't respond to messages, use the forum please ]

michinyon

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

CrossRoads

++ (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

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

PaulS

Quote
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:

Code: [Select]
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).

robtillaart


WARNING: You should never use pre or post increment statements in a macro or function.

What output do you expect ?  6 numbers
Code: [Select]

#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?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

MarkT



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...
[ I won't respond to messages, use the forum please ]

Nick Gammon

Code: [Select]
    ++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:

Code: [Select]
    fakeMillis++;             


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

Code: [Select]
foo += 2;  // add 2 to foo

Useless comment.
http://www.gammon.com.au/electronics

robtillaart

Quote
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 ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

GoForSmoke

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

Code: [Select]

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() {};
I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Go Up