/*
Forum: https://forum.arduino.cc/t/einfache-if-schleife/1176612
Wokwi: https://wokwi.com/projects/378132967574695937
*/
#include <Servo.h>
constexpr byte servoPin = 9;
constexpr byte button_pin = 13;
Servo servo;
int closed = 90; // servo position in degrees
int open = 0;
byte oldState = 1; // Speichert den alten Status "closed"/"open"
// damit man erkennen kann, wann sich state ändert
byte state = 1; // Speichert den aktuellen Status "closed/open", der sich
// durch einen Tastendruck ändern kann
void setup()
{
Serial.begin(115200);
servo.attach(servoPin);
pinMode(button_pin, INPUT_PULLUP); // Setzt den Modus des Pins so, dass er bei offener Taste HIGH ausgibt
// Der Taster wird so angeschlossen, dass der Pin auf Masse/GND
// bei Betätigung gelegt wird. Da der interne Pullup-Widerstand hochohmig ist,
// fliesst dabei nur ein kleiner Strom.
servo.write(open);
}
void loop()
{
if (buttonJustDown()) { // Prüft, ob die Taste gerade von HIGH auf LOW geschaltet wurde
state = !state; // und invertiert dann state (0 wird zu 1, 1 wird zu 0)
}
if (state != oldState){ // Nur wenn sich state geändert hat, geht es in den folgenden Zweig
oldState = state; // In diesem Fall merken wir uns den "neuen" Status auch in oldState
// und verhindern, dass wir bei folgenden Durchgängen bei denen sich
// state nicht geändert hat, wieder hier hineinkommen.
switch (state){ // Je nach state geht es in die case-Zweige
case 0: servo.write(closed); // bei state == 0 schließen wir
Serial.println("Closing");
break;
case 1: servo.write(open); // bei state == 1 öffnen wir
Serial.println("Opening");
break;
}
}
}
boolean buttonJustDown(){ // Gibt genau dann einmal true zurück, wenn buttonState von HIGH auf LOW wechselt
static unsigned long lastChange = 0; // Hier merken wir uns den zeitpunkt, wann der letzte Wechsel HIGH/LOW
// per digitalRead() erkannt wurde
static byte buttonState = HIGH; // Speichert den entprellten Zustand des Buttons
static byte lastState = HIGH; // Speichert den letzten unentprellten Zustand
boolean justDown = false; // Liefert am Ende den Rückgabewert der Funktion
byte actState = digitalRead(button_pin); // Liest den aktuellen nicht entprellten Zustand des Buttons
if (actState != lastState) { // Prüft, ob der zuvor ermittelte und der aktuelle ungleich sind
lastChange = millis(); // Falls ja, merken wir uns die Zeit in ms
lastState = actState; // und den "neuen" nicht entprellten Zustand
}
if (actState != buttonState && millis()-lastChange > 30){ // Wenn der aktuelle Wert nicht dem entprellten
// entspricht UND der letzte Wechsel länger als
// 30 ms her ist, dann sollte sich der Zustand des
// Buttons nun stabil geändert haben
buttonState = actState; // Deshalb akzeptieren wir diesen Zustand nun als
// neuen entprellten Zustand des Buttons
if (buttonState == LOW) { // Hier kommt jetzt der "Kunstgriff": Wir geben dann genau einmal TRUE
justDown = true; // zurück, wenn sich der Zustand von HIGH zu LOW geändert hat
}
}
return justDown; // Gibt (meistens) FALSE zurück und nur beim Übergang von HIGH auf LOW einmal TRUE
}