Up Down counter using a transition table

Files at this revision

API Documentation at this revision

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
diff -r 7c0953072ecb -r 1e34d5c96ecf main.cpp
--- 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);
     }
 }