Writing a timing library, asking for suggestions

I am writing a timing library. (Well I am playing around)
Can you think of other functions that could be useful to add?

#include <CheckTime.h>

//Instantiate objects
CheckTime MyTimer;  
CheckTime My2ndTimer;  
CheckTime My3rdTimer;  
CheckTime FlashLED;
CheckTime Flash2ndLED;  

void setup()
{
  Serial.begin(9600);
  
  MyTimer.StartTiming(5000UL);    //Start this timer with 5 second delay
  FlashLED.StartTiming(100UL);    //Start this timer with 1/10 second delay 
  My2ndTimer.StartTiming(6000UL); //Start this timer with 6 second delay
  Flash2ndLED.StartTiming(500UL); //Start this timer with 1/2 second delay 
  My3rdTimer.StartTiming(10000UL); //Start this timer with 10 second delay

  pinMode(13,OUTPUT); //LED connected to this pin
  pinMode(12,OUTPUT); //LED connected to this pin
  pinMode(11,OUTPUT); //LED connected to this pin
  pinMode(10,OUTPUT); //LED connected to this pin
}

void loop()
{
  //Ex: #1, limits how long something is done before a delay period is up
  if(MyTimer.DoUntil())    //As long as we have not reached the delay time, execute the code within
  {
    if(FlashLED.Repeat())  //When this delay is over execute the code within, then start again.
    {
      digitalWrite(13,!digitalRead(13));
    }
    
  }

  //Ex: #2, executes something once after a delay period
  if(My2ndTimer.DoWhen())   //When the timer delay is over, execute the code within 
  {
    Serial.println("Time is UP");
    digitalWrite(12,!digitalRead(12)); //Toggle LED on then off
    delay(1); //so you can see the LED flash
    digitalWrite(12,!digitalRead(12));
  }
  
    //Ex: #3, executes something after a delay period then start the delay period again
  if(My3rdTimer.DoWhen())   //When the timer delay is over, execute the code within 
  {
    digitalWrite(11,!digitalRead(11));
    My3rdTimer.StartTiming(10000UL);  //Restart this delay period
    delay(1); //so you can see the LED flash
    digitalWrite(11,!digitalRead(11));
  }

  //Ex: #4, executes something over and over again after a delay period 
  if(Flash2ndLED.Repeat())  //When the delay is over, execute the code within, then start again.
  {
    digitalWrite(10,!digitalRead(10));
  }


} //END of loop()
#include <Arduino.h>

// CheckTime.cpp
// CheckTime.h"
//
// Rev 1.00   October 3, 2015 functional code
//
//=============================================================================
//                    F U N C T I O N    P R O T O T Y P E S
//=============================================================================

//                       C l a s s   C h e c k T i m e 

class CheckTime
{
public:
  //CheckTime();
  void begin();
  void StartTiming(unsigned long);
  void ResetTiming();
  void EnableTiming();
  void DisableTiming();
  void SetDelay(unsigned long);
  bool IsEnabled();
  bool Repeat();
  bool DoWhen();
  bool DoUntil();

private:
  bool enabled;
  unsigned long _Delay;
  unsigned long lastMillis; 

};  // END of CheckTime class  
// In C++ you must have a ; at the end of a class definition
//*****************************************************************************

#include "CheckTime.h"

//
//*****************************************************************************
//                     C l a s s   C h e c k T i m e 
//*****************************************************************************
//Constructor

//CheckTime::CheckTime()
//{
//} // END of CheckTime()

//********************************************************** 
//Initialization
//void CheckTime::begin()
//{
//} // END of begin()

//********************************************************** 
//
void CheckTime::StartTiming(unsigned long Delay)
{
  _Delay = Delay;
  lastMillis = millis();  
  enabled = true;
} // END of StartTimer()

//********************************************************** 
//
void CheckTime::EnableTiming()
{
  enabled = true;  
} // END of EnableTimer()

//********************************************************** 
//
void CheckTime::DisableTiming()
{
  enabled = false;  
} // END of DisableTimer()

