MrAlvin

state machine example B

Mar 20th, 2016
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.91 KB | None | 0 0
  1. /*
  2.  *  This is a sample sketch to show a solution to Simons 4x LED challenge
  3.  *  see: https://www.facebook.com/groups/1437500423193520/permalink/1705520479724845/
  4.  *  
  5.  *  The challenge is that any one of three events can occur
  6.  *    Event A : the user can press a button
  7.  *    Event B : time has passed
  8.  *    Event C : the user releases the button
  9.  *    
  10.  *    Event A & C can only happen sequentally. That is one event has to happen before the other can happen
  11.  *    Ecent B can only happen after event A
  12.  *    Event C can happen at any time after event A has happened
  13.  *    
  14.  *
  15.  * Test circuit:
  16.  *
  17.  *  Connect a push-button to pin 10 (ButtonPin), connect other side of button to ground.
  18.  *  Connect LEDs (including resistors) to pins 3, 4, 5 & 6
  19.  *  
  20.  *  Pin 13 (StatusPin) is used as a I-am-alive-blinking-signal
  21.  *  
  22.  *  This skect uses the ButtoOne library from https://github.com/MrAlvin/ButtonOne
  23.  *
  24.  */
  25.  
  26. #include "ButtonOne.h"
  27.  
  28. // Setup a ButtonOne instance on pin 10.  
  29. ButtonOne button(10);
  30.  
  31. #define LED1_PIN 3
  32. #define LED2_PIN 4
  33. #define LED3_PIN 5
  34. #define LED4_PIN 6
  35. #define DEBUG_LED_PIN 13
  36.  
  37. boolean button_pressed = false;    // flag used to evaluate on event B - the passing of time between activation of LEDs
  38. unsigned long previousMillis = 0;  // used to track the passing of "interval" time
  39. unsigned long interval = 0;        // used to track time to occur between LED activations. Default action is; that LED 1 turns on, as the button is pressed
  40. int idx = 1;                       // used keep track of the current state in the state-machine
  41.  
  42. //*********************************************
  43. // setup function - to run once:
  44. //*********************************************
  45. void setup() {
  46.   // enable the standard led on pin 13.
  47.   pinMode(DEBUG_LED_PIN, OUTPUT);      // sets the digital pin as output
  48.  
  49.   pinMode(LED1_PIN, OUTPUT);      // sets the digital pin as output
  50.   pinMode(LED2_PIN, OUTPUT);      // sets the digital pin as output
  51.   pinMode(LED3_PIN, OUTPUT);      // sets the digital pin as output
  52.   pinMode(LED4_PIN, OUTPUT);      // sets the digital pin as output
  53.  
  54.   //initiate internal button management values
  55.   button.begin();
  56.  
  57.   // link the Press function to be called on a button Press event.  
  58.   button.attachPress(btnPress);
  59.   // link the Release function to be called on a button Release event.
  60.   button.attachRelease(btnRelease);
  61. } // setup
  62.  
  63.  
  64. //*********************************************
  65. // main code -  to run repeatedly:
  66. //*********************************************
  67. void loop() {
  68.   // check for event A (button press)
  69.   button.check();
  70.  
  71.   // if event A has occured, check for event B
  72.   if(button_pressed)  take_action();
  73.  
  74.   // something I usually use when dealing with event-style programming
  75.   debug_blink();  // lets me know that the program is up and running
  76. } // loop
  77.  
  78.  
  79. //*********************************************
  80. // button events:
  81. //*********************************************
  82. // this function will be called when the button is pressed
  83. void btnPress() {
  84.   button_pressed = true;  // raise flag. Response to flag happens in the main loop()
  85. } // btnPress
  86.  
  87. // this function will be called when the button is released - which is also event C
  88. void btnRelease() {
  89.   button_pressed = false; // button is no longer pressed
  90.   LedsOff();              // turn off all LEDs
  91.   idx = 1;                // reset the pointer in the state machine, so ready for next press of the button
  92.   previousMillis = 0;     // reset the time tracker
  93.   interval = 0;           // set time interval for time to pass between pressing of button to turn on LED 1
  94. } // btnRelease
  95.  
  96.  
  97. //*********************************************
  98. // state machine:
  99. //*********************************************
  100. void take_action() {
  101.   switch(idx){
  102.     case 1: //time to pass before turning on LED 1
  103.       // no time needs to pass, so simply move on
  104.       idx++;
  105.       break;
  106.     case 2: //turn on LED one
  107.       led_1_on();
  108.       interval = 1000; // time until LED 2 will be turned on
  109.       idx++;           // ready to activate LED 2
  110.       break;
  111.     case 3: //wait for time to pass
  112.       if( time_has_passed() ) idx++;
  113.       break;
  114.     case 4: //turn on LED two
  115.       led_2_on();
  116.       interval = 1000; // time until LED 3 will be turned on
  117.       idx++;           // ready to activate LED 3
  118.       break;
  119.     case 5: //wait for time to pass
  120.       if( time_has_passed() ) idx++;
  121.       break;
  122.     case 6: //turn on LED three
  123.       led_3_on();
  124.       interval = 1000; // time until LED 4 will be turned on
  125.       idx++;           // ready to activate LED 4
  126.       break;
  127.     case 7: //wait for time to pass
  128.       if( time_has_passed() ) idx++;
  129.       break;
  130.     case 8: //turn on LEDE four
  131.       led_4_on();
  132.       idx++;           // ready to simply waite
  133.       break;
  134.     case 9: //just hang out here, do nothing, and wait for button release
  135.       break;
  136.   }
  137. } //take_action
  138.  
  139.  
  140. //*********************************************
  141. // timer function:
  142. //*********************************************
  143. boolean time_has_passed() {
  144.   if (millis() - previousMillis > interval) {
  145.     previousMillis = millis();  // store the current time, so we can waite "interval" amount of time, before we take next action
  146.     return true;
  147.   }else{
  148.     return false;    
  149.   }
  150. } //time_has_passed
  151.  
  152.  
  153.  
  154. //*********************************************
  155. // LED functions:
  156. //*********************************************
  157. void LedsOff(){
  158.   led_1_off();
  159.   led_2_off();
  160.   led_3_off();
  161.   led_4_off();
  162. }
  163.  
  164.  
  165. void led_1_on(){
  166.   digitalWrite(LED1_PIN, HIGH);
  167. }
  168.  
  169. void led_1_off(){
  170.   digitalWrite(LED1_PIN, LOW);
  171. }
  172.  
  173.  
  174. void led_2_on(){
  175.   digitalWrite(LED1_PIN, HIGH);
  176. }
  177.  
  178. void led_2_off(){
  179.   digitalWrite(LED1_PIN, LOW);
  180. }
  181.  
  182.  
  183. void led_3_on(){
  184.   digitalWrite(LED1_PIN, HIGH);
  185. }
  186.  
  187. void led_3_off(){
  188.   digitalWrite(LED1_PIN, LOW);
  189. }
  190.  
  191. void led_4_on(){
  192.   digitalWrite(LED1_PIN, HIGH);
  193. }
  194.  
  195. void led_4_off(){
  196.   digitalWrite(LED1_PIN, LOW);
  197. }
  198.  
  199.  
  200. //*********************************************
  201. // I-am-alive debug LED blink function:
  202. //*********************************************
  203. #define ON_DELAY  500
  204. #define OFF_DELAY 500
  205.  
  206. void debug_blink() {
  207.   static unsigned long blink_millis = 0;
  208.   static unsigned long blink_interval = 0;
  209.   static boolean do_on = true;
  210.  
  211.   if ( millis() - blink_millis >  blink_interval )  { // if its time to change the blink
  212.     if (do_on) { //use a flag to determine wether to turn on or off the Blink LED
  213.       digitalWrite(DEBUG_LED_PIN, HIGH);   // set the LED on, if okay to use power for it
  214.       blink_millis = millis();
  215.       blink_interval = ON_DELAY; // wait for a second
  216.       do_on = false;
  217.     }else{
  218.       digitalWrite(DEBUG_LED_PIN, LOW);    // set the LED off
  219.       // set the time to do next blink
  220.       blink_millis = millis();
  221.       blink_interval = OFF_DELAY;  // wait for a second
  222.       do_on = true;
  223.     }
  224.   }
  225. } //debug_blink
  226.  
  227. // End
Advertisement
Add Comment
Please, Sign In to add comment