I prefer a state machine approach. Like this:
//Import Libraries
#include <ezButton.h>
// Map constant names to IO pins
const byte Furnace_Rly = 13;
const byte LightOn_Rly = 12;
const byte LightOff_Rly = 11;
const byte Door1_Rly = 10;
const byte Door2_Rly = 9;
const byte Door3_Rly = 8;
const byte Door4_Rly = 7;
const unsigned long ResponseTime = 20UL*60UL* 1000UL;
const unsigned long TimeDoorsOpen = 900UL*1000UL; // This is the time in milliseconds that the doors will remain open
unsigned long SystemActivatedTime;
unsigned long DoorOpenTime;
// Define EZButton
ezButton Door1_Sen(6);
ezButton Door2_Sen(5);
ezButton Door3_Sen(4);
ezButton Door4_Sen(3);
ezButton Tone_Sen(2);
ezButton Motion_Sen(1);
// Create System Variables
int Door1_State; // State of the door sensor
int Door2_State; // State of the door sensor
int Door3_State; // State of the door sensor
int Door4_State; // State of the door sensor
void setup()
{
// Setup EZButton
Door1_Sen.setDebounceTime(250); // set debounce time to 250 milliseconds
Door2_Sen.setDebounceTime(250); // set debounce time to 250 milliseconds
Door3_Sen.setDebounceTime(250); // set debounce time to 250 milliseconds
Door4_Sen.setDebounceTime(250); // set debounce time to 250 milliseconds
Tone_Sen.setDebounceTime(250); // set debounce time to 250 milliseconds
Motion_Sen.setDebounceTime(250); // set debounce time to 250 milliseconds
// Setup IO pins
pinMode(Furnace_Rly, OUTPUT); // Relay to turn the furnace off
pinMode(LightOn_Rly, OUTPUT); // Override Light On Control Relay
pinMode(LightOff_Rly, OUTPUT); // Ovveride Light Off Control Relay
pinMode(Door1_Rly, OUTPUT); // Bay 1 Door Relay
pinMode(Door2_Rly, OUTPUT); // Bay 2 Door Relay
pinMode(Door3_Rly, OUTPUT); // Bay 3 Door Relay
pinMode(Door4_Rly, OUTPUT); // Bay 4 Door Relay
}
enum States {IDLE,WaitingForMotion,ALARM,OpenAllDoors,WaitingForClose,CloseAllDoors};
States State;
void loop()
{
HandleButtons();
switch(State)
{
case IDLE:
if (Tone_Sen.isReleased())
{
SystemActivatedTime=millis();
digitalWrite(LightOn_Rly, HIGH); // Turn Lights On
State=WaitingForMotion;
}
break;
case WaitingForMotion:
if (Motion_Sen.isReleased())
{
State=OpenAllDoors;
}
if(millis()-SystemActivatedTime>ResponseTime)
State=IDLE;
break;
case OpenAllDoors:
digitalWrite(Furnace_Rly, HIGH); //Furnace off
OpenTheDoors();
DoorOpenTime=millis();
State=WaitingForClose;
break;
case WaitingForClose:
if(millis()-DoorOpenTime > TimeDoorsOpen)
State=CloseAllDoors;
break;
case CloseAllDoors:
FlashLights();
CloseTheDoors();
digitalWrite(Furnace_Rly, LOW); //Furnace back on
State=IDLE;
break;
default:
break;
}
}
void HandleButtons()
{
// EZButton
Door1_Sen.loop();
Door2_Sen.loop();
Door3_Sen.loop();
Door4_Sen.loop();
Tone_Sen.loop();
Motion_Sen.loop();
}
void OpenTheDoors()
{
// System Activation by Tone, don't reactivate within 15 seconds
// Trigger Doors open when motion is sensed within the response time
// Read Door Sensors
Door1_State = Door1_Sen.getState();
Door2_State = Door2_Sen.getState();
Door3_State = Door3_Sen.getState();
Door4_State = Door4_Sen.getState();
if (Door1_State == LOW) // Sense if Door 1 is Open
{
digitalWrite(Door1_Rly, HIGH); // Open Door 1 if not open
}
if (Door2_State == LOW) // Sense if Door 2 is Open
{
digitalWrite(Door2_Rly, HIGH); // Open Door 2 if not open
}
if (Door3_State == LOW) // Sense if Door 3 is Open
{
digitalWrite(Door3_Rly, HIGH); // Open Door 3 if not open
}
if (Door4_State == LOW) // Sense if Door 4 is Open
{
digitalWrite(Door4_Rly, HIGH); // Open Door 4 if not open
}
delay(750); // Wait for 750 millisecond(s)
digitalWrite(Door1_Rly, LOW); // Close door switch after a delay
digitalWrite(Door2_Rly, LOW); // Close door switch after a delay
digitalWrite(Door3_Rly, LOW); // Close door switch after a delay
digitalWrite(Door4_Rly, LOW); // Close door switch after a delay
}
void FlashLights()
{
for(int lp=0;lp < 10;lp++)
{
digitalWrite(LightOff_Rly, HIGH); // Switch the lights off override on
delay(900);
digitalWrite(LightOff_Rly, LOW); // Switch the lights off override off
delay(900);
}
}
void CloseTheDoors()
{
if (Door1_State == HIGH) // Sense if Door 1 is Closed
{
digitalWrite(Door1_Rly, HIGH); // Close Door 1 if not Closed
}
if (Door2_State == HIGH) // Sense if Door 2 is Closed
{
digitalWrite(Door2_Rly, HIGH); // Close Door 2 if not Closed
}
if (Door3_State == HIGH) // Sense if Door 3 is Closed
{
digitalWrite(Door3_Rly, HIGH); // Close Door 3 if not Closed
}
if (Door4_State == HIGH) // Sense if Door 4 is Closed
{
digitalWrite(Door4_Rly, HIGH); // Close Door 4 if not Closed
}
delay(750);
digitalWrite(Door1_Rly, LOW); // Close door switch after a delay
digitalWrite(Door2_Rly, LOW); // Close door switch after a delay
digitalWrite(Door3_Rly, LOW); // Close door switch after a delay
digitalWrite(Door4_Rly, LOW); // Close door switch after a delay
}