using ulong = unsigned long int;
//////////////////////////////////////////////////////////////////////////////
/// @brief Helper class for non-blocking execution of
/// code sections at certain intervals.
///
//////////////////////////////////////////////////////////////////////////////
class Interval {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief Determine whether the specified interval has expired.
///
/// @param duration Interval duration
/// @return true when the interval has elapsed
/// @return false interval not elapsed yet
//////////////////////////////////////////////////////////////////////////////
bool operator()(const ulong duration) {
if (false == isStarted) { return start(false); }
return (millis() - timeStamp >= duration) ? start(true) : false;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief reset timer
///
//////////////////////////////////////////////////////////////////////////////
void stop() { isStarted = false; }
private:
bool start(bool state = false) {
isStarted = !state; // Set the value to true on the first call
timeStamp = millis();
return state;
}
private:
bool isStarted {false}; // Flag = true if the first Operator() call has been made.
ulong timeStamp {0};
};
constexpr uint8_t LED_PIN {4};
constexpr ulong INTERVAL_ON {100};
constexpr ulong INTERVAL_OFF {1900};
Interval interval;
void blink(uint8_t pin, ulong on, ulong off) {
switch(digitalRead(pin)) {
case HIGH: if ( interval(on) ) { digitalWrite(pin,LOW); } break;
case LOW: if ( interval(off) ) { digitalWrite(pin,HIGH); } break;
default: break;
}
}
void setup() { pinMode(LED_PIN, OUTPUT); }
void loop() {
blink(LED_PIN, INTERVAL_ON, INTERVAL_OFF);
}