//********************************************************** 
//
bool CheckTime::IsEnabled()
{
  return enabled;
} // END of IsEnabled()

//********************************************************** 
//
void CheckTime::ResetTiming()
{
  lastMillis = millis();  
} // END of ResetTimer()

//********************************************************** 
//
void CheckTime::SetDelay(unsigned long Delay)
{
  _Delay = Delay;  
} // END of SetDelay()

//********************************************************** 
//
bool CheckTime::Repeat()
{
  if(enabled && millis() - lastMillis >= _Delay)
  {
    lastMillis = lastMillis + _Delay;
    return true;
  }

  return false;
} // END of Repeat()

//********************************************************** 
//
bool CheckTime::DoWhen()
{
  if(enabled && millis() - lastMillis >= _Delay)
  {
    enabled = false;
    return true;
  }  

  return false;
} // END of DoWhen()

//**********************************************************
//
bool CheckTime::DoUntil()
{
  if(enabled && millis() - lastMillis <= _Delay)
  {
    return true;
  }  

  enabled = false;
  return false;
} // END of DoUntil()

//**********************************************************

DoWhen() and DoUntil() don't actually DO anything. So, the choice of names is poor.

CheckTime doesn't adequately define what the class is for.

  lastMillis = millis();

as opposed to timingStarted? What a lousy name.

Should the user or the instance keep track of whether timing is enabled, when ResetTiming() is called? That function restarts the timer. So, again, could use a better name.

SetDelay() sets the interval, not the delay.

But, the most important problem is that it is up to each instance to check, periodically, to see if it is time to do something. The instances can't say "call me when...".

Otherwise, nice first attempt.

I would like the ladder logic equivalent of a timer

makeTimer(name,timeBase); //in set up

startTimer(name);

timerTiming(name); // something I can use in a "if"

timerDone(name); // something I can use in a "if"

timerDisplay(name,type);//time countdown, count up, etc

resetTimer(name);

one day I will learn to code as my first few attempts at this were so bad I deleted them....lol

Here's my take:
Timer.h:

// Timer.h
// OO based timer class by aarg, Arduino forum 2015-10-04

#include <Arduino.h>
#define MILLIS_PER_SEC 1000UL

class Timer {
  private:
    unsigned long interval;
    unsigned long previousMillis;

  public:
    Timer(unsigned long interval);

    void start();
    byte complete();
    unsigned long elapsed();
    unsigned long remaining();
};

// end class

Timer.cpp:

// Timer.cpp
// OO based timer class by aarg, Arduino forum 2015-10-04
//

#include "Timer.h"

Timer::Timer(unsigned long iv)  //class constructor
{
  interval = iv;
}

void Timer::start()
{
  previousMillis = millis();
}

unsigned long Timer::elapsed()
{
  return millis() - previousMillis;
}

byte Timer::complete()
{
  if (elapsed() >= interval)  //if the time interval has elapsed
  {
    previousMillis += interval;                //save the time of change
    return true;
  }
  else
  {
    return false;
  }
}

unsigned long Timer::remaining()
{
  return interval - elapsed();
}

// end class definition

The sketch:

// OO based blink sketch by aarg, Arduino forum 2015-10-04

#include <Timer.h>

Timer LEDtimer(5 * MILLIS_PER_SEC);
Timer SerialTimer(MILLIS_PER_SEC / 2);

void setup()
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  LEDtimer.start();
  SerialTimer.start();
}

void loop()
{
  // toggle the LED on/off every 5 seconds
  if (LEDtimer.complete())
  {
    digitalWrite(LED_BUILTIN, not digitalRead(LED_BUILTIN));
    LEDtimer.start();
  }

  // print the LED timer's remaining time 10 times a second
  if (SerialTimer.complete())
  {
    Serial.println(LEDtimer.remaining());
    SerialTimer.start();
  }
}

I am not in favour of timing libraries - especially if they are just dressing up millis() in a nice party frock. Spend the same amount of effort writing a tutorial on the use of millis() and the end-user will be much better served.

