const uint16_t BLINK_INTERVAL = 500; // Time interval between toggling LED1 in milliseconds
const uint16_t ALARM_INTERVAL = 3000; // Time interval between toggling LED1 in milliseconds
const uint32_t SOLENOID_INTERVAL = 15000; // Interval_SOLENOID = 86400000 and will be set to 05:30 AM
const uint8_t all_safe_LED = 7; // The all_safe_LED is connected to pin 13
const uint8_t alert_LED = 12; // The alert_LED is connected to pin 12
const uint8_t activate_Sirene = 11; // The activate_Sirene is connected to pin 11
const uint8_t door_Switch = 10; // door_Switch is connected to pin 10
const uint8_t reset_Switch = 9; // Reset_Switch is connected to pin 9
const uint8_t relay_Solenoid = 8; // Relay sensor to activate solenoid on pin 8
const byte opened_HIGH = HIGH; // constants used for door-switch-state
const byte closed_LOW = LOW;
// constants for the states (can be changed to enum)
const byte doorClosed = 0;
const byte checkDoorOpenTime = 1;
const byte doorOpenAlarm = 2;
const byte checkDoorClosed = 3;
// array with names of the states
const char myStateNames[][24] = {
"doorClosed",
"checkDoorOpenTime",
"doorOpenAlarm",
"checkDoorClosed"
};
byte doorControlState = checkDoorOpenTime;
// variables for non-blocking timing based on millis()
unsigned long doorOpenTimer;
unsigned long blinkTimer;
unsigned long alarmTimer;
unsigned long beepOnOffTimer;
unsigned long MyTestTimer = 0; // Timer-variables MUST be of type unsigned long
const byte OnBoard_LED = 13;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
PrintFileNameDateTime();
pinMode(all_safe_LED, OUTPUT); // Configure all_safe_LED pin as a digital output
pinMode(alert_LED, OUTPUT); // Configure alert_LED pin as a digital output
pinMode(activate_Sirene, OUTPUT); // Configure activate_Sirene pin as a digital output
pinMode(door_Switch, INPUT); // Configure door_Switch pin as a digital input
pinMode(reset_Switch, INPUT); // Configure reset_Switch pin as a digital input
pinMode(relay_Solenoid, OUTPUT); // SOLENOID
digitalWrite(all_safe_LED, LOW); // Set all_safe_LED low initially
digitalWrite(alert_LED, LOW); // Set alert_LED low initially
digitalWrite(activate_Sirene, LOW); // Set activate_Sirene low initially
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 250);
// all the time keep on checking if door is closed
// if door is opened do all the things related to this
// green LED off, blink red led, let alarm beep etc.
checkDoorStatus();
}
void checkDoorStatus() {
printStateIfChanged();
// whenever door is closed
if (digitalRead(door_Switch) == closed_LOW) {
doorControlState = doorClosed;
}
switch (doorControlState) {
// mutually exclusive execute code below case
case doorClosed:
// check if door is opened
if (digitalRead(door_Switch) == opened_HIGH) {
Serial.println("state doorClosed - door open HIGH detected!");
digitalWrite(all_safe_LED, LOW);
blinkTimer = millis();
doorOpenTimer = millis();
doorControlState = checkDoorOpenTime;
}
else { // when door closed
digitalWrite(all_safe_LED, HIGH); // switch on green LED
digitalWrite(alert_LED,LOW); // switch off red LED
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
// mutually exclusive execute code below case
case checkDoorOpenTime:
// blink red LED
if ( TimePeriodIsOver(blinkTimer, BLINK_INTERVAL) ) {
digitalWrite(alert_LED, !digitalRead(alert_LED) ); // invert IO-pin with the NOT-operator
}
// check if door is opened for more than 10 seconds
// check if more than 10000 milliseconds have passed by
if ( TimePeriodIsOver(doorOpenTimer, 10000) ) {
// when REALLY more than 10000 milliseconds HAVE passed by
Serial.println("state checkDoorOpenTime - door open-HIGH too long beeping");
digitalWrite(alert_LED, HIGH);
beepOnOffTimer = millis();
alarmTimer = millis();
// doorOpenTimer = millis();
doorControlState = doorOpenAlarm;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
// mutually exclusive execute code below case
case doorOpenAlarm:
// switch on/off sirene every 250 milliseconds = beep at 2 Hz
if ( TimePeriodIsOver(beepOnOffTimer, 250) ) {
digitalWrite(activate_Sirene, !digitalRead(activate_Sirene) );
}
// beep for 3 seconds
// check if 3000 milliseconds have passed by
if ( TimePeriodIsOver(alarmTimer, 3000) ) {
// when 3000 milliseconds REALLY have passed by
Serial.println("beepingtime 3 seconds over");
digitalWrite(activate_Sirene,LOW); // switch beeper off
doorControlState = checkDoorClosed;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
// mutually exclusive execute code below case
case checkDoorClosed:
// check if door is opened for more than 10 seconds
// check if more than 10000 milliseconds have passed by
if ( TimePeriodIsOver(doorOpenTimer, 10000) ) {
// when REALLY more than 10000 milliseconds have passe by
Serial.println("door opened for more than 10 seconds");
Serial.println("repeat alarm sequence blink then beep");
alarmTimer = millis();
blinkTimer = millis();
doorOpenTimer = millis();
doorControlState = checkDoorOpenTime; // repeat blinking and alarm-beeping
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
} // END-OF-SWITCH
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
// helper-function that prints the name of the states ONE time
// only in case the state has changed
void printStateIfChanged() {
static byte lastState;
if (lastState != doorControlState) {
Serial.print("state changed from ");
Serial.print(myStateNames[lastState]);
Serial.print(" to ");
Serial.println(myStateNames[doorControlState]);
lastState = doorControlState; // update variable lastState
}
}