For one of my Sonoff switches I'm using a timer to ping my PC so it switches everything off with my PC (see code). Originally, for the sake of time (forgive the pun), I ripped code from [url link="]this page[/url]. However, it was a bit more complicated to use that I anticipated and resetting the timer interval didn't always work (I don't know if it ever did, tbh). So I wrote my own, with significantly fewer lines. The only major disadvantage is that you can't register multiple timers under one loop method.
Anyway, here it is:
#ifndef _TIMER_h
#define _TIMER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
#include <functional>
class Timer
{
protected:
int _interval;
std::function<void()> _callback;
unsigned long _lastRunTime;
bool _enabled;
void constructor(int interval, std::function<void()> callback, bool startImmediately);
public:
Timer(int interval, std::function<void()> callback);
Timer(int interval, std::function<void()> callback, bool startImmediately);
void loop();
void start();
void stop();
bool enabled();
void reset(int interval);
};
#endif
#include "Timer.h"
void Timer::constructor(int interval, std::function<void()> callback, bool startImmediately) {
_interval = interval;
_callback = callback;
_enabled = false;
if (startImmediately)
start();
}
Timer::Timer(int interval, std::function<void()> callback) {
constructor(interval, callback, false);
}
Timer::Timer(int interval, std::function<void()> callback, bool startImmediately) {
constructor(interval, callback, startImmediately);
}
void Timer::loop() {
if (!_enabled)
return;
if (millis() - _lastRunTime >= _interval) {
_callback();
_lastRunTime = millis();
}
}
void Timer::start() {
_enabled = true;
_lastRunTime = millis();
}
void Timer::stop() {
_enabled = false;
}
bool Timer::enabled() {
return _enabled;
}
void Timer::reset(int interval) {
stop();
_interval = interval;
start();
}
As you can see, there are two constructors; one for the setup and one for the setup as well as defining if it should start immediately. It's got a simple stop and start and you can reset the interval. Just call Timer.loop() in your loop() method to keep it running.
Here's the example code from what I used to develop it:
#include "Timer.h"
#include "Led.h"
#include "Button.h"
void resetTimer();
void toggleTimer();
Led led(13);
auto ledToggle = std::bind(&Led::toggle, &led);
Timer timer(1000, ledToggle, true);
Button button(0, toggleTimer, resetTimer);
bool shortReset = false;
void toggleTimer() {
if (timer.enabled())
timer.stop();
else
timer.start();
}
void resetTimer() {
if (shortReset)
timer.reset(250);
else
timer.reset(1000);
shortReset = !shortReset;
}
void setup() {
}
void loop() {
timer.loop();
button.loop();
}