Endlicher Zustandsautomat ohne globale Variablen

Hallo,

immer wieder lande ich bei dem Punkt, an dem ich mir einen einfach zu programmierenden und zugleich sehr flexiblen (Eintritt, Austritt, Timer,..) endlichen Zustandsautomaten wünsche.

Gibt es so etwas im Arduinouniversum überhaupt?

Wenn ich da jedesmal bei Null anfange, lande ich immer wieder beim setzen globaler Variablen, mit denen ich mich dann spaghetticodemäßig durch's FSM-Chaos wurstel.

Gruß Chris

Hallo,

also es gibt sehr verschiedene Arten Zustandsautomaten zu programmieren. Verschachtelte Switch Statements, Tabelle, das State Pattern (Buch "Entwurfsmuster").

Vielleicht ist das eine Lektüre für dich, Teile des Buchs gibt es mittlerweile frei als PDF

Der Buchautor ist Entwickler einer eigenen Software, geht aber auch auf andere Ansätze ein. Allerdings sind diese Kapitel nicht im obigen PDF. Über die Software von state-machine.com gab es zumindest hier auch mal einen Eintrag im Arduino Playground. Finde ihn gerade nicht. Bin allerdings bisher nicht so richtig warm damit geworden.

[Edit]
Wiedergefunden
https://playground.arduino.cc/Code/QP

Einen endlichen Zustandsautomaten realisiere ich üblicherweise mittels switch/case. Das habe ich ein paarmal geübt, bis ich nicht mehr darüber nachdenken muß. Und wenn man es dann kann, ist es ganz einfach :slight_smile:

Zu Anfang meiner Arduino-Zeit habe ich ein paar Timer-Bibliotheken geladen, aber nutzen tue ich sie nicht.

Es gibt auch INTERVAL mit dem Beispiel Doppelblitzer:

// http://forum.arduino.cc/index.php?topic=413734.msg2850515#msg2850515
// [Projekt] INTERVAL

#include <INTERVAL.h>

const byte LED = 13;
const unsigned long dauer[] = {200, 50, 50, 50};
const byte anzahlDauer = sizeof(dauer) / sizeof(dauer[0]);
byte index;

void setup()
{
  pinMode(LED, OUTPUT);
}

void loop()
{
  INTERVAL(dauer[index])
  {
    digitalWrite(LED, !digitalRead(LED));
    index = ++index % anzahlDauer;
  }
}

Das switch/case das hier immer verwendet wird es lediglich eine Variante um Zustandsautomaten zu implementieren. Einfach, aber keineswegs am besten

Man kann Funktionen so verknüpfen dass eine Funktion einen Zeiger auf die nächste Funktion zurückgibt. Entweder über void Zeiger oder indem man den Zeiger in ein struct verpackt.

Eine andere schöne Variante für komplexere Systeme ist eine Zustandstabelle:
https://www.mikrocontroller.net/articles/Statemachine#Umsetzung_in_Tabellenform

OOP ist natürlich auch eine Option

Serenifly:
Das switch/case das hier immer verwendet wird es lediglich eine Variante um Zustandsautomaten zu implementieren. Einfach, aber keineswegs am besten

Jawoll...

Wie immer: Ein Problem und Tausend verschiedene Wege zum Ziel.

Goto!
(Computed Goto)
Ist eine dieser Möglichkeiten.
Und nicht die schlechteste.
(mögen auch andere dabei dicke Backen bekommen)

Gibt es so etwas im Arduinouniversum überhaupt?

Natürlich!
Nahezu alle Arduinoprogramme sind endliche Automaten.
Und das hat nichts damit zu tun, ob der Autor den Begriff überhaupt schon mal gehört hat.

Tipp:
Multitasking und endliche Automaten werden gerne in einen Topf geworfen.
Kommen oft gemeinsam vor, ist aber nicht das gleiche.

Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:

Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay,

Blink Without Delay
Der Wachmann

Multitasking Macros
Intervall Macro

Für FSMs habe ich immer zwei Ansätze je nach Komplexität.
Entweder die schon beschriebene switch/case Konstrukte, oder
Arrays mit Zustandsübergängen und Funktionspointern.

D.h. bewirkt z.B. ein Byte einen Zustandswechsel des Hauptautomaten, so landet man beim nächsten
Byte automatisch in einer anderen Funktion. Statt switch/case wird hier ein Funktionspointer umgesetzt.

Oft auch eine Kombination.
Also Hauptautomat über Funktionspointer und irgentwelche "Subautomaten" über Switch/case.

Ulli

Vielen Dank Euch allen.

Mein besonderer Dank geht an combie, dessen zwei letzten Links mir sehr geholfen haben!

Gruß Chris

Fein, wenn du die Makros nutzen kannst...
Dash macht mich glücklish!

Verstehst du auch, wie die Makros funktionieren?
(wäre schon recht fein/wichtig!)