Hi all,
I found an excellent home alarm system wrote by Steven Bell at the following site:https://create.arduino.cc/projecthub/thestevenbell/arduino-alarm-system-db084a
The problem I have though, is that the alarm alerts only for as long as the PIR outputs a high signal. Ideally, in a home alarm the alarm should alert for a fixed period of time (eg. 5 minutes), or until manually deactivated with a code within the 5 minute period.
What I thus need is for the alarm to latch onto a alerting state for a fixed period of time. I have tried using the millis function, but as a newcomer to that function, I have not been able to make it work (after a week of trying different ways) I realize the sketch employs advanced programming techniques, thus I am at a loss to figure out exactly where to use the millis function, as it should start counting when the alarm is triggered.
I have considered using a discrete timer (555 timer, controlled by the Arduino), but that adds too much complexity to the project, a programmatical method is simpler.
The use of Delay is not practical in this case, as it blocks the disarming of the alarm by entering a code.
All advice will be greatly appreciated.
The code is below
Start your code here
/*
* LCD backpack SDA pin to analog pin A4 (on Nano)
* LCD backpack SDL pin to analog pin A5 (on Nano)
* LCD VCC pin to 5V
* LCD GND pin to GND
*/
#include <TwiLiquidCrystal.h>
TwiLiquidCrystal lcd(0x27);
//#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
// LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
//LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
boolean doInitilizeLCD = true;
// –KEY PAD START —————————————————-
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the symbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{‘1’, ‘2’, ‘3’, ‘A’},
{‘4’, ‘5’, ‘6’, ‘B’},
{‘7’, ‘8’, ‘9’, ‘C’},
{‘*’, ‘0’, ‘#’, ‘D’}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
char customKey;
char accessCode[] = “9113”;
char keyPadInput[] = “zzzz”;
unsigned char inputCounter = 0;
unsigned char inputMaxCount = 4;
// –KEY PAD END ——————————————————
int ledPin = 11; // LED on Pin 11, lights up when PIR is active and armed.
int powerledPin = 13; // LED on Pin 13, indicates power on, always HIGH
int pirPin = 10; // Input for HC-S501
int pirValue; // Place to store read PIR Value
int doorPin = A0; // door magnetic switch
int doorValue; // Place to store read magnetic switch Value
int alarmPin = A2; // Relay to switch siren
int statusPin = A3; // LED on Pin A3, lights up when PIR is active, must be off before arming.
// –Active Buzzer START ———————————————-
int buzzer = 12;//the pin of the active buzzer
boolean shouldBeAlerting = false;
// –Active Buzzer END ——————————————————
enum ArmedStates {ARMED, DISARMED};
ArmedStates armedState = DISARMED;
short armedTimerInterval = 5;
unsigned long armedTimer = millis();
unsigned long previousMillis1 = 0;
unsigned long startMillis = 0;
unsigned long currentMillis;
//const unsigned long delayTime = 600000;
bool debug = false;
void setup() {
Serial.begin(9600);
while (!Serial); // wait for Serial to connect
Serial.println(“ready”);
pinMode(buzzer, OUTPUT); // set up pin as output
pinMode(ledPin, OUTPUT); // set up pin as output
pinMode(powerledPin, OUTPUT); // set pin as output
pinMode(alarmPin, OUTPUT); // set pin as output
pinMode(pirPin, INPUT); // set pin as input
pinMode(doorPin, INPUT); // set pin as input
pinMode(statusPin, OUTPUT); // set pin as output
lcd.begin(16, 2); // set up and register the LCD
lcd.backlight();
//startMillis = millis(); //initial start time
}
void loop() {
digitalWrite(powerledPin, HIGH);
if (pirValue==HIGH) {
digitalWrite(statusPin, HIGH);
} else {
digitalWrite(statusPin, LOW);
}
initilizeLCD();
handleKeyPadInput();
handlePIR();
alert();
//handleAlarm;
}
const char* getStateString(enum ArmedStates armedState) {
switch (armedState)
{
case ARMED: return “ARMED”;
case DISARMED: return “DISARMED”;
}
}
//
void initilizeLCD() {
if (doInitilizeLCD) {
doInitilizeLCD = false;
lcd.clear();
String a = getStateString(armedState);
if (debug) {
Serial.println(“armedState: ” + a);
}
lcd.setCursor(0, 0);
lcd.print(a);
lcd.setCursor(0, 1);
lcd.print(“PRESS * to ARM.”);
}
}
void handleLCD(bool shouldClearLCD) {
if (shouldClearLCD) {
lcd.clear();
}
String a = getStateString(armedState);
if (debug) {
Serial.println(“armedState: ” + a);
}
lcd.setCursor(0, 0);
lcd.print(a);
lcd.setCursor(0, 1);
lcd.print(“DISARM KEY:”);
uint8_t cursorStart = 11;
lcd.setCursor(cursorStart, 1);
lcd.cursor();
// overwrites the LCD screen positions with blank space or keypad input
for (int i = 0; i < 4; i++) {
if (keyPadInput[i] == ‘z’) {
lcd.setCursor(cursorStart + i, 1);
lcd.print(” “);
} else {
lcd.setCursor(cursorStart + i, 1);
lcd.print(keyPadInput[i]);
}
}
}
void handleKeyPadInput() {
customKey = customKeypad.getKey();
if (customKey) {
Serial.print(“customKey: “);
Serial.println(customKey);
if (armedState == DISARMED ) {
if (customKey == ‘*’) {
armedState = ARMED;
handleLCD(true);
//delay (30000);
}
} else {
if (customKey == ‘*’) {
resetCodeInput();
} else if (customKey == ‘#’) {
if (strcmp(keyPadInput, accessCode) == 0 ) {
Serial.println(“Keypad input matches access code”);
// Disarm the system
resetCodeInput();
armedState = DISARMED;
doInitilizeLCD = true;
initilizeLCD();
} else {
resetCodeInput();
}
} else {
if (inputCounter <= 3) {
keyPadInput[inputCounter] = customKey;
inputCounter++;
handleLCD(true);
} else {
// do nothing
}
}
}
}
}
void resetCodeInput() {
Serial.println(“reseting keyPadInput”);
for (int i = 0; i < 4; i++) {
keyPadInput[i] = ‘z’;
}
inputCounter = 0;
handleLCD(true);
}
void handlePIR() {
pirValue = digitalRead(pirPin);
doorValue = digitalRead(doorPin);
}
void alert() {
if ((pirValue > 0 && armedState == ARMED )||(doorValue == LOW && armedState == ARMED )) {
shouldBeAlerting = true;
//startMillis = millis;
}
//else if (doorValue == LOW && armedState == ARMED ) {
//shouldBeAlerting = true;
//}
else {
shouldBeAlerting = false;
}
if (shouldBeAlerting) {
Serial.println(“shouldBeAlerting”);
}
handleLed();
handleBuzz();
handleAlarm();
}
void handleLed () {
// handle the alarm LED
if (shouldBeAlerting) {
Serial.println(“setting LED HIGH”);
digitalWrite(ledPin, HIGH);
} else {
// Serial.println(“setting LED LOW”);
digitalWrite(ledPin, LOW);
}
}
void handleBuzz() {
if (shouldBeAlerting) {
unsigned char i;
for (i = 0; i < 10; i++)
{
digitalWrite(buzzer, HIGH);
delay(1);//wait for 1ms
digitalWrite(buzzer, LOW);
delay(1);//wait for 1ms
}
//output another frequency
for (i = 0; i < 20; i++)
{
digitalWrite(buzzer, HIGH);
delay(2);//wait for 2ms
digitalWrite(buzzer, LOW);
delay(2);//wait for 2ms
}
}
}
void handleAlarm () {
// handle the siren
if (shouldBeAlerting) {
Serial.println(“siren on”);
startMillis = millis;
const unsigned long delayTime = 600000;
if(currentMillis – startMillis >= delayTime); // Alarm to sound for 5 minutes, or until disarmed
digitalWrite(alarmPin, HIGH);
}
else {
digitalWrite(alarmPin, LOW);
}
}
Hi.
Using the millis() function should work, but I’m not familiar enough with that project to know if something will interfere with it.
Why do you say it didn’t work. What happened?
I see that you have the following line commented on the code:
startMillis = millis;
But, it should be:
startMillis = millis();
Regards,
Sara