Unsere vernetzte Welt; Erklärung endlicher Zustandsmaschinen
Mann/Frau sollen nach Gottes Bild geschaffen worden sein. Auf ähnliche Weise erschaffen Männer und Frauen heute Maschinen nach unserem eigenen Vorbild. Ein Beispiel hierfür ist die Finite-State-Machine- Programmierung , kurz FSM. Ingenieure und Entwickler nutzen heute Computer, um Aufgaben zu erledigen, die früher von Hand ausgeführt wurden. Zum Beispiel: Liegt schmutzige Wäsche herum? – Ich weiß, dass ich es tue. Früher mussten wir die Kleidung in einer Wanne oder einem Waschbecken ausspülen, Seife hinzufügen, schrubben, erneut ausspülen und so weiter, um ein sauberes T-Shirt für die Arbeit oder zum Ausgehen zu bekommen. Jetzt haben wir Waschmaschinen, die diese Arbeit für uns erledigen. Wir sind an diesem Punkt angelangt, als Ingenieure Tausende von Produkten und Geräten entwickelt haben, die Programme ausführen, die auf menschlichem Denken oder Handeln basieren. Dies ist keine Ausnahme vom heutigen maschinellen Lernen oder anderen KI-Schlagworten. Millionen von Geräten und Anwendungen werden entwickelt, um die Effizienz und den Komfort von Menschen zu steigern, und viele dieser unterstützenden Prozesse existieren dank FSMs.
Finite-State-Maschinen sind einfach eine mathematische Berechnung einer Reihe von Ursachen mit Ereignissen. Bezogen auf unser Waschmaschinenbeispiel bestimmt das FSM, wann der Spülgang gestartet, wann geschleudert und wann ganz gestoppt werden soll. Um eine Finite State Machine (FSM) besser zu verstehen, müssen wir zunächst das Konzept eines „Zustands“ definieren. Ein Zustand ist eine einzigartige Information innerhalb eines größeren Rechenprogramms. Die FSM-Berechnung ändert sich oder geht als Reaktion auf externe Eingaben von einem Zustand in einen anderen über . Ein FSM wird durch eine Auflistung oder logische Reihenfolge seiner Zustände definiert; seinen Anfangszustand und die Bedingungen für jeden Übergang, der mit einem End- oder Endzustand endet. Das FSM ist eine Reihe von Gedanken, die vom Computer programmiert werden, um Operationen basierend auf Eingaben auszuführen – so wie der Mensch denkt und handelt, tun es auch unsere Maschinen und die Computer, die sie steuern.
Zustände sind die DNA des FSM, die internes Verhalten oder Interaktionen mit einer Umgebung vorgibt, wie z. B. die Annahme von Eingaben oder die Erzeugung von Ausgaben, die dazu führen können, dass das System seinen Zustand ändert oder nicht. Der Zustand soll abhängig von den unterschiedlichen Bedingungen, die in Ihrem FSM definiert sind, gezielt ausgeführt werden. Dieses Konzept ist für Hardware- und Elektroingenieure sehr wichtig, da viele praktische Probleme wie die Programmierung von Waschmaschinen (wann man Wasser oder Seife hinzufügt, wann man schleudert oder ruhen soll) leicht mit FSM anstelle der klassischen sequentiellen Programmierparadigmen gelöst werden können. Mit anderen Worten: Ein FSM ist eine eher „elektrische und elektronische“ Lösung zur Lösung eines Hardwareproblems im Vergleich zur sequentiellen Programmierung.
Nachfolgend finden Sie zwei Beispiele für FSMs, die eine logische Entscheidungsfindung mit weniger Zeit- und Energieaufwand für die Bereitstellung eines getesteten logischen Programms ermöglichen. Das FSM ist Ihr erster Schritt zum Edge Computing auf Einzelgeräteebene in industriellen IoT Anwendungen.
Mealy-Maschine: Bei der Berechnung der Mealy-Maschine hängen die Ausgaben jedes Zustands vom tatsächlichen Zustand und seinen aktuellen Eingabewerten ab. Typischerweise führt bei jeder Mealy-Berechnung die Eingabe eines Zustands zu einer einzelnen Ausgabe eines Übergangs oder eines Endzustands. Die Waschmaschine füllt sich mit Wasser – wenn der Füllstand X erreicht ist, stoppen Sie den Wasserlauf.
Moore-Maschine: Bei der Moore-Maschine hängen die Ausgänge jedes Zustands vom tatsächlichen Zustand ab und basieren normalerweise auf getakteten sequentiellen Systemen. Die Waschmaschine schleudert nach 4 Minuten und stoppt die Maschine.
ZUSTANDSDIAGRAMM
Jedes FSM muss beschrieben werden, bevor es durch ein Zustandsdiagramm codiert wird – die Art und Weise, wie wir die Gedanken der Maschine darstellen können. Das folgende Beispiel zeigt das FSM-Verhalten und seine Übergänge, die (normalerweise) mithilfe von Blasen zur Beschreibung von Zuständen und Pfeilen für Übergänge gezeichnet werden. Ein allgemeiner Hinweis bei der ordnungsgemäßen Ausführung eines FSM besteht außerdem darin, einen eindeutigen gegenwärtigen Zustand zu haben, in dem der nächste (zukünftige) Zustand, der ausgeführt wird, leicht anhand der Programmierberechtigungen des Staates identifiziert werden kann.
Im obigen Diagramm veranschaulichen wir einen abgeschlossenen Mealy Finite State Machine-Prozess. Nehmen wir an, dass der Vorgang in Status 1 beginnt und dann in Status 2 übergeht, sobald die Programmierberechtigungen erfüllt sind. Nach dem Übergang zu Stufe 2 berechnet das FSM den aktuellen Status, bis ein Auslöser erreicht wird, um zu Status 3 oder Status 4 überzugehen. Beachten Sie, dass Status 3 und Phase 4 in diesem Diagramm End- oder Endzustände sind, die zu berechneten Daten für Sie führen Endergebnis des Projekts.
Ubidots FSM
Beginnen wir nun damit, einen FSM zu programmieren, um Daten an Ubidots und Ihnen die Arbeit mit dieser Programmiermethode in der Praxis näherzubringen. Bei unserem FSM versuchen wir, den ursprünglichen Bedarf zu erkennen und darauf zu reagieren. Wir bauen eine schnelle Moore-Maschine: Senden Sie jede Minute Sensordaten von unserem Mikrocontroller (Espressif ESP8266) an Ubidots
Basierend auf dieser anfänglichen Anforderung haben wir uns entschieden, zwei Zustände mithilfe eines Moore Machine FSM-Berechnungsmodells zu implementieren:
- WARTEN: Nichts tun, bis eine Minute vergangen ist (ca. 59 Sekunden im Ruhezustand bleiben).
- READ_SEND: Lesen Sie den analogen Eingang des Mikrocontrollers, an dem der Sensor angebracht ist, und senden Sie das Ergebnis nach 60 Sekunden per MQTT Ubidots
Das folgende Zustandsdiagramm veranschaulicht die Programmierlogik unseres FSM:
Aus diesem Diagramm wird deutlich, 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. Ab dem nächsten WAIT-Zustand läuft das Programm kontinuierlich im WAIT-Zustand, bis die unabhängige Zeit 60 Sekunden erreicht oder überschreitet. Sobald die 60-Sekunden-Marke erreicht ist, wechselt das FSM von WAIT zu READ_SEND. Nachdem der Wert gesendet wurde, wechselt das FSM für weitere ca. 59 Sekunden zurück in den WAIT-Modus, bevor der Übergang erneut berechnet wird.
Codierung
Um das Verständnis dieses Beispiels etwas zu erleichtern, schauen wir uns einen praktischen FSM-Code an, der in vier separate Teile unterteilt wurde, um die einzelnen Zustände und Übergangsbedingungen detailliert zu beschreiben. Den vollständigen Code finden Sie hier.
Teil 1 – Einschränkungen definieren
// Bibliotheken einschließen #include " Ubidots ESPMQTT.h" // Konstanten definieren #define TOKEN "...." // Ihr Ubidots TOKEN #define WIFINAME "...." //Ihre SSID #define WIFIPASS "... ." // Dein WLAN-Pass #define WAIT 0 #define READ_SEND 1 uint8_t fsm_state = WAIT; // Ausgangszustand int msCount = 0; // Gleitkommawert des Zeitzählers; // Speicherplatz für den auszulesenden Wert Ubidots client(TOKEN);
Dieser erste Teil des Codes ist nicht sehr interessant, da wir lediglich die MQTT-Bibliothek zum Senden von Daten an Ubidots importieren und einige erforderliche Definitionen vervollständigen. Es ist wichtig zu beachten, dass wir hier die beiden Zustände WAIT und READ_SEND als Konstanten innerhalb des gesamten Codes definieren und den aktuellen Zustand mithilfe der Variablen fsm_state definieren. Der nächste Teil des Codes reserviert Speicherplatz für den unabhängigen Timer und den auszulesenden Wert sowie den zu initialisierenden MQTT-Client.
Es ist wichtig, dass Sie nicht vergessen, die richtigen Werte für Ihr TOKEN sowie den Namen und das Passwort Ihres WLAN-Netzwerks festzulegen. Wenn Sie nicht wissen, wo Sie Ihren Token finden, finden Sie im Ubidots Hilfecenter 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 Teil des Codes stellen wir einen Rückruf bereit, der bei Bedarf Daten vom Server verarbeitet. Für unser FSM ist dieser Schritt erforderlich, um Ihren Code ordnungsgemäß zu kompilieren. MQTT-Artikel beschrieben , verarbeitet die Callback-Funktion die Änderungen Ihrer Variablen in Ubidots und es ist notwendig, den Code zu kompilieren und 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 unserem Setup() legen wir den Nullpunkt des analogen Pins als Eingang fest (Sie sollten die Nummer des PINs abhängig von der physischen Verbindung Ihres Sensors bearbeiten), um den ADC verwenden zu können, der es dem Sensor ermöglicht, die Umgebungsdaten zu lesen und eine Float-Zahl als Wert darstellen. Außerdem initialisieren wir den WiFi-Client und übergeben die Rückruffunktion basierend auf den zuvor definierten Programmierparametern.
Teil 4 – Hauptfunktionen – Loop()
void loop() { switch(fsm_state) { case WAIT: if (msCount >= 60000){ msCount = 0; fsm_state = READ_SEND; } brechen; case READ_SEND: value = analogRead(A0); if(!client.connected()){ client.reconnect(); } /* Routine zum Senden von Daten */ client.add("stuff", value); Kunde. ubidots Publish("source1"); client.loop(); fsm_state = WARTEN; brechen; Standard: Pause; } // Erhöht den Zähler msCount += 1; Verzögerung(1); }
Eine beliebte Methode zur Implementierung von FSM in Mikrocontrollern ist die Verwendung der Switch-Case -Steuerungsstruktur. In unserem Beispiel sind die Fälle unsere Zustände und die Schalter die fsm_state
. Sehen wir uns genauer an, wie jeder Staat gestaltet ist:
Eine beliebte Methode zur Implementierung von FSM in Mikrocontrollern ist die Verwendung der Switch-Case -Steuerungsstruktur. In unserem Beispiel sind die Schalterfälle unsere Zustände und die Programmierung, die einen Übergang verursacht, der durch die Variable fsm_state dargestellt wird. Hier bestimmen wir READ_SEND vs. WAIT, wobei Werte von 1 oder 0 respektvoll gesendet werden, um jede Phase des FSM und den Übergang zwischen Vorgängen basierend auf dem unabhängigen 60-Sekunden-Timer zu identifizieren.
Sehen wir uns genauer an, wie jeder Staat gestaltet ist:
- WARTEN: Aus dem Code dieses Zustands können wir schließen, dass er nichts bewirkt, wenn das bei
msCount
weniger als 60.000 Millisekunden beträgt; Sobald diese Bedingung erreicht ist, ändert sich der Wert vonfsm_state
und wir gehen zum nächsten Status über, dem READ_SEND-Status. - READ_SEND: Hier lesen wir den Wert unseres Sensors und fügen ihn dann einfach zu einer Variablen namens „stuff“ hinzu und veröffentlichen seine Daten auf einem Gerät namens „source1“. Beim Ausführen dieses Programms wechseln wir immer zurück in den WAIT-Zustand, bevor wir eine zweite Ausgabe ausgeben.
Schließlich erhöhen wir aus unserer Switch-Case-Struktur heraus den Wert unseres Timers und haben eine sehr kleine Verzögerung von 1 Millisekunde, um die Zeit mit unserem Zähler in Einklang zu bringen.
An dieser Stelle fragen Sie sich vielleicht, warum wir das alles programmieren, wenn wir die übliche sequentielle Programmierung verwenden können? Stellen Sie sich vor, dass Sie in Ihrer Routine drei zusätzliche Aufgaben erledigen müssen:
- Steuern Sie einen Servomotor mithilfe von PWM
- Werte auf einem LCD-Bildschirm anzeigen
- 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 und die Zustandsfunktionen können außerdem unmittelbare Aufgaben basierend auf den Eingabewerten und nicht nur einer einzelnen Ausgabe ausführen. Mit FSM können Sie eine logischere Entscheidungsfindung mit weniger Zeit- und Energieaufwand für die Bereitstellung eines getesteten logischen Programms durchführen. Der Wert von FSM liegt in seiner Fähigkeit, Prozesse auf der Ebene einzelner Geräte zu berechnen – der erste Schritt im Edge Computing.
Testen
Unsere Skripte funktionieren wie erwartet. Es wird ein neues Gerät namens „source1“ mit einer Variablen namens „stuff“ erstellt, das den Sensorwert alle 60 Sekunden in Ubidots empfängt und speichert.
Verbesserungen und Ideen
Ein FSM kann auf viele Arten implementiert werden, und manchmal kann die Pflege switch-case-Anweisung Eine zusätzliche Verbesserung des hier in Teil 1 erläuterten Codes bestünde darin, die Wartezeit von einer Millisekunde zwischen den einzelnen analysierten Fällen zu vermeiden. Dies kann mit millis() durchgeführt werden.
Abschluss
Der Mensch/die Frau hat unsere Computer so entworfen, dass sie nach unserem eigenen Vorbild funktionieren, und Finite-State-Maschinen sind die Programmierung, die es Maschinen ermöglicht, Aufgaben auszuführen und den Menschen wertvolle Hilfe und Sicherheit in unserem täglichen Leben zu bieten. Da die Technologie und das Wissen zur Implementierung von FSMs immer billiger und zugänglicher werden, werden wir weiterhin erleben, wie Einplatinencomputer (SBCs) Industriefabriken und Fertigungshallen durchdringen. Die Steuerung einfacher Prozesse mit FSM-Programmierung auf SBCs treibt weiterhin vernetzte Lösungen voran, die Industrie gateway und SPS-Klassiker wie Dell, Siemens usw. ergänzen und gleichzeitig lokale Lösungen bereitstellen, die $ an Hardware- und Betriebskosten einsparen.