Coding HSMs on Arduino

I'm looking for a way to code heirarchical state machines without something heavy duty like the QM tools. I found a great flat state machine implementation by mbedded Ninja and it works perfectly, but you can only have one layer of states.

Any hints?

Show us what you've tried.

This doesn’t have all the code, but it shows the gist. It does work, but only for “flat” state machines without any nested states (all leaf states).

#include <stdio.h>

// Local includes
#include “main.h”
#include “StateMachine.h”
#include “events.h”

void Led_Init();
void Led_Idle();
void Led_On();
void Led_Off();

typedef struct {
const char * name;
void (*func)(void);
} stateFunctionRow_t;

/// \brief Maps a state to it’s state transition function, which should be called
/// when the state transitions into this state.
/// \warning This has to stay in sync with the state_t enum!
static stateFunctionRow_t stateFunctionA = {
// NAME // FUNC
{ “ST_IDLE”, &Led_Idle }, // ST_IDLE
{ “ST_LED_ON”, &Led_On }, // ST_LED_ON
{ “ST_LED_OFF”, &Led_Off }, // ST_LED_OFF
};

typedef struct {
state_t currState;
event_t event;
state_t nextState;
} stateTransMatrixRow_t;

static stateTransMatrixRow_t stateTransMatrix = {
// CURR STATE // EVENT // NEXT STATE
{ ST_IDLE, EV_BUTTON_PUSHED, ST_LED_ON },
{ ST_LED_ON, EV_TIME_OUT, ST_LED_OFF },
{ ST_LED_ON, EV_BUTTON_PUSHED, ST_IDLE },
{ ST_LED_OFF, EV_TIME_OUT, ST_LED_ON },
{ ST_LED_OFF, EV_BUTTON_PUSHED, ST_IDLE }
};

void StateMachine_Init(stateMachine_t * stateMachine) {
printf(“Initialising state machine.\r\n”);
stateMachine->currState = ST_IDLE;
}

void StateMachine_RunIteration(stateMachine_t *stateMachine, event_t event) {

// Iterate through the state transition matrix, checking if there is both a match with the current state
// and the event
for(int i = 0; i < sizeof(stateTransMatrix)/sizeof(stateTransMatrix[0]); i++) {
if(stateTransMatrix*.currState == stateMachine->currState) {*
if((stateTransMatrix.event == event) || (stateTransMatrix*.event == EV_ANY)) {
_ // Transition to the next state*
stateMachine->currState = stateTransMatrix*.nextState;
// Call the function associated with transition*

* (stateFunctionA[stateMachine->currState].func)();
break;
}
}
}
}
const char * StateMachine_GetStateName(state_t state) {
return stateFunctionA[state].name;
}*_