Example of device rapid polling in C
Fork of Task330_polling by
Revision 2:d0c39c3d3743, committed 2018-01-30
- Comitter:
- noutram
- Date:
- Tue Jan 30 11:41:43 2018 +0000
- Parent:
- 1:e84a51c98d75
- Child:
- 3:6f8a649663f0
- Commit message:
- Polling with a FSM in C
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SW1Poll.cpp Tue Jan 30 11:41:43 2018 +0000
@@ -0,0 +1,69 @@
+#include "demo-self-test.hpp"
+#include "SW1Poll.hpp"
+
+//Change this to pick the LED and Switch
+#define sw sw1
+#define led red_led
+
+//This is private to this file
+enum State {LOW, LOW_DEBOUNCE, HIGH, HIGH_DEBOUNCE};
+static State state; // Internal state
+static Timer t; // Each instance has it's own timer, so this is is finite
+
+//PUBLIC APIs
+void sw1Controller_init()
+{
+ state = LOW;
+ t.reset();
+ led = 0;
+}
+
+//THIS IS REPETETIVE AND NOT BEST PRACTISE BUT I'VE HELD BACK TO MAINTAIN CLARITY
+
+//The public API - poll the switches
+//Bascially, a mealy machine - uses a timer to manage switch bounce
+//Must be called rapidly
+void sw1FSM()
+{
+ switch (state) {
+ //Waiting for switch to rise:
+ case LOW:
+ if (sw == 1) {
+ state = LOW_DEBOUNCE;
+ t.reset();
+ t.start();
+ }
+ break;
+
+ case LOW_DEBOUNCE:
+ if (t.read_ms() >= 200) {
+ state = HIGH;
+ t.stop();
+ t.reset();
+ }
+ break;
+
+ case HIGH:
+ if (sw == 0) {
+ led = !led; //Toggle output on state transition
+ state = HIGH_DEBOUNCE;
+ t.reset(); //(purely defensive)
+ t.start();
+ }
+ break;
+ case HIGH_DEBOUNCE:
+ if (t.read_ms() >= 200) {
+ state = LOW;
+ t.stop();
+ t.reset();
+ }
+ break;
+ default:
+ t.stop();
+ t.reset();
+ state = LOW;
+ break;
+ } //end switch
+
+ //This is a Mealy Machine - so no output logic follows
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SW1Poll.hpp Tue Jan 30 11:41:43 2018 +0000 @@ -0,0 +1,5 @@ +#ifndef __SW1Poll__ +#define __SW1Poll__ +extern void sw1Controller_init(); +extern void sw1FSM(); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SW2Pol.cpp Tue Jan 30 11:41:43 2018 +0000
@@ -0,0 +1,69 @@
+#include "demo-self-test.hpp"
+#include "SW1Poll.hpp"
+
+//Change this to pick the LED and Switch
+#define sw sw2
+#define led green_led
+
+//This is private to this file
+enum State {LOW, LOW_DEBOUNCE, HIGH, HIGH_DEBOUNCE};
+static State state; // Internal state
+static Timer t; // Each instance has it's own timer, so this is is finite
+
+//PUBLIC APIs
+void sw2Controller_init()
+{
+ state = LOW;
+ t.reset();
+ led = 0;
+}
+
+//THIS IS REPETETIVE AND NOT BEST PRACTISE BUT I'VE HELD BACK TO MAINTAIN CLARITY
+
+//The public API - poll the switches
+//Bascially, a mealy machine - uses a timer to manage switch bounce
+//Must be called rapidly
+void sw2FSM()
+{
+ switch (state) {
+ //Waiting for switch to rise:
+ case LOW:
+ if (sw == 1) {
+ state = LOW_DEBOUNCE;
+ t.reset();
+ t.start();
+ }
+ break;
+
+ case LOW_DEBOUNCE:
+ if (t.read_ms() >= 200) {
+ state = HIGH;
+ t.stop();
+ t.reset();
+ }
+ break;
+
+ case HIGH:
+ if (sw == 0) {
+ led = !led; //Toggle output on state transition
+ state = HIGH_DEBOUNCE;
+ t.reset(); //(purely defensive)
+ t.start();
+ }
+ break;
+ case HIGH_DEBOUNCE:
+ if (t.read_ms() >= 200) {
+ state = LOW;
+ t.stop();
+ t.reset();
+ }
+ break;
+ default:
+ t.stop();
+ t.reset();
+ state = LOW;
+ break;
+ } //end switch
+
+ //This is a Mealy Machine - so no output logic follows
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SW2Poll.hpp Tue Jan 30 11:41:43 2018 +0000 @@ -0,0 +1,5 @@ +#ifndef __SW2Poll__ +#define __SW2Poll__ +extern void sw2Controller_init(); +extern void sw2FSM(); +#endif \ No newline at end of file
--- a/SWPoll.hpp Mon Oct 23 09:47:16 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#include "mbed.h"
-
-class SWPoll {
-private:
- enum State {LOW, LOW_DEBOUNCE, HIGH, HIGH_DEBOUNCE};
- State state; // Internal state
- DigitalIn& sw; // These are references (aliases) and MUST be initialised
- DigitalOut& led; // ""
- Timer t; // Each instance has it's own timer, so this is is finite
-
-public:
- //Constructor - MUST be given two parameters (for the switch and led) BY REFERENCE
- SWPoll(DigitalIn& gpioIn, DigitalOut& gpioOut) : sw(gpioIn), led(gpioOut) {
- state = LOW;
- t.reset();
- led = 0;
- }
- //Destructor - should the instance go out of scope, this is called
- ~SWPoll() {
- //Shut down
- t.stop();
- t.reset();
- led = 0;
- }
- //The public API - poll the switches
- //Bascially, a mealy machine - uses a timer to manage switch bounce
- void poll() {
- switch (state)
- {
- //Waiting for switch to rise:
- case LOW:
- if (sw == 1) {
- state = LOW_DEBOUNCE;
- t.reset();
- t.start();
- }
- break;
-
- case LOW_DEBOUNCE:
- if (t.read_ms() >= 200) {
- state = HIGH;
- t.stop();
- t.reset();
- }
- break;
-
- case HIGH:
- if (sw == 0) {
- led = !led; //Toggle output on state transition
- state = HIGH_DEBOUNCE;
- t.reset(); //(purely defensive)
- t.start();
- }
- break;
- case HIGH_DEBOUNCE:
- if (t.read_ms() >= 200) {
- state = LOW;
- t.stop();
- t.reset();
- }
- break;
- default:
- t.stop();
- t.reset();
- state = LOW;
- break;
- } //end switch
-
- //This is a Mealy Machine - so no output logic follows
- }
-};
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/demo-self-test.cpp Tue Jan 30 11:41:43 2018 +0000
@@ -0,0 +1,21 @@
+#include "demo-self-test.hpp"
+
+void POST()
+{
+ puts("LEDs ON");
+ red_led = 1;
+ yellow_led = 1;
+ green_led = 1;
+ onboardLED = 1;
+ wait(0.5);
+ puts("LEDs OFF");
+ red_led = 0;
+ yellow_led = 0;
+ green_led = 0;
+ onboardLED = 0;
+ wait(0.5);
+ puts("Polling Switches");
+ printf("sw1: %d\r\n", (sw1 == 1));
+ printf("sw2: %d\r\n", (sw2 == 1));
+ printf("Blue Button: %d\r\n", (button == 1));
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo-self-test.hpp Tue Jan 30 11:41:43 2018 +0000 @@ -0,0 +1,17 @@ +#ifndef __DEMO_SELF_TEST__ +#define __DEMO_SELF_TEST__ + +#include "mbed.h" +extern void POST(); + +//Hardware objects +extern DigitalOut red_led; //CountUp is in its critical section +extern DigitalOut yellow_led; //CountDown is in its critical section +extern DigitalOut green_led; //counter != 0 +extern DigitalOut onboardLED; + +extern DigitalIn button; +extern DigitalIn sw1; +extern DigitalIn sw2; + +#endif \ No newline at end of file
--- a/main.cpp Mon Oct 23 09:47:16 2017 +0000
+++ b/main.cpp Tue Jan 30 11:41:43 2018 +0000
@@ -1,5 +1,7 @@
#include "mbed.h"
-#include "SWPoll.hpp"
+#include "demo-self-test.hpp"
+#include "SW1Poll.hpp"
+#include "SW2Poll.hpp"
#define N 1000000
#define RELEASED 0
@@ -19,27 +21,33 @@
DigitalIn sw1(PE_12);
DigitalIn sw2(PE_14);
-SWPoll switch1(sw1, red_led);
-SWPoll switch2(sw2, green_led);
//LOOK AT SWPoll.hpp for the definition of the SWPoll class
int main() {
+ POST();
//Main uses a Timer
yellow_led = 1;
Timer t;
+
+ //Initialise the state machines
+ sw1Controller_init();
+ sw2Controller_init();
//Now loop forever
t.start();
while(1) {
+
//Flash the yellow on the "main thread"
if (t.read_ms() >= 500) {
yellow_led = !yellow_led;
t.reset();
}
- switch1.poll();
- switch2.poll();
+
+ //Update state machines
+ sw1FSM();
+ sw2FSM();
};
}
