CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Finite State Machine , pointer to functn , transition table

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
AshrafAbuBaker



Joined: 07 Jan 2015
Posts: 4

View user's profile Send private message Send e-mail ICQ Number

Finite State Machine , pointer to functn , transition table
PostPosted: Wed Jan 07, 2015 6:55 am     Reply with quote

Hi every One,
i had working on this for two days and i didn't know what is wrong with my code.
i am trying to implement a finite state machine to control a relay.
i did this with transition table and transition function.
the code can't execute the function .
any help, please
Code:

#define  MAX_LEGAL_TRANSITIONS 4               // FSM maximum transitons
typedef void (*doact) ();
void Close_Relay();
void Open_Relay();
void Do_Nothing ();
 
enum State {sNormal,sVoltageERROR};
enum Event {eNormal,eVoltageERROR};



typedef struct
{
      State   init ;
      Event   even  ;
      doact *doAction ;
      State   final ;
      // MY_FN doAction ;
} TABLECONTROL;
/* Control table used with the table driven implementation.
   reflects the full FSM.
 */


State CurrentState = sNormal ;
 
 TABLECONTROL ControlTable [MAX_LEGAL_TRANSITIONS]  =

   { sNormal, eNormal , &Do_nothing , sNormal     }  ,
   { sNormal, eVoltageERROR , &open_relay , sVoltageERROR},
   { sVoltageERROR, eVoltageERROR ,  &Do_nothing ,  sVoltageERROR},
   { sVoltageERROR,eNormal,&close_relay,sNormal}
} ;

//TABLECONTROL open_state ={sNormal,eVoltageERROR,open_relay,sVoltageERROR};

void StateTransition(Event eve)
{
int i=0;
int found=FALSE;


while ( (i <MAX_LEGAL_TRANSITIONS) && (Found == false))
      {
           
         if ( ( CurrentState == ControlTable[i].init) && (eve == ControlTable[i].even) )
         {
            /* Perform the action */
            (*ControlTable[i].doAction) ()  ;
            CurrentState = ControlTable[i].final ;
            Found = true  ;
         }
        // printf(lcd_putc,"\fC:%d S:%d E:%d\ni:%d",currentstate,controltable[i].init,ControlTable[i].event,i);
         //delay_ms(500);
         ++i ;
      }
     
}
.
.

void Open_Relay()
{
           output_low(pin_b5);
           delay_ms(20);
           output_high(pin_b5);
           delay_ms(20);
           printf(lcd_putc,"\fOpening Relay");
      delay_ms(1000);
}
void Close_Relay()
{
output_low(pin_b6);
     
      delay_ms(20);
     
      output_high(pin_b6);
     
      delay_ms(20);
     
      printf(lcd_putc,"\fCloseing Relay");
      delay_ms(1000);
}

void Do_Nothing ()
{
}
.
.
void main
{
Event OccurEvent=eNormal;//Default event at the beginning

  while(true)
  {
  .
  .
  .
   if((Vrmsp<=120)||(Vrmsp>=270)) //voltage protection
         OccurEvent=eVoltageERROR; 
   else if ((Vrmsp>140)&&(Vrmsp<260))
         OccurEvent=eNormal;
           
   StateTransition(OccurEvent);
}

}

_________________
I am an electronics Engineer, interesting in designing electronics systems related to renewable energy and energy saving.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 07, 2015 12:11 pm     Reply with quote

I made some changes to your code to get function pointers working.
It now works. The program gives the following output in MPLAB Simulator:
(Tested with MPLAB vs. 8.92 and CCS vs. 5.035)
Code:

Start
Do Nothing
Opening Relay
Do Nothing
Closing Relay

Do Nothing
Opening Relay
Do Nothing
Closing Relay

Do Nothing
Opening Relay
Do Nothing
Closing Relay


See the changes marked in bold below:
Quote:

#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

#define MAX_LEGAL_TRANSITIONS 4

typedef void (*doact) ();

void Close_Relay();
void Open_Relay();
void Do_Nothing();

enum State {sNormal,sVoltageERROR};
enum Event {eNormal,eVoltageERROR};

