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) : retFalse();
  }

private:
  bool start(bool state = false) {
    isStarted = !state;   // Set the value to true on the first call
    timeStamp = millis();
    return state;
  }
  bool retFalse() { return false; }

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);
}