Monday, February 24, 2014

State Machines

What is a State Machine?

A state machine is a why to keep track of where you are in the middle of a process. The example from current G4 is the plunger app. Its states are:
  1. Fail
  2. Start of Closed - waiting for plunger to fall
  3. waiting for the right conditions to open the valve.
  4. Start of Open - waiting for plunger to arrive.
  5. Plunger never arrived - Use blow valve to assist (not longer used due to EPA)
  6. Plunger Arrived - 1 sec state to record values at time of arrival.
  7. Afterflow - waiting for the right conditions to close the valve.

 How do I implement a state machine?

  • An integer variable is usually used to keep track of the current state. Optionally the state can ALSO be keep in a string for ease of displaying on the front panel or by host systems.
  • Expanding on its use in plunger, it is now common to add a Disabled state. This gives the host only one place to look for overall status.
  • Usually the state is not retained, but some processes need to know what happened at power down, so that recovery can be adjusted.
  • In it's simplest form one switch statement chooses which code to execute by the value of the current state.
  • More complex programs can use up to three switch statements
    1. Change of state at the beginning  to initialize a state
    2. Normal operation
    3. Change of state at the end to cleanup a state.

Example: 

IF Old_State <> Curr_State THEN 
    (* When state changes - Initialize new State *)
    CASE Curr_State of
       State_Open: 
            Statusbool := OpenInit();
       State_Close:
            StatusBool := CloseInit();
       State_Disabled:
            (* do nothing *)
       ELSE  (* Bad value reset Close *)
            Curr_State := State_Disabled;
    END_CASE;
    Old_State :=  Curr_State;
END_IF;
    CASE Curr_State of
    State_Open: 
         Statusbool := Open();
    State_Close:
         StatusBool := Close();
END_CASE;
CASE Old_State of     (* When state changes - Terminate new State *)
    State_Open: 
        Statusbool := OpenTerm();
    State_Close:
        StatusBool := CloseTerm();
END_CASE;
(* ********************* *)
OpenInit
    Open_Valve = TRUE;
(* ********************* *)
OPEN
    IF timetoclose THEN
        Curr_State = State_Close;
    END_IF;
(* ********************* *)
OpenTerm
    (* Record open time *)

No comments:

Post a Comment