0
votes

I currently measure elapsed time in my sketch with a code to measure elapsed time like the one seen here. The code needs to be accurate to about 1 second, but I would like to program it to be as robust as possible.

unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval) 
{foo;}

I'm wondering what the best way to add a pause functionality so that if bool pause == true either previousMillis or interval adjusts to make sure that foo fires after pause==false for interval

Right now I'm thinking something along the lines of:

//global setup
bool pause=false;
unsigned long previousMillis = 0;
unsigned long interval = 1000;
_________
unsigned long currentMillis = millis();
RClock();
if ((unsigned long)(currentMillis - previousMillis) >= interval) 
{
 interval=1000;
 foo;
}

void RClock()
{
  if(pause)
  {
     unsigned long runtime = millis()-previousMillis;
     unsigned long timeleft= interval-runtime;
     previousMillis=millis();
     interval=timeleft;
  }
}

Is there a better way to do this? I feel like it should be a more simple operation.

Edit To clear things up, my goal is for foo to trigger when pause==true for a total of interval so if interval=1000(ms) and, during that time, pause==true for 500(ms) foo would occour after 1500 ms

Edit 2

To clarify further, the time something runs before pause==true needs to be taken into acount lets say that:

  • interval = 1000(ms) when the program starts.

  • The program runs for 500(ms)

  • After 500(ms) pause == true

  • After 3hr Pause == false

    foo will be triggered after 500(ms) more of Pause == false

3
Your question is not very clear. You want to "pause the chronometer' while pause==true?fnocetti
Correct. My end goal is for foo to trigger when pause==true for a total of intervalATE-ENGE
where in your code you are assigning pause=true? What I understood from question is you want to execute foo for 500ms for every 1000ms, correct?svtag

3 Answers

0
votes
if (pause && ((unsigned long)(currentMillis - previousMillis) >= interval))
0
votes

millis() goes back to zero for one millisecond every 50 days. Hence the extra test. PreviousMillis != 0 controls the triggering

void Loop()
{
   //...
   if (pause)
   {
      previousMillis = millis();
      if (previousMillis == 0)
        previousMillis = 1;   // avoid the one in a billion chance of missing a trigger
   }
   if (previousMillis && ((millis() - previousMillis) > interval))
   {
      previousMillis = 0;     // prevents retriggering
      foo();
   }
   //...
}

The timer is set coninuously withe the current 'time' while pause == true.

When not in pause, the timer will pass the second test after interval ms.

The timer is set to zero when done; this avoids false triggers.

0
votes

Currently I've written the following code that has the functionality I want, but I'm sure it's not the best way to go about it

(Global Vars)

unsigned long time_B  =0
unsigned long time_E = 0

(Code)

//...
unsigned long RClock (bool reset, bool pause)
{
  unsigned long Ctime=millis();
  if(reset)
  {
    time_B=Ctime;
    //Serial.println("reset");
  }
  if(pause)
  {
    time_B=Ctime-time_E;
    //Serial.println("pause");
  }
  time_E=Ctime-time_B;
  return time_E;  
}
//...