/* HOW TO USE:
*
* Arm the alarm by flipping the Key-Switch to the down-position
* Trigger the alarm by pressing the "Tür-Kontaktschalter" when the Key-Switch is flipped
* When the alarm is active, the LED1 on the Relay should blink, indicating the state of the relay
* Deactivate the active alarm by toggling the Key-Switch to the up-position
* Or wait for the alarm to time out (currently after 30 seconds)
* After an alarm timeout, you have to re-arm the alarm by disarming and arming it again (flipping the Key-Switch up and down)
*/
// Define the pins
#define RELAY_PIN 16
//#define RELAY_PIN_2 17 // Not used
#define KEY_SWITCH_PIN 22
#define DOOR_PIN 19
#define LED_PIN 23
#define SLEEP_BUTTON_PIN 18
// Suggested by RenzGPT
#define ALARM_IS_ARMED HIGH // Alarm is armed when the Key-Circuit is closed
#define ALARM_IS_TRIGGERED LOW // Alarm is triggert when the Door-Circuit is closed
// Define the duration for which the relay should stay active (in milliseconds)
const uint32_t RELAY_TOGGLE_INTERVAL = 400; // 0.4 seconds
const uint32_t ALARM_MAX_ACTIVE_TIME = 10000; // 30 seconds (maybe increase to 5-10 Minutes)
// Variables to keep track of the state and timing
uint32_t alarm_activated_time = 0;
uint32_t relay_last_toggle_time = 0;
bool alarm_active = false;
bool relay_state = false;
bool alarm_timed_out = false;
// State machine states
enum AlarmState {
ALARM_DEACTIVATED,
ALARM_ARMED,
ALARM_ACTIVE,
ALARM_ACTIVE_COUNTDOWN,
ALARM_TIMEOUT,
};
AlarmState current_state = ALARM_DEACTIVATED;
void setup() {
Serial.begin(115200);
Serial.println("Alarm-System is started!");
// Initialize the pins
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(KEY_SWITCH_PIN, INPUT_PULLUP);
pinMode(DOOR_PIN, INPUT_PULLUP);
pinMode(SLEEP_BUTTON_PIN, INPUT_PULLUP);
// Make sure the relay is off initially
digitalWrite(RELAY_PIN, LOW);
digitalWrite(LED_PIN, HIGH);
}
void enter_ALARM_DEACTIVATED(){
current_state = ALARM_DEACTIVATED;
Serial.println("ALARM_DEACTIVATED");
}
void enter_ALARM_ARMED(){
current_state = ALARM_ARMED;
Serial.println("ALARM_ARMED");
}
void enter_ALARM_ACTIVE(){
current_state = ALARM_ACTIVE;
relay_state = true;
relay_last_toggle_time = millis();
Serial.println("ALARM_ACTIVE");
}
void enter_ALARM_ACTIVE_COUNTDOWN(){
current_state = ALARM_ACTIVE_COUNTDOWN;
alarm_activated_time = millis();
Serial.println("ALARM_ACTIVE_COUNTDOWN");
}
void enter_ALARM_TIMEOUT(){
current_state = ALARM_TIMEOUT;
Serial.println("ALARM_TIMEOUT");
}
void loop() {
// Read the state of the key switch and the door
bool key_switch_state = digitalRead(KEY_SWITCH_PIN);
bool door_state = digitalRead(DOOR_PIN);
bool sleep_button_state = digitalRead(SLEEP_BUTTON_PIN);
if(sleep_button_state == 0){
digitalWrite(RELAY_PIN, HIGH);
}else{
// State machine handling
switch (current_state) {
case ALARM_DEACTIVATED:
// Set variables for ALARM_DEACTIVATED state
alarm_active = false;
relay_state = false;
alarm_timed_out = false;
// Switch to ALARM_ARMED state if the Key-Switch is activated
if(key_switch_state == ALARM_IS_ARMED)
enter_ALARM_ARMED();
break;
case ALARM_ARMED:
// Set variables for ALARM_ARMED state
alarm_active = false;
relay_state = false;
alarm_timed_out = false;
// Switch to ALARM_DEACTIVATED state if the Key-Switch is deactivated
if(key_switch_state != ALARM_IS_ARMED)
enter_ALARM_DEACTIVATED();
// Switch to ALARM_ACTIVE state if the Door-Circuit is activated
else if(door_state == ALARM_IS_TRIGGERED)
enter_ALARM_ACTIVE();
break;
case ALARM_ACTIVE:
// Set variables for ALARM_ACTIVE state
alarm_active = true;
alarm_timed_out = false;
// Toggle the relay_state when Timer
if(millis() >= relay_last_toggle_time + RELAY_TOGGLE_INTERVAL){
// Toggle Relay State
relay_state = !relay_state;
relay_last_toggle_time = millis();
}
// Switch to ALARM_DEACTIVATED state if the Key-Switch is deactivated
if(key_switch_state != ALARM_IS_ARMED)
enter_ALARM_DEACTIVATED();
// Switch to ALARM_TIMEOUT state if the ALARM_ACTIVE state is longer active than ALARM_MAX_ACTIVE_TIME
else if(door_state != ALARM_IS_TRIGGERED)
enter_ALARM_ACTIVE_COUNTDOWN();
break;
case ALARM_ACTIVE_COUNTDOWN:
// Set variables for ALARM_ACTIVE state
alarm_active = true;
alarm_timed_out = false;
// Toggle the relay_state when Timer
if(millis() >= relay_last_toggle_time + RELAY_TOGGLE_INTERVAL){
// Toggle Relay State
relay_state = !relay_state;
relay_last_toggle_time = millis();
}
//The Alarm was triggered again. Reset the Cooldown
if(door_state == ALARM_IS_TRIGGERED)
enter_ALARM_ACTIVE();
// Switch to ALARM_DEACTIVATED state if the Key-Switch is deactivated
else if(key_switch_state != ALARM_IS_ARMED)
enter_ALARM_DEACTIVATED();
// Switch to ALARM_TIMEOUT state if the ALARM_ACTIVE state is longer active than ALARM_MAX_ACTIVE_TIME
else if(millis() >= alarm_activated_time + ALARM_MAX_ACTIVE_TIME)
enter_ALARM_ARMED();
break;
/*
case ALARM_TIMEOUT:
alarm_active = false;
relay_state = false;
alarm_timed_out = false;
// Switch to ALARM_DEACTIVATED state if the Key-Switch is deactivated
if(key_switch_state != ALARM_IS_ARMED)
enter_ALARM_DEACTIVATED();
break;
*/
default:
enter_ALARM_DEACTIVATED();
break;
}
// Write Relay State
digitalWrite(RELAY_PIN, relay_state);
}
}