Checking GPIO State in Embedded C Programming - c

We have an embedded C programming assignment where we have to implement a state machine that changes a series of LED's depending on a Joystick Input. Two of the conditions are: "if Left LED is on and Down is Pressed Change to Right LED" and "if Right LED is on and Down is Pressed Change to Left LED". I know how to turn on certain LED's on button presses but I have no idea how to check the state of a GPIO pin/LED and change another LED based on the state when the joystick is used. I basically just want to know how to "call" the state of an LED.
This is the state machine sample code so far:
void
StateMachine ()
{
// REPLACE THE FOLLOW CODE WITH YOUR SOLUTION
// This code just toggles top LED and set left or right LED.
//
// Solution.
uint8_t Joystick;
uint8_t Toggle = 0;
while (1)
{
Joystick = GetJoystick();
if (Joystick == 'L')
{
WriteLED ('L', LED_ON);
WriteLED ('R', LED_OFF);
}
else if (Joystick == 'R')
{
WriteLED ('L', LED_OFF);
WriteLED ('R', LED_ON);
}
if (Toggle == 0)
{
WriteLED ('T', LED_ON);
Toggle = 1;
}
else
{
WriteLED ('T', LED_OFF);
Toggle = 0;
}
}
}
Update: This is my WriteLED method
void
WriteLED (uint8_t LED, uint8_t State)
{
// Check for correct state
if ((State != LED_OFF) && (State != LED_ON))
{
return;
}
// Turn on/off the LED
switch (LED)
{
case 'L':
HAL_GPIO_WritePin (LD4_GPIO_Port, LD4_Pin, State);
break;
case 'T':
HAL_GPIO_WritePin (LD3_GPIO_Port, LD3_Pin, State);
break;
case 'B':
HAL_GPIO_WritePin (LD6_GPIO_Port, LD6_Pin, State);
break;
case 'R':
HAL_GPIO_WritePin (LD5_GPIO_Port, LD5_Pin, State);
break;
}
return;
}

If the assignment is specifically asking for a "state machine" then the software should somehow have different internal "states" corresponding to the different LED output requirements. There are lots of ways to represent a state machine -- (were you shown one?) -- For example:
// enumeration of the required states
enum OutputState {
stateAllOff, // I'm *guessing* this is the required initial state?
stateLeftLED,
stateRightLED,
// ... any other states that are specified.
// ... but *not* random combinations of LEDs that are not part of the specification.
};
enum OutputState currentState = stateAllOff; // or whatever initial state is required
// [...] I'm not going to do the actual assignment here
A state machine doesn't have to read the LED states, it just "remembers" them in the currentState variable. Now the rest of the code becomes a straightforward implementation of the conditions you were given so...
"if Left LED is on and Down is Pressed Change to Right LED"
if (currentState == stateLeftLED) {
if (Joystick == "D") {
WriteLED ('R', LED_ON);
WriteLED ('L', LED_OFF);
currentState = stateRightLED;
}
}

STM's HAL library offers a ReadPin function analog to the WritePin function you already used.
It's declaration looks as follows:
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
Which means you could read the state of a certain pin like this:
GPIO_PinState ld6_state = HAL_GPIO_ReadPin(LD6_GPIO_Port, LD6_Pin);
GPIO_PinState is an enumeration:
typedef enum
{
GPIO_PIN_RESET = 0,
GPIO_PIN_SET
}GPIO_PinState;
All that's left is comparing the return value of the read function (ld6_state) to either of the enumeration values. As mentioned by the first answer you'll most likely experience some bouncing of your inputs which is caused by the mechanical construction of your buttons. I guess figuring out how to solve that is part of the assignment so I'll leave that up to you. Keywords to look for: debounce or debouncing

Normally the state of an GPIO is saved in a register variable. You either need a definition of this variable or a vector pointing to its adress to read (or manipulate) it directly. Do you have documentation of the method WriteLED? It could give you a hint.
If you don't find anything you could still implement a flag to indicate which LED you switched on most recently.
Generally the Embedded Programming depends highly on the Chip you are working with and the corresponding compiler.
So to give you a better answer, you should first provide important information like the Hardware and Software you are using and libraries you want to implement.

You likely want to put a delay in your main loop.
Unless your joystick function locks the code until it sees a change, that toggle on your top LED is going to happen so fast that you are likely to see a dim glow or perhaps even nothing at all depending on the rise time of your hardware.
Like Wizzard said you should be able to find the status of your LED by looking in a register. How this is done is totally down to your hardware.
It would also most likely be suitable to use a few static booleans so you can save the state of the LEDs and check these to get your LED values, but this is not a perfect implementation. Register checks are better.

Related

Looking for good algorithm to run specific code on given time. (Arduino C program)

