Menu
CoddyTech

Benannte Zustände mit enum

Teil des Abschnitts Timing ohne Delay der Arduino-Journey von Coddy. Lektion 9 von 18.

Ein Modus mit der Nummer 0, 1 oder 2 funktioniert, aber if (mode == 2) sagt nicht, wofür 2 steht. Ein enum gibt jeder Zahl einen Namen:

enum State { READY, RUNNING, DONE };
State state = READY;

Die erste Zeile erstellt einen neuen Typ, State, dessen einzige Werte READY, RUNNING und DONE sind. Intern sind sie weiterhin 0, 1 und 2, aber die Namen geben an, wofür jeder Wert steht. Die zweite Zeile erstellt eine Variable dieses Typs.

Ein enum und ein switch passen zusammen: ein case pro Zustand.

switch (state) {
  case READY:
    // was READY tut und wann es zum nächsten Zustand wechselt
    break;
  case RUNNING:
    // ...
    break;
}

Um zu einem neuen Zustand zu wechseln, setze state und merke dir, wann er begonnen hat: state = DONE; stateStart = millis();. Jeder Zustand misst dann seine eigene Dauer mit millis() - stateStart. Diese Art, einen Sketch zu schreiben, wird Zustandsmaschine genannt.

challenge icon

Aufgabe

Mittel

Eine Maschine hat drei Zustände. READY ist für dich bereits implementiert: Die grüne LED leuchtet, und ein Tastendruck startet die Maschine. Füge die beiden anderen Fälle hinzu:

  • RUNNING: Die gelbe LED leuchtet. Schalte sie nach 2000 ms aus und gehe zu DONE.
  • DONE: Die rote LED leuchtet. Schalte sie nach 1000 ms aus und gehe zurück zu READY.

Speichere stateStart bei jeder Änderung. Klicke auf Run, drücke den Knopf und klicke dann auf Check.

Probier es selbst

const int buttonPin = 2;
const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;

enum State { READY, RUNNING, DONE };
State state = READY;

unsigned long stateStart = 0;   // wann der aktuelle Zustand begonnen hat

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(redLed, OUTPUT);
}

void loop() {
  unsigned long now = millis();

  switch (state) {
    case READY:
      digitalWrite(greenLed, HIGH);
      if (digitalRead(buttonPin) == LOW) {
        digitalWrite(greenLed, LOW);
        state = RUNNING;
        stateStart = now;
      }
      break;

    // case RUNNING hinzufügen: Gelb einschalten; nach 2000 ms Gelb ausschalten und zu DONE wechseln

    // case DONE hinzufügen: Rot einschalten; nach 1000 ms Rot ausschalten und zu READY zurückkehren
  }
}
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