Zustandsautomaten

Was ist ein Zustandsautomat?

Ein Zustandsautomat ist ein Automat der eine endliche Anzahl an Zuständen hat und in dem einen Zustandsübergang durch eine Eingabe ausgelöst wird. Zustandsautomaten findet man überall.

Zustandsautomaten Um einen Zustandsautomaten zu verwirklichen, muss man sich erst einmal klar machen, welche Zustände es gibt und wie man von einem in den anderen kommt. Dazu kann man sich was selber malen: Hab mal wieder 'ne Ampel…

Die Wölkchen sind unsere Zustände. Die Pfeile sind die möglichen Zustandsänderungen und die Texte bezeichnen die Bedingungen. Das ganze fassen wir jetzt in ein Stück Software. Zunächst lassen sich die Zustände sehr einfach in einer enum abbilden. Zustandswechsel lassen sich einfach in einen Switchcase machen.

const byte Taste_1 = 4;
const byte LED_ROT = 1;
const byte LED_GELB = 2;
const byte LED_GRUEN = 3;

enum AMPEL { 
  ROT, GELB, ROTGELB, GRUEN };

AMPEL ampel = ROT;
unsigned long zeit = 0;


void setup() {
  pinMode(LED_ROT, OUTPUT);
  pinMode(LED_GELB, OUTPUT);
  pinMode(LED_GRUEN, OUTPUT);
  pinMode(Taste_1, INPUT_PULLUP);

  ampel = ROT;
}

void loop() {
  switch (ampel) {
  case ROT:
    // Ist die Ampel rot, dann wird die Ampel direkt rot gelb.
    if (digitalRead(Taste_1) == 0) {
      ampel = ROTGELB;
      zeit = millis();
    }
    break;
  case ROTGELB:
    if ((millis() - zeit) > 2000) {
      ampel = GRUEN;
      zeit = millis();
    }
    break;
  case GRUEN:
    if ((millis() - zeit) > 30000) {
      ampel = GELB;
      zeit = millis();
    }
    break;
  case GELB:
    if ((millis() - zeit) > 3000) {
      ampel = ROT;
    }
    break;
  default:
    ampel = ROT;
  }
  showAmpel();
}

/*
aktuellen Zustand anzeigen.
*/
void showAmpel() {
  switch (ampel) {
  case ROT:
    digitalWrite(LED_ROT , HIGH);
    digitalWrite(LED_GELB , LOW);
    digitalWrite(LED_GRUEN , LOW);
    break;
  case ROTGELB:
    digitalWrite(LED_ROT , HIGH);
    digitalWrite(LED_GELB , HIGH);
    digitalWrite(LED_GRUEN , LOW);
    break;
  case GRUEN:
    digitalWrite(LED_ROT , LOW);
    digitalWrite(LED_GELB , LOW);
    digitalWrite(LED_GRUEN , HIGH);
    break;
  case GELB:
    digitalWrite(LED_ROT , LOW);
    digitalWrite(LED_GELB , HIGH);
    digitalWrite(LED_GRUEN , LOW);
    break;
  }
}