time compare when millis() is close to reset to 0

Hi mates, I've a question which I hard figure out to solve, thanks for help.

I've a sensible routine that checks for how long a button is pressed, I would use the variable millis() to calculate the difference and act according to it, in particular there may be 2 cases: the button is released before X millis or it keeps pressed (there may be some seconds).

Now if the button is pressed and millis will reach its limits, what can I have as result of substraction? Let's make and example with easier numbers, let's suppose I need to count 2 seconds to make a decision and that the limit of millis() is 1000. I press the button when millis is 999 and I save this value:

unsigned long timesaved; unsigned long result_of_substraction; if (button is pressed and was not pressed before) {timesaved=millis, button is pressed} if (button is pressed and was pressed before) {result_of_substraction=millis-timesaved if (result_of_substraction>2) {do what I need}

now millis becomes 0, what it will be result_of_substraction? 1? and when millis is 1, it will be 2 and so on? Is this the right approach to don't have any problem? Thank you

You can test this out to get a handle on unsigned math.

void setup() {

  // byte is unsigned char (0-255)
  // makes demo easier than unsigned long
  // but the principle is the same
  byte val1 = 254;
  byte val2 = 4;

  byte result = val2 - val1;
  int signed_num = val2 - val1;

  Serial.print( "4 - 254 = " );
  Serial.print( result );
  Serial.println( " using unsigned math" );
  Serial.print( "4 - 254 = " );
  Serial.print( signed_num );
  Serial.println( " using signed math" );

void loop() {
  // put your main code here, to run repeatedly:


Now if the button is pressed and millis will reach its limits, what can I have as result of substraction?

will your code run for ~50 days ? if not you don't need to worry about millis() overflowing its 32 bits and rolling over to 0

That being said, if you memorize the millis() at the time of the button press (say in variable pressTime) and perform a subtraction: millis() - pressTime that will give you the duration (in ms) of the press even if millis() has rolled-over.

of course if you keep the button pressed for more than 50 days (or so) then you'll have an issue and the duration will be wrong (or right modulo ~50 days)

Thank you for your kind help, at this moment I don’t have arduino here to program,
I just suppose my solution is good, using all unsigned numbers, so (as example I gave)

1-999 (supposing that 1000 is like ff:ff:ff:ff) gives 2?

Thanks for the second answer too, yes the system will run forever, it’s not a question of pressing it for 50 days but the moment when I press, if it will be closest to the reset of the counter it will be saved as that, and then the substraction needs to give the time passed without overflow, or negative numbers, etc.

If you use subtraction for checking time (as in the following example) the calculations will work perfectly even when millis() rolls over to 0

if (millis() - startTime >= interval) {
    // do stuff

Have a look at how millis() is used to manage timing in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.


Maybe a visual will help.

Clear, thank you!