Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.2.0 #11

Merged
merged 1 commit into from
Oct 25, 2017
Merged
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
73 changes: 51 additions & 22 deletions Fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
#include "Fsm.h"


State::State(void (*on_enter)(), void (*on_exit)())
State::State(void (*on_enter)(), void (*on_state)(), void (*on_exit)())
: on_enter(on_enter),
on_state(on_state),
on_exit(on_exit)
{
}
Expand All @@ -26,7 +27,9 @@ State::State(void (*on_enter)(), void (*on_exit)())
Fsm::Fsm(State* initial_state)
: m_current_state(initial_state),
m_transitions(NULL),
m_num_transitions(0)
m_num_transitions(0),
m_num_timed_transitions(0),
m_initialized(false)
{
}

Expand Down Expand Up @@ -90,20 +93,22 @@ Fsm::Transition Fsm::create_transition(State* state_from, State* state_to,

void Fsm::trigger(int event)
{
// Find the transition with the current state and given event.
for (int i = 0; i < m_num_transitions; ++i)
if (m_initialized)
{
if (m_transitions[i].state_from == m_current_state &&
m_transitions[i].event == event)
// Find the transition with the current state and given event.
for (int i = 0; i < m_num_transitions; ++i)
{
m_current_state = m_transitions[i].make_transition();
return;
if (m_transitions[i].state_from == m_current_state &&
m_transitions[i].event == event)
{
Fsm::make_transition(&(m_transitions[i]));
return;
}
}
}
}


void Fsm::check_timer()
void Fsm::check_timed_transitions()
{
for (int i = 0; i < m_num_timed_transitions; ++i)
{
Expand All @@ -114,32 +119,56 @@ void Fsm::check_timer()
{
transition->start = millis();
}
else
{
else{
unsigned long now = millis();
Serial.println(now);
if (now - transition->start >= transition->interval)
{
m_current_state = transition->transition.make_transition();
Fsm::make_transition(&(transition->transition));
transition->start = 0;
}
}
}
}
}

void Fsm::run_machine()
{
// first run must exec first state "on_enter"
if (!m_initialized)
{
m_initialized = true;
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();
}

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

// Execute the handlers in the correct order.
if (state_from->on_exit != NULL)
state_from->on_exit();
if (transition->state_from->on_exit != NULL)
transition->state_from->on_exit();

if (transition->on_transition != NULL)
transition->on_transition();

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

m_current_state = transition->state_to;

if (state_to->on_enter != NULL)
state_to->on_enter();
//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];
if (ttransition->transition.state_from == m_current_state)
ttransition->start = now;
}

return state_to;
}
12 changes: 8 additions & 4 deletions Fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@

struct State
{
State(void (*on_enter)(), void (*on_exit)());

State(void (*on_enter)(), void (*on_state)(), void (*on_exit)());
void (*on_enter)();
void (*on_state)();
void (*on_exit)();
};

Expand All @@ -45,8 +45,10 @@ class Fsm
void add_timed_transition(State* state_from, State* state_to,
unsigned long interval, void (*on_transition)());

void check_timed_transitions();

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

private:
struct Transition
Expand All @@ -56,7 +58,6 @@ class Fsm
int event;
void (*on_transition)();

State* make_transition();
};
struct TimedTransition
{
Expand All @@ -68,13 +69,16 @@ class Fsm
static Transition create_transition(State* state_from, State* state_to,
int event, void (*on_transition)());

void make_transition(Transition* transition);

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

TimedTransition* m_timed_transitions;
int m_num_timed_transitions;
bool m_initialized;
};


Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ feature branch.

# Changelog

**2.2.0 - 12/03/2016**

* Add `on_state()` handler to states
* New `run_machine()` method to invoke machine execution (includes a `check_timed_transitions()` call)
* New `timed_switchoff.ino` example sketch to ilustrate new `on_state()` and `run_machine()` funcionality
* Corrections:
- `make_transition()` correctly initialices timed transitions start milliseconds (`make_transition()` is now a fsm method)
- Initial state `on_enter()` handler is now correctly executed on fsm first run
- Removed `Serial.println(now);` trace in _Fsm.cpp_
- Correct initialization of `m_num_timed_transitions`


**2.1.0 - 21/11/2015**

* Add timed transitions
Expand Down
7 changes: 4 additions & 3 deletions examples/light_switch/light_switch.ino
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <Fsm.h>
#include "Fsm.h"

// State machine variables
#define FLIP_LIGHT_SWITCH 1

State state_light_on(on_light_on_enter, &on_light_on_exit);
State state_light_off(on_light_off_enter, &on_light_off_exit);
State state_light_on(on_light_on_enter, NULL, &on_light_on_exit);
State state_light_off(on_light_off_enter, NULL, &on_light_off_exit);
Fsm fsm(&state_light_off);

// Transition callback functions
Expand Down Expand Up @@ -53,6 +53,7 @@ void setup()

void loop()
{
// No "fsm.run_machine()" call needed as no "on_state" funcions or timmed transitions exists
delay(2000);
fsm.trigger(FLIP_LIGHT_SWITCH);
delay(2000);
Expand Down
18 changes: 9 additions & 9 deletions examples/multitasking/multitasking.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// multitasking on an arduino. Two LED's are turned on and off at irregular
// intervals; the finite state machines take care of the transitions.

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

#define LED1_PIN 10
#define LED2_PIN 11
Expand All @@ -27,11 +27,11 @@ void on_led2_off_enter() {
digitalWrite(LED2_PIN, LOW);
}

State state_led1_on(&on_led1_on_enter, NULL);
State state_led1_off(&on_led1_off_enter, NULL);
State state_led1_on(&on_led1_on_enter, NULL, NULL);
State state_led1_off(&on_led1_off_enter, NULL, NULL);

State state_led2_on(&on_led2_on_enter, NULL);
State state_led2_off(&on_led2_off_enter, NULL);
State state_led2_on(&on_led2_on_enter, NULL, NULL);
State state_led2_off(&on_led2_off_enter, NULL, NULL);

Fsm fsm_led1(&state_led1_off);
Fsm fsm_led2(&state_led2_off);
Expand All @@ -50,8 +50,8 @@ void setup() {


void loop() {
fsm_led1.check_timer();
fsm_led2.check_timer();

delay(100);
fsm_led1.run_machine();
fsm_led2.run_machine();
delay(200);
}

Loading