Adding Relay to a working project (Home security Alarm)

Hi everyone.
I am new at the forum, but these days i spend great time with arduino. It is very interesting to me, so i hope that will be active and contribute to the community.

Now the "Problem" that i have.

I am willing to make arduino home security alarm with door sensor, keypad and display.
I have managed to connect all of these items to the ardunio board and (long story short) i have made THIS project. I have made some changes to the code to work with the I2C display instead the regular one (big thing for me as a beginner, and it was successfull :slight_smile: ). It is working great with the buzzer alarming if the intruder gets into the house and don't enter the password, BUT i am willing to insert big 12v siren trough relay.

I have experience with connecting electronics but minimal with programming. So, for example, i would like to add relay on pin xx that will be activated at the "Alarmfunction" but i don't know how to do it.

Here is the code that is working, and needs to be "upgraded" with the relay option.
Can you help?

Since there is limitation on the length of the post, i will split the code into several posts

#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <NewPing.h>
#include "NewTone.h"

/*-----------------------KEYPAD-----------------------*/
const byte numRows= 4; //number of rows on the keypad
const byte numCols= 4; //number of columns on the keypad
char keypressed;
//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols]=
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {9, 8, 7, 6};//Rows 0 to 3
byte colPins[numCols] = {5, 4, 3, 2};//Columns 0 to 3             
//initializes an instance of the Keypad class
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

/*--------------------------CONSTANTS-------------------------*/
const int buzzer = A1;      //Buzzer/small speaker
const int doorMagSen = 10;    //Door magnetic sensor
const int windowMagSen = 11; //Window magnetic sensors
LiquidCrystal_I2C lcd(0x27, 16, 2);  
NewPing sonar(A0,A0,2000); // Trig Echo Max distance
/*--------------------------VARIABLES------------------------*/
String password="2580"; //Variable to store the current password
String tempPassword=""; //Variable to store the input password
int doublecheck;
boolean armed = false;  //Variable for system state (armed:true / unarmed:false)
boolean input_pass;   //Variable for input password (correct:true / wrong:false)
boolean storedPassword = true;
boolean changedPassword = false;
boolean checkPassword = false;
int distance;
int i = 1; //variable to index an array

/**********************************************************************************/

void setup() {
  lcd.init(); 
  lcd.backlight();
  pinMode(doorMagSen,INPUT_PULLUP);       //Set all magnetic sensors as input withn internal pullup resistor
  pinMode(windowMagSen,INPUT_PULLUP);
}

void loop() { //Main loop
  if (armed){
    systemIsArmed();  //Run function to activate the system
  }
  else if (!armed){
    systemIsUnarmed();  //Run fuction to de activate the system
  }
}

/********************************FUNCTIONS************************************/

//While system is unarmed
void systemIsUnarmed(){
  int screenMsg=0;
  lcd.clear();                  //Clear lcd
  unsigned long previousMillis = 0;           //To make a delay by using millis() function
  const long interval = 5000;           //delay will be 5 sec. 
                          //every "page"-msg of lcd will change every 5 sec
  while(!armed){                  //While system is unarmed do...
    unsigned long currentMillis = millis();   //Store the current run-time of the system (millis function)
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        if(screenMsg==0){           //First page-message of lcd
        lcd.setCursor(0,0);
        lcd.print("SYSTEM ALARM OFF");
        lcd.setCursor(0,1);
        lcd.print("----------------");
        screenMsg=1;
        }
        else{                 //Second page-message of lcd
          lcd.setCursor(0,0);
          lcd.print("A to arm        ");
          lcd.setCursor(0,1);
        lcd.print("B to change pass");
        screenMsg=0;
        }
      }
    keypressed = myKeypad.getKey();       //Read the pressed button
    if (keypressed =='A'){            //If A is pressed, activate the system
      NewTone(buzzer,500,200);
      systemIsArmed();            //by calling the systemIsArmed function
    }
    else if (keypressed =='B'){//If B is pressed, change current password
      doublecheck=0;
      NewTone(buzzer,500,200);
      storedPassword=false;
      if(!changedPassword){         //By calling the changePassword function
        changePassword();
      }
    }
  }
}

The rest

