Pages: [1] 2   Go Down
Author Topic: Millis() rover over handling  (Read 1560 times)
0 Members and 1 Guest are viewing this topic.
South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In this code, will millis() roll over be a problem?  This routine is called to run a motor twice a day all year.  The mills() is only used to check for a stuck door.  If I've got the logic of it figured out, I think if the rollover does occur during this routine, it just won't have the error protection.  That's fine, I just don't want it to be forced into an error if the rollover happens during the routine.
Code:
void OpenDoor(){
  digitalWrite(HBRIDGEpower, HIGH);  //power up the H Bridge
  delay(1000);  //give it a chance to stabilize
  digitalWrite(motorOpenPin, HIGH);    //Turn on the motor pin that give the open direction
  unsigned long startMillis = millis(); //create a counter
  while(1){
    if (millis() - startMillis > 30000) DoorError(); //longer than 30 sec means the string is tangled
    if (digitalRead(TopSwitch) == 0) { //Switch is closed
      digitalWrite(motorClosePin, LOW);  //Brake
      digitalWrite(motorOpenPin, LOW);  //Brake
      delay(500); //wait a bit
      digitalWrite(HBRIDGEpower, LOW);  //power down the H Bridge
      break;
    }
    delay(10);
  }
}
Logged

Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3941
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As long as the interval being timed (30 sec here) is less than the ~50 day millis() rollover interval, and if the comparison is done with subtraction and unsigned variables as it is here (good job!) then the rollover will never be a problem. The code will operate the same even if rollover occurs during the 30 second interval.
« Last Edit: July 05, 2013, 02:26:14 pm by Jack Christensen » Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As long as the interval being timed (30 sec here) is less than the ~50 day millis() rollover interval, and if the comparison is done with subtraction and unsigned variables as it is here (good job!) then the rollover will never be a problem. The code will operate the same even if rollover occurs during the 30 second interval.

Thanks!
Logged

Portugal
Offline Offline
Edison Member
*
Karma: 37
Posts: 1531
Pretending you know everything then you will learn nothing.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As long as the interval being timed (30 sec here) is less than the ~50 day millis() rollover interval, and if the comparison is done with subtraction and unsigned variables as it is here (good job!) then the rollover will never be a problem.
I don't agree with this.
There is a possible failure when the rollover occurs.
Code:
unsigned long startMillis = millis(); //create a counter
  while(1){
    if (millis() - startMillis > 30000) DoorError(); //longer than 30 sec means the string is tangled
    if (digitalRead(TopSwitch) == 0) { //Switch is closed
      digitalWrite(motorClosePin, LOW);  //Brake
      digitalWrite(motorOpenPin, LOW);  //Brake
      delay(500); //wait a bit
      digitalWrite(HBRIDGEpower, LOW);  //power down the H Bridge
      break;
    }
    delay(10);
Lets assume startMillis is now 4,294,967,293( near the end of an unsigned long) and then the mills() function return on the if the value of 4 because the rollover had just happened, this "if (millis() - startMillis > 30000) DoorError();" will be false even if the 30 seconds pass.So there is a leak in your code.
I know the probabilities of that happen are very very small but the failure is there.
Logged

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13471
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
 while(1){
    if (millis() - startMillis > 30000) DoorError(); //longer than 30 sec means the string is tangled
    if (digitalRead(TopSwitch) == 0) { //Switch is closed
      digitalWrite(motorClosePin, LOW);  //Brake
      digitalWrite(motorOpenPin, LOW);  //Brake
      delay(500); //wait a bit
      digitalWrite(HBRIDGEpower, LOW);  //power down the H Bridge
      break;
    }
    delay(10);

don't know how DoorError() is implemented, should it shut down the HBRIDGE and motors?

@hugoPT
as the math is unsigned it will work, you can test it in a small sketch
Code:
void setup()
{
  Serial.begin(9600);
  unsigned long a = 4,294,967,293;
  unsigned long b = 1000;
  unsigned long c = b - 1;
  Serial.println(c);
}

void loop(){}
Logged

Rob Tillaart

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

Portugal
Offline Offline
Edison Member
*
Karma: 37
Posts: 1531
Pretending you know everything then you will learn nothing.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes you are right.
Logged

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
while(1){
    if (millis() - startMillis > 30000) DoorError(); //longer than 30 sec means the string is tangled
    if (digitalRead(TopSwitch) == 0) { //Switch is closed
      digitalWrite(motorClosePin, LOW);  //Brake
      digitalWrite(motorOpenPin, LOW);  //Brake
      delay(500); //wait a bit
      digitalWrite(HBRIDGEpower, LOW);  //power down the H Bridge
      break;
    }
    delay(10);
  }

There is no problem with rollover, however I can see DoorError being called every 10 mS.
Logged

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
There is no problem with rollover, however I can see DoorError being called every 10 mS.
why?  I don't see it.
Logged

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, I see what you're saying. 
If DoorError() is called, it shuts the whole system down ending with an endless while{} statement, waiting for the user to fix the problem.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When you just post snippets we have to guess what the rest does. smiley-razz
Logged

Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As long as the interval being timed (30 sec here) is less than the ~50 day millis() rollover interval, ...
It will be good for 30 seconds, but not for ~50 days. The maximum interval we can time is half of that (2^32 / 2 - 1 = ~24.86 days).

  32-bit max interval -> ~24.86days
  16-bit max interval -> 32.767 seconds
    8-bit max interval -> 127 milliseconds
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12739
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It will be good for 30 seconds, but not for ~50 days. The maximum interval we can time is half of that (2^32 / 2 - 1 = ~24.86 days).

Are you certain?  Are you certain enough to wager?
Logged

Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It will be good for 30 seconds, but not for ~50 days. The maximum interval we can time is half of that (2^32 / 2 - 1 = ~24.86 days).

Are you certain?  Are you certain enough to wager?

Certain of what?

My post is addressing whether this quote is true or false:

"As long as the interval being timed (30 sec here) is less than the ~50 day millis() rollover interval, and if the comparison is done with subtraction and unsigned variables as it is here (good job!) then the rollover will never be a problem."

I say yes, but only if interval being timed is less than ~24 days.

Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12739
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I say yes, but only if interval being timed is less than ~24 days.

And I say you're wrong.  How would you like to proceed?
Logged

Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you only care to express your opinion, I have nothing further to add.

If on the other hand, you want to contribute with insight or knowledge this is my take:

The difference between two unsigned quantities (as in the code discussed above and quoted below) is signed and so the interval is limited to the LONG_MIN ... LONG_MAX range.

Code:
   if (millis() - startMillis > 30000) DoorError(); //longer than 30 sec means the string is tangled

Logged

Pages: [1] 2   Go Up
Jump to: