Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 37 additions & 40 deletions Fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,81 @@
// along with arduino-fsm. If not, see <http://www.gnu.org/licenses/>.

#include "Fsm.h"
#include <assert.h>


State::State(void (*on_enter)(), void (*on_state)(), void (*on_exit)())
: on_enter(on_enter),
on_state(on_state),
on_exit(on_exit)
State::State(void (*on_enter)(), void (*on_state)(), void (*on_exit)(), const char *name)
: on_enter(on_enter),
on_state(on_state),
on_exit(on_exit),
name(name)
{
}


Fsm::Fsm(State* initial_state)
: m_current_state(initial_state),
m_transitions(NULL),
m_num_transitions(0),
m_num_timed_transitions(0),
m_initialized(false)
Fsm::Fsm(State *initial_state)
: m_current_state(initial_state),
m_transitions(NULL),
m_num_transitions(0),
m_num_timed_transitions(0),
m_initialized(false)
{
}


Fsm::~Fsm()
{
free(m_transitions);
free(m_timed_transitions);
m_transitions = NULL;
m_timed_transitions = NULL;
}


void Fsm::add_transition(State* state_from, State* state_to, int event,
void (*on_transition)())
void Fsm::add_transition(State *state_from, State *state_to, int event,
void (*on_transition)(), const char *name)
{
if (state_from == NULL || state_to == NULL)
return;

Transition transition = Fsm::create_transition(state_from, state_to, event,
on_transition);
m_transitions = (Transition*) realloc(m_transitions, (m_num_transitions + 1)
* sizeof(Transition));
on_transition, name);
m_transitions = (Transition *)realloc(m_transitions, (m_num_transitions + 1) * sizeof(Transition));
m_transitions[m_num_transitions] = transition;
m_num_transitions++;
}


void Fsm::add_timed_transition(State* state_from, State* state_to,
unsigned long interval, void (*on_transition)())
TimedTransition *Fsm::add_timed_transition(State *state_from, State *state_to,
unsigned long interval, void (*on_transition)(), const char *name)
{
if (state_from == NULL || state_to == NULL)
return;
return NULL;

Transition transition = Fsm::create_transition(state_from, state_to, 0,
on_transition);
on_transition, name);

TimedTransition timed_transition;
timed_transition.transition = transition;
timed_transition.start = 0;
timed_transition.interval = interval;

m_timed_transitions = (TimedTransition*) realloc(
m_timed_transitions, (m_num_timed_transitions + 1) * sizeof(TimedTransition));
assert(m_num_timed_transitions < MAX_TIMED_TRANSITIONS);
m_timed_transitions[m_num_timed_transitions] = timed_transition;
m_num_timed_transitions++;
}

return &m_timed_transitions[m_num_timed_transitions];
}

Fsm::Transition Fsm::create_transition(State* state_from, State* state_to,
int event, void (*on_transition)())
Transition Fsm::create_transition(State *state_from, State *state_to,
int event, void (*on_transition)(), const char *name)
{
Transition t;
t.state_from = state_from;
t.state_to = state_to;
t.event = event;
t.on_transition = on_transition;
t.name = name;

return t;
}