Teach a man to fish and he can feed his family for his lifetime. Give him a fish and they will all be hungry again tomorrow.

...R

@PaulS
Naming is poor.
Agreed, I too am not am excited about the naming.

MayBe:
CheckTime CreateTimer
DoWhen() Done()
DoWhile() While()
After() New function, same as !While() would be.
ResetTimer() Restart()
SetDelay() SetInterval()

@gpop1
Timer, Done, Display are reasonable

@Robin2
I fully agree.

Teach a man to fish and he can feed his family for his lifetime. Give him a fish and they will all be hungry again tomorrow.

And then there is the man only likes candy.

Robin2:
...especially if they are just dressing up millis() in a nice party frock...

It's encapsulation.

Robin2:
I am not in favour of timing libraries - especially if they are just dressing up millis() in a nice party frock. Spend the same amount of effort writing a tutorial on the use of millis() and the end-user will be much better served.

Teach a man to fish and he can feed his family for his lifetime. Give him a fish and they will all be hungry again tomorrow.

...R

I like the party frock

I find the hardest part to explain to people is when to take a new time stamp. For some reason people just struggle with the concept of where in the program to add the new time stamp. If telling them this is the point we start and this is the point we say that the timer is done then they will get the idea. Once they get the idea of where to do things in a logical order the use of millis() prevmillis will become easier.

sometimes small steps work better

aarg:
It's encapsulation.

I much prefer party frocks. :slight_smile:

...R

I much prefer party frocks.

Depends on who's wearing them...

@aarg
Got some ideas from your code.
Thank you very much.

@Robin2

I much prefer party frocks. :slight_smile:

Or no party frocks at all. :wink:

Here is version 1.01 of the library:

#include <CreateTimer.h>

//Instantiate objects
CreateTimer MyTimer;  
CreateTimer My1stTimer;
CreateTimer My2ndTimer;  
CreateTimer My3rdTimer;  
CreateTimer FlashLED;
CreateTimer Flash2ndLED;  

void setup()
{
  Serial.begin(9600);

  MyTimer.Start(5000UL);     //Start this timer with 5 second Interval
  My1stTimer.Start(4000UL);  //Start this timer with 4 second Interval
  FlashLED.Start(100UL);     //Start this timer with 100ms Interval 
  My2ndTimer.Start(6000UL);  //Start this timer with 6 second Interval
  Flash2ndLED.Start(500UL);  //Start this timer with 500ms Interval 
  My3rdTimer.Start(10000UL); //Start this timer with 10 second Interval

  pinMode(13,OUTPUT); //LED connected to this pin
  pinMode(12,OUTPUT); //LED connected to this pin
  pinMode(11,OUTPUT); //LED connected to this pin
  pinMode(10,OUTPUT); //LED connected to this pin
  pinMode(9,OUTPUT);  //LED connected to this pin
}

