/*
Forum:https://forum.arduino.cc/t/kann-mir-jemand-sagen-warum-der-button-nicht-funktioniert/1446985/5
Wokwi:https://wokwi.com/projects/465894655305497601
ec2021
Ampel-Statemachine mit Fussgänger-Taste, die unabhängig von den Phasen abgefragt wird
beim Übergang von der Grün-Phase in die Gelb-Phase werden aller vorherigen
Tasteneingaben verworfen
Hier: Keine Led, nur Serielle Textausgabe
*/
enum class Phase {ROT, ROT_GELB, GRUEN, GELB};
constexpr unsigned long GruenStandard {10000};
constexpr unsigned long GruenVerkuerzt { 3000};
constexpr unsigned long GelbDauer { 3000};
constexpr unsigned long RotDauer { 5000};
constexpr unsigned long RotGelbDauer { 3000};
constexpr byte tasterPin {2};
Phase AmpelPhase;
unsigned long phasenStart = 0;
boolean tasteGedrueckt = false;
void setup() {
Serial.begin(115200);
pinMode(tasterPin, INPUT_PULLUP);
// StartBedingungen setzen:
phasenWechsel(Phase::GRUEN, "Grün");
}
void loop() {
TasterAbfrage();
AmpelMaschine();
}
void AmpelMaschine() {
switch (AmpelPhase) {
case Phase::ROT:
if (zeitAbgelaufen(RotDauer)) {
phasenWechsel(Phase::ROT_GELB, "Rot Gelb");
}
break;
case Phase::ROT_GELB:
if (zeitAbgelaufen(RotGelbDauer)) {
phasenWechsel(Phase::GRUEN, "Grün");
}
break;
case Phase::GRUEN:
if (zeitAbgelaufen((tasteGedrueckt) ? GruenVerkuerzt : GruenStandard)) {
// Hier wird der Tasten-Status zurückgesetzt, unabhängig davon, ob die
// nun folgende Phase aus Zeit- oder aus Tastengründen eingeleitet wurde.
// Damit verfallen hier alle vor und während der Grünphase getätigten
// Tasteneingaben
tasteGedrueckt = false;
phasenWechsel(Phase::GELB, "Gelb");
}
break;
case Phase::GELB:
if (zeitAbgelaufen(GelbDauer)) {
phasenWechsel(Phase::ROT, "Rot");
}
break;
}
}
void TasterAbfrage() {
if (digitalRead(tasterPin) == LOW) {
tasteGedrueckt = true;
delay(30); // Einfaches "Debouncen", 30 ms sind hier zu verkraften ;-)
}
}
void phasenWechsel(Phase naechstePhase, char * txt) {
AmpelPhase = naechstePhase;
Serial.println(txt);
phasenStart = millis();
}
boolean zeitAbgelaufen(unsigned long intervall) {
return (millis() - phasenStart > intervall);
}