Zustandsautomat für eine Ampel
Teil des Abschnitts Timing ohne Delay der Arduino-Journey von Coddy. Lektion 10 von 18.
Eine Ampel ist eine Zustandsmaschine: Sie befindet sich immer in einem Zustand (grün, gelb oder rot), jeder Zustand dauert eine festgelegte Zeit, und jeder Zustand weiß, welcher als Nächstes kommt:
- GREEN: Grün an; nach 2 s zu YELLOW wechseln
- YELLOW: Gelb an; nach 1 s zu RED wechseln
- RED: Rot an; nach 2 s zu GREEN wechseln
Jede Zeile wird zu einem case:
case GREEN:
setLights(HIGH, LOW, LOW);
if (now - lightStart >= 2000) {
light = YELLOW;
lightStart = now;
}
break;Mit delay(2000) würde die Ampel auch funktionieren, aber nichts anderes könnte laufen. Mit millis() dauert jeder Durchlauf von loop() nur Mikrosekunden, sodass das Board Zeit für andere Aufgaben hat: hier für eine Status-LED, die die ganze Zeit blinkt, um zu zeigen, dass der Controller aktiv ist.
Aufgabe
MittelDie Status-LED an Pin 13 blinkt bereits, und enum und lightStart sind bereit. Schreibe die Ampel als switch (light) mit einem case pro Licht:
- grün 2 s, gelb 1 s, rot 2 s, dann wieder grün
- immer nur eine LED gleichzeitig, mit
setLights() - kein
delay(), damit die Status-LED weiter blinkt
Klicke auf Run und dann auf Check.
Probier es selbst
const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;
const int statusLed = 13; // die LED auf der Platine
enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0; // als die aktuelle Ampelleuchte anging
unsigned long statusPrevious = 0;
int statusState = LOW;
void setup() {
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(statusLed, OUTPUT);
}
void setLights(int green, int yellow, int red) {
digitalWrite(greenLed, green);
digitalWrite(yellowLed, yellow);
digitalWrite(redLed, red);
}
void loop() {
unsigned long now = millis();
// die Status-LED wechselt alle 250 ms ihren Zustand, um zu zeigen, dass der Controller läuft
if (now - statusPrevious >= 250) {
statusPrevious = now;
if (statusState == LOW) {
statusState = HIGH;
} else {
statusState = LOW;
}
digitalWrite(statusLed, statusState);
}
// die Ampel: ein switch (light) mit einem case pro Ampelleuchte
// Grün 2 s, Gelb 1 s, Rot 2 s, dann wieder Grün
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Timing ohne Delay
2Zustandsautomaten
Den Modus merkenMit switch auswählenBenannte Zustände mit enumZustandsautomat für eine AmpelModi mit einer Taste durchschaltenÜbe selbstständig: Arduino-Playground