Skip to content

Commit 68dd63f

Browse files
Thelmosjonblack
authored andcommitted
v2.2.0 (#11)
* 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`
1 parent 27a6d8b commit 68dd63f

File tree

8 files changed

+330
-38
lines changed

8 files changed

+330
-38
lines changed

Fsm.cpp

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
#include "Fsm.h"
1717

1818

19-
State::State(void (*on_enter)(), void (*on_exit)())
19+
State::State(void (*on_enter)(), void (*on_state)(), void (*on_exit)())
2020
: on_enter(on_enter),
21+
on_state(on_state),
2122
on_exit(on_exit)
2223
{
2324
}
@@ -26,7 +27,9 @@ State::State(void (*on_enter)(), void (*on_exit)())
2627
Fsm::Fsm(State* initial_state)
2728
: m_current_state(initial_state),
2829
m_transitions(NULL),
29-
m_num_transitions(0)
30+
m_num_transitions(0),
31+
m_num_timed_transitions(0),
32+
m_initialized(false)
3033
{
3134
}
3235

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

9194
void Fsm::trigger(int event)
9295
{
93-
// Find the transition with the current state and given event.
94-
for (int i = 0; i < m_num_transitions; ++i)
96+
if (m_initialized)
9597
{
96-
if (m_transitions[i].state_from == m_current_state &&
97-
m_transitions[i].event == event)
98+
// Find the transition with the current state and given event.
99+
for (int i = 0; i < m_num_transitions; ++i)
98100
{
99-
m_current_state = m_transitions[i].make_transition();
100-
return;
101+
if (m_transitions[i].state_from == m_current_state &&
102+
m_transitions[i].event == event)
103+
{
104+
Fsm::make_transition(&(m_transitions[i]));
105+
return;
106+
}
101107
}
102108
}
103109
}
104110

105-
106-
void Fsm::check_timer()
111+
void Fsm::check_timed_transitions()
107112
{
108113
for (int i = 0; i < m_num_timed_transitions; ++i)
109114
{
@@ -114,31 +119,56 @@ void Fsm::check_timer()
114119
{
115120
transition->start = millis();
116121
}
117-
else
118-
{
122+
else{
119123
unsigned long now = millis();
120124
if (now - transition->start >= transition->interval)
121125
{
122-
m_current_state = transition->transition.make_transition();
126+
Fsm::make_transition(&(transition->transition));
123127
transition->start = 0;
124128
}
125129
}
126130
}
127131
}
128132
}
129133

134+
void Fsm::run_machine()
135+
{
136+
// first run must exec first state "on_enter"
137+
if (!m_initialized)
138+
{
139+
m_initialized = true;
140+
if (m_current_state->on_enter != NULL)
141+
m_current_state->on_enter();
142+
}
143+
144+
if (m_current_state->on_state != NULL)
145+
m_current_state->on_state();
146+
147+
Fsm::check_timed_transitions();
148+
}
130149

131-
State* Fsm::Transition::make_transition()
150+
void Fsm::make_transition(Transition* transition)
132151
{
152+
133153
// Execute the handlers in the correct order.
134-
if (state_from->on_exit != NULL)
135-
state_from->on_exit();
154+
if (transition->state_from->on_exit != NULL)
155+
transition->state_from->on_exit();
156+
157+
if (transition->on_transition != NULL)
158+
transition->on_transition();
136159

137-
if (on_transition != NULL)
138-
on_transition();
160+
if (transition->state_to->on_enter != NULL)
161+
transition->state_to->on_enter();
162+
163+
m_current_state = transition->state_to;
139164

140-
if (state_to->on_enter != NULL)
141-
state_to->on_enter();
165+
//Initialice all timed transitions from m_current_state
166+
unsigned long now = millis();
167+
for (int i = 0; i < m_num_timed_transitions; ++i)
168+
{
169+
TimedTransition* ttransition = &m_timed_transitions[i];
170+
if (ttransition->transition.state_from == m_current_state)
171+
ttransition->start = now;
172+
}
142173

143-
return state_to;
144174
}

Fsm.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626

2727
struct State
2828
{
29-
State(void (*on_enter)(), void (*on_exit)());
30-
29+
State(void (*on_enter)(), void (*on_state)(), void (*on_exit)());
3130
void (*on_enter)();
31+
void (*on_state)();
3232
void (*on_exit)();
3333
};
3434

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

48+
void check_timed_transitions();
49+
4850
void trigger(int event);
49-
void check_timer();
51+
void run_machine();
5052

5153
private:
5254
struct Transition
@@ -56,7 +58,6 @@ class Fsm
5658
int event;
5759
void (*on_transition)();
5860

59-
State* make_transition();
6061
};
6162
struct TimedTransition
6263
{
@@ -68,13 +69,16 @@ class Fsm
6869
static Transition create_transition(State* state_from, State* state_to,
6970
int event, void (*on_transition)());
7071

72+
void make_transition(Transition* transition);
73+
7174
private:
7275
State* m_current_state;
7376
Transition* m_transitions;
7477
int m_num_transitions;
7578

7679
TimedTransition* m_timed_transitions;
7780
int m_num_timed_transitions;
81+
bool m_initialized;
7882
};
7983

8084

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ feature branch.
2222

2323
# Changelog
2424

25+
**2.2.0 - 12/03/2016**
26+
27+
* Add `on_state()` handler to states
28+
* New `run_machine()` method to invoke machine execution (includes a `check_timed_transitions()` call)
29+
* New `timed_switchoff.ino` example sketch to ilustrate new `on_state()` and `run_machine()` funcionality
30+
* Corrections:
31+
- `make_transition()` correctly initialices timed transitions start milliseconds (`make_transition()` is now a fsm method)
32+
- Initial state `on_enter()` handler is now correctly executed on fsm first run
33+
- Removed `Serial.println(now);` trace in _Fsm.cpp_
34+
- Correct initialization of `m_num_timed_transitions`
35+
36+
2537
**2.1.0 - 21/11/2015**
2638

2739
* Add timed transitions

examples/light_switch/light_switch.ino

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
#include <Fsm.h>
1+
#include "Fsm.h"
22

33
// State machine variables
44
#define FLIP_LIGHT_SWITCH 1
55

6-
State state_light_on(on_light_on_enter, &on_light_on_exit);
7-
State state_light_off(on_light_off_enter, &on_light_off_exit);
6+
State state_light_on(on_light_on_enter, NULL, &on_light_on_exit);
7+
State state_light_off(on_light_off_enter, NULL, &on_light_off_exit);
88
Fsm fsm(&state_light_off);
99

1010
// Transition callback functions
@@ -53,6 +53,7 @@ void setup()
5353

5454
void loop()
5555
{
56+
// No "fsm.run_machine()" call needed as no "on_state" funcions or timmed transitions exists
5657
delay(2000);
5758
fsm.trigger(FLIP_LIGHT_SWITCH);
5859
delay(2000);

examples/multitasking/multitasking.ino

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// multitasking on an arduino. Two LED's are turned on and off at irregular
33
// intervals; the finite state machines take care of the transitions.
44

5-
#include <Fsm.h>
5+
#include "Fsm.h"
66

77
#define LED1_PIN 10
88
#define LED2_PIN 11
@@ -27,11 +27,11 @@ void on_led2_off_enter() {
2727
digitalWrite(LED2_PIN, LOW);
2828
}
2929

30-
State state_led1_on(&on_led1_on_enter, NULL);
31-
State state_led1_off(&on_led1_off_enter, NULL);
30+
State state_led1_on(&on_led1_on_enter, NULL, NULL);
31+
State state_led1_off(&on_led1_off_enter, NULL, NULL);
3232

33-
State state_led2_on(&on_led2_on_enter, NULL);
34-
State state_led2_off(&on_led2_off_enter, NULL);
33+
State state_led2_on(&on_led2_on_enter, NULL, NULL);
34+
State state_led2_off(&on_led2_off_enter, NULL, NULL);
3535

3636
Fsm fsm_led1(&state_led1_off);
3737
Fsm fsm_led2(&state_led2_off);
@@ -50,8 +50,8 @@ void setup() {
5050

5151

5252
void loop() {
53-
fsm_led1.check_timer();
54-
fsm_led2.check_timer();
55-
56-
delay(100);
53+
fsm_led1.run_machine();
54+
fsm_led2.run_machine();
55+
delay(200);
5756
}
57+

0 commit comments

Comments
 (0)