void loop()
{
  //Ex: #1, executes code as in an Interval period
  if(MyTimer.While())     //As long as we have not reached the Interval time, execute the code within
  {
    if(FlashLED.Repeat()) //When this Interval is over execute the code within, then start again.
    {
      digitalWrite(13,!digitalRead(13));
    }
  }

  Serial.print("Time left in MyTimer = ");
  Serial.println(MyTimer.Remaining()); //Output the time left in this timer

  //Example #2 executes code after an Interval has passed. This will continue. 
  if(My1stTimer.After())   //After we have reached the Interval time, continue to execute this code
  {
    digitalWrite(9,!digitalRead(9));
    delay(50);             //so you can see the LED flash  
  }

  //  Serial.print("Time left in My1stTimer = ");
  //  Serial.println(My1stTimer.Remaining()); //Output the time left in this timer

  //Ex: #3, executes code "ONCE ONLY" after an Interval period
  if(My2ndTimer.Finished()) //When the timer Interval is over, execute the code within 
  {
    Serial.println("My2ndTimer Interval has expired");
    digitalWrite(12,!digitalRead(12)); //Toggle LED on then off
    delay(1);                          //so you can see the LED flash
    digitalWrite(12,!digitalRead(12));
  }

  //  Serial.print("Time left in My2ndTimer = ");
  //  Serial.println(My2ndTimer.Remaining()); //Output the time left in this timer

  //Ex: #4, executes code after an Interval period, then starts the Interval period again
  if(My3rdTimer.Finished())    //When the timer Interval is over, execute the code within 
  {
    digitalWrite(11,!digitalRead(11));
    delay(1);                  //so you can see the LED flash
    digitalWrite(11,!digitalRead(11));
    My3rdTimer.Start(10000UL); //Restart this Interval period
  }

  //  Serial.print("Time left in My3rdTimer = ");
  //  Serial.println(My3rdTimer.Remaining()); //Output the time left in this timer

  //Ex: #5, executes code over and over again, i.e. after an Interval period 
  if(Flash2ndLED.Repeat()) //When the Interval is over, execute the code within, then start again.
  {
    digitalWrite(10,!digitalRead(10));
  }

  //  Serial.print("Time left in Flash2ndLED = ");
  //  Serial.println(Flash2ndLED.Remaining()); //Output the time left in this timer

} //END of loop()
#include <Arduino.h>

// CreateTimer.cpp
// CreateTimer.h"
//
// Rev 
// 1.00   October 2, 2015 Functional code
// 1.01   October 4, 2015 Renamed variables and functions. Added: After() Remaining() Elapsed()
//
//=============================================================================
//                    F U N C T I O N    P R O T O T Y P E S
//=============================================================================

//                      C l a s s   C r e a t e T i m  e r  
 
class CreateTimer
{
public:
  //CreateTimer();
  void begin();
  void Start(unsigned long);
  void Restart();
  void Enable();
  void Disable();
  void SetInterval(unsigned long);
  bool IsEnabled();
  unsigned long Elapsed(); //1.01
  unsigned long Remaining(); //1.01
  bool Repeat();
  bool Finished();
  bool While();
  bool After(); //1.01
  
private:
  bool enabled;
  unsigned long _Interval;
  unsigned long lastMillis; 
  unsigned long _temp; //temporary variable 1.01

};  // END of CreateTimer class  
// In C++ you must have a ; at the end of a class definition
//*****************************************************************************

#include "CreateTimer.h"

//
//*****************************************************************************
//                    C l a s s   C r e a t e T i m e r  
//*****************************************************************************
//Constructor

//CreateTimer::CreateTimer()
//{
//} // END of CreateTimer()

//********************************************************** 
//Initialization
//void CreateTimer::begin()
//{
//} // END of begin()

//********************************************************** 
//
void CreateTimer::Start(unsigned long Interval)
{
  _Interval = Interval;
  lastMillis = millis();  
  enabled = true;
} // END of Start()

//********************************************************** 
//
void CreateTimer::Enable()
{
  enabled = true;  
} // END of Enable()

//********************************************************** 
//
void CreateTimer::Disable()
{
  enabled = false;  
} // END of Disable()

//********************************************************** 
//
bool CreateTimer::IsEnabled()
{
  return enabled;
} // END of IsEnabled()

//********************************************************** 
//
void CreateTimer::Restart()
{
  lastMillis = millis();  
} // END of Restart()

//********************************************************** 
//
unsigned long CreateTimer::Elapsed() //1.01
{
  return millis() - lastMillis;
} // END of Elapsed()

//********************************************************** 
//
unsigned long CreateTimer::Remaining() //1.01
{
  _temp = _Interval - Elapsed();
  if(_Interval >= _temp)
  {
  return _temp;
  }
  else
  {
  return 0;  //if there was an under flow, return zero
  }
} // END of Remaining()

//********************************************************** 
//
void CreateTimer::SetInterval(unsigned long Interval)
{
  _Interval = Interval;  
} // END of SetInterval()

