FSM Library (Playground)- Verständnisfrage

Hallo,

im Text zur FSM Library (Arduino Playground - FiniteStateMachine Library) steht, dass zu jedem einzelnen Zustand eine enter-, update- und eine exit-Funktion gehört (zu finden unter „State Creation“):

State( enterFunction , updateFunction , exitFunction )

State ethernetDebugState = State( connectToHost , debug , closeConnectionToHost );

In dem im Playground weiter unten aufgezeigten LED-Beispiel enthalten die einzelnen Zustände jedoch jeweils lediglich eine Funktion.

State On = State(ledOn);

Wie lässt sich dies mit der weiter oben beschriebenen Aussage in Einklang bringen?

Gruß Chris

Vielleicht weil in dem Beispiel mit der LED diese nur 2 Zustände kennt: nämlich AN oder AUS ?

Ich verstehe die Antwort in sofern, dass eine LED nur zwei Zustände haben kann.

Im Bezug auf meine Frage bringt mich diese Erkenntnis jedoch nicht wirklich weiter.

Ein weiteres Beispiel zur FSM würde mir bestimmt helfen. Leider finde ich im Netz nur dieses Eine.

Gruß Chris

Guckst du FiniteStateMachine.h :

...
class State {
	public:
		State( void (*updateFunction)() );
		State( void (*enterFunction)(), void (*updateFunction)(), void (*exitFunction)() );
...

Es gibt also 2 Möglichkeiten, ein State Objekt zu erzeugen, entweder mit den 3 Funktionen, oder nur mit updateFunktion.

Ah- ok. War für mich anhand der erklärenden Texte so nicht nachvollziehbar. :roll_eyes:

Dankeschön!

Gruß Chris

Da der Funktionsumfang der FSM Bibliothek gelinde gesagt nicht sofort ersichtlich ist ( :roll_eyes: ), habe ich mir mal die Mühe gemacht, sämtliche relevanten Informationen so gut es ging zu übersetzen und um sinnvolle Kommentare zu ergänzen.

Alles natürlich wie beim Lotto ohne Gewähr:

/******************************************************************************************************************/
/*****************************************  Beschreibung FSM  *****************************************************/
/******************************************************************************************************************/

/*                                          Endlicher Zustandsautomat
  
      Mit einem endlichen Zustandsautomaten lassen sich Zustände verwalten.
      Er verwaltet sowohl die Übergänge zwischen den einzelnen Zuständen, als auch die Zustände an sich.
      Die Übergänge lassen sich sowohl durch äußere Eingaben, als auch durch interne Logiken auslösen.
      
      Übergänge können entweder sofort erfolgen oder bis zur nächsten Zustands-Aktualisierung zurückgestellt werden.
      Letzteres wird häufiger verwendet, da dadurch sichergestellt wird, dass alle Codebestandteile,
      die sich auf den aktuellen Zustand beziehen, gleichzeitig ausgeführt werden.
      
      Das weiter unten aufgeführte Beispiel benötigt lediglich der Einfachheit
      halber sowohl die Button_Library als auch die LED_Library.
  
*/

/******************************************************************************************************************/
/*****************************************  Aufbau  ***************************************************************/
/******************************************************************************************************************/


  
// Diese Bibliothek geht davon aus, dass sämtliche Funktionalitäten im Sketch hinterlegt sind,
// damit die einzelnen Zustände über eine einfache Abfrage die entsprechende Funktion auslösen können.

// Zustände erwarten entweder nur eine update_Funktion,
// oder eine enter_, update_ und exit_Funktion.

// Diese Funktionen werden anhand folgendes Schemas aufgerufen:
  
  current.exit();    // Momentanen Zustand verlassen
  next.enter();      // Zum nächsten Zustand wechseln
  current = next;    // Den eben noch nächsten Zustand zum momentanen Zustand machen
  
  current.update();  // Wenn momentan kein Übergang stattfindet



/******************************************************************************************************************/
/*****************************************  Initialisierung eines Zustandsautomatens  *****************************/
/******************************************************************************************************************/



  FSM(State)

// Beispiel:
  
