Go Down

Topic: Millis() rover over handling (Read 1 time) previous topic - next topic

SouthernAtHeart

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: [Select]
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);
  }
}

Jack Christensen

#1
Jul 05, 2013, 09:20 pm Last Edit: Jul 05, 2013, 09:26 pm by Jack Christensen Reason: 1
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.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

SouthernAtHeart


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!

HugoPT

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: [Select]
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.
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

robtillaart

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

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(){}
Rob Tillaart

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

Go Up