Ampelschaltung

Hallo,

ich bin gerade am Programmieren einer Ampelschaltung. Nun bin ich aber auf ein Problem gestoßen:

Wie bekomme ich es hin, dass wenn man den Taster drückt die KFZ-Ampel auf Rot gehen und dann die Fußgängerampeln auf Grün?
Durch die Delays kann ich auch nicht dazwischen immer testen, ob der Taster gedrückt ist, da man den Taster ja nur kurz drückt und wenn dies halt während dem delay ist und erst danach abgefragt wird, ist der Taster bei der Abfrage nicht mehr gedrückt!
Momentan ist es so, dass immer nur am Anfang angefragt wird, ob der Taster gedrückt ist.

Ich bitte um Hilfe.

Programmcode:

// Variablen

 // Zeit

 int Warten = 2000;
 int Gelb = 2000;
 int Gruen = 10000;


// Ampel 1
int kfz_rot1 = 13;
int kfz_gelb1 = 12;
int kfz_gruen1 = 11;

// Ampel 2
int kfz_rot2 = 10;
int kfz_gelb2 = 9;
int kfz_gruen2 = 8;

// Ampel 3
int kfz_rot3 = 7;
int kfz_gelb3 = 6;
int kfz_gruen3 = 5;

// Fußgaengerampel
int fg_rot = 4;
int fg_gruen = 3;

// Taster
int taste = 2;

void setup() {
 pinMode(kfz_rot1, OUTPUT);
 pinMode(kfz_gelb1, OUTPUT);
 pinMode(kfz_gruen1, OUTPUT);
 
 pinMode(kfz_rot2, OUTPUT);
 pinMode(kfz_gelb2, OUTPUT);
 pinMode(kfz_gruen2, OUTPUT);
 
 pinMode(kfz_rot3, OUTPUT);
 pinMode(kfz_gelb3, OUTPUT);
 pinMode(kfz_gruen3, OUTPUT);
 
 pinMode(fg_rot, OUTPUT);
 pinMode(fg_gruen, OUTPUT);

 pinMode(taste, INPUT_PULLUP);

 
 // Alle Ampeln auf Rot schalten
 digitalWrite(kfz_rot1, HIGH);
 digitalWrite(kfz_rot2, HIGH);
 digitalWrite(kfz_rot3, HIGH);
 digitalWrite(fg_rot, HIGH);
 digitalWrite(kfz_gelb1, LOW);
 digitalWrite(kfz_gelb2, LOW);
 digitalWrite(kfz_gelb3, LOW);
 digitalWrite(fg_gruen, LOW);
 digitalWrite(kfz_gruen1, LOW);
 digitalWrite(kfz_gruen2, LOW);
 digitalWrite(kfz_gruen3, LOW);
}

void loop() {
 delay(Warten);
 if(digitalRead(taste) == LOW) {
   // Fußgaengerampel auf Gruen
   digitalWrite(fg_rot, LOW);
   digitalWrite(fg_gruen, HIGH);
   delay(Gruen);
   // Fußgaengerampel auf Rot
   digitalWrite(fg_rot, HIGH);
   digitalWrite(fg_gruen, LOW);
 }
 
  
   // Ampel 1 auf Gruen
   digitalWrite(kfz_gelb1, HIGH);
   delay(Gelb);
   digitalWrite(kfz_rot1, LOW);
   digitalWrite(kfz_gelb1, LOW);
   digitalWrite(kfz_gruen1, HIGH);
   delay(Gruen);
   // Ampel 1 auf Rot
   digitalWrite(kfz_gelb1, HIGH);
   digitalWrite(kfz_gruen1, LOW);
   delay(Gelb);
   digitalWrite(kfz_rot1, HIGH);
   digitalWrite(kfz_gelb1, LOW);
   delay(Warten);

   //Ampel 2 auf Gruen
   digitalWrite(kfz_gelb2, HIGH);
   delay(Gelb);
   digitalWrite(kfz_rot2, LOW);
   digitalWrite(kfz_gelb2, LOW);
   digitalWrite(kfz_gruen2, HIGH);
   delay(Gruen);
   // Ampel 2 auf Rot
   digitalWrite(kfz_gelb2, HIGH);
   digitalWrite(kfz_gruen2, LOW);
   delay(Gelb);
   digitalWrite(kfz_rot2, HIGH);
   digitalWrite(kfz_gelb2, LOW);
   delay(Warten);

   //Ampel 3 auf Gruen
   digitalWrite(kfz_gelb3, HIGH);
   delay(Gelb);
   digitalWrite(kfz_rot3, LOW);
   digitalWrite(kfz_gelb3, LOW);
   digitalWrite(kfz_gruen3, HIGH);
   delay(Gruen);
   // Ampel 3 auf Rot
   digitalWrite(kfz_gelb3, HIGH);
   digitalWrite(kfz_gruen3, LOW);
   delay(Gelb);
   digitalWrite(kfz_rot3, HIGH);
   digitalWrite(kfz_gelb3, LOW);

}

