Advertisement
skizziks_53

5-relay gate sketch v.1

Apr 14th, 2018
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.67 KB | None | 0 0
  1. /*
  2.   Reddit 5-relay gate sketch v.1
  3.   March 13, 2018
  4.  
  5.   For having four relays that need delayed functions, it is easier IMO to just make a class and give them all the methods.
  6.   If a relay does not need a turn-on delay, then you just set that property to zero.
  7.   The flasher is also placed into a class as well.
  8.  
  9.   The classes are written in-line first, and the object declarations begin on line 255.
  10.   Setup()  begins on line 300 and the main loop() begins on line 312.
  11.  
  12. */
  13.  
  14. // Below is one variable that you can use to enable or disable all the serial prints at once.
  15. bool show_serialPrint_statements = true;
  16.  
  17. const int button_Pin = 2;     // the number of the pushbutton pin
  18. const int open_right_gate_relay_pin =  10;      // the number of the relay pin
  19. const int open_left_gate_relay_pin =  11;      // the number of the relay pin
  20. const int close_right_gate_relay_pin =  8;      // the number of the relay pin
  21. const int close_left_gate_relay_pin =  9;      // the number of the relay pin
  22. const int light_gate_relay_pin =  12;      // the number of the relay pin
  23.  
  24.  
  25. // CLASS BEGINS ######################################################################################
  26. class Gate_Relay {
  27.   private:
  28.     unsigned long relay_start_time = 0; // This is the starting time of whatever mode the relay is in.
  29.     unsigned long relay_current_time = 0; // This is to get the current time in.
  30.     int pin_number; // the pin number of this relay.
  31.     float start_delay; // This is the time delay to wait after being started, to turn the relay on.
  32.     float run_time; // This is the time to keep the relay on.
  33.   public:
  34.     Gate_Relay(int, float, float);
  35.     void beginRelay(unsigned long);
  36.     void checkRelay();
  37.     int relay_mode; // This is a number that tells what mode the relay is in: 0=relay off, 1=startup delay, 2=relay on, 3=shutting off
  38. };
  39.  
  40. Gate_Relay::Gate_Relay(int pin, float sd, float rt) { // This is the constructor.
  41.   pin_number = pin;
  42.   relay_mode = 0;
  43.   start_delay = sd;
  44.   run_time = rt;
  45. };
  46.  
  47. void Gate_Relay::beginRelay(unsigned long thisTime) {
  48.   relay_start_time = thisTime;
  49.   relay_mode = 1;
  50. };
  51.  
  52. void Gate_Relay::checkRelay() {
  53.   switch (relay_mode) {
  54.     case 0:
  55.       // There is nothing to do for relay_mode == 0, because this means the relay is [off].
  56.       // This method does not change the relay mode from zero to 1, the beginRelay method does that.
  57.       break;
  58.     case 1:
  59.       // This is what happens if the relay is in the startup delay:
  60.       relay_current_time = millis();
  61.       if (relay_current_time > relay_start_time) {
  62.         if (relay_current_time > (relay_start_time + (start_delay * 1000))) { // If the start_delay time has passed, then:
  63.           relay_mode = 2; // switch the relay mode to the next [run] mode.
  64.           relay_start_time = millis(); // reset the relay start time, since now it has to time how long the relay pin is HIGH
  65.           digitalWrite(pin_number, HIGH);
  66.           // Below writes the serial.print lines for each of the relays.
  67.           if (show_serialPrint_statements == true) {
  68.             switch (pin_number) {
  69.               case open_right_gate_relay_pin:
  70.                 Serial.println("open_right_gate_relay = ON");
  71.                 break;
  72.               case open_left_gate_relay_pin:
  73.                 Serial.println("open_left_gate_relay = ON");
  74.                 break;
  75.               case close_right_gate_relay_pin:
  76.                 Serial.println("close_right_gate_relay = ON");
  77.                 break;
  78.               case close_left_gate_relay_pin:
  79.                 Serial.println("close_left_gate_relay = ON");
  80.                 break;
  81.             }
  82.           }
  83.         }
  84.       }
  85.       else {
  86.         relay_start_time = millis(); // This is to reset the relay_start_time in case millis() has rolled over.
  87.       }
  88.       break;
  89.     case 2:
  90.       // This is what happens if the relay is in the run (HIGH) mode:
  91.       relay_current_time = millis();
  92.       if (relay_current_time > relay_start_time) {
  93.         if (relay_current_time > (relay_start_time + (run_time * 1000))) {
  94.           // If the time to keep the relay on has passed, then:
  95.           relay_mode = 3; // switch the relay mode to the [shutting off] mode
  96.           relay_start_time = millis(); // This is to reset the relay_start_time in case millis() has rolled over.
  97.         }
  98.       }
  99.       else {
  100.         relay_start_time = millis(); // This is to reset the relay_start_time in case millis() has rolled over.
  101.       }
  102.       break;
  103.     case 3:
  104.       digitalWrite(pin_number, LOW); // Turn the relay pin off again.
  105.       relay_mode = 0; // shut off mode
  106.       // Below writes the serial.print lines for each of the relays.
  107.       if (show_serialPrint_statements == true) {
  108.         switch (pin_number) {
  109.           case open_right_gate_relay_pin:
  110.             Serial.println("open_right_gate_relay = OFF");
  111.             break;
  112.           case open_left_gate_relay_pin:
  113.             Serial.println("open_left_gate_relay = OFF");
  114.             break;
  115.           case close_right_gate_relay_pin:
  116.             Serial.println("close_right_gate_relay = OFF");
  117.             break;
  118.           case close_left_gate_relay_pin:
  119.             Serial.println("close_left_gate_relay = OFF");
  120.             break;
  121.         }
  122.       }
  123.       break;
  124.     default:
  125.       // nothing here
  126.       break; // The Arduino switch-case example leaves off the ending {break;} statement ???
  127.       // For any condition you should also have a closing {break;} statement.
  128.       // Some compilers will say it's wrong if you don't do that.
  129.   }
  130. };
  131. // CLASS ENDS ######################################################################################
  132.  
  133.  
  134.  
  135. // CLASS BEGINS ######################################################################################
  136. class Flasher_Light {
  137.   private:
  138.     unsigned long flash_start_time = 0; // This is the starting time of whatever mode the relay is in.
  139.     unsigned long flash_current_time = 0; // This is to get the current time in, to change the mode of the flasher.
  140.     int pin_number; // the pin number of this relay.
  141.     int blink_interval; // This is the time in milliseconds to blink this flasher on and off.
  142.     unsigned long blink_start_time; // These two variables are used for blinking the relay pin on and off.
  143.     unsigned long blink_current_time;
  144.     float start_delay; // This is the time delay in seconds to wait after the button is pressed.
  145.     // The flasher just runs constantly until it shuts down, so it doesn't have a 'run time'.
  146.     float shutdown_delay; // This is the time (in seconds) to keep running after the button is released.
  147.     int flasher_mode; // 0=flasher off, 1=startup delay, 2=flasher on, 3=flasher shutting down
  148.     int flash_pin_state = 0; // This is used for cycling the flasher pin on and off.
  149.   public:
  150.     Flasher_Light(int, float, int, float);
  151.     void beginFlasher(unsigned long);
  152.     void checkFlasher();
  153.     void shutDownFlasher(unsigned long);
  154. };
  155.  
  156. Flasher_Light::Flasher_Light(int pin, float start_d, int f_interval, float stop_d) { // This is the constructor used.
  157.   pin_number = pin;
  158.   blink_interval = f_interval;
  159.   flasher_mode = 0;
  160.   start_delay = start_d;
  161.   shutdown_delay = stop_d;
  162. };
  163.  
  164. void Flasher_Light::beginFlasher(unsigned long thisTime) {
  165.   flash_start_time = thisTime;
  166.   blink_start_time = thisTime;
  167.   flasher_mode = 1;
  168.   flash_pin_state = 1;
  169.   digitalWrite(pin_number, flash_pin_state);
  170.   // Below writes the serial.print lines for each of the relays.
  171.   if (show_serialPrint_statements == true) {
  172.     Serial.println("flasher turning on + flasher blink = ON");
  173.     // I also print the flasher pin state here, since it is starting out set to 'on'.
  174.   }
  175. };
  176.  
  177. void Flasher_Light::checkFlasher() {
  178.   // int flasher_mode; // 0=flasher off, 1=startup delay, 2=flasher on, 3=flasher shutting down
  179.   switch (flasher_mode) {
  180.     case 0:
  181.       // flasher is not active
  182.       break;
  183.     case 1:
  184.       // This is the start-up delay:
  185.       flash_current_time = millis();
  186.       if (flash_current_time > flash_start_time) {
  187.         if (flash_current_time > (flash_start_time + (start_delay * 1000))) {
  188.           // If the start_delay time has passed, then:
  189.           flasher_mode = 2; // switch the flasher mode to the [run] mode
  190.           // We don't need to do anything else here, because the purpose of mode#2 is just to make sure the flasher does not run mode#1 or mode#3 code.
  191.         }
  192.       }
  193.       else {
  194.         flash_start_time = millis(); // This is to reset the relay_start_time in case millis() has rolled over.
  195.       }
  196.       break;
  197.     case 2:
  198.       // -nothing here-
  199.       // When the button is released, that triggers the flasher mode change from #2 to #3.
  200.       break;
  201.     case 3:
  202.       // flasher shutting down
  203.       flash_current_time = millis();
  204.       if (flash_current_time > flash_start_time) {
  205.         if (flash_current_time > (flash_start_time + (shutdown_delay * 1000))) {
  206.           // If the shutdown_delay time has passed, then:
  207.           flasher_mode = 0; // switch the flasher mode to the [off] mode
  208.           if (show_serialPrint_statements == true) {
  209.             Serial.println("flasher shutting off");
  210.           }
  211.         }
  212.       }
  213.       else {
  214.         flash_start_time = millis(); // This is to reset the relay_start_time in case millis() has rolled over.
  215.       }
  216.       break;
  217.     default:
  218.       // nothing
  219.       break;
  220.   }
  221.  
  222.   // The code below blinks the light on and off.
  223.   if (flasher_mode > 1) { // modes 0 and 1 are 'off', but modes 2 and 3 are 'flasher blinking':
  224.     blink_current_time = millis();
  225.     if (blink_current_time > blink_start_time) {
  226.       if (blink_current_time > (blink_start_time + blink_interval)) {
  227.         // This changes the flasher pin state if the blink_interval time has passed.
  228.         if (flash_pin_state == 0) {
  229.           flash_pin_state = 1;
  230.           if (show_serialPrint_statements == true) {
  231.             Serial.println("flasher blink = ON");
  232.           }
  233.         }
  234.         else {
  235.           flash_pin_state = 0;
  236.           if (show_serialPrint_statements == true) {
  237.             Serial.println("flasher blink = OFF");
  238.           }
  239.         }
  240.         digitalWrite(pin_number, flash_pin_state);
  241.         blink_start_time = millis(); // Reset the blink change time to now, since it just changed now.
  242.       }
  243.     }
  244.     else {
  245.       blink_start_time = millis(); // This is to reset the relay_start_time in case millis() has rolled over.
  246.     }
  247.   }
  248. };
  249.  
  250. void Flasher_Light::shutDownFlasher(unsigned long thisTime) {
  251.   flash_start_time = thisTime;
  252.   flasher_mode = 3;
  253. };
  254. // CLASS ENDS ######################################################################################
  255.  
  256.  
  257.  
  258. // Below is declaring Gate_Relay objects:
  259. //the constructor format is as follows: [int] pin number, [float] startup delay time in seconds, [float] relay run time in seconds
  260. Gate_Relay Open_right_gate_relay = Gate_Relay(open_right_gate_relay_pin, 0, 4);
  261. Gate_Relay Open_left_gate_relay = Gate_Relay(open_left_gate_relay_pin, 1, 4);
  262. Gate_Relay Close_right_gate_relay = Gate_Relay(close_right_gate_relay_pin, 2, 4);
  263. Gate_Relay Close_left_gate_relay = Gate_Relay(close_left_gate_relay_pin, 1, 4);
  264.  
  265. // below is declaring the Flasher1 object:
  266. Flasher_Light Flasher1 = Flasher_Light(light_gate_relay_pin, 0, 500, 7.5);
  267. // constructor: [int] pin#, [float] start_delay (seconds), [int] blink_interval (milliseconds), [float] stop_delay (seconds)
  268.  
  269.  
  270. const int buttonCheck_interval_milliseconds = 500; // This is the milliseconds interval to check if the button has been pressed or not.
  271. const int button_debounce_time_milliseconds = 100; // This is the time used to de-bounce the button (the time that the button does not accept input after it is pressed).
  272. bool button_enabled = true; // This is to disable the button for debouncing.
  273. unsigned long previous_buttonCheckTime = 0; // This stores the clock time in milliseconds.
  274. unsigned long current_buttonCheckTime = 0; // This stores the clock time in milliseconds.
  275. // The button-checking code will constantly re-use the above two variables, so nothing else can use them.
  276.  
  277. bool current_gate_state = false; // The button uses these two variables to make sure it only triggers on a button state change.
  278. bool previous_gate_state = false;
  279.  
  280. unsigned long buttonPress_startTime = 0; // This is to save a copy of the time that the button is pressed.
  281. unsigned long buttonRelease_startTime = 0; // This is to save a copy of the time that the buttn is released.
  282.  
  283.  
  284.  
  285.  
  286. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  287.  
  288. // function prototypes:
  289. void check_button(); // This checks if the button has been pressed.
  290. void check_button_debounce(); // If the button was pressed, this checks if it can be enabled again.
  291.  
  292. void open_the_gate(unsigned long); // This sets the gate state to "open".
  293. void close_the_gate(unsigned long); // This sets the gate state to "closed".
  294.  
  295.  
  296. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  297.  
  298. void setup() {
  299.   Serial.begin(9600);
  300.   pinMode(open_left_gate_relay_pin, OUTPUT);
  301.   pinMode(open_right_gate_relay_pin, OUTPUT);
  302.   pinMode(close_left_gate_relay_pin, OUTPUT);
  303.   pinMode(close_right_gate_relay_pin, OUTPUT);
  304.   pinMode(light_gate_relay_pin, OUTPUT);
  305.   pinMode(button_Pin, INPUT_PULLUP); // I changed this to input_pullup because that way you don't need an external pulldown resistor.
  306.   Serial.println("OK: exiting setup()");
  307. }
  308.  
  309. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  310.  
  311. void loop() {
  312.   if (button_enabled == true) { // This section only checks the button when it's not being de-bounced.
  313.     check_button();
  314.   }
  315.   else {
  316.     check_button_debounce();
  317.   }
  318.  
  319.   Open_right_gate_relay.checkRelay();
  320.   Open_left_gate_relay.checkRelay();
  321.   Close_right_gate_relay.checkRelay();
  322.   Close_left_gate_relay.checkRelay();
  323.   Flasher1.checkFlasher();
  324.  
  325. } // end of main loop()
  326.  
  327. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  328.  
  329. void check_button() {
  330.   // This checks if the button has been pressed.
  331.   current_buttonCheckTime = millis();
  332.   if (current_buttonCheckTime > previous_buttonCheckTime) {
  333.     if (current_buttonCheckTime > (previous_buttonCheckTime + buttonCheck_interval_milliseconds)) {
  334.       if (digitalRead(button_Pin) == LOW) { // If the button is being pressed...
  335.         if (current_gate_state == false) {
  336.           current_gate_state = true;
  337.           if (previous_gate_state == false) { // This check is to make sure that the code inside ONLY runs the first time that the button goes from low to high.
  338.             if (show_serialPrint_statements == true) {
  339.               Serial.println("button pressed"); // This tells when the button is pressed, but only once when it goes from un-pressed to pressed.
  340.             }
  341.             button_enabled = false; // This turns off the button check long enough to avoid any bouncing.
  342.             previous_gate_state = true; // This changes to true to prevent this code from running again, unless the button state goes from low to high again.
  343.             buttonPress_startTime = millis();
  344.             open_the_gate(buttonPress_startTime);
  345.           }
  346.         }
  347.       }
  348.       else { // If the button is NOT being pressed...
  349.         if (current_gate_state == true) {
  350.           if (previous_gate_state == true) {
  351.             // This section is what happens after the button is released.
  352.             previous_gate_state = false;
  353.             if (show_serialPrint_statements == true) {
  354.               Serial.println("button released"); // This tells when the button is released, but only once when it goes from pressed to released.
  355.             }
  356.             buttonRelease_startTime = millis(); // Save the time that the button was released.
  357.             close_the_gate(buttonRelease_startTime);
  358.           }
  359.           current_gate_state = false;
  360.         }
  361.       }
  362.       previous_buttonCheckTime = millis(); // Re-set the previous check time to now, since the button-press check was run.
  363.     }
  364.   }
  365.   else {
  366.     previous_buttonCheckTime = millis(); // millis() rollover condition
  367.   }
  368. }
  369.  
  370. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  371.  
  372. void check_button_debounce() {
  373.   // If the button was pressed, this checks if it can be enabled again after the debouncing time interval has passed.
  374.   current_buttonCheckTime = millis();
  375.   if (current_buttonCheckTime > buttonPress_startTime) {
  376.     if (current_buttonCheckTime > (buttonPress_startTime + button_debounce_time_milliseconds)) {
  377.       button_enabled = true;
  378.       if (show_serialPrint_statements == true) {
  379.         Serial.println("button debounce finished");
  380.       }
  381.     }
  382.   }
  383.   else {
  384.     buttonPress_startTime = millis(); // millis() rollover condition
  385.   }
  386. }
  387.  
  388. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  389.  
  390. void open_the_gate(unsigned long buttonPressedTime) {
  391.   if (show_serialPrint_statements == true) {
  392.     Serial.println("gate is opening");
  393.   }
  394.   Open_right_gate_relay.beginRelay(buttonPressedTime);
  395.   Open_left_gate_relay.beginRelay(buttonPressedTime);
  396.   Flasher1.beginFlasher(buttonPressedTime);
  397. }
  398.  
  399. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  400.  
  401. void close_the_gate(unsigned long buttonReleasedTime) {
  402.   // If the open-relays are not totally finished when the button is released.
  403.   // they they get shut off before turning on the closing relays.
  404.   if (show_serialPrint_statements == true) {
  405.     Serial.println("gate is closing");
  406.   }
  407.   if (Open_right_gate_relay.relay_mode != 0) {
  408.     Open_right_gate_relay.relay_mode = 3; // mode 3 is the relay turning-off mode
  409.   }
  410.   if (Open_left_gate_relay.relay_mode != 0) {
  411.     Open_left_gate_relay.relay_mode = 3; // mode 3 is the relay turning-off mode
  412.   }
  413.   Close_right_gate_relay.beginRelay(buttonReleasedTime);
  414.   Close_left_gate_relay.beginRelay(buttonReleasedTime);
  415.   Flasher1.shutDownFlasher(buttonReleasedTime);
  416. }
  417.  
  418.  
  419.  
  420. // ~~~~~~~ [end] ~~~~~~~~~~
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement