Guidance on Finite State Machine

Following advice here on the forum, I have implemented a FSM in my code for controlling a dog flap in an external door. Here is the logical flow chart I drew to try to design the system:-

Here is the code I am using (for Node MCU ESP8266). WARNING - I am new to coding! I can't figure out why the system will correctly check if the Master Switch and Door Sensor state when first booted. However, once passed these states, Ready State or Monitor Flap Open, , I can turn on and off the master switch and open the door, without it changing back to these initial states. Do I have to check inside each state for all inputs, which seems to defeat the purpose of the Switch Case statement. Also, I cant quite discern the logic of including breaks after each case. Any help appreciated!

I have to split code into next post, as it's too long.

Do I have to check inside each state for all inputs

Unlikely

Why not read the switch states in loop() and only use the values required in the code for a particular state ?

breaks at the end of a case stop the code simply falling through to the code for the next case in the sketch and executing it

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
const char* ssid     = "XXXXXXXXXXXXXXXXXX";
const char* password = "YYYYYYYYYYYYYYYYYY";


const unsigned long flapOpenTime = 30000; //in addition to timing of piR pot
unsigned long previousTime = 0; //priortime flap opened
unsigned long priorTime = 0; // prior time for WiFi timeout
const long timeoutTime = 2000; // Define timeout time in milliseconds (example: 2000ms = 2s)
const int relay2 = D1; //LOW state switches relay to linear actuator to close flap GPIO 5
const int relay1 = D2; //LOW state switches relay to linear actuator to open flap  GPIO 4
const int pIRoUT = D5;  // HIGH signal when motion detected GPIO 14
const int pIRiN = D6; // HIGH signal when motion detected GPIO 12
const int masterSwitch = D3; //manual switch to close flap- GPIO 0 - boot fails if pulled low - so should be switch off when starting system
const int doorSensor = D7; // reed switch to check if door is closed before starting system GPIO 13 
String stringState;
String priorStringState;//convert stringState into Char so can display in Serial Monitor


int priorpIRiNStatus;
int priorpIRoUTStatus;
int priorSystemState;


// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");


void openFlap()
{
  digitalWrite(relay1, LOW);// turn relay 1 ON
  digitalWrite(relay2, HIGH);// turn relay 2 OFF
}//openFlap()


void closeFlap()
{
  digitalWrite(relay1, HIGH);// turn relay 1 OFF
  digitalWrite(relay2, LOW);// turn relay 2 ON
}//closeFlap()




enum _state_enum
{
  CHECK_MASTER_SWITCH, //manual switch to turn off system
  MONITOR_DOOR_OPEN,//If door is open, close flap
  CHECK_TIME,//check time of day to decide which action to take
  DAY_TIME,//Day time dogs can come in and go out
  BED_TIME, //allow 1 hour between 2300hrs and midnight for dogs to come in before system turns off for night
  NIGHT_TIME, // system closed from midnight to 8 am
  READY, // system waiting for valid activity from PIR sensors
  CMD_OPEN_FLAP, //transition state when flap is opening
  MONITOR_OPEN_FLAP,//make sure flap doesn't close while dog is walking through
  CMD_CLOSE_FLAP, //transition state when flap is closing
  
};
_state_enum systemState = CHECK_MASTER_SWITCH;


void setup() {
  closeFlap();
  Serial.begin(115200);
  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.print ("Connected to:  ");
  Serial.println(WiFi.localIP());
  Serial.println ("Waiting 30 seconds to stabalize PIRs");


  pinMode(relay1, OUTPUT);// set pin as output for relay 1
  pinMode(relay2, OUTPUT);// set pin as output for relay 2
  pinMode(pIRiN, INPUT);
  pinMode(pIRoUT, INPUT);
  pinMode(doorSensor, INPUT);
  pinMode(masterSwitch, INPUT);
  
  // Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(0);
  
  delay(30000); //wait for PIRs to stabalize
}
void loop() 
{
    timeClient.update();
    int currentHour = timeClient.getHours();
    int currentMin = timeClient.getMinutes();
    int currentSecs = timeClient.getSeconds();
    int doorSensorStatus = digitalRead(doorSensor);
    int masterSwitchStatus = digitalRead(masterSwitch);
    unsigned long currentTime = millis(); // Current time
    int pIRiNStatus = digitalRead(pIRiN);
    int pIRoUTStatus = digitalRead(pIRoUT);
  
 if (systemState != priorSystemState)
 {
   Serial.print (F("States - FROM:- "));
    Serial.print (priorStringState);
    Serial.print (F(" TO -> "));
    Serial.println (stringState);
    Serial.print (F("doorSensorStatus:-  "));
    Serial.println  (doorSensorStatus);
    Serial.print (F("masterSwitchStatus:-  "));
    Serial.println (masterSwitchStatus);
    Serial.print (F("Current Time:- "));
    Serial.print (currentHour);
    Serial.print (F("H:"));
    Serial.print (currentMin);
    Serial.print (F("m:"));
    Serial.print (currentSecs);
    Serial.println (F("s:"));
    Serial.print (F("PriorPIR  / CurrentPIR - INSIDE "));
    Serial.print (priorpIRiNStatus);
    Serial.print (F(" / "));
    Serial.println (pIRiNStatus);
    Serial.print (F("PriorPIR  / CurrentPIR - OUTSIDE "));
    Serial.print (priorpIRoUTStatus);
    Serial.print (F(" / "));
    Serial.println (pIRoUTStatus);
    Serial.print (F("Relay 1 / Relay 2:- "));
    Serial.print (digitalRead(relay1));
    Serial.print (F(" / "));
    Serial.println (digitalRead(relay2));
    Serial.print ("Flap Elapsed Time: ");
    Serial.println (currentTime - previousTime);
    Serial.println (F("***********************"));
 } 
     


  switch (systemState)
  {
    //Check that system is switched on
    case CHECK_MASTER_SWITCH:
      priorSystemState = systemState;
      priorStringState = stringState;
      if(masterSwitchStatus == 1)
      {
        closeFlap();
        systemState = CHECK_MASTER_SWITCH;
        stringState = "CHECK_MASTER_SWITCH";
      }
      else
      {
        systemState = MONITOR_DOOR_OPEN;
        stringState = "MONITOR_DOOR_OPEN";
      }
       
      break;


    case MONITOR_DOOR_OPEN: //If door is open do not open flap
        priorSystemState = systemState;
        priorStringState = stringState;
      if (doorSensorStatus == 1) //continue monitoring and close flap


          { closeFlap();
            systemState = MONITOR_DOOR_OPEN;
            stringState = "MONITOR_DOOR_OPEN";
          }

        else
          {
            systemState = CHECK_TIME;
            stringState = "CHECK_TIME";
          }
      break;
     
     case CHECK_TIME:
      priorSystemState = systemState;
      priorStringState = stringState;


    if(currentHour >= 8 && currentHour <= 23)
      {
        systemState = DAY_TIME;
        stringState = "DAY_TIME";
      }
    if(currentHour > 23 &&currentHour <  0)
      {
        systemState = BED_TIME;
      }
    else
      {
        systemState = NIGHT_TIME;
      }

      break;
 
    case DAY_TIME:  //transition state
          priorSystemState = systemState;
          priorStringState = stringState;
          
           systemState = READY;
           stringState = "READY";
        
      
    case BED_TIME:  // If OUTSIDE PIR sensor went from LOW to HIGH then open the flap. 
                    //Leeway time to let the dogs in ONLY, but does not allow them out after 11pm.
          priorSystemState = systemState;  
          priorStringState = stringState;   
      if ((pIRoUTStatus != priorpIRoUTStatus && pIRoUTStatus == 1)
        && (currentHour >= 23 && currentHour <= 0))
        {
          systemState = CMD_OPEN_FLAP;
          stringState = "CMD_OPEN_FLAP";
          previousTime = currentTime;
        }
            priorpIRiNStatus = pIRiNStatus;
            priorpIRoUTStatus = pIRoUTStatus;
      

    case NIGHT_TIME: //after BED_TIME, shut down system for night
          priorSystemState = systemState;  
          priorStringState = stringState;  
      if(currentHour >= 0 && currentHour <= 8)


        {
        closeFlap(); 
        systemState = NIGHT_TIME;
        stringState = "NIGHT_TIME";
        }
            
    case READY:  // If either PIR sensor went from LOW to HIGH then open the flap.
      priorSystemState = systemState; 
      priorStringState = stringState;
      
      if (doorSensorStatus == 1)
        {systemState = MONITOR_DOOR_OPEN;}
      else if (masterSwitchStatus == 1)
        {systemState = CHECK_MASTER_SWITCH;}
      else if ((pIRiNStatus != priorpIRiNStatus && pIRiNStatus == 1)
           ||
          (pIRoUTStatus != priorpIRoUTStatus && pIRoUTStatus == 1))
        {        
        systemState = CMD_OPEN_FLAP;
        stringState = "CMD_OPEN_FLAP";
        previousTime = currentTime;
        }
      else systemState = CHECK_TIME;


          priorpIRiNStatus = pIRiNStatus;
          priorpIRoUTStatus = pIRoUTStatus;

      break;

    case CMD_OPEN_FLAP:
          priorSystemState = systemState;   
          priorStringState = stringState;//displays as string to view in serial.print
        openFlap();
        systemState = MONITOR_OPEN_FLAP;
        stringState = "MONITOR_OPEN_FLAP";
           
      break;

    case MONITOR_OPEN_FLAP:
        priorSystemState = systemState;
        priorStringState = stringState;
      if ((pIRiNStatus == 0 && pIRoUTStatus == 0) && (currentTime - previousTime >= flapOpenTime))
    
        {        
        systemState = CMD_CLOSE_FLAP;
        stringState = "CMD_CLOSE_FLAP";
        }
      break;


    case CMD_CLOSE_FLAP:
          priorSystemState = systemState;
          priorStringState = stringState;
        closeFlap();
        systemState = CHECK_MASTER_SWITCH;
        stringState = "CHECK_MASTER_SWITCH";
        
      break;
  priorpIRiNStatus = pIRiNStatus;
  priorpIRoUTStatus = pIRoUTStatus;
 
  }
}

UKHeliBob:
Why not read the switch states in loop() and only use the values required in the code for a particular state ?

UKHeliBob - Thank you for your reply. I have posted the code, following your comment and if I understood your suggestion correctly, I believe that I am already reading the switch states in the loop. Do I need to read the switch states in every case also? I notice that while I am conditionally serial printing on each change of systemState, some of the variables do not appear to be updating, specifically *masterSwitchStatus *and *doorSensorStatus *

I can't figure out why the system will correctly check if the Master Switch and Door Sensor state when first booted. However, once passed these states, Ready State or Monitor Flap Open, , I can turn on and off the master switch and open the door, without it changing back to these initial states. Do I have to check inside each state for all inputs, which seems to defeat the purpose of the Switch Case statement.

Warning! I am not very good at following other people's code (sometimes I can't follow my own code!!!)

You seem to be confusing states with tests and actions, for example

case CHECK_MASTER_SWITCH:

Checking the master switch is not a state, it's an test. States are things that persist until something changes them, for example your dog flap being closed is a state. You then have to decide what actions have to happen while in the DOGFLAPCLOSED state by doing a test of anything that will move it to a different state. DOGFLAPOPENING is another state.

So,
Inside the DOGFLAPCLOSED state you test for anything that would cause the flap to be opened. When that event happens you start the motors and change the state to DOGFLAPOPENING. In the DOGFLAPOPENING state you test for whatever would cause the flap to stop opening, then stop the flap and move to the next state.

You don't need priorSystemState = systemState; because in each state you test to see if you should move to the next state, and the next state will test for moving to the one after that. You have to work out for each state what needs to be checked and what action to take as a result.

Summary:
States persist for a long time, 'long' being anything longer than it takes loop() to go round once up to as long as you like, years if necessary.
Tests take place in each state to see if an action should be taken and a move to a different state
Actions are the outputs, such as opening the flap. Once an action starts move to a different state.

++Karma; // For what you have done so far.

EDIT
I've tried to clarify what I said a bit.

Apart from any problems with logic there could also be problems with your circuit. How are the inputs wired ? Are there pullup or pulldown resistors in place to keep them at a known state at all times or are they floating at an unknown, maybe HIGH, maybe LOW, maybe changing state ?

I would also advise you to stop using Strings, particularly when you keep changing their value as you do. I suggest that you use an array of string (lowercase s) pointers indexed by the value of the state variable. That way you can simply print the text that you require without setting a variable to a different value

​PerryBebbington - Thank you for your response. That does clarify matters for me. I had thought that if the
Master Switch was off, then that would be an Off state and same for if the door (not flap) was open, that too
would be a state. Potentially, they can persist for quite an extended time. But I can see that they are also
conditions which determine other states. Should I also move the Time of Day states into conditions for when
to open the flap?

I will try to recode using this logic and see how that goes.

I'll post update here if successful!

Thanks again - Paul

MODERATOR EDIT - removed HTML tags from the post

If the door (not flap) was open, that too would be a state.

I suggest you have 4 states:

  • Closed
  • Opening
  • Open
  • Closing

So, yes, open is a state.

Should I also move the Time of Day states into conditions for when to open the flap?

Yes, time of day is something that triggers a change or is a condition for opening or not opening the door. Time of day is not a state, it keep changing "Tempus fugit ad reditus umquam".

NB Can you edit your post to use the standard format?

UKHeliBob:
Apart from any problems with logic there could also be problems with your circuit. How are the inputs wired ? Are there pullup or pulldown resistors in place to keep them at a known state at all times or are they floating at an unknown, maybe HIGH, maybe LOW, maybe changing state ?

The PIRS are 3v3 versions and I just simply read in the signal. The Master Switch takes the input Pin to ground as does the door sensor (reed switch). Should I have resisters on these circuits?

UKHeliBob:
I would also advise you to stop using Strings, particularly when you keep changing their value as you do. I suggest that you use an array of string (lowercase s) pointers indexed by the value of the state variable. That way you can simply print the text that you require without setting a variable to a different value

I guess you mean where I am translating the enum value to a string, so I can make sense of the conditional Serialprint output. I had a sense that I was doing this in a clumsy manner, but I don’t really know how to implement your suggestion. Would you mind sharing an example of how this is done in an array?

PerryBebbington:
NB Can you edit your post to use the standard format?

Apologies, but I have no idea what I have done wrong? Which post is not in standard format?

Should I have resisters on these circuits?

Yes. You can activate the built in pullup resistors by using INPUT_PULLUP in the pinMode()s

As to the strings, here is an example

char * messages[] = {"a message", "another message", "and another"};

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.println(messages[0]);
  Serial.println(messages[1]);
  Serial.println(messages[2]);
}

void loop()
{
}

You can, of course, use a variable such as your state variable as the array index

joatmon13:
Apologies, but I have no idea what I have done wrong? Which post is not in standard format?

#7

Apologies, but I have no idea what I have done wrong?  Which post is not in standard format?

If you edit #7 I think you will find it has tt tags around it. Remove them.

They were pre tags and I have removed them

joatmon13:
I can't figure out why the system will correctly check if the Master Switch and Door Sensor state when first booted. However, once passed these states, Ready State or Monitor Flap Open, , I can turn on and off the master

I'm noticing that your flowchart doesn't have a 'begin' state. It's the job of setup() to initialise things, and that's what the 'begin' box is about.

Also, if the master switch is off, there's two flows of execution coming out of it? What? Which does it do - close the flap, or "master switch"? And what's with the two simultaneous flows of execution coming out of "ready"? I mean - I know what you mean, but as a diagram it makes no sense.

Anyway. As for states, the only things that need to be FSM states are those loops where the sketch is waiting for something to happen. Those trapezoidal blocks are your states - note that 'MONITOR OPEN FLAP' also ought to be trapezoidal to keep things consistent.