Vielen Dank!

Du hast das Problem doch schon richtig erkannt: Das delay stört.
Also musst Du es ohne delay aufbauen und die Zeitsteuerung über millis() realisieren.
Suche dazu nach BlinkWithoutDelay und der Nachtwächtererklärung.

Gruß Tommy

Tobibell:
Hallo,

ich bin gerade am Programmieren einer Ampelschaltung. Nun bin ich aber auf ein Problem gestoßen:

Wie bekomme ich es hin, dass wenn man den Taster drückt die KFZ-Ampel auf Rot gehen und dann die Fußgängerampeln auf Grün?
Durch die Delays kann ich auch nicht dazwischen immer testen, ob der Taster gedrückt ist, da man den Taster ja nur kurz drückt und wenn dies halt während dem delay ist und erst danach abgefragt wird, ist der Taster bei der Abfrage nicht mehr gedrückt!

Ein Tastschalter für eine Bedarfsanforderung müßte ungefähr fünfhundert mal pro Sekunde abgefragt werden. Regelmäßig, und nicht immer nur mal dann, wenn in einer delay()-Kette gerade mal ein paar Mikrosekunden Zeit zwischen zwei delay() Aufrufen übrig ist.

Das funktioniert jedenfalls NICHT mit einer "Idiotenprogrammlogik mit delay"), sondern es funktioniert beispielsweise mit einer Finite-State-Machine-Programmlogik ohne delay,mit Zustandsfunktionen und Timeouts.

In jeder Ampelanlage hat jede einzelne Ampel zu jedem beliebigen Zeitpunkt einen bestimmten Zustand.

Bei Dreifarben-Ampeln zum Beispiel zur Verkehrsregelung auf Fahrbahnen, sind das beispielsweise die Zustände:

  • rot
    -rot/gelb
  • grün
    -gelb
    -rot
    -aus
    -gelbes Blinken

bei Zweifarben-Ampeln zum Beispiel für Fußgänger, gibt es fast immer nur drei mögliche Zustände:

  • rot
  • grün
  • aus

Je nachdem, wieviele Dreifarben-Ampeln und Zweifarben-Ampeln Du zu einer Gesamt-Ampelanlage kombinierst, gibt es am Ende womöglich zahlreiche mögliche Zustände, aber die Anzahl verschiedener Zustände ist endlich und abzählbar, und kann daher auch leicht programmiert werden.

Die meisten Zustandswechsel finden ganz simpel nach Zeitablauf (Timeout) statt, aber einzelne Zustandswechsel können ggf. auch durch Drücken eines Bedarfstasters ausgelöst werden.

Und damit das Zusammenspiel aus Zustandsfunktionen und Timeouts mit Bededarfsschaltern problemlos klappt, darf die Programmlogik eben NICHT auf delay() -Ablaufketten basieren, damit würdest Du die Ablaufsteuerung in eine Sackgasse führen, was einfache Änderungs- und Erweiterungsmöglichkeiten betrifft.

Für ein reibungsfreies Zusammenspiel bietet sich daher eher die Programmlogik einer Finite-State-Machine (FSM, Zustandsautomat) an, mit einer Zustandsfunktion für jeden möglichen Schaltzustand der Ampelanlage.

Oder man sieht eine Ampelanlage programmtechnisch als "konkurrierende Zustandsautomaten, in denen jede Zweifrben- un jede Dreifarben-Ampel jeweils einen eigenen Zustandsautomaten darstellt, der in Konkurrenz zu den anderen Zustandsautomaten (anderen Einzelampeln) läuft.

Entschuldigung für die späte Rückantwort!

Ich habe es immernoch nicht ganz verstanden mit der "Nachtwächtererklärung".

Kann mir dies jemand mal an dem Beispiel mit der Ampel erklären?

Ich wäre sehr dankbar!

Da hätte ich Geschreibsel von mir im Angebot: Anleitung: Endlicher Automat mit millis() oder Anleitung Ein Endlicher Automat entsteht

Nachtdelaywächter (klick es)

An welchem Punkt hast Du Schwierigkeiten?
Da können wir dann ansetzen.

Stefan

jurs:
aber die Anzahl verschiedener Zustände ist endlich und abzählbar

Na ja, genau betrachtet ist das abzählbar überflüssig, ja sogar eher verwirrend,
endlich ist restriktiver und mit unendlichen Mengen hat man hier nicht zu tun.

Vielen Dank an alle Antworten!

Ich habe es ENDLICH geschafft, dass es funktioniert! =)