BlinkWithoutDelay Overflow

I am working on a project where I have about 10 buttons on a gaming joystick controlling 3 sets of LED lights. Some of the lights blink in different patterns and others pulse like a heart and so on. I wanted to use the code I found on the BlinkWithoutDelay learning guide, but I wanted to make sure it would work for what I need it to. From what I can tell, the code uses 2 long data type variables to keep track of the milliseconds that have passed since it last checked the state of the lights, like so:

unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);

My question is, if I have my Arduino running constantly (because I want to always be checking for button presses) wont the previousMillis and currentMillis reach their limit fairly quickly? I haven't done the math but I don't think it could keep track of more than a few days worth of milliseconds. If I am on the right track, is there a way to reset those values every once and a while so that I could have the Arduino always on?

As long as you are using "unsigned long" you are fine, they will overflow in 49.7 days, but your code will not break, it will continue working.

Think about it. Lets say it will overflow at 100 back to 0. If we are checking if(millis() - lastMillis > 50) and millis() overflowed and is 10 and lastMillis is still at 90, then the result it 10 - 90 = -80, but -80 cannot be held by an unsigned long, thus it underflows back to 20 (100 + -80 = 20), which is the exact time that has passed.

Also, can you please put your code in code tags like this, select your code and press the </> button

wont the previousMillis and currentMillis reach their limit fairly quickly

If you think that 49 and a bit days is fairly quickly, then yes.

However, using the current - previous methodology the calculation will still be correct during and after the rollover.

Yes indeed, 2^32 mS is a lot of mS!

Ok, I think I understand. Correct me if I am wrong, but once either long reaches 2^32 milliseconds in roughly 49 days 17 hours 2 minutes 47 seconds and 296 milliseconds (minus one second because of the leap second on June 30th at 23:59:60 this year) it will not only keep working but will roll over to 0 but still keep correct math too? If that is the case, not only has that completely blown my mind, but that is perfect for what I need.

minus one second because of the leap second

No. Leap seconds are a political artifact having to do with higher-level calendar functions than are implemented by the Arduino. millis() and delay() ONLY operate on real elapsed time since the last reset. :slight_smile:

Drillbit:
...it will not only keep working but will roll over to 0 but still keep correct math too?

Just takes 70 seconds to prove / disprove...

const int ledPin = 13;

void setup() 
{
  Serial.begin( 115200 );
  pinMode( ledPin, OUTPUT );
}

void loop() 
{
  static unsigned short previousMillis;
  const unsigned short interval = 1000;
  static int ledState;
  
  unsigned short currentMillis;
  unsigned short delta;

  currentMillis = millis();

  delta = currentMillis - previousMillis;

  if ( delta >= interval ) 
  {
    Serial.write( '\t' );
    Serial.print( currentMillis );
    Serial.print( F( "\t-\t" ) );
    Serial.print( previousMillis );
    Serial.print( F( "\t=\t" ) );
    Serial.print( delta );
    Serial.println();
    
    // save the last time you blinked the LED
    previousMillis = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if ( ledState == LOW )
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite( ledPin, ledState );
  }
}

wont the previousMillis and currentMillis reach their limit fairly quickly?

Your clock goes up to 12, right? Doesn't it reach its limit fairly quickly? Ohno! What do you do when it does?

Also see this: Gammon Forum : Electronics : Microprocessors : millis() overflow ... a bad thing?