//********************************************************** 
//
bool CreateTimer::Repeat()
{
  if(enabled && Elapsed() >= _Interval)
  {
    lastMillis = lastMillis + _Interval;
    return true;
  }

  return false;
} // END of Repeat()

//********************************************************** 
//
bool CreateTimer::Finished()
{
  if(enabled && Elapsed() >= _Interval)
  {
    enabled = false;
    return true;
  }  

  return false;
} // END of Finished()

//**********************************************************
//
bool CreateTimer::While()
{
  if(enabled && Elapsed() <= _Interval)
  {
    return true;
  }  

  enabled = false;
  return false;
} // END of While()

//**********************************************************
//
bool CreateTimer::After() //1.01
{
  if(enabled && Elapsed() <= _Interval)
  {
    return false;
  }  

  enabled = false;
  return true;
} // END of After()


// END of CreateTimer class definition

Attached is the zip file.
.

CreateTimer.zip (2.8 KB)

Robin2:
I much prefer party frocks. :slight_smile:

...R

But then, isn't millis() just timer 0 wearing pretty underwear?

aarg:
But then, isn't millis() just timer 0 wearing pretty underwear?

Now you are getting me all steamed up :slight_smile:

You are, of course, quite correct. But I think millis() does add some useful simplification - and it is itself very simple. There is really no need to read its documentation.

...R

Her s the latest version of the library:

#include <CreateTimer.h>
/*
CreateTimer::Start(unsigned long);              Starts your timer, requires an Interval 
CreateTimer::StartRepeat(unsigned long, long);  Starts your timer, requires an Interval, requires a "Repeat" value  
CreateTimer::Restart();                         The timer Interval is restarted
CreateTimer::Enable();                          Allow timer action
CreateTimer::Disable();                         Disable timer action
CreateTimer::SetInterval(unsigned long);        Change timer Interval
CreateTimer::IsEnabled();                       bool returns the timer enable status
CreateTimer::Remaining();	                unsigned long returns the ms left in this timer
CreateTimer::Repeat();                          bool true when interval is reached, may repeat timing
                                                     if you used StartRepeat() to start the timer
CreateTimer::Once();                            bool true when interval is reached, then false there after
CreateTimer::While();                           bool true until interval is reached, false there after
CreateTimer::After();                           bool false until interval is reached, true there after  
*/

//Instantiate objects
CreateTimer MyTimer;  
CreateTimer My1stTimer;
CreateTimer My2ndTimer;  
CreateTimer My3rdTimer;  
CreateTimer FlashLED;
CreateTimer Flash2ndLED;  

void setup()
{
  Serial.begin(9600);

  MyTimer.Start(5000UL);             //Start this timer with a 5 second Interval
  My1stTimer.Start(4000UL);          //Start this timer with a 4 second Interval
  FlashLED.Start(100UL);             //Start this timer with a 100ms Interval 
  My2ndTimer.Start(6000UL);          //Start this timer with a 6 second Interval
  Flash2ndLED.StartRepeat(500UL,20); //Start this timer with a 500ms Interval, Repeat 20 times 
  My3rdTimer.Start(10000UL);         //Start this timer with a 10 second Interval

  pinMode(13,OUTPUT); //LED connected to this pin
  pinMode(12,OUTPUT); //LED connected to this pin
  pinMode(11,OUTPUT); //LED connected to this pin
  pinMode(10,OUTPUT); //LED connected to this pin
  pinMode(9,OUTPUT);  //LED connected to this pin
}