typedef struct
{
State init;
Event even;
doact doAction; // *** Removed asterisk '*' in front of doAction.
State final;
}TABLECONTROL;


State CurrentState = sNormal;

// *** Removed ampersand '&' in front of function name:
TABLECONTROL ControlTable [MAX_LEGAL_TRANSITIONS] =
{
{ sNormal, eNormal, Do_nothing, sNormal},
{ sNormal, eVoltageERROR, open_relay, sVoltageERROR},
{ sVoltageERROR, eVoltageERROR, Do_nothing, sVoltageERROR},
{ sVoltageERROR, eNormal, close_relay,sNormal}
};


void StateTransition(Event eve)
{
int i=0;
int found=FALSE;

// *** FOR TESTING - Call the function in each ControlTable entry:
i=0;
(*ControlTable[i].doAction)(); // *** FOR TESTING ***

i=1;
(*ControlTable[i].doAction)(); // *** FOR TESTING ***

i=2;
(*ControlTable[i].doAction)(); // *** FOR TESTING ***

i=3;
(*ControlTable[i].doAction)(); // *** FOR TESTING ***

/*
while((i < MAX_LEGAL_TRANSITIONS) && (Found == false))
{
if((CurrentState == ControlTable[i].init) && (eve == ControlTable[i].even))
{
(*ControlTable[i].doAction)();
CurrentState = ControlTable[i].final;
Found = true;
}
++i;
}
*/

}


void Open_Relay()
{
printf("Opening Relay \r");
}

void Close_Relay()
{
printf("Closing Relay \r");
}

void Do_Nothing()
{
printf("Do Nothing \r");

}

//===================================

void main()
{
int16 Vrmsp = 0;

printf("Start \r");

Event OccurEvent = eNormal; //Default event at the beginning

while(TRUE)
{
if((Vrmsp<=120)||(Vrmsp>=270)) //voltage protection
OccurEvent=eVoltageERROR;
else if ((Vrmsp>140)&&(Vrmsp<260))
OccurEvent=eNormal;

StateTransition(OccurEvent);

printf("\r");
}

}
AshrafAbuBaker



Joined: 07 Jan 2015
Posts: 4

View user's profile Send private message Send e-mail ICQ Number

PostPosted: Thu Jan 08, 2015 3:34 am     Reply with quote

thanks alot you are the best.
your code have worked very well
but when i test mine with state_transition function
Code:

void state_transition (EVENT event)
{
int i=0;
int found=false;

while((i < MAX_LEGAL_TRANSITIONS) && (Found == false))
  {
   if((CurrentState == ControlTable[i].init) && (event == ControlTable[i].even))
     {
      (*ControlTable[i].doAction)();
      CurrentState = ControlTable[i].final;
      Found = true;
     }
    ++i;
   }
}

if doesn't work when the condition is true to change the event and make different action.
Do_nothing () is executed, but open_relay(), close_relay() aren't executed.
I am sure there is something silly and a common mistake I have did in this code, but I can't find it.
_________________
I am an electronics Engineer, interesting in designing electronics systems related to renewable energy and energy saving.
AshrafAbuBaker



Joined: 07 Jan 2015
Posts: 4

View user's profile Send private message Send e-mail ICQ Number

PostPosted: Thu Jan 08, 2015 5:09 am     Reply with quote

it can not enter if statement enless in the first row in state transition table, when it has to execute Do_nothing
_________________
I am an electronics Engineer, interesting in designing electronics systems related to renewable energy and energy saving.
AshrafAbuBaker



Joined: 07 Jan 2015
Posts: 4

View user's profile Send private message Send e-mail ICQ Number

PostPosted: Thu Jan 08, 2015 5:17 am     Reply with quote

ok, Now it works Laughing Laughing Laughing
But do you know what was wrong with it ??
Crying or Very sad

I only did this modification on the if statement
Code:

 if ( (  ControlTable[i].init == CurrentState ) && (  ControlTable[i].even==event))

instead of
Code:

if ( ( CurrentState == ControlTable[i].init) && (eve == ControlTable[i].even) )
 

So what is the difference between two statements?
It took me 3 days to figure it out Embarassed
_________________
I am an electronics Engineer, interesting in designing electronics systems related to renewable energy and energy saving.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group