void Fsm::trigger(int event)
{
// Serial.printf("Trigger powerFSM %d\n", event);
if (m_initialized)
{
// Find the transition with the current state and given event.
Expand All @@ -112,14 +108,15 @@ void Fsm::check_timed_transitions()
{
for (int i = 0; i < m_num_timed_transitions; ++i)
{
TimedTransition* transition = &m_timed_transitions[i];
TimedTransition *transition = &m_timed_transitions[i];
if (transition->transition.state_from == m_current_state)
{
if (transition->start == 0)
{
transition->start = millis();
}
else{
else
{
unsigned long now = millis();
if (now - transition->start >= transition->interval)
{
Expand All @@ -140,16 +137,17 @@ void Fsm::run_machine()
if (m_current_state->on_enter != NULL)
m_current_state->on_enter();
}

if (m_current_state->on_state != NULL)
m_current_state->on_state();

Fsm::check_timed_transitions();
}

void Fsm::make_transition(Transition* transition)
void Fsm::make_transition(Transition *transition)
{

// Serial.printf("Transition powerFSM transition=%s, from=%s to=%s\n", transition->name, transition->state_from->name, transition->state_to->name);

// Execute the handlers in the correct order.
if (transition->state_from->on_exit != NULL)
transition->state_from->on_exit();
Expand All @@ -159,16 +157,15 @@ void Fsm::make_transition(Transition* transition)

if (transition->state_to->on_enter != NULL)
transition->state_to->on_enter();

m_current_state = transition->state_to;

//Initialice all timed transitions from m_current_state
unsigned long now = millis();
for (int i = 0; i < m_num_timed_transitions; ++i)
{
TimedTransition* ttransition = &m_timed_transitions[i];
TimedTransition *ttransition = &m_timed_transitions[i];
if (ttransition->transition.state_from == m_current_state)
ttransition->start = now;
}

}
68 changes: 35 additions & 33 deletions Fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,70 +16,72 @@
#ifndef FSM_H
#define FSM_H


#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#include <Arduino.h>
#else
#include <WProgram.h>
#include <WProgram.h>
#endif


struct State
{
State(void (*on_enter)(), void (*on_state)(), void (*on_exit)());
State(void (*on_enter)(), void (*on_state)(), void (*on_exit)(), const char *name);
void (*on_enter)();
void (*on_state)();
void (*on_exit)();
const char *name;
};

struct Transition
{
State *state_from;
State *state_to;
int event;
void (*on_transition)();
const char *name;
};

struct TimedTransition
{
Transition transition;
unsigned long start;
unsigned long interval;
};

#define MAX_TIMED_TRANSITIONS 8

class Fsm
{
public:
Fsm(State* initial_state);
Fsm(State *initial_state);
~Fsm();

void add_transition(State* state_from, State* state_to, int event,
void (*on_transition)());
void add_transition(State *state_from, State *state_to, int event,
void (*on_transition)(), const char *name);

TimedTransition *add_timed_transition(State *state_from, State *state_to,
unsigned long interval, void (*on_transition)(), const char *name);

void add_timed_transition(State* state_from, State* state_to,
unsigned long interval, void (*on_transition)());
State *getState() const { return m_current_state; }

void check_timed_transitions();

void trigger(int event);
void run_machine();

private:
struct Transition
{
State* state_from;
State* state_to;
int event;
void (*on_transition)();

};
struct TimedTransition
{
Transition transition;
unsigned long start;
unsigned long interval;
};

static Transition create_transition(State* state_from, State* state_to,
int event, void (*on_transition)());

void make_transition(Transition* transition);
static Transition create_transition(State *state_from, State *state_to,
int event, void (*on_transition)(), const char *name);

void make_transition(Transition *transition);

private:
State* m_current_state;
Transition* m_transitions;
State *m_current_state;
Transition *m_transitions;
int m_num_transitions;

TimedTransition* m_timed_transitions;
TimedTransition m_timed_transitions[MAX_TIMED_TRANSITIONS];
int m_num_timed_transitions;
bool m_initialized;
};


#endif
7 changes: 4 additions & 3 deletions examples/timed_switchoff/Fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ void Fsm::add_transition(State* state_from, State* state_to, int event,


void Fsm::add_timed_transition(State* state_from, State* state_to,
unsigned long interval, void (*on_transition)())
unsigned long interval, void (*on_transition)(), const char *name)
{
if (state_from == NULL || state_to == NULL)
return;

Transition transition = Fsm::create_transition(state_from, state_to, 0,
on_transition);
on_transition, name);

TimedTransition timed_transition;
timed_transition.transition = transition;
Expand All @@ -80,13 +80,14 @@ void Fsm::add_timed_transition(State* state_from, State* state_to,


Fsm::Transition Fsm::create_transition(State* state_from, State* state_to,
int event, void (*on_transition)())
int event, void (*on_transition)(), const char *name)
{
Transition t;
t.state_from = state_from;
t.state_to = state_to;
t.event = event;
t.on_transition = on_transition;
t.name = name;

return t;
}
Expand Down