Timed Events In Code (Repeated and Once only)

Hello!

Very frequently I see posts saying 'How can I do 'this and that' at the same time or 'I'm doing X but it's stopping me from being able to do Y.... and then blinkWithoutDelay gets posted over and over again. I thought that maybe we could offer the people in these situations a simpler solution.

As such, I'd like to offer up a super simple class to be included that allows people to do repetitive or one time 'timed actions'. It essentially encapsulates a millis timer and takes in a float as the number of seconds, or an unsigned long for milliseconds. Nothing too special but super easy to use, which I think is where the value is.

Open to discussion in regards to comments, criticisms, improvements! etc.

The only downside I see is 'spoon feeding' the budding learner and not allowing them to figure out how it works for themselves - although they can also look at the TimedEvents.h code.

Here's the TimedEvents.h (944 Bytes)
(TimedEvents v0.1)

#ifndef TIMEDEVENTS_H
#define TIMEDEVENTS_H

// TimedEvent Version 0.1

class TimedEvent {
  private:
    unsigned long timeCapture;
    bool complete = false;
  
  public:
    bool every(float timer) {
      if ((millis() - timeCapture) > (unsigned long)(timer*1000)) {
        timeCapture = millis();
        return true;
      }
      else
        return false;
    }
  
    bool everyMs(unsigned long timer) {
      if ((millis() - timeCapture) > timer) {
        timeCapture = millis();
        return true;
      }
      else
        return false;
    }
    
    bool onceAt(float timer) {
      if (!complete && millis() >= (unsigned long)(timer*1000)) {
        complete = true;
        return true;
      }
      else
        return false;
    }

    bool onceAtMs(unsigned long timer) {
      if (!complete && millis() >= timer) {
        complete = true;
        return true;
      }
      else
        return false;
    }
};

#endif

And an example of it being used:

#include "TimedEvents.h"

#define LED_ONE 6
#define LED_TWO 7
#define LED_THREE 8

// Timed Events can be global variables
TimedEvent t1;
TimedEvent t2;

TimedEvent t4;
TimedEvent t5;


void setup() {
  Serial.begin(9600);
  pinMode(LED_ONE, OUTPUT);
  pinMode(LED_TWO, OUTPUT);
  pinMode(LED_THREE, OUTPUT);
}

void loop() {
// The TimedEvent.every() function takes a float and returns true once every 'x' seconds
// The TimedEvent.everyMs() function takes an unsigned long and returns true once every 'x' milliseconds

  if (t1.everyMs(500)) // Repeat every 500 milliseconds
    digitalWrite(LED_ONE, !digitalRead(LED_ONE));

  if (t2.every(1.0f)) // Repeat every 1.0 second
    digitalWrite(LED_TWO, !digitalRead(LED_TWO));

  static TimedEvent t3; // TimedEvent can also be static local variables
  if (t3.every(1.5f)) // // Repeat every 1.5 seconds
    digitalWrite(LED_THREE, !digitalRead(LED_THREE));



// The TimedEvent.onceAt() function takes a float and returns true once only at 'x' seconds
// The TimedEvent.onceAtMs() function takes an unsigned long and returns true once only at 'x' milliseconds

  if (t4.onceAtMs(3000)) { // Once at 3000 milliseconds
    Serial.print("Here's a one time event at: ");
    Serial.println(millis());
  }

  if (t5.onceAt(5.0f)) { // Once at 5 seconds
    Serial.print("Here's a one time event at: ");
    Serial.println(millis());
  }

  static TimedEvent t6;
  if (t6.onceAtMs(7000)) { // Once at 3000 milliseconds
    Serial.print("Here's a one time event at: ");
    Serial.println(millis());
  }
}


See it in action: TimedEvents V0.1 - Wokwi Arduino Simulator

@st3v3n92
I've moved this to introductory tutorials at the suggestion of another member of the forum as that seems to be a more appropriate place for it.

1 Like

My MobaTools library already contains such a class 'MoToTimebase'. It also contains a class to create one-shot timers without dealing with millis() directly.
But as always there are many possible solutions... And everyone has to decide for himself whether he wants to do it the 'hard' way and learn how millis() works, or whether he is looking for an easy and convenient solution :wink:

While I admire your attempt to help newbies the problem is not that the help isn't there in the forum already the problem is that many newbies don't find the help unless and until someone points it out, as you seem to have noticed.

If you can find a way to actually get people to read the help that's already here then I am sure I and every other forum member who is completely bored out of our boxes with posting the same links to the same tutorials will probably buy you enough drinks to drown in beer or wine or whatever it is you like to drink!

1 Like