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

state machine

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



Joined: 23 Oct 2006
Posts: 175

View user's profile Send private message

state machine
PostPosted: Sun Nov 30, 2014 2:19 pm     Reply with quote

I am looking for a state machine example.

Is it possible to implement a state machine on a pic microcontroller?

If yes can i find any example ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Sun Nov 30, 2014 3:18 pm     Reply with quote

Yes.

Use an enum, and table of function addresses, in the same order as the enum entries.

Just call the function corresponding to the enum value.

At a smaller level, the code can be inline using a switch. There is a simple one in the code I just posted in the thread 'urgent doubt' for handling accelerating/decelerating a stepper motor.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Re: state machine
PostPosted: Sun Nov 30, 2014 4:53 pm     Reply with quote

andys wrote:
I am looking for a state machine example.

Is it possible to implement a state machine on a pic microcontroller?

If yes can i find any example ?

Yes, there is loads of help on this forum, google and Wiki.

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 30, 2014 11:36 pm     Reply with quote

This CCS example file has a state machine in the handle_incoming_usb()
routine:
Quote:
c:\program files\picc\examples\ex_usb_serial3.c

It has an enum of the states and uses switch-case as Ttelmah said.

It starts at state = 0, which is the GET_COMMAND state. It will stay in
that state each time handle_incoming_usb() is called, until it gets a 'W',
and then increments the state = 1 and exits.
The next time handle_incoming_usb(void) is called, it will run the
code in GET_ADDY0 and increment state = 2.
The next time handle_incoming_usb(void) is called, it will run GET_ADDY2
and increment the state = 3. And so on.

In this thread, Ttelmah has posted an example of a state machine
in the #int_timer2 routine:
http://www.ccsinfo.com/forum/viewtopic.php?t=43908
mcr1981



Joined: 27 Oct 2010
Posts: 28

View user's profile Send private message

A little video with code...
PostPosted: Mon Dec 01, 2014 3:04 pm     Reply with quote

It's in Spanish but you'll get the idea. Very very basic with one input and one output.



EDIT (forgot the link Embarassed ):
https://www.youtube.com/watch?v=bUkG0hOof3E
andys



Joined: 23 Oct 2006
Posts: 175

View user's profile Send private message

state machine
PostPosted: Mon Dec 01, 2014 5:35 pm     Reply with quote

something like this it will work ? :

Code:

enum state{state_A=0,state_B}currentState;

float read_analog_indput(void)
{
float value;
set_adc_channel(0);
value=read_adc();
return value;
}

void state_A_Handler(int event)
{
if (event>5)
   {
   currentState=state_B;
   output_low(pin_b3);
   }
else
   {
   currentState=state_A;
   output_high(pin_b3);
   }
}

void state_B_Handler(int event)
{
if (event==5)
   {
   currentState=state_B;
   output_low(pin_b3);
   }
else
   {
   currentState=state_A;
   output_high(pin_b3);
   }
}

void state_machine(currentstate)
{
float tmp;

   while (1)
   {
   tmp=read_analog_indput;
   if(currentState==state_A)
         {
         state_A_Handler(tmp)
         }
   else   
      state_B_Handler(tmp)
   }
}
andys



Joined: 23 Oct 2006
Posts: 175

View user's profile Send private message

state machine
PostPosted: Mon Dec 01, 2014 6:08 pm     Reply with quote

something like this it will work ? :

Code:

enum state{state_A=0,state_B}currentState;

float read_analog_indput(void)
{
float value;
set_adc_channel(0);
value=read_adc();
return value;
}

void state_A_Handler(int event)
{
if (event>5)
   {
   currentState=state_B;
   output_low(pin_b3);
   }
else
   {
   currentState=state_A;
   output_high(pin_b3);
   }
}

void state_B_Handler(int event)
{
if (event==5)
   {
   currentState=state_B;
   output_low(pin_b3);
   }
else
   {
   currentState=state_A;
   output_high(pin_b3);
   }
}

void state_machine(currentstate)
{
float tmp;

   while (1)
   {
   tmp=read_analog_indput;
   if(currentState==state_A)
         {
         state_A_Handler(tmp)
         }
   else   
      state_B_Handler(tmp)
   }
}
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Dec 01, 2014 9:16 pm     Reply with quote

Hi andys,

It looks like you've missed the mark by a fairly wide margin. Why not tell us clearly and concisely what you are trying to do, and let us suggest the best way to solve your issue? Perhaps a 'state machine' is not the best solution?

John
andys



Joined: 23 Oct 2006
Posts: 175

View user's profile Send private message

state machine
PostPosted: Tue Dec 02, 2014 5:11 am     Reply with quote

I am trying to create a state machine. (i would like to learn how a state machine is implemeted at pic microcntroller).

I had adc as input and LED as output and state A and B. The state machine is start at state A.

How to do this?
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Dec 02, 2014 6:39 am     Reply with quote

Software state machines are somewhat less clearly defined than hardware ones. The classifications of Moore, Mealy etc. don't really apply.

Also, they are necessarily discrete rather than continuous, and generally cannot be as rigidly nor as quickly clocked as hardware machines.

A common way of implementing a software state machine is to have a routine called regularly, for example by a main loop. The routine will have a state variable, an enum (or the old way: an integer with defines) which defines the possible states.

There will generally be a state handler, most often a switch on the state variable. There may be a state interpreter/actioner that does things, such as outputting in particular states, and/or there may be code in the state handler that does actions on state transitions.

One for your very simple example might look like this (this is untested code):

Code:

typedef enum States { state_A, state_B }

State State = state_A;

...


value = read_adc();

// State Handler
switch (State)
{
   state_A:
      if (value > 5)
      {
         State = state_B;
      }
      break;

   state_B:
      if (value <= 5)
      {
         State = state_A;
      }

   default:
      // Catch undefined states.
      // Force state_A.
      State = state_A;
      break; // Not strictly necessary
}

// State Actions/decode/interpret
switch (State)
{
   state_A:
      output_high(PIN_B3);
      break;
   state_B:
      output_low(PIN_B3);
      break;
}   



This will set the required outputs every time the routine is called. If you want to be more efficient then put the outputs in the handler. Remember, though, that that can cause confusion as they are not referring to the state on entry, but to the NEW state. I prefer to always do such actions BEFORE changing the state variable, but that is just a style thing.
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