//
// Timerklasse
//
class Timer {
public:
void start() { timeStamp = millis(); }
bool operator()(const unsigned long duration) { return (millis() - timeStamp >= duration) ? true : false; }
private:
unsigned long timeStamp{0};
};
//
// Datenstruktur für Schalter und globale Konstanten/Variablen
//
enum class SwSate : byte { noaction, changed, wait };
struct Switch {
const byte pin;
byte cState;
byte pState;
SwSate state;
};
constexpr byte OUT {4};
constexpr int DEBOUNCE_TIME {50}; // Millisekunden
Timer sTimer; // Timerobjekt für das Entprellen erzeugen.
struct Switch mySwitch{3,LOW,LOW,SwSate::noaction}; // Schalterobjekt
//
// Forward-Deklaration der Funktionen
//
void pulse();
bool switchChanged();
//
// Hauptprogramm
//
void setup() {
pinMode(mySwitch.pin, INPUT);
pinMode(OUT, OUTPUT);
// Verhindert erste Pulsauslösung nach dem Einschalten
// unabhängig von der Schalterstellung
delay(10);
mySwitch.pState = digitalRead(mySwitch.pin);
}
void loop()
{
if (switchChanged()) {pulse();}
}
void pulse() {
digitalWrite(OUT, HIGH); //Setzt den Ausgang auf 1
delay(500); //Verzögerung von 0,5s
digitalWrite(OUT, LOW); //Setzt den Ausgang auf 0
}
bool switchChanged() {
bool isAction {false};
mySwitch.cState = digitalRead(mySwitch.pin);
if (mySwitch.cState != mySwitch.pState) {
if (mySwitch.state != SwSate::wait) { mySwitch.state = SwSate::changed; }
}
switch (mySwitch.state) {
case SwSate::changed:
sTimer.start();
mySwitch.state = SwSate::wait;
break;
case SwSate::wait:
if (sTimer(DEBOUNCE_TIME)) {
mySwitch.pState = mySwitch.cState;
mySwitch.state = SwSate::noaction;
isAction = true;
}
break;
default: break;
}
return isAction;
}