Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Resetting millis() - again

  1. #1

    Resetting millis() - again

    Hi

    I have a project that potentially sits for weeks on end, but at any point could be 'triggered'.

    There are various millis() based timers involved in the event while it is occurring, and the event can last a varying length of time.

    I have read all over the shop that you should never reset millis(), as it's not required and might break libraries.

    My question is.... why not? I cannot check for a possible rollover conflict after approx 49 days, as the event lengths change considerably.

    Therefore, surely, it's just simpler to say that if the event isn't occurring, and the millis() timer is over a certain limit, then reset the millis() to zero and avoid the potential rollover mid event issue?

    Hmm

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,140
    Best is to use relative offsets on millis() for each timer involved.
    A uint32_t will always give the offset even after rollover of the millis() return value

    No idea what the usage for each looks like - seems this might cover the use case?
    Code:
    uint32_t aTime;
    bool aActive=false;
    
    if ( time to wait 3300 milliseconds) {
     // 'a' thing START now
     aActive = true;
     aTime = millis();
    }
    
    if ( aActive && (millis() - aTime > 3300 ) {
     aActive = false;
     // 'a' thing DONE now
    }

  3. #3
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    586
    Quote Originally Posted by SteveCS View Post
    Hi

    I have a project that potentially sits for weeks on end, but at any point could be 'triggered'.

    There are various millis() based timers involved in the event while it is occurring, and the event can last a varying length of time.

    I have read all over the shop that you should never reset millis(), as it's not required and might break libraries.

    My question is.... why not? I cannot check for a possible rollover conflict after approx 49 days, as the event lengths change considerably.

    Therefore, surely, it's just simpler to say that if the event isn't occurring, and the millis() timer is over a certain limit, then reset the millis() to zero and avoid the potential rollover mid event issue?

    Hmm
    Check <this post> for a good reference (thanks & credit to rcarr) on how to avoid any potential problems when millis() rolls over.

    Mark J Culross
    KD5RXT

  4. #4
    OK. I will look into this further

    I had this in my code, but it doesn't compile anyway, as the 'timer0_millis = 0;' line throws an error

    Code:
      currentMillis = millis();
    
      if ((triggered == false) && (currentMillis > 4294963696)) {                                      // Reset millis() counter 1 hour before rollover assuming event isn't in progress
        noInterrupts ();
        timer0_millis = 0;
        interrupts ();
      }

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,140
    Trying to reset the global system milliseconds value can only cause trouble.

    Quote Originally Posted by defragster View Post
    Best is to use relative offsets on millis() for each timer involved.
    ...
    Above code, here using elapsedMillis that seems to be linked in above link?
    Same net effect - usage is cleaner - as the millis() ref is in the class code:
    Code:
    elapsedMillis aTime;
    bool aActive=false;
    
    if ( time to wait 3300 milliseconds) {
     // 'a' thing START now
     aActive = true;
     aTime = 0;
    }
    
    if ( aActive && (aTime > 3300 ) {
     aActive = false;
     // 'a' thing DONE now
    }

  6. #6
    Not sure my thick head understands that process

    Is that basically only allowing the process to start if there is enough time remaining (3300 milliseconds)? This means I need to know the length of my process, which can vary greatly.

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,140
    Quote Originally Posted by SteveCS View Post
    Not sure my thick head understands that process

    Is that basically only allowing the process to start if there is enough time remaining (3300 milliseconds)? This means I need to know the length of my process, which can vary greatly.
    Not seeing any code - assuming 'something happens' and sometime after that further response is needed?

    That's what that code does: Waits for event "if ( time to wait 3300 milliseconds)" then gives a way to see when 3300 ms has passed from that time.

    If the use case is different, it can be evolved once understood as a way to time a known interval from a given start point.

    Given example code perhaps that could be demonstrated if it isn't clear.

  8. #8
    Senior Member JarkkoL's Avatar
    Join Date
    Jul 2013
    Posts
    150
    I believe the reason why you should never reset the global timer is because other libraries likely assume that the time goes forward, so breaking this assumption likely causes a world of trouble.

    What you should do instead is to keep your own timer and keep updating it with the delta time, something like:
    Code:
    static unsigned long previousTime=millis();
    unsigned long currentTime=millis();
    unsigned long deltaTime=currentTime-previousTime;
    myTime+=deltaTme;
    previousTime=currentTime;
    Even if the global millis() rolls over, the deltaTime will be correct. Then it's up to you to handle myTime update correctly (e.g. add condition to increment myTimeHi when it rolls over)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •