Menu
CoddyTech

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.

challenge icon

Aufgabe

Mittel

Die 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
}
quiz iconTeste dich selbst

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

Übe selbstständig: Arduino-Playground