Up Down counter using a transition table
Revision 1:1e34d5c96ecf, committed 2020-12-10
- Comitter:
- eencae
- Date:
- Thu Dec 10 14:22:22 2020 +0000
- Parent:
- 0:7c0953072ecb
- Commit message:
- Initial Commit
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Thu Dec 10 13:42:11 2020 +0000
+++ b/main.cpp Thu Dec 10 14:22:22 2020 +0000
@@ -24,9 +24,20 @@
// Button A on board
InterruptIn buttonA(p29);
-// array of states in the FSM, each element is the output of the counter
-// set the output in binary to make it easier, 1 is LED on, 0 is LED off
-int g_fsm[4] = {0b0001,0b0010,0b0100,0b1000};
+// struct for state
+struct State {
+ int output; // output value for current state
+ int time; // wait time for state (ms)
+ int next_state[2]; // next state (depending on direction 0 - UP, 1 - DOWN)
+};
+
+// array of states in the FSM, each element is the output of the counter, wait time, next state(s)
+State g_fsm[4] = {
+ {0b0001,500,{1,3}},
+ {0b0010,500,{2,0}},
+ {0b0100,500,{3,1}},
+ {0b1000,500,{0,2}},
+};
// flag - must be volatile as changes within ISR
// g_ prefix makes it easier to distinguish it as global
@@ -44,7 +55,7 @@
// since Button A has an external pull-down, we should disable to internal pull-down
// resistor that is enabled by default using InterruptIn
buttonA.mode(PullNone);
-
+
// set inital state
int state = 0;
// set initial direction
@@ -55,67 +66,17 @@
// check if flag i.e. interrupt has occured
if (g_buttonA_flag) {
g_buttonA_flag = 0; // if it has, clear the flag
-
// swap direction when button has been pressed
- // (could just use ! but want this to be explicit to aid understanding)
- if (direction == UP) {
- direction = DOWN;
- } else {
- direction = UP;
- }
+ direction = ! direction;
}
- output = g_fsm[state]; // output current state
+ // set output of current state (use dot syntax to access struct members)
+ output = g_fsm[state].output;
+ // implement required delay
+ thread_sleep_for(g_fsm[state].time);
+ // set the next state depending on direction
+ state = g_fsm[state].next_state[direction];
- // check which state we are in and see which the next state should be next depending on direction
- switch(state) {
- case 0:
- switch(direction) {
- case UP:
- state = 1;
- break;
- case DOWN:
- state = 3;
- break;
- }
- break;
- case 1:
- switch(direction) {
- case UP:
- state = 2;
- break;
- case DOWN:
- state = 0;
- break;
- }
- break;
- case 2:
- switch(direction) {
- case UP:
- state = 3;
- break;
- case DOWN:
- state = 1;
- break;
- }
- break;
- case 3:
- switch(direction) {
- case UP:
- state = 0;
- break;
- case DOWN:
- state = 2;
- break;
- }
- break;
- default: // default case
- error("Invalid state!"); //invalid state - call error routine
- state = 0;
- break;
- }
-
- thread_sleep_for(500);
}
}