I'm writing a timer/scheduler simple program for Arduino.
It's a c program, with 'main' loop that is running again and again.
Arduino has DS3231 RTC module connected to it and provides the current day-of-week, hour, minute, second, etc.
What I need to achieve is sending a specific string over the serial port, but in contrast to many examples about 'lighting a LED at a specific time' - I can't allow the code to run more than once.
So, if a normal 'light a LED on a specific time' just loops again and again the 'if' check and according to it sets the digital output 'HIGH' or 'LOW' (again and again) - I can't use this approach.
The approach I'm using now, and it works, is like this:
I made an array with the wanted times, and 'action code' for each time - all of them are Integers, like this:
const int A = 6; // Action Array Size
int ActionTimes[A][4] = {
{6,18,37,1},
{6,18,38,2},
{5,15,20,11},
{5,16,35,51},
{5,16,40,52},
{5,23,55,15}
};
Then, from the main loop I call a "Check" function that runs a 'for' loop to check if there is an action that should be run in this current time:
int i;
for ( i = 0; i < A; i++ ) {
if ((dt.DayOfWeek()==ActionTimes[i][0]) && (dt.Hour()==ActionTimes[i][1]) && (dt.Minute()==ActionTimes[i][2]) && (dt.Second() < 2)) {
RunMyAction(ActionTimes[i][3]);
}
And then - I have the 'action' function that runs the actual needed code, like this:
void RunMyAction(const int& MyActionCode)
{
switch(MyActionCode) {
case 1:
digitalWrite(2, LOW); // Turn the LED on by making the voltage LOW
Serial.println("S041ONE");
break;
case 2:
digitalWrite(2, HIGH); // Turn the LED off by making the voltage HIGH
Serial.println("S017ONE");
break;
case 11: //Before Knissat Shabat - Full status update.
Serial.println("S01D00000D00ES02D01001100ES03D00101101ES04D1100D0DDES05D10011DDDE");
delay(1000);
break;
case 15: //Last GoodNight Shabat - Full status update.
Serial.println("S01D00000000ES02D00000000ES03D00000100ES04D1000D00DES05D00011DDDE");
delay(1500);
break;
case 51:
Serial.println("S036OFE");
delay(1500);
break;
case 52:
Serial.println("S047OFES036ONE");
delay(1500);
break;
}
}
That works for me and 'do the job' but I feel (algorithmically speaking) maybe it's not the best way to write it.
For example - all the actions and the needed times are hard-coded into the program itself. For any added action - I have to manually change the const of the array size, manually change the array definition, and add additional code to the switch function.
(Thought about excel-made #include files to merge into the array part and the switch function, but this also has to re-compile the program for every time/action change).
Would appreciate any insight about how to look at it for more professional, effective, way.
Many thanks!
To avoid executing the same action twice in a row, I'd add a global variable to hold the index into ActionTImes[] of the most recently executed action, then test that variable in the if statement.
int latestActionIndex = -1; // -1 so on startup we don't think we've executed ActionTimes[0].
then in the For loop:
if ((dt.DayOfWeek()==ActionTimes[i][0])
&& (dt.Hour()==ActionTimes[i][1])
&& (dt.Minute()==ActionTimes[i][2]
&& latestActionIndex != i)) {
latestActionIndex = i; // note that we've run this action
RunMyAction(ActionTimes[i][3]);
}
I removed the (dt.Second() < 2) from the if statement, because the action will likely execute within a second or so of dt.second() == 0, and the new variable keeps RunMyAction() from being executed more than once.

debounce with two button to turn on different leds with Arduino

I want to make debounce for two buttons. So turn on Red led or Green led knowing which button have pressed My program only works for 1 button.
I think that I need a array for two several buttons.
Could anyone help me to improve my code two buttons or more ?
int boton = 11;
int led = 13;
boolean estadoAnterior = LOW;
boolean estadoActual = LOW;
boolean ledOn = false;
int cont=0;
void setup()
{
pinMode(boton, INPUT);
pinMode(led, OUTPUT);
Serial.begin(9600);
}
boolean rebote(boolean eAnterior)
{
boolean eActual = digitalRead(boton);
if (eAnterior != eActual)
{
delay(5);
eActual = digitalRead(boton);
}
return eActual;
}
void loop()
{
estadoActual = rebote(estadoAnterior);
if (estadoAnterior == LOW && estadoActual == HIGH)
{
ledOn = !ledOn;
cont++;
Serial.println(cont);
}
estadoAnterior = estadoActual;
digitalWrite(led, ledOn);
}
Overall, using a busy-delay is a rather crude way to de-bounce buttons, but it will work for hobbyist purposes.
Change estadoAnterior into an array of expected button states.
Make an array of ints for the button pins boton. (In real MCU programming, this would be an array of ports + masks.)
In the debounce function, make an array of de-bounce bool values for buttons that need debouncing. Check which ones that need debouncing in a loop.
If any button needed debouncing, wait 5ms. Not per button, but once. (Btw 5ms may or may not be enough depending on button type)
Read that button again and use the result.
A more professional approach might be something along the lines of this.
Once done, rewrite all identifiers to English. We don't use our native language when programming, because that turns the source code into a mess. Your code is some mix of English and your native language, it is very hard to read.

Embedded C programming: Clearing LCD properly

I am trying to write the code for an embedded board (RX63N)in which I want to use the LCD along with the on board switches for the following functionality:
On pressing the switch the program should "pause" or "unpause" depending on the previous state and the LCD should display "paused" when it is paused. On unpausing, the LCD should display the custom graphics at the position defined by x and y. It is displayed using the function Set_LCD_Char(N) where N is defined as a custom graphic from a bitmap image. But I will need to clear the LCD before making any changes and that is where I am struggling. On using lcd_clear() function anywhere in the while keeps the LCD blank (or almost blank i.e. the text and graphics are so faint that they are as good as absent) Can someone please help me? heres the code:
while (1)
{
// lcd_clear();
if(g_sw3_press == true){ //detect switch press
pause_flag = !pause_flag;
g_sw3_press = false; //reset switch
}
if (pause_flag){
RESET_ALL_LEDS();
jet_x = 0;
jet_y = 0;
Set_Font_Bitmap(); //changes from text mode to bitmap
Set_LCD_Pos(jet_x,jet_y);
Set_LCD_Char(3);
}
else if(!(pause_flag)){
ALL_RED_LEDS_ON();
Set_Font_8_by_8();
lcd_display(LCD_LINE1, " PAUSED ");
}
}
Firstly, it's generally not a good idea to do a busy polling loop as you are doing. But I can't recommend any concrete alternatives as platform and OS (if any) have not been provided (perhaps your platform has no support for events).
Anyway, not sure if this is the answer you need. But since you ask for an example and I can't effectively put code into the comments, below is what I mean. The problem is that you are continuously writing and clearing the LCD. So in effect the two operations are competing with each other. So one way to solve this is to only update the LCD when the state changes.
while (1)
{
if(g_sw3_press == true){ //detect switch press
pause_flag = !pause_flag;
g_sw3_press = false; //reset switch
} else {
/* No state change - nothing to do. Poll again. */
continue;
}
lcd_clear();
if (pause_flag){
RESET_ALL_LEDS();
jet_x = 0;
jet_y = 0;
Set_Font_Bitmap(); //changes from text mode to bitmap
Set_LCD_Pos(jet_x,jet_y);
Set_LCD_Char(3);
} else {
ALL_RED_LEDS_ON();
Set_Font_8_by_8();
lcd_display(LCD_LINE1, " PAUSED ");
}
}

Problems with Arduino remotely controlling an outlet

This is a project that will be turned in, in 8 hours! We are stuck with this problem and thought of this place as a kind of last resort.
I'm trying to turn on/off a remotely controlled outlet with an Arduino.
We get inconsistencies when doing so. Sometimes when it goes into the if statement that ”should be ON” but instead turns the power off of the outlet and vice versa.
Code:
// on off remote control
int off = 12;
int on = 13;
void setup() {
pinMode(off, OUTPUT); // sets the digital pin as output
pinMode(on, OUTPUT);
}
void loop() {
// ..first we getting response from server if remote control should be on/off,
// working fine so not really relevant to problem.
// then we determine if outlet should be ON or OFF:
response.toCharArray(responseCharArray,100);
if(strstr( responseCharArray, "active") && strstr( responseCharArray, "1")) {
// This should turn ON the outlet.
digitalWrite(on, HIGH);
delay(250);
digitalWrite(on, LOW);
Serial.println("should be ON");
}
else if(strstr( responseCharArray, "active") && strstr( responseCharArray, "0")) {
// This should turn OFF the outlet.
digitalWrite(off, HIGH);
delay(250);
digitalWrite(off, LOW);
Serial.println("should be OFF");
}
}
Picture of the wiring:
Question:
What could be missing here? Since it randomly turns it on/off while entering same if statement.
There is too little information here.
Notice that your code will trigger (turn on) if responseCharArray contains something like e.g. "retroactively from 1941", or turn off for something like "active for 37 seconds".
In other words, that string-matching is not very precise, but it's hard to know what it should be since I don't know anything about the format of the response.
Perhaps it should at least be
if(strstr(responseCharArray, "active=1") != NULL)
or something, to at least lock the 1 to the active part.
In the logging that you do, print out the value of responseCharArray too. This will let you analyze whether or no the decision-making made sense.
Also, as always, triple-check your wiring and watch for e.g. back-feeding.

Is there a typical state machine implementation pattern?

We need to implement a simple state machine in C.
Is a standard switch statement the best way to go?
We have a current state (state) and a trigger for the transition.
switch(state)
{
case STATE_1:
state = DoState1(transition);
break;
case STATE_2:
state = DoState2(transition);
break;
}
...
DoState2(int transition)
{
// Do State Work
...
if(transition == FROM_STATE_2) {
// New state when doing STATE 2 -> STATE 2
}
if(transition == FROM_STATE_1) {
// New State when moving STATE 1 -> STATE 2
}
return new_state;
}
Is there a better way for simple state machines
EDIT:
For C++, I think the Boost Statechart library might be the way to go. However, it does not help with C. Lets concentrate on the C use case.
I prefer to use a table driven approach for most state machines:
typedef enum { STATE_INITIAL, STATE_FOO, STATE_BAR, NUM_STATES } state_t;
typedef struct instance_data instance_data_t;
typedef state_t state_func_t( instance_data_t *data );
state_t do_state_initial( instance_data_t *data );
state_t do_state_foo( instance_data_t *data );
state_t do_state_bar( instance_data_t *data );
state_func_t* const state_table[ NUM_STATES ] = {
do_state_initial, do_state_foo, do_state_bar
};
state_t run_state( state_t cur_state, instance_data_t *data ) {
return state_table[ cur_state ]( data );
};
int main( void ) {
state_t cur_state = STATE_INITIAL;
instance_data_t data;
while ( 1 ) {
cur_state = run_state( cur_state, &data );
// do other program logic, run other state machines, etc
}
}
This can of course be extended to support multiple state machines, etc. Transition actions can be accommodated as well:
typedef void transition_func_t( instance_data_t *data );
void do_initial_to_foo( instance_data_t *data );
void do_foo_to_bar( instance_data_t *data );
void do_bar_to_initial( instance_data_t *data );
void do_bar_to_foo( instance_data_t *data );
void do_bar_to_bar( instance_data_t *data );
transition_func_t * const transition_table[ NUM_STATES ][ NUM_STATES ] = {
{ NULL, do_initial_to_foo, NULL },
{ NULL, NULL, do_foo_to_bar },
{ do_bar_to_initial, do_bar_to_foo, do_bar_to_bar }
};
state_t run_state( state_t cur_state, instance_data_t *data ) {
state_t new_state = state_table[ cur_state ]( data );
transition_func_t *transition =
transition_table[ cur_state ][ new_state ];
if ( transition ) {
transition( data );
}
return new_state;
};
The table driven approach is easier to maintain and extend and simpler to map to state diagrams.
You might have seen my answer to another C question where I mentioned FSM! Here is how I do it:
FSM {
STATE(x) {
...
NEXTSTATE(y);
}
STATE(y) {
...
if (x == 0)
NEXTSTATE(y);
else
NEXTSTATE(x);
}
}
With the following macros defined
#define FSM
#define STATE(x) s_##x :
#define NEXTSTATE(x) goto s_##x
This can be modified to suit the specific case. For example, you may have a file FSMFILE that you want to drive your FSM, so you could incorporate the action of reading next char into the the macro itself:
#define FSM
#define STATE(x) s_##x : FSMCHR = fgetc(FSMFILE); sn_##x :
#define NEXTSTATE(x) goto s_##x
#define NEXTSTATE_NR(x) goto sn_##x
now you have two types of transitions: one goes to a state and read a new character, the other goes to a state without consuming any input.
You can also automate the handling of EOF with something like:
#define STATE(x) s_##x : if ((FSMCHR = fgetc(FSMFILE) == EOF)\
goto sx_endfsm;\
sn_##x :
#define ENDFSM sx_endfsm:
The good thing of this approach is that you can directly translate a state diagram you draw into working code and, conversely, you can easily draw a state diagram from the code.
In other techniques for implementing FSM the structure of the transitions is buried in control structures (while, if, switch ...) and controlled by variables value (tipically a state variable) and it may be a complex task to relate the nice diagram to a convoluted code.
I learned this technique from an article appeared on the great "Computer Language" magazine that, unfortunately, is no longer published.
In Martin Fowler's UML Distilled, he states (no pun intended) in Chapter 10 State Machine Diagrams (emphasis mine):
A state diagram can be implemented in three main ways: nested switch, the State pattern, and
state tables.
Let's use a simplified example of the states of a mobile phone's display:
Nested switch
Fowler gave an example of C# code, but I've adapted it to my example.
public void HandleEvent(PhoneEvent anEvent) {
switch (CurrentState) {
case PhoneState.ScreenOff:
switch (anEvent) {
case PhoneEvent.PressButton:
if (powerLow) { // guard condition
DisplayLowPowerMessage(); // action
// CurrentState = PhoneState.ScreenOff;
} else {
CurrentState = PhoneState.ScreenOn;
}
break;
case PhoneEvent.PlugPower:
CurrentState = PhoneState.ScreenCharging;
break;
}
break;
case PhoneState.ScreenOn:
switch (anEvent) {
case PhoneEvent.PressButton:
CurrentState = PhoneState.ScreenOff;
break;
case PhoneEvent.PlugPower:
CurrentState = PhoneState.ScreenCharging;
break;
}
break;
case PhoneState.ScreenCharging:
switch (anEvent) {
case PhoneEvent.UnplugPower:
CurrentState = PhoneState.ScreenOff;
break;
}
break;
}
}
State pattern
Here's an implementation of my example with the GoF State pattern:
State Tables
Taking inspiration from Fowler, here's a table for my example:
Source State Target State Event Guard Action
--------------------------------------------------------------------------------------
ScreenOff ScreenOff pressButton powerLow displayLowPowerMessage
ScreenOff ScreenOn pressButton !powerLow
ScreenOn ScreenOff pressButton
ScreenOff ScreenCharging plugPower
ScreenOn ScreenCharging plugPower
ScreenCharging ScreenOff unplugPower
Comparison
Nested switch keeps all the logic in one spot, but the code can be hard to read when there are a lot of states and transitions. It's possibly more secure and easier to validate than the other approaches (no polymorphism or interpreting).
The State pattern implementation potentially spreads the logic over several separate classes, which may make understanding it as a whole a problem. On the other hand, the small classes are easy to understand separately. The design is particularly fragile if you change the behavior by adding or removing transitions, as they're methods in the hierarchy and there could be lots of changes to the code. If you live by the design principle of small interfaces, you'll see this pattern doesn't really do so well. However, if the state machine is stable, then such changes won't be needed.
The state tables approach requires writing some kind of interpreter for the content (this might be easier if you have reflection in the language you're using), which could be a lot of work to do up front. As Fowler points out, if your table is separate from your code, you could modify the behavior of your software without recompiling. This has some security implications, however; the software is behaving based on the contents of an external file.
Edit (not really for C language)
There is a fluent interface (aka internal Domain Specific Language) approach, too, which is probably facilitated by languages that have first-class functions. The Stateless library exists and that blog shows a simple example with code. A Java implementation (pre Java8) is discussed. I was shown a Python example on GitHub as well.
I also have used the table approach. However, there is overhead. Why store a second list of pointers? A function in C without the () is a const pointer. So you can do:
struct state;
typedef void (*state_func_t)( struct state* );
typedef struct state
{
state_func_t function;
// other stateful data
} state_t;
void do_state_initial( state_t* );
void do_state_foo( state_t* );
void do_state_bar( state_t* );
void run_state( state_t* i ) {
i->function(i);
};
int main( void ) {
state_t state = { do_state_initial };
while ( 1 ) {
run_state( state );
// do other program logic, run other state machines, etc
}
}
Of course depending on your fear factor (i.e. safety vs speed) you may want to check for valid pointers. For state machines larger than three or so states, the approach above should be less instructions than an equivalent switch or table approach. You could even macro-ize as:
#define RUN_STATE(state_ptr_) ((state_ptr_)->function(state_ptr_))
Also, I feel from the OP's example, that there is a simplification that should be done when thinking about / designing a state machine. I don't thing the transitioning state should be used for logic. Each state function should be able to perform its given role without explicit knowledge of past state(s). Basically you design for how to transition from the state you are in to another state.
Finally, don't start the design of a state machine based on "functional" boundaries, use sub-functions for that. Instead divide the states based on when you will have to wait for something to happen before you can continue. This will help minimize the number of times you have to run the state machine before you get a result. This can be important when writing I/O functions, or interrupt handlers.
Also, a few pros and cons of the classic switch statement:
Pros:
it is in the language, so it is documented and clear
states are defined where they are called
can execute multiple states in one function call
code common to all states can be executed before and after the switch statement
Cons:
can execute multiple states in one function call
code common to all states can be executed before and after the switch statement
switch implementation can be slow
Note the two attributes that are both pro and con. I think the switch allows the opportunity for too much sharing between states, and the interdependency between states can become unmanageable. However for a small number of states, it may be the most readable and maintainable.
there is also the logic grid which is more maintainable as the state machine gets bigger
For a simple state machine just use a switch statement and an enum type for your state. Do your transitions inside the switch statement based on your input. In a real program you would obviously change the "if(input)" to check for your transition points. Hope this helps.
typedef enum
{
STATE_1 = 0,
STATE_2,
STATE_3
} my_state_t;
my_state_t state = STATE_1;
void foo(char input)
{
...
switch(state)
{
case STATE_1:
if(input)
state = STATE_2;
break;
case STATE_2:
if(input)
state = STATE_3;
else
state = STATE_1;
break;
case STATE_3:
...
break;
}
...
}
switch() is a powerful and standard way of implementing state machines in C, but it can decrease maintainability down if you have a large number of states. Another common method is to use function pointers to store the next state. This simple example implements a set/reset flip-flop:
/* Implement each state as a function with the same prototype */
void state_one(int set, int reset);
void state_two(int set, int reset);
/* Store a pointer to the next state */
void (*next_state)(int set, int reset) = state_one;
/* Users should call next_state(set, reset). This could
also be wrapped by a real function that validated input
and dealt with output rather than calling the function
pointer directly. */
/* State one transitions to state one if set is true */
void state_one(int set, int reset) {
if(set)
next_state = state_two;
}
/* State two transitions to state one if reset is true */
void state_two(int set, int reset) {
if(reset)
next_state = state_one;
}
I found a really slick C implementation of Moore FSM on the edx.org course Embedded Systems - Shape the World UTAustinX - UT.6.02x, chapter 10, by Jonathan Valvano and Ramesh Yerraballi....
struct State {
unsigned long Out; // 6-bit pattern to output
unsigned long Time; // delay in 10ms units
unsigned long Next[4]; // next state for inputs 0,1,2,3
};
typedef const struct State STyp;
//this example has 4 states, defining constants/symbols using #define
#define goN 0
#define waitN 1
#define goE 2
#define waitE 3
//this is the full FSM logic coded into one large array of output values, delays,
//and next states (indexed by values of the inputs)
STyp FSM[4]={
{0x21,3000,{goN,waitN,goN,waitN}},
{0x22, 500,{goE,goE,goE,goE}},
{0x0C,3000,{goE,goE,waitE,waitE}},
{0x14, 500,{goN,goN,goN,goN}}};
unsigned long currentState; // index to the current state
//super simple controller follows
int main(void){ volatile unsigned long delay;
//embedded micro-controller configuration omitteed [...]
currentState = goN;
while(1){
LIGHTS = FSM[currentState].Out; // set outputs lines (from FSM table)
SysTick_Wait10ms(FSM[currentState].Time);
currentState = FSM[currentState].Next[INPUT_SENSORS];
}
}
For simple cases, you can use your switch style method. What I have found that works well in the past is to deal with transitions too:
static int current_state; // should always hold current state -- and probably be an enum or something
void state_leave(int new_state) {
// do processing on what it means to enter the new state
// which might be dependent on the current state
}
void state_enter(int new_state) {
// do processing on what is means to leave the current state
// might be dependent on the new state
current_state = new_state;
}
void state_process() {
// switch statement to handle current state
}
I don't know anything about the boost library, but this type of approach is dead simple, doesn't require any external dependencies, and is easy to implement.
You might want to look into the libero FSM generator software. From a state description language and/or a (windows) state diagram editor you may generate code for C, C++, java and many others ... plus nice documentation and diagrams.
Source and binaries from iMatix
This article is a good one for the state pattern (though it is C++, not specifically C).
If you can put your hands on the book "Head First Design Patterns", the explanation and example are very clear.
One of my favourite patterns is the state design pattern. Respond or behave differently to the same given set of inputs.
One of the problems with using switch/case statements for state machines is that as you create more states, the switch/cases becomes harder/unwieldy to read/maintain, promotes unorganized spaghetti code, and increasingly difficult to change without breaking something. I find using design patterns helps me to organize my data better, which is the whole point of abstraction.
Instead of designing your state code around what state you came from, instead structure your code so that it records the state when you enter a new state. That way, you effectively get a record of your previous state. I like #JoshPetit's answer, and have taken his solution one step further, taken straight from the GoF book:
stateCtxt.h:
#define STATE (void *)
typedef enum fsmSignal
{
eEnter =0,
eNormal,
eExit
}FsmSignalT;
typedef struct fsm
{
FsmSignalT signal;
// StateT is an enum that you can define any which way you want
StateT currentState;
}FsmT;
extern int STATECTXT_Init(void);
/* optionally allow client context to set the target state */
extern STATECTXT_Set(StateT stateID);
extern void STATECTXT_Handle(void *pvEvent);
stateCtxt.c:
#include "stateCtxt.h"
#include "statehandlers.h"
typedef STATE (*pfnStateT)(FsmSignalT signal, void *pvEvent);
static FsmT fsm;
static pfnStateT UsbState ;
int STATECTXT_Init(void)
{
UsbState = State1;
fsm.signal = eEnter;
// use an enum for better maintainability
fsm.currentState = '1';
(*UsbState)( &fsm, pvEvent);
return 0;
}
static void ChangeState( FsmT *pFsm, pfnStateT targetState )
{
// Check to see if the state has changed
if (targetState != NULL)
{
// Call current state's exit event
pFsm->signal = eExit;
STATE dummyState = (*UsbState)( pFsm, pvEvent);
// Update the State Machine structure
UsbState = targetState ;
// Call the new state's enter event
pFsm->signal = eEnter;
dummyState = (*UsbState)( pFsm, pvEvent);
}
}
void STATECTXT_Handle(void *pvEvent)
{
pfnStateT newState;
if (UsbState != NULL)
{
fsm.signal = eNormal;
newState = (*UsbState)( &fsm, pvEvent );
ChangeState( &fsm, newState );
}
}
void STATECTXT_Set(StateT stateID)
{
prevState = UsbState;
switch (stateID)
{
case '1':
ChangeState( State1 );
break;
case '2':
ChangeState( State2);
break;
case '3':
ChangeState( State3);
break;
}
}
statehandlers.h:
/* define state handlers */
extern STATE State1(void);
extern STATE State2(void);
extern STATE State3(void);
statehandlers.c:
#include "stateCtxt.h:"
/* Define behaviour to given set of inputs */
STATE State1(FsmT *fsm, void *pvEvent)
{
STATE nextState;
/* do some state specific behaviours
* here
*/
/* fsm->currentState currently contains the previous state
* just before it gets updated, so you can implement behaviours
* which depend on previous state here
*/
fsm->currentState = '1';
/* Now, specify the next state
* to transition to, or return null if you're still waiting for
* more stuff to process.
*/
switch (fsm->signal)
{
case eEnter:
nextState = State2;
break;
case eNormal:
nextState = null;
break;
case eExit:
nextState = State2;
break;
}
return nextState;
}
STATE State3(FsmT *fsm, void *pvEvent)
{
/* do some state specific behaviours
* here
*/
fsm->currentState = '2';
/* Now, specify the next state
* to transition to
*/
return State1;
}
STATE State2(FsmT *fsm, void *pvEvent)
{
/* do some state specific behaviours
* here
*/
fsm->currentState = '3';
/* Now, specify the next state
* to transition to
*/
return State3;
}
For most State Machines, esp. Finite state machines, each state will know what its next state should be, and the criteria for transitioning to its next state. For loose state designs, this may not be the case, hence the option to expose the API for transitioning states. If you desire more abstraction, each state handler can be separated out into its own file, which are equivalent to the concrete state handlers in the GoF book. If your design is simple with only a few states, then both stateCtxt.c and statehandlers.c can be combined into a single file for simplicity.
In my experience using the 'switch' statement is the standard way to handle multiple possible states. Although I am surpirsed that you are passing in a transition value to the per-state processing. I thought the whole point of a state machine was that each state performed a single action. Then the next action/input determines which new state to transition into. So I would have expected each state processing function to immediately perform whatever is fixed for entering state and then afterwards decide if transition is needed to another state.
There is a book titled Practical Statecharts in C/C++.
However, it is way too heavyweight for what we need.
For compiler which support __COUNTER__ , you can use them for simple (but large) state mashines.
#define START 0
#define END 1000
int run = 1;
state = START;
while(run)
{
switch (state)
{
case __COUNTER__:
//do something
state++;
break;
case __COUNTER__:
//do something
if (input)
state = END;
else
state++;
break;
.
.
.
case __COUNTER__:
//do something
if (input)
state = START;
else
state++;
break;
case __COUNTER__:
//do something
state++;
break;
case END:
//do something
run = 0;
state = START;
break;
default:
state++;
break;
}
}
The advantage of using __COUNTER__ instead of hard coded numbers is that you
can add states in the middle of other states, without renumbering everytime everything.
If the compiler doesnt support __COUNTER__, in a limited way its posible to use with precaution __LINE__
You can use minimalist UML state machine framework in c. https://github.com/kiishor/UML-State-Machine-in-C
It supports both finite and hierarchical state machine. It has only 3 API's, 2 structures and 1 enumeration.
The State machine is represented by state_machine_t structure. It is an abstract structure that can be inherited to create a state machine.
//! Abstract state machine structure
struct state_machine_t
{
uint32_t Event; //!< Pending Event for state machine
const state_t* State; //!< State of state machine.
};
State is represented by pointer to state_t structure in the framework.
If framework is configured for finite state machine then state_t contains,
typedef struct finite_state_t state_t;
// finite state structure
typedef struct finite_state_t{
state_handler Handler; //!< State handler function (function pointer)
state_handler Entry; //!< Entry action for state (function pointer)
state_handler Exit; //!< Exit action for state (function pointer)
}finite_state_t;
The framework provides an API dispatch_event to dispatch the event to the state machine and two API's for the state traversal.
state_machine_result_t dispatch_event(state_machine_t* const pState_Machine[], uint32_t quantity);
state_machine_result_t switch_state(state_machine_t* const, const state_t*);
state_machine_result_t traverse_state(state_machine_t* const, const state_t*);
For further details on how to implement hierarchical state machine refer the GitHub repository.
code examples
https://github.com/kiishor/UML-State-Machine-in-C/blob/master/demo/simple_state_machine/readme.md
https://github.com/kiishor/UML-State-Machine-in-C/blob/master/demo/simple_state_machine_enhanced/readme.md
In C++, consider the State pattern.
Your question is similar to "is there a typical Data Base implementation pattern"?
The answer depends upon what do you want to achieve? If you want to implement a larger deterministic state machine you may use a model and a state machine generator.
Examples can be viewed at www.StateSoft.org - SM Gallery. Janusz Dobrowolski
I would also prefer a table driven approach. I have used switch statements in the past. The main problem I have encountered is debugging transitions and ensuring that the designed state machine has been implemented properly. This occurred in cases where there was a large number of states and events.
With the table driven approach are the states and transitions are summarized in one place.
Below is a demo of this approach.
/*Demo implementations of State Machines
*
* This demo leverages a table driven approach and function pointers
*
* Example state machine to be implemented
*
* +-----+ Event1 +-----+ Event2 +-----+
* O---->| A +------------------->| B +------------------->| C |
* +-----+ +-----+ +-----+
* ^ |
* | Event3 |
* +-----------------------------------------------------+
*
* States: A, B, C
* Events: NoEvent (not shown, holding current state), Event1, Event2, Event3
*
* Partly leveraged the example here: http://web.archive.org/web/20160808120758/http://www.gedan.net/2009/03/18/finite-state-machine-matrix-style-c-implementation-function-pointers-addon/
*
* This sample code can be compiled and run using GCC.
* >> gcc -o demo_state_machine demo_state_machine.c
* >> ./demo_state_machine
*/
#include <stdio.h>
#include <assert.h>
// Definitions of state id's, event id's, and function pointer
#define N_STATES 3
#define N_EVENTS 4
typedef enum {
STATE_A,
STATE_B,
STATE_C,
} StateId;
typedef enum {
NOEVENT,
EVENT1,
EVENT2,
EVENT3,
} Event;
typedef void (*StateRoutine)();
// Assert on number of states and events defined
static_assert(STATE_C==N_STATES-1,
"Number of states does not match defined number of states");
static_assert(EVENT3==N_EVENTS-1,
"Number of events does not match defined number of events");
// Defining State, holds both state id and state routine
typedef struct {
StateId id;
StateRoutine routine;
} State;
// General functions
void evaluate_state(Event e);
// State routines to be executed at each state
void state_routine_a(void);
void state_routine_b(void);
void state_routine_c(void);
// Defining each state with associated state routine
const State state_a = {STATE_A, state_routine_a};
const State state_b = {STATE_B, state_routine_b};
const State state_c = {STATE_C, state_routine_c};
// Defning state transition matrix as visualized in the header (events not
// defined, result in mainting the same state)
State state_transition_mat[N_STATES][N_EVENTS] = {
{ state_a, state_b, state_a, state_a},
{ state_b, state_b, state_c, state_b},
{ state_c, state_c, state_c, state_a}};
// Define current state and initialize
State current_state = state_a;
int main()
{
while(1) {
// Event to receive from user
int ev;
printf("----------------\n");
printf("Current state: %c\n", current_state.id + 65);
printf("Event to occur: ");
// Receive event from user
scanf("%u", &ev);
evaluate_state((Event) ev); // typecast to event enumeration type
printf("-----------------\n");
};
return (0);
}
/*
* Determine state based on event and perform state routine
*/
void evaluate_state(Event ev)
{
//Determine state based on event
current_state = state_transition_mat[current_state.id][ev];
printf("Transitioned to state: %c\n", current_state.id + 65);
// Run state routine
(*current_state.routine)();
}
/*
* State routines
*/
void state_routine_a() {
printf("State A routine ran. \n");
}
void state_routine_b() {
printf("State B routine ran. \n");
}
void state_routine_c() {
printf("State C routine ran. \n");
}
Boost has the statechart library. http://www.boost.org/doc/libs/1_36_0/libs/statechart/doc/index.html
I can't speak to the use of it, though. Not used it myself (yet)

Resources