/*
Forum:https://forum.arduino.cc/t/kann-mir-jemand-sagen-warum-der-button-nicht-funktioniert/1446985/5
Wokwi:https://wokwi.com/projects/465896081261023233
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
Allerdings zeigt diese Version auch die Dauer der letzten Phase an
*/
enum class Phase {ROT, ROT_GELB, GRUEN, GELB, UNBEKANNT};
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 = Phase::UNBEKANNT;
unsigned long phasenStart = 0;
boolean tasteGedrueckt = false;
void setup() {
Serial.begin(115200);
pinMode(tasterPin, INPUT_PULLUP);
delay(10);
// 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, "RotGelb");
}
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) {
if (AmpelPhase != Phase::UNBEKANNT) {
if (AmpelPhase == Phase::ROT_GELB) {
Serial.print(": ");
} else {
Serial.print(":\t ");
};
Serial.print((millis() - phasenStart) / 1000);
Serial.println(" s");
}
AmpelPhase = naechstePhase;
Serial.print(txt);
phasenStart = millis();
}
boolean zeitAbgelaufen(unsigned long intervall) {
return (millis() - phasenStart > intervall);
}