So, habe noch ein wenig gewerkelt ... ![]()
/*
Forum: https://forum.arduino.cc/t/kann-mir-jemand-sagen-warum-der-button-nicht-funktioniert/1446985/5
Wokwi: https://wokwi.com/projects/465920814099614721
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
Diese Version zeigt die Dauer der letzten Phase an.
Sie wurde um eine weitere Phase erweitert, die Fussgängern
erlaubt, nachdem sie Rot erhalten haben, den Ăbergang
zu verlassen (quasi der Ersatz fĂźr die fehlende Gelb-Phase fĂźr
Fussgänger)
Serielle Textausgabe und Led fßr Fahrzeuge und Fussgänger
*/
class SignalAnlage {
private:
byte rot;
byte gelb;
byte gruen;
byte fussRot;
byte fussGruen;
void RotGelbGruen(byte r, byte y, byte g) {
digitalWrite(rot, r);
digitalWrite(gelb, y);
digitalWrite(gruen, g);
}
public:
// Pinreihenfolge: Rot, Gelb, Gruen, Fussg_Rot, Fussg_Gruen
SignalAnlage(byte r, byte g, byte gr, byte fR, byte fG)
: rot(r), gelb(g), gruen(gr), fussRot(fR), fussGruen(fG) {};
void init() {
pinMode(rot, OUTPUT);
pinMode(gelb, OUTPUT);
pinMode(gruen, OUTPUT);
pinMode(fussRot, OUTPUT);
pinMode(fussGruen, OUTPUT);
}
// Rot, Gelb, Gruen
void Rot() {
RotGelbGruen(HIGH, LOW, LOW);
}
void RotGelb() {
RotGelbGruen(HIGH, HIGH, LOW);
}
void Gruen() {
RotGelbGruen(LOW, LOW, HIGH);
}
void Gelb() {
RotGelbGruen(LOW, HIGH, LOW);
}
void FussgaengerRot() {
digitalWrite(fussGruen, LOW);
digitalWrite(fussRot, HIGH);
}
void FussgaengerGruen() {
digitalWrite(fussGruen, HIGH);
digitalWrite(fussRot, LOW);
}
};
SignalAnlage ampel(5, 6, 7, 3, 4);
enum class Phase {ROT, RAEUMEN, 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 RaeumDauer { 3000};
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);
ampel.init();
delay(100);
// StartBedingungen setzen:
phasenWechsel(Phase::ROT, "Rot");
ampel.Rot();
ampel.FussgaengerGruen();
}
void loop() {
TasterAbfrage();
AmpelMaschine();
}
void AmpelMaschine() {
switch (AmpelPhase) {
case Phase::ROT:
if (zeitAbgelaufen(RotDauer)) {
ampel.FussgaengerRot();
phasenWechsel(Phase::RAEUMEN, "Räumen");
}
break;
case Phase::RAEUMEN:
if (zeitAbgelaufen(RaeumDauer)) {
ampel.RotGelb();
phasenWechsel(Phase::ROT_GELB, "RotGelb");
}
break;
case Phase::ROT_GELB:
if (zeitAbgelaufen(RotGelbDauer)) {
ampel.Gruen();
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;
ampel.Gelb();
phasenWechsel(Phase::GELB, "Gelb");
}
break;
case Phase::GELB:
if (zeitAbgelaufen(GelbDauer)) {
ampel.Rot();
ampel.FussgaengerGruen();
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);
}
siehe https://wokwi.com/projects/465920814099614721
Jetzt mit einer FuĂgänger-Räumphase bevor die Fahrzeugampel auf RotGelb geht ... und mit Leds fĂźr Fahrzeug- und FuĂgängerampel.