View previous topic :: View next topic |
Author |
Message |
andys
Joined: 23 Oct 2006 Posts: 175
|
state machine |
Posted: Sun Nov 30, 2014 2:19 pm |
|
|
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: 19496
|
|
Posted: Sun Nov 30, 2014 3:18 pm |
|
|
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
|
Re: state machine |
Posted: Sun Nov 30, 2014 4:53 pm |
|
|
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
|
|
Posted: Sun Nov 30, 2014 11:36 pm |
|
|
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
|
A little video with code... |
Posted: Mon Dec 01, 2014 3:04 pm |
|
|
It's in Spanish but you'll get the idea. Very very basic with one input and one output.
EDIT (forgot the link ):
https://www.youtube.com/watch?v=bUkG0hOof3E |
|
|
andys
Joined: 23 Oct 2006 Posts: 175
|
state machine |
Posted: Mon Dec 01, 2014 5:35 pm |
|
|
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
|
state machine |
Posted: Mon Dec 01, 2014 6:08 pm |
|
|
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
|
|
Posted: Mon Dec 01, 2014 9:16 pm |
|
|
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
|
state machine |
Posted: Tue Dec 02, 2014 5:11 am |
|
|
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
|
|
Posted: Tue Dec 02, 2014 6:39 am |
|
|
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. |
|
|
|