  FSM ethernetStateMachine = FSM(ethernetDebugState);
  
// Initialisiert einen Zustandsautomaten namens "ethernetStateMachine" mit dem  Zustand "ethernetDebugState"
  


/******************************************************************************************************************/
/*****************************************  Initialisierung von Zuständen  ****************************************/
/******************************************************************************************************************/



State(updateFunction)

// Beispiel:

State On = State(ledOn);  // Initialisierung lediglich mit der update_Funktion



State(enterFunction, updateFunction, exitFunction)

// Beispiel:

State ethernetDebugState = State(connectToHost, debug, closeConnectionToHost);



/******************************************************************************************************************/
/*****************************************  Functions State Functions  ********************************************/
/******************************************************************************************************************/



void enter()   // Diese Funktion wird immer dann ausgelöst, wenn in den entsprechenden Zustand gewechselt wird.


void update()  // Diese Funktion wird immer dann ausgelöst, wenn der Zustandsautomat aktualisiert wird,
               // während der entsprechende Zustand momentan aktiv ist.


void exit()    // Diese Funktion wird immer dann aufgerufen, wenn der entsprechende Zustand verlassen wird.



/******************************************************************************************************************/
/*****************************************  Finite State Machine Functions  ***************************************/
/******************************************************************************************************************/



void update()                            // Diese Funktion aktualisiert den momentanen Zustand
                                         // des entsprechenden Zustandsautomatens
                                         // Beispiel:
                                         ledStateMachine.update();

void transitionTo(State)                 // Mit dieser Funktion kann eine Zustandsänderung herbeigeführt werden,
                                         // deren Änderungszeitpunkt zu Beginn der nächsten Aktualisierung stattfinden wird
                                         // Beispiel:
                                         ledStateMachine.transitionTo(FadeIn);

void immediateTransitionTo(State)        // Diese Funktion wechselt sofort vom aktuellen zum nächsten Zustand
                                         // des des entsprechenden Zustandsautomatens
                                         // Beispiel:
                                         ledStateMachine.immediateTransitionTo(FadeIn);

State& getCurrentState()                 // Gibt den momentanen Status des entsprechenden Zustandsautomatens zurück
                                         // Beispiel:
                                         ledStateMachine.getCurrentState();


boolean isInState(State)                 // Prüft, ob der angefragte Zustand dem momentanen Zustand entspricht
                                         // Beispiel:
                                         ledStateMachine.isInState(On)



/******************************************************************************************************************/
/*****************************************  Beispielcode  *********************************************************/
/******************************************************************************************************************/



#include <FiniteStateMachine.h>     // FSM-Library (http://arduino-info.wikispaces.com/HAL-LibrariesUpdates)
#include <Button.h>                 // Button-Library (http://arduino-info.wikispaces.com/HAL-LibrariesUpdates)
#include <LED.h>                    // LED-Library (http://arduino-info.wikispaces.com/HAL-LibrariesUpdates)



State On = State(ledOn);            // Initialisierung der einzelnen Zustände (mit Verweisen auf einzelne Funktionen)
State Off = State(ledOff); 
State FadeIn = State(ledFadeIn);
State FadeOut = State(ledFadeOut); 

FSM ledStateMachine = FSM(On);      // Initialisierung eines Zustandsautomatens namens "ledStateMachine"
                                    // mit dem Zustand "On"


const byte NUMBER_OF_STATES = 4;    // Gesamtanzahl der möglichen Zustände

Button button = Button(12,PULLUP);  // Initialisierung eines Knopfes
byte buttonPresses = 0;             // Zählervariable die festhält, wie oft der Knopf bereits gedrückt wurde

LED led = LED(13);                  // Initialisierung einer LED



void setup()
{
}



void loop()
{
  if (button.uniquePress())                              // Sobald der Knopf gedrückt wird,
  {
    buttonPresses = ++buttonPresses % NUMBER_OF_STATES;  // wird die Zählervariable erhöht, 
                                                         // diese im Anschluss auf 0 bis 3 beschränkt
    switch(buttonPresses)                                // und der passende Zustandswechsel eingeleitet.
    {
      case 0: 
        ledStateMachine.transitionTo(On);                // Bei "0" wird z.B. in den Zustand "On" gewechselt,
        break;                                           // welcher im Anschluss die Funktion ledOn aktiviert.
      case 1: 
        ledStateMachine.transitionTo(Off); 
        break;
      case 2: 
        ledStateMachine.transitionTo(FadeIn); 
        break;
      case 3: 
        ledStateMachine.transitionTo(FadeOut); 
        break;
    }
  }
  ledStateMachine.update();  // Permanent den Zustand aktualisieren
}



/*****************************************  Ausgelagerte Funktionen  **********************************************/



void ledOn()  // LED an
{ 
  led.on();
}

void ledOff()  // LED aus
{ 
  led.off(); 
}

void ledFadeIn()  // LED fadet ein
{ 
  led.fadeIn(500); 
}

void ledFadeOut()  // LED fadet aus
{ 
  led.fadeOut(500);
}

Vielleicht hilft es ja dem Einen oder Anderen.

Gruß Chris

Am besten ist bei sowas in den Header schauen. Da sieht man welche Methoden es gibt. Wenn man Glück hat sind sie auch dokumentiert. Manchmal stehen die Kommentare auch in der .cpp Datei. Aber der Header ist erst mal übersichtlicher, da er nur die Deklarationen der Methoden enthält und nicht deren Definition.

Was meinst Du mit "der Header"?

Griuß Chris

*.h Datei im Lib Verzeichnis.

Die .h Datei der Bibliothek

Auch gut ist eine IDE mit Autovervollständigung, so dass man schon beim Eintippen sieht was es an Optionen gibt. Obwohl die wenigsten Libs so geschrieben sind, dass da bei eine komplette Beschreibung der Methode anzeigen. Aber man sieht immerhin was an Methoden gibt.

Hallo,

jetzt hab ich doch noch einmal eine Frage bzgl. der FSM Library.

Im Playground steht..

State& getCurrentState()

"Returns the current state"

Ich gehe nun davon aus, dass ich mir mit dieser Funktion den momentanen Zustand eines bestimmten Zustandsautomatens anzeigen lassen kann.

Wenn jetzt mein Zustandsautomat z.B. fsm_01 heisst, wie müsste ich das ganze denn schreiben, wenn ich mir den Zustand über die serielle Schnittstelle anzeigen lassen wollen würde?

Serial.println(fsm_01.getCurrentState());

..funktioniert leider nicht.

Gruß Chris

Serial.println(fsm_01.getCurrentState());

Evtl. so ?

Dim fsm1state as int = 0 ' oder was gebraucht wird
fsm1state = (fsm_01.getCurrentState())
Serial.println(fsm1state)

Was gebraucht wird weiss ich nicht, da ich mich mit den Innereien von Bibliotheken noch nicht auskenne.

Jeder einzelne Zustand besteht aus wenigen Zeichen (z.B. “Funktion_01”).

Der Fehler scheint ehr in der Zeile…

fsm_01.getCurrentState()

…zu liegen, denke ich. :relaxed:

Gruß Chris

Schau dir mal die Zeile genau an. Das liefert dir eine Referenz auf ein State Objekt. Was will print() damit anfangen können?

Ok,

ich bin jetzt mal ein wenig anders an die Sache rangegangen, doch leider kompiliert es noch immer nicht.

Hock jetzt praktisch schon den ganzen Nachmittag dran. :frowning:

Hier mein Code um die Funktion zu testen:

/******************************************************************************************************************/
/*****************************************  Beispielcode  *********************************************************/
/******************************************************************************************************************/

/*

  Code springt bei 3000 in Funktion_02 und bei 6000 wieder zurück zur Funktion_01.
  
*/

#include <FiniteStateMachine.h>

State Funktion_01 = State(a_func_01_in, a_func_01, a_func_01_out);
State Funktion_02 = State(a_func_02_in, a_func_02, a_func_02_out); 

FSM SerialMachine = FSM(Funktion_01);

boolean time_01 = 0;
boolean time_02 = 0;
boolean time_03 = 0;

unsigned long last_time = 0;

void setup()
{
  Serial.begin(9600);
}



void loop()
{
  if(millis() >= 3000 && !time_01)
  {
    Serial.println(millis());
    SerialMachine.transitionTo(Funktion_02);
    time_01 = 1;
  }
  if(millis() >= 6000 && !time_02)
  {
    SerialMachine.transitionTo(Funktion_01);
    time_02 = 1;
  }
  SerialMachine.update();
  FSM_status();
}



/*****************************************  Ausgelagerte Funktionen  **********************************************/



void a_func_01_in()
{ 
  Serial.print("Funktion 1 wurde aufgerufen bei ");
  Serial.println(millis());
}

void a_func_01()
{ 
  // Serial.println("Funktion 1 aktiv!");
}

void a_func_01_out()
{ 
  Serial.print("Funktion 1 wurde verlassen bei ");
  Serial.println(millis());
}

void a_func_02_in()
{ 
  Serial.print("Funktion 2 wurde aufgerufen bei ");
  Serial.println(millis());
}

void a_func_02()
{ 
  // Serial.println("Funktion 2 aktiv!");
}

void a_func_02_out()
{ 
  Serial.print("Funktion 2 wurde verlassen bei ");
  Serial.println(millis());
}

void FSM_status()
{
  if(millis() - last_time >= 1000)
  {
    if(SerialMachine.getCurrentState() == Funktion_01);
    {
      Serial.println("Serielle Ausgabe: Funktion_01 geschaltet");
    }
    last_time = millis();
  }
}

Weiss einfach nicht, wo das Problem sein soll. :~

Gruß Chris

sorry for english only speaking

this does not compile in IDE 1.6.8

if(SerialMachine.getCurrentState() == Funktion_01)

is there a new syntax to make this comparison?