joatmon13:
Following advice here on the forum, I have implemented a FSM in my code for controlling a dog flap in an external door. Here is the logical flow chart I drew to try to design the system:-

Looking at this chart and all I come up with is.. You should just leave the dog outside.

-jim lee

Thank you all for contributions (including Jim’s suggestion!). I think I have the flow chart and code fixed. I may have a hardware issue with the relays which sometime output 12v and other times strange 3-7 volts. I decided to place a short 1 second delay between changing relays and it seems to have resolved the issue.

Meanwhile, here is the updated flow chart and code:-

I have implemented the Char Array approach instead of string, which has removed strings and that seems to work.

//Designed for ESP8266 with 2 PIR's, 2 Switches and 2 relays driving a linear actuator
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
const char* ssid     = "XXXXXXXXXXXXXXXXXXXXXX";
const char* password = "YYYYYYYYYYYYYYYYYYYYYY";
const unsigned long flapOpenTime = 30000; //in addition to timing of piR pot
unsigned long previousTime = 0; //priortime flap opened
unsigned long priorTime = 0; // prior time for WiFi timeout
const long timeoutTime = 2000; // Define timeout time in milliseconds (example: 2000ms = 2s)
const int relay2 = D1; //LOW state switches relay to linear actuator to close flap GPIO 5
const int relay1 = D2; //LOW state switches relay to linear actuator to open flap  GPIO 4
const int pIRoUT = D5;  // HIGH signal when motion detected GPIO 14
const int pIRiN = D6; // HIGH signal when motion detected GPIO 12
const int masterSwitch = D3; //manual switch to close flap- GPIO 0 - boot fails if pulled low - so should be switch off when starting system
const int doorSensor = D7; // reed switch to check if door is closed before starting system GPIO 13 
int priorpIRiNStatus;
int priorpIRoUTStatus;
int priorSystemState;

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

void openFlap()
{
  digitalWrite(relay1, LOW);// turn relay 1 ON
  delay (1000);
  digitalWrite(relay2, HIGH);// turn relay 2 OFF
}//openFlap()

void closeFlap()
{
  digitalWrite(relay1, HIGH);// turn relay 1 OFF
  delay (1000);
  digitalWrite(relay2, LOW);// turn relay 2 ON
  
}//closeFlap()

enum _state_enum
{
  START,
  SYSTEM_READY, //checks door is closed, master switch is on and corrrect time of day
  MONITOR_ACTIVITY, // system waiting for valid activity from PIR sensors
  CMD_OPEN_FLAP, //transition state when flap is opening
  BED_TIME,
  MONITOR_OPEN_FLAP,//make sure flap doesn't close while dog is walking through
  CMD_CLOSE_FLAP, //transition state when flap is closing
  };
_state_enum systemState = START;

const char * messages[] = {
  "START",
  "SYSTEM_READY",
  "MONITOR_ACTIVITY",
  "CMD_OPEN_FLAP",
  "BED_TIME",
  "MONITOR_OPEN_FLAP",
  "CMD_CLOSE_FLAP"
 };

void setup() {
  
  Serial.begin(115200);
  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.print ("Connected to: ");
  Serial.println(WiFi.localIP());
  Serial.println (" wait 30 seconds for PIRs to stabalize");

  pinMode(relay1, OUTPUT);// set pin as output for relay 1
  pinMode(relay2, OUTPUT);// set pin as output for relay 2
  pinMode(pIRiN, INPUT_PULLUP);
  pinMode(pIRoUT, INPUT_PULLUP);
  pinMode(doorSensor, INPUT_PULLUP);
  pinMode(masterSwitch, INPUT_PULLUP);
  
  // Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT 0 = 0
  timeClient.setTimeOffset(0);
  closeFlap();
  delay(30000); //wait for PIRs to stabalize
}

void loop() 
{
    timeClient.update();
    int currentHour = timeClient.getHours();
    int currentMin = timeClient.getMinutes();
    int currentSecs = timeClient.getSeconds();
    int doorSensorStatus = digitalRead(doorSensor);
    int masterSwitchStatus = digitalRead(masterSwitch);
    unsigned long currentTime = millis(); // Current time
    int pIRiNStatus = digitalRead(pIRiN);
    int pIRoUTStatus = digitalRead(pIRoUT);
  
 if (systemState != priorSystemState)
 {
    Serial.print (F("States - FROM:- "));
    Serial.print (messages[priorSystemState]);
    Serial.print (F(" TO -> "));
    Serial.println (messages[systemState]);
    Serial.print (F("doorSensorStatus:-  "));
    Serial.println  (doorSensorStatus);
    Serial.print (F("masterSwitchStatus:-  "));
    Serial.println (masterSwitchStatus);
    Serial.print (F("Current Time:- "));
    Serial.print (currentHour);
    Serial.print (F("H:"));
    Serial.print (currentMin);
    Serial.print (F("m:"));
    Serial.print (currentSecs);
    Serial.println (F("s:"));
    Serial.print (F("PriorPIR  / CurrentPIR - INSIDE "));
    Serial.print (priorpIRiNStatus);
    Serial.print (F(" / "));
    Serial.println (pIRiNStatus);
    Serial.print (F("PriorPIR  / CurrentPIR - OUTSIDE "));
    Serial.print (priorpIRoUTStatus);
    Serial.print (F(" / "));
    Serial.println (pIRoUTStatus);
    Serial.print (F("Relay 1 / Relay 2:- "));
    Serial.print (digitalRead(relay1));
    Serial.print (F(" / "));
    Serial.println (digitalRead(relay2));
    Serial.print ("Flap Elapsed Time: ");
    Serial.println (currentTime - previousTime);
    Serial.println (F("***********************"));
 } 
     
  switch (systemState)
  {
    //Check that system is switched on
    case START:
      if(masterSwitchStatus == 0 && doorSensorStatus == 0)
      {
        systemState = SYSTEM_READY;
      }
      else systemState  = START;

      break;
    
    case SYSTEM_READY:
      if(masterSwitchStatus == 0 && doorSensorStatus == 0
        && currentHour >= 8 && currentHour <= 23)
      {
        systemState = MONITOR_ACTIVITY; 
      }
      else systemState = START;
       break;
     
    case MONITOR_ACTIVITY:  // If either PIR sensor went from LOW to HIGH then open the flap.

      if ((pIRiNStatus != priorpIRiNStatus && pIRiNStatus == 1)
           ||
          (pIRoUTStatus != priorpIRoUTStatus && pIRoUTStatus == 1))
        {        
          systemState = CMD_OPEN_FLAP;
          previousTime = currentTime;
        }  
          priorpIRiNStatus = pIRiNStatus; //is this necessary here?
          priorpIRoUTStatus = pIRoUTStatus; //is this necessary here?S
      break;

    case BED_TIME:  // If OUTSIDE PIR sensor went from LOW to HIGH then open the flap. 
                    //Leeway time to let the dogs in ONLY, but does not allow them out after 11pm.
 
      if ((pIRoUTStatus != priorpIRoUTStatus && pIRoUTStatus == 1)
        && (currentHour >= 23 && currentHour <= 0))
        {
          systemState = CMD_OPEN_FLAP;
          previousTime = currentTime;
        }
            priorpIRiNStatus = pIRiNStatus;
            priorpIRoUTStatus = pIRoUTStatus;
            
    case CMD_OPEN_FLAP:
          priorSystemState = systemState;   
               openFlap();
        systemState = MONITOR_OPEN_FLAP;
      break;

    case MONITOR_OPEN_FLAP:
      priorSystemState = systemState;
        if (((pIRiNStatus == 0 && pIRoUTStatus == 0) && (currentTime - previousTime >= flapOpenTime))
          || masterSwitchStatus == 1
          || doorSensorStatus == 1)
        {        
        systemState = CMD_CLOSE_FLAP;
        }
      break;

    case CMD_CLOSE_FLAP:
          priorSystemState = systemState;
              closeFlap();
        systemState = START;
      break;

  priorpIRiNStatus = pIRiNStatus;
  priorpIRoUTStatus = pIRoUTStatus;
 
  }
}