void loop()
{
  // The following 6 examples are non blocking
  
  //*************************************************************************
  //Ex: #1, This timer was started by: MyTimer.Start(5000UL); 
  //executes code while in an Interval period.
  if(MyTimer.While())     
  {
    //**********************************************************************
    //Ex: #2, This timer was started by: FlashLED.Start(100UL);  
    //executes code after an Interval period, the timer restarts automatically      
    if(FlashLED.Repeat()) 
    {
      digitalWrite(13,!digitalRead(13));
    }
  }

  Serial.print("Time left in MyTimer = ");
  Serial.println(MyTimer.Remaining());     //Outputs the time in ms left in this timer

  //*************************************************************************
  //Example #3 This timer was started by: My1stTimer.Start(4000UL);
  //executes code after an Interval has passed   
  if(My1stTimer.After())   
  {
    digitalWrite(12,!digitalRead(12));
    delay(50);             //so you can see the LED flash  
  }

  //  Serial.print("Time left in My1stTimer = ");
  //  Serial.println(My1stTimer.Remaining()); //Outputs the time in ms left in this timer

  //*************************************************************************
  //Ex: #4, This timer was started by: My2ndTimer.Start(6000UL);
  //executes code "ONCE ONLY" after an Interval period
  if(My2ndTimer.Once()) 
  {
    Serial.println("My2ndTimer Interval has expired");
    digitalWrite(11,!digitalRead(11)); //Toggle LED on then off
    delay(10);                         //so you can see the LED flash
    digitalWrite(11,!digitalRead(11));
  }

  //  Serial.print("Time left in My2ndTimer = ");
  //  Serial.println(My2ndTimer.Remaining()); //Outputs the time in ms left in this timer

  //*************************************************************************
  //Ex: #5, This timer was started by: My3rdTimer.Start(10000UL); 
  //executes code after an Interval period, then starts the Interval period timing again
  if(My3rdTimer.Once())    
  {
    Serial.println("My3rdTimer Interval has expired");
    digitalWrite(10,!digitalRead(10));
    delay(10);                 //so you can see the LED flash
    digitalWrite(10,!digitalRead(10));
    
    My3rdTimer.Start(10000UL); //Start this Interval period again
  }

  //  Serial.print("Time left in My3rdTimer = ");
  //  Serial.println(My3rdTimer.Remaining()); //Outputs the time in ms left in this timer

  //*************************************************************************
  //Ex: #6, This timer was started by:  Flash2ndLED.StartRepeat(500UL,20);  
  //executes code after an Interval, this happens "Repeat" number of times   
  if(Flash2ndLED.Repeat()) 
  {
    digitalWrite(9,!digitalRead(9));
    delay(100);               //so you can see and count the the LED flashes
    digitalWrite(9,!digitalRead(9));

  }

  //  Serial.print("Time left in Flash2ndLED = ");
  //  Serial.println(Flash2ndLED.Remaining()); //Outputs the time in ms left in this timer

} //END of loop()

Attached is the zip file for the library.

CreateTimer.zip (3.41 KB)

#include <Arduino.h>

// CreateTimer.cpp
// CreateTimer.h"
//
//  Rev 
//  1.00   October 2,  2015 Functional code
//  1.01   October 4,  2015 Renamed variables and functions. Added: After() Remaining() Elapsed()
//  1.02   October 10, 2015 Added the Repeat option to the Start function
//
//=============================================================================
//                    F U N C T I O N    P R O T O T Y P E S
//=============================================================================

//                      C l a s s   C r e a t e T i m  e r  
 
class CreateTimer
{
public:
  //CreateTimer();
  //void begin();
  void Start(unsigned long);  
  void StartRepeat(unsigned long, long);  //1.02
  void Restart();
  void Enable();
  void Disable();
  void SetInterval(unsigned long);
  unsigned long Remaining();         //1.01
  bool IsEnabled();
  bool Repeat();
  bool Once();
  bool While();
  bool After();         //1.01
  
private:
  unsigned long Elapsed();         //1.01  No access to the user

  long _Repeat;                          //1.02
  bool enabled;
  unsigned long _Interval;
  unsigned long lastMillis; 
  unsigned long _temp;         //temporary variable 1.01

};  // END of CreateTimer class  
// In C++ you must have a ; at the end of a class definition
//*****************************************************************************

#include "CreateTimer.h"

//
//*****************************************************************************
//                    C l a s s   C r e a t e T i m e r  
//*****************************************************************************
//Constructor

//CreateTimer::CreateTimer()
//{
//} // END of CreateTimer()

//********************************************************** 
//Initialization
//void CreateTimer::begin()
//{
//} // END of begin()

// ********************************************************** 
// Initialize the timer. This starts the timing for this timer.
void CreateTimer::Start(unsigned long Interval)
{
  _Interval = Interval;
  _Repeat = -1;               //1.02
  lastMillis = millis();  
  enabled = true;
} // END of Start()

//********************************************************** 
// Initialize the timer. This starts the timing for this timer. "Repeat" is the number of repeating intervals.  
void CreateTimer::StartRepeat(unsigned long Interval,long Repeat)   //1.02
{
  _Interval = Interval;
  _Repeat = Repeat;            
  lastMillis = millis();  
  enabled = true;
} // END of StartRepeat()

//********************************************************** 
// Enable the timer
void CreateTimer::Enable()
{
  enabled = true;  
} // END of Enable()

//********************************************************** 
// Disable the timer
void CreateTimer::Disable()
{
  enabled = false;  
} // END of Disable()

//********************************************************** 
// Return true if the timer is enabled false if disabled
bool CreateTimer::IsEnabled()
{
  return enabled;
} // END of IsEnabled()

//********************************************************** 
// Restart the timing sequence
void CreateTimer::Restart()
{
  lastMillis = millis();  
} // END of Restart()

//********************************************************** 
//
unsigned long CreateTimer::Elapsed() //1.01
{
  return millis() - lastMillis;
} // END of Elapsed()

//********************************************************** 
// Return the time left in the timer: >=0 time left <= interval
unsigned long CreateTimer::Remaining() //1.01
{
  _temp = _Interval - Elapsed();
  if(_Interval >= _temp)
  {
    return _temp;
  }
  else
  {
    return 0;  //under flow, return zero
  }
} // END of Remaining()

//********************************************************** 
// Change the timer interval 
void CreateTimer::SetInterval(unsigned long Interval)
{
  _Interval = Interval;  
} // END of SetInterval()

//********************************************************** 
// Return false in the interval, return true at the end of the interval, then restart the timer
bool CreateTimer::Repeat()
{ 
  if(enabled && Elapsed() >= _Interval)
  {
    //_Repeat being negative indicates this is a continuous timer.
    if(_Repeat < 0)  
    {
      lastMillis = lastMillis + _Interval;
      return true;
    }
    //_Repeat being positive, indicates this is a timer that "Repeats" a given number of times.
 //2,147,483,647 is the maximum number the timer can repeat
    else if(_Repeat-- != 0)
    {
      lastMillis = lastMillis + _Interval;
      return true;
    }
    else
    {
      //We have now completed this _Repeat sequence
      enabled = false;
      return false;  
    }
  }

  return false;
} // END of Repeat()

//********************************************************** 
// Return false in the interval, return true "at" the end of the interval, then false there after
bool CreateTimer::Once()
{
  if(enabled && Elapsed() >= _Interval)
  {
    enabled = false;
    return true;
  }  

  return false;
} // END of Once()

//**********************************************************
// Return true while in the interval and false after the interval has expired 
bool CreateTimer::While()
{
  if(enabled && Elapsed() <= _Interval)
  {
    return true;
  }  

  enabled = false;
  return false;
} // END of While()

//**********************************************************
// Return false in the interval and true after the interval has expired 
bool CreateTimer::After() //1.01
{
  if(enabled && Elapsed() <= _Interval)
  {
    return false;
  }  

  enabled = false;
  return true;
} // END of After()


// END of CreateTimer class definition
  void Start(unsigned long);  
  void StartRepeat(unsigned long, long);  //1.02
  void Restart();
  void Enable();
  void Disable();
  void SetInterval(unsigned long);

It is usually a good idea to provide a name for the variable, do the user can make a reasonable guess what the arguments mean. I HATE guessing games.

Thanks PaulS

Edit:
Made some name changes in the library
Attached version 1.03

CreateTimer.zip (3.77 KB)

larryd:
Made some name changes in the library
Attached version 1.03

I like it, thank you! and please, don't abandon it ..