//While system is armed
void systemIsArmed(){               
  lcd.clear();
  int count=10;               //Count 10sec before activate
  unsigned long previousMillis = 0;         
  const long interval = 1000; 
  while(!armed){    
    distance = sonar.ping_cm(); //Store distance from sensor only for first time
    //While system is unarmed - for 10sed do...
    lcd.setCursor(0,0);
    lcd.print(" SYSTEM WILL BE ");      //Print message to lcd with 10 sec timer
    lcd.setCursor(0,1);
    lcd.print("   ARMED IN ");
    unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        //Screen counter 10sec
        if (count>1){
        count--;            //Countdown timer
        }
        else{
          armed=true;           //Activate the system!
        break;
        }
      }
    lcd.setCursor(12,1);
    lcd.print(count);           //show the timer at lcd second line 13 possition 
  }
  while (armed){                //While system is armed do...
    lcd.setCursor(0,0);
    lcd.print("SYSTEM IS ARMED!");
    lcd.setCursor(0,1);
    lcd.print("----------------");
    int door = digitalRead(doorMagSen);   //Read magnetic sensros and ultrasonic sensor
    int window = digitalRead(windowMagSen);
    int curr_distanse = sonar.ping_cm();

    //Check values
    if (window==HIGH){
      alarmFunction(); //Call alarm!
    } 
    if (door==HIGH){
      unlockPassword(); //Disarm the system with correct password
    }
        //Ultrasonic sensor code
    if (curr_distanse < (distance -5)){ //Check distanse (minus 5 for safety) with current distanse
      alarmFunction();
    }
  }
}
//Door is opend, unlcok the system!
void unlockPassword() {
  int count=16;             //20 sec for alarm!
  retry:                  //label for goto, retry in case of wrong password
    tempPassword="";            //reset temp password (typing...)
  lcd.clear();              //clear lcd
  i=6;                  //variable to put * while typing pass
  unsigned long previousMillis = 0;       
  const long interval = 1000;
  boolean buzzerState = false;      //variable to help us make  a beep NewTone
  while(!checkPassword){          //While waiting for correct password do...
    unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis; //play beep NewTone every 1 sec
        if (!buzzerState){
          NewTone(buzzer, 700);
          buzzerState=true;
        }
        else{
          noNewTone(buzzer);
          buzzerState=false;
        }
        if (count>0){           //Screen counter 20sec
        count--;
        }
        else{
          alarmFunction();      //Times is up, ALARM!
          break;
        }
      }
    keypressed = myKeypad.getKey();
    lcd.setCursor(0,0);
    lcd.print("ALARM IN: "); 
    //For screen counter - 20sec
    if (count>=10){
      lcd.setCursor(14,0);
      lcd.print(count);       //print countdown timer at lcd
    }
    else{               //catch '0'bellow 10 (eg 09)
      lcd.setCursor(14,0);
      lcd.print(" ");
      lcd.print(count);
    }
    lcd.setCursor(0,1);
    lcd.print("PASS>");
    if (keypressed != NO_KEY){      //Accept only numbers and * from keypad
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
      keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
      keypressed == '8' || keypressed == '9' ){
        tempPassword += keypressed;
        lcd.setCursor(i,1);
        lcd.print("*");       //Put * on lcd
        i++;
        NewTone(buzzer,500,200);    //Button NewTone
      }
      else if (keypressed == '*'){  //Check for password
        if (password==tempPassword){//If it's correct unarmed the system
          armed=false;
          NewTone(buzzer,700,500);
          break;
        }
        else{           //if it's false, retry
          tempPassword="";
          NewTone(buzzer,200,200);
          delay(300);
          NewTone(buzzer,200,200);
          delay(300);
          goto retry;
        }
      }
    }
  } 
  
}

//Alarm
void alarmFunction(){
  retry: //label for goto
  tempPassword="";
  lcd.clear();
  i=6;
  unsigned long previousMillis = 0;       
  const long interval = 500;
  boolean buzzerState = false;
  while(!checkPassword){          //Waiting for password to deactivate the alarm...
    unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis; //Play a beep NewTone every 0.5 second
        if (!buzzerState){
          NewTone(buzzer, 700);
          buzzerState=true;
        }
        else{
          noNewTone(buzzer);
          buzzerState=false;
        }
      }
    keypressed = myKeypad.getKey();
    lcd.setCursor(0,0);
    lcd.print("  !!! ALARM !!! "); 
    lcd.setCursor(0,1);
    lcd.print("PASS>");
    if (keypressed != NO_KEY){      //Accept only numbers and *
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
      keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
      keypressed == '8' || keypressed == '9' ){
        tempPassword += keypressed;
        lcd.setCursor(i,1);
        lcd.print("*");
        i++;
      }
      else if (keypressed == '*'){
        if (password==tempPassword){
          armed=false;
          NewTone(buzzer,700,500);
          break;
        }
        else{
          tempPassword="";
          NewTone(buzzer,200,200);
          delay(300);
          NewTone(buzzer,200,200);
          delay(300);
          goto retry;
        }
      }
    }
  } 
}
//Change current password
void changePassword(){
  retry: //label for goto
  tempPassword="";
  lcd.clear();
  i=1;
  while(!changedPassword){  
    keypressed = myKeypad.getKey();   //Read pressed keys
    lcd.setCursor(0,0);
    lcd.print("CURRENT PASSWORD");
    lcd.setCursor(0,1);
    lcd.print(">");
    if (keypressed != NO_KEY){
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
      keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
      keypressed == '8' || keypressed == '9' ){
        tempPassword += keypressed;
        lcd.setCursor(i,1);
        lcd.print("*");
        i++;
        NewTone(buzzer,800,200);        
      }
      else if (keypressed=='#'){
        break;
      }
      else if (keypressed == '*'){
        i=1;
        if (password==tempPassword){
          storedPassword=false;
          NewTone(buzzer,500,200);
          newPassword();
          break;
        }
        else{               //Try again
          tempPassword="";
          NewTone(buzzer,500,200);
          delay(300);
          NewTone(buzzer,500,200);
          delay(300);
          goto retry;
        }
      }
    }
  }
}
String firstpass;
//Setup new password
void newPassword(){
  tempPassword="";
  changedPassword=false;
  lcd.clear();
  i=1;
  while(!storedPassword){
    keypressed = myKeypad.getKey(); 
    if (doublecheck==0){
      lcd.setCursor(0,0);
      lcd.print("SET NEW PASSWORD");
      lcd.setCursor(0,1);
      lcd.print(">");
    }
    else{
      lcd.setCursor(0,0);
      lcd.print("One more time...");
      lcd.setCursor(0,1);
      lcd.print(">");
    }
    if (keypressed != NO_KEY){
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
      keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
      keypressed == '8' || keypressed == '9' ){
        tempPassword += keypressed;
        lcd.setCursor(i,1);
        lcd.print("*");
        i++;
          NewTone(buzzer,800,200);
      }
      else if (keypressed=='#'){
        break;
      }
      else if (keypressed == '*'){
        if (doublecheck == 0){
          firstpass=tempPassword;
          doublecheck=1;
          newPassword();
        }
        if (doublecheck==1){
          doublecheck=0;
          if (firstpass==tempPassword){
            i=1;
            firstpass="";
            password = tempPassword; 
            tempPassword="";//erase temp password
            lcd.setCursor(0,0);
            lcd.print("PASSWORD CHANGED");
            lcd.setCursor(0,1);
            lcd.print("----------------");
              storedPassword=true;
              NewTone(buzzer,500,400);
              delay(2000);
              lcd.clear();
              break;
          }
          else{
            firstpass="";
            newPassword();
          }
        }
      } 
    }
  }
}
If (buzzerState == true){
Pinxx = HIGH;

Initiate pin xx to low at beginning
Attach pin xx To a logic level relay Board and off you go.

If I understand then this will turn your relay on when your alarm is functioning I.e. buzzer is on
Warning. I’m an amateur so just saying my thoughts.

Many factory made relay modules are "LOW true" meaning that the relay coil is energized when the input pin is LOW instead of HIGH. Keep that in mind in your design.

pmagowan:

If (buzzerState == true){

Pinxx = HIGH;



Initiate pin xx to low at beginning 
Attach pin xx To a logic level relay Board and off you go.

If I understand then this will turn your relay on when your alarm is functioning I.e. buzzer is on
Warning. I’m an amateur so just saying my thoughts.

Thanks for the reply.

If you can search the code, "buzzerState" also can be found as variable on the door opening event, so the relay may be turned on also there where it should be off.

As i am writing, you gave me an idea playing with alarmfunction instead buzzerstate, so please tell me if it is possible realizing.
Can i put code something like

If (alarmfunction == true){
Pinxx = HIGH;

Thanks.

JCA34F:
Many factory made relay modules are "LOW true" meaning that the relay coil is energized when the input pin is LOW instead of HIGH. Keep that in mind in your design.

Yes, i am native with this since i had one day headache with relay that did not wanted to turn on on HIGH :slight_smile: . Then i realized that i had LOW true relay module.

Obviously you must have a state somewhere that relates to when your alarm is sounding. All you need to do is link this state to the pin you use to drive the relay.

If you buy an appropriate relay board then its specs will tell you if it is driven by low or high signal.

you need to define your relayPin eg

const int relayPin = xx;

set the pinmode in setup. Here it is HIGH

pinMode (relayPin, OUTPUT);
relayPin = HIGH;

Then bind it to your alarm state

if (alarmfunction == TRUE){
relayPin = LOW;
}
else {
relayPin == HIGH;
}

That is my take on it but I am a beginner

MADE IT!!!!

I was like

And my wife was looking at me like WTF :slight_smile:

What i have done?
At the start, i defined the pin and pinMode.

Next, just by realizing how it works, i put the relay LOW on the "unarmed" state, and put the relay HIGH on the "alarmstate". Everything works like a charm. Thanks @pmagowan

pmagowan:
Thanks

One thing, the logical constants true and false that are built in to C, are lower case 'true' and 'false'. Not 'TRUE' and 'FALSE'.