Unsere vernetzte Welt; Erklärung endlicher Automaten

Der Mensch wurde angeblich nach Gottes Ebenbild geschaffen. Ähnlich erschaffen wir heute Maschinen nach unserem Ebenbild. Ein Beispiel dafür ist die Programmierung , kurz FSM). Ingenieure und Entwickler nutzen Computer, um Aufgaben zu automatisieren, die früher manuell erledigt wurden. Kennen Sie das? Früher mussten wir die Wäsche in der Wanne oder im Waschbecken ausspülen, Seife hinzufügen, schrubben, erneut ausspülen und so weiter, um ein sauberes T-Shirt für die Arbeit oder einen Abend in der Stadt zu haben. Heute erledigen Waschmaschinen diese Arbeit für uns. Ingenieure haben Tausende von Produkten und Geräten entwickelt, die Programme basierend auf menschlichen Gedanken und Handlungen ausführen. Auch hier spielen maschinelles Lernen und andere KI-Buzzwords eine Rolle. Millionen von Geräten und Anwendungen werden entwickelt, um die Effizienz und den Alltag zu erleichtern, und viele dieser hilfreichen Prozesse verdanken ihre Existenz endlichen Zustandsautomaten.

Endliche Zustandsautomaten (FSM) sind im Grunde mathematische Berechnungen einer Abfolge von Ursachen und Ereignissen. In unserem Beispiel mit der Waschmaschine bestimmt der FSM, wann der Spülgang startet, wann geschleudert wird und wann die Maschine vollständig stoppt. Um einen endlichen Zustandsautomaten (FSM) besser zu verstehen, müssen wir zunächst den Begriff „Zustand“ definieren. Ein Zustand ist eine eindeutige Information innerhalb eines größeren Rechenprogramms. Die Berechnung des FSM ändert sich oder wechselt in Reaktion auf externe Eingaben von einem Zustand in einen anderen . Ein FSM wird durch eine Auflistung oder logische Reihenfolge seiner Zustände definiert: seinen Anfangszustand und die Bedingungen für jeden Übergang, abschließend den Endzustand. Der FSM ist eine Abfolge von Gedankengängen, die vom Computer programmiert werden, um Operationen basierend auf Eingaben auszuführen – genau wie der Mensch denkt und handelt, so tun es auch unsere Maschinen und die Computer, die sie steuern.

Zustände sind die DNA des endlichen Automaten (FSM) und bestimmen dessen internes Verhalten sowie die Interaktion mit der Umgebung, beispielsweise die Annahme von Eingaben oder die Ausgabe von Ausgaben, die eine Zustandsänderung des Systems bewirken können. Der jeweilige Zustand wird abhängig von den im FSM definierten Bedingungen ausgeführt. Dieses Konzept ist für Hardware- und Elektrotechniker von großer Bedeutung, da sich viele praktische Probleme, wie die Programmierung von Waschmaschinen (wann Wasser oder Waschmittel hinzugefügt werden soll, wann geschleudert oder pausiert werden soll), mithilfe von FSMs anstelle der klassischen sequenziellen Programmierparadigmen leicht lösen lassen. Anders ausgedrückt: Ein FSM ist im Vergleich zur sequenziellen Programmierung eine eher „elektronische“ Lösung für Hardwareprobleme.

Nachfolgend finden Sie zwei Beispiele für FSMs, die logische Entscheidungen mit geringerem Zeit- und Energieaufwand für die Bereitstellung eines getesteten logischen Programms ermöglichen. Der FSM ist Ihr erster Schritt zum Edge Computing auf Einzelgeräteebene in industriellen IoT Anwendungen.

Mealy-Maschine: Bei der Berechnung einer Mealy-Maschine hängen die Ausgaben jedes Zustands vom aktuellen Zustand und seinen aktuellen Eingabewerten ab. Typischerweise führt jede Mealy-Berechnung dazu, dass die Eingabe eines Zustands genau eine Ausgabe erzeugt, die entweder zu einem Übergang oder zu einem Endzustand führt. Die Waschmaschine füllt sich mit Wasser – sobald der Wasserstand X erreicht ist, wird der Wasserzulauf gestoppt.

Moore-Maschine: Bei der Moore-Maschine hängen die Ausgänge jedes Zustands vom aktuellen Zustand ab und basieren normalerweise auf getakteten sequenziellen Systemen. Die Waschmaschine schleudert nach 4 Minuten. Stoppen Sie die Maschine.

Zustandsdiagramm

Jeder endliche Automat (FSM) muss vor der Codierung mithilfe eines Zustandsdiagramms beschrieben werden – so können wir die Denkweise der Maschine visualisieren. Das folgende Beispiel zeigt das Verhalten des FSM und seine Übergänge, die (typischerweise) mit Kreisen für Zustände und Pfeilen für Übergänge dargestellt werden. Wichtig bei der korrekten Implementierung eines FSM ist außerdem, dass es einen eindeutigen aktuellen Zustand gibt, dessen nächster (zukünftiger) Zustand anhand seiner Programmierinformationen leicht identifiziert werden kann.

Das obige Diagramm veranschaulicht einen vollständigen Mealy-Zustandsautomaten. Wir gehen davon aus, dass der Vorgang in Zustand 1 beginnt und in Zustand 2 übergeht, sobald die Programmiervoraussetzungen erfüllt sind. Nach dem Übergang in Zustand 2 berechnet der Zustandsautomat den aktuellen Zustand, bis ein Auslöser den Übergang zu Zustand 3 oder Zustand 4 bewirkt. Beachten Sie, dass Zustand 3 und Zustand 4 in diesem Diagramm Endzustände darstellen, die zu berechneten Daten für das Endergebnis Ihres Projekts führen.

Ubidots FSM

Jetzt beginnen wir mit der Programmierung eines endlichen Automaten (FSM), der Daten an Ubidots und Ihnen praktische Erfahrung mit dieser Programmiermethode ermöglicht. Unser FSM zielt darauf ab, die anfängliche Anforderung zu identifizieren und darauf zu reagieren. Wir bauen eine einfache Moore-Maschine: Sie sendet jede Minute Sensordaten von unserem Mikrocontroller (Espressif ESP8266) an Ubidots

Ausgehend von dieser ersten Anforderung haben wir uns entschieden, zwei Zustände mithilfe eines Moore-Maschinen-FSM-Berechnungsmodells zu implementieren:

  • WARTEN: Nichts tun, bis eine Minute vergangen ist (ca. 59 Sekunden im Leerlaufzustand verharren).
  • READ_SEND: Lies den analogen Eingang des Mikrocontrollers, an dem der Sensor angeschlossen ist, und sende das Ergebnis nach 60 Sekunden über MQTT Ubidots

Das folgende Zustandsdiagramm veranschaulicht die Programmlogik unseres FSM:

Aus diesem Diagramm geht hervor, dass der Übergang von WAIT zu READ_SEND ausschließlich davon abhängt, ob der unabhängige Zeitwert größer oder kleiner als 60 Sekunden ist. Ausgehend vom nächsten WAIT-Zustand läuft das Programm so lange im WAIT-Zustand, bis der unabhängige Zeitwert 60 Sekunden erreicht oder überschreitet. Sobald die 60-Sekunden-Marke erreicht ist, wechselt der FSM von WAIT zu READ_SEND. Nach dem Senden des Werts wechselt der FSM für weitere ca. 59 Sekunden zurück in den WAIT-Zustand, bevor er den Übergang erneut berechnet.

Codierung

Um dieses Beispiel etwas verständlicher zu machen, betrachten wir einen praktischen FSM-Code, der in vier separate Teile unterteilt wurde, um jeden Zustand und seine Übergangsbedingungen detailliert darzustellen. Der vollständige Code ist hier zu finden.

Teil 1 – Definition von Einschränkungen

// Bibliotheken einbinden #include "UbidotsESPMQTT.h" // Konstanten definieren #define TOKEN "...." // Ihr Ubidots -Token #define WIFINAME "...." // Ihre SSID #define WIFIPASS "...." // Ihr WLAN-Passwort #define WAIT 0 #define READ_SEND 1 uint8_t fsm_state = WAIT; // Anfangszustand int msCount = 0; // Zeitzähler float value; // Speicherplatz für den zu lesenden Wert Ubidots client(TOKEN);

Der erste Teil des Codes ist nicht besonders interessant, da wir lediglich die MQTT-Bibliothek zum Senden von Daten an Ubidots importieren und einige erforderliche Definitionen vornehmen. Wichtig ist, dass wir hier die beiden Zustände WAIT und READ_SEND als Konstanten im gesamten Code definieren und den aktuellen Zustand über die Variable fsm_state festlegen. Im nächsten Teil des Codes wird Speicherplatz für den unabhängigen Timer, den zu lesenden Wert und den zu initialisierenden MQTT-Client reserviert.

Vergessen Sie nicht, die korrekten Werte für Ihr Token sowie Ihren WLAN-Netzwerknamen und Ihr Passwort einzugeben. Falls Sie nicht wissen, wo Sie Ihr Token finden, konsultieren Sie bitte das Ubidots Hilfecenter für weitere Tipps und Tricks.

Teil 2 – Rückruf

// Hilfsfunktionen void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Nachricht angekommen ["); Serial.print(topic); Serial.print("] "); for (int i=0;i < length;i++) { Serial.print((char)payload[i]); } Serial.println(); }

In diesem Codeabschnitt implementieren wir eine Callback-Funktion, die bei Bedarf Daten vom Server verarbeitet. Für unseren Zustandsautomaten (FSM) ist dieser Schritt erforderlich, um den Code korrekt zu kompilieren. Wie bereits in unserem Artikel zu MQTT , verarbeitet die Callback-Funktion Änderungen an Ihren Variablen in Ubidots Daher ist es notwendig, den Code zu kompilieren und die Callback-Funktion zu definieren.

Teil 3 – Hauptfunktionen – Setup()

// Hauptfunktionen void setup() { // Digitalen Pin LED_BUILTIN als Ausgang initialisieren. pinMode(A0, INPUT); client.wifiConnection(WIFINAME, WIFIPASS); client.begin(callback); }

Beginnen wir nun mit den Hauptfunktionen. In unserer `setup()`-Funktion konfigurieren wir den analogen Pin 0 als Eingang (die Pin-Nummer muss je nach Anschlussart Ihres Sensors angepasst werden), um den Analog-Digital-Wandler (ADC) zu nutzen. Dieser ermöglicht es dem Sensor, Umgebungsdaten zu erfassen und als Gleitkommazahl darzustellen. Außerdem initialisieren wir den WLAN-Client und übergeben die Callback-Funktion anhand der zuvor definierten Programmierparameter.

Teil 4 – Hauptfunktionen – Schleife()

void loop() { switch(fsm_state) { case WAIT: if (msCount >= 60000){ msCount = 0; fsm_state = READ_SEND; } break; case READ_SEND: value = analogRead(A0); if(!client.connected()){ client.reconnect(); } /* Routine zum Senden von Daten */ client.add("stuff", value);ubidotsPublish("source1"); client.loop(); fsm_state = WAIT; break; default: break; } // Inkrementiert den Zähler msCount += 1; delay(1); }

Eine gängige Methode zur Implementierung von Zustandsautomaten in Mikrocontrollern ist die Verwendung der Switch-Case -Anweisung. In unserem Beispiel entsprechen die Fälle den Zuständen und die Schalter der `fsm_state` . Betrachten wir nun genauer, wie die einzelnen Zustände aufgebaut sind:

Eine gängige Methode zur Implementierung von Zustandsautomaten (FSM) in Mikrocontrollern ist die Verwendung der Switch-Case -Anweisung. In unserem Beispiel stellen die Switch-Case-Anweisungen die Zustände dar, und die Programmsteuerung, die einen Zustandsübergang auslöst, wird durch die Variable `fsm_state` repräsentiert. Wir legen fest, ob `READ_SEND` oder `WAIT` verwendet werden sollen. Die Werte 1 bzw. 0 werden gesendet, um die einzelnen Phasen des Zustandsautomaten zu identifizieren und den Übergang zwischen den Operationen anhand eines unabhängigen 60-Sekunden-Timers zu steuern.

Schauen wir uns nun genauer an, wie die einzelnen Bundesstaaten gestaltet sind:

  • WARTEN: Aus dem Code dieses Zustands können wir schließen, dass er nichts unternimmt, wenn das unter msCount weniger als 60000 Millisekunden beträgt; sobald diese Bedingung erreicht ist, ändert sich der Wert von fsm_state und wir gehen in den nächsten Zustand über, den Zustand READ_SEND.
  • READ_SEND: Hier lesen wir den Wert unseres Sensors, addieren ihn zu einer Variablen namens „stuff“ und senden die Daten an ein Gerät namens „source1“. Beim Ausführen dieses Programms wechseln wir vor jeder zweiten Ausgabe wieder in den Wartezustand.

Schließlich erhöhen wir außerhalb unserer Switch-Case-Struktur den Wert unseres Timers und fügen eine sehr kurze Verzögerung von 1 Millisekunde ein, um die Zeit mit unserem Zähler konsistent zu machen.

An dieser Stelle fragen Sie sich vielleicht, warum wir das alles programmieren sollten, wenn wir die übliche sequentielle Programmierung verwenden können? Stellen Sie sich vor, Sie haben drei zusätzliche Aufgaben, die Sie innerhalb Ihrer Routine ausführen müssen:

  1. Einen Servomotor mittels PWM steuern
  2. Werte auf einem LCD-Bildschirm anzeigen
  3. Ein Tor schließen oder öffnen

Bei der Ausführung mehrerer Aufgaben ermöglicht der FSM eine minimale Datenspeicherung im lokalen Speicher eines Geräts. Zudem können die Zustandsfunktionen basierend auf den Eingabewerten unmittelbare Aufgaben ausführen und nicht nur eine einzelne Ausgabe generieren. Mithilfe des FSM lassen sich logischere Entscheidungen treffen, wodurch der Zeit- und Energieaufwand für die Bereitstellung eines getesteten logischen Programms reduziert wird. Der Wert des FSM liegt in seiner Fähigkeit, Prozesse auf Geräteebene zu berechnen – dem ersten Schritt im Edge Computing.

Testen

Unser Skript funktioniert wie erwartet. Es wird ein neues Gerät namens „source1“ erstellt, das über eine Variable namens „stuff“ verfügt, die alle 60 Sekunden den Wert des Sensors in Ubidotsempfängt und speichert.

Verbesserungen und Ideen

Ein endlicher Automat (FSM) lässt sich auf vielfältige Weise implementieren, und die Verwendung einer Switch-Case-Anweisung kann bei einer sehr großen Anzahl von Zuständen mühsam sein. Eine weitere Verbesserung des hier in Teil 1 erläuterten Codes wäre, die Wartezeit von einer Millisekunde zwischen den einzelnen analysierten Fällen zu vermeiden. Dies lässt sich mit der Funktion `millis()` realisieren.

Abschluss

Wir Menschen haben Computer nach unserem Vorbild programmiert, und endliche Zustandsautomaten (FSMs) ermöglichen es Maschinen, Aufgaben auszuführen und uns im Alltag wertvolle Unterstützung und Sicherheit zu bieten. Da die Technologie und das Know- edge Einplatinencomputer weiterhin in Industrieanlagen und Produktionshallen Einzug halten. Die Steuerung einfacher Prozesse mit FSM-Programmierung auf SBCs treibt vernetzte Lösungen voran, die industrielle gateway und SPS-Systeme von Herstellern wie Dell, Siemens usw. ergänzen und gleichzeitig lokale Lösungen ermöglichen, die $ an Hardware- und Betriebskosten einsparen.