I am trying to develop a burglar alert system. I am using PIR sensor, Arduino Mega and SIM800L. I have connected PIR sensor to interrupt pin. Whenever motion is dected, a function corresponding to the interrupt will be called. In that function I am sending a SMS to notify with an alert message. If motion is detected 2 times, I will call the emergency contact number.
This is the code I have written.
#include <SoftwareSerial.h>
#define PIR1 2
#define SIREN 13
#define statusLED 12
SoftwareSerial SMS(11, 10);// rx(11-arduino) connect to tx(gsm module)
// tx(10-arduino) connect to rx(gsm module)
String CONTACT1 = "xxxxxxxxxx"; //mobile number
boolean status;
byte motionCtr = 0;
unsigned long latestMovementTime = 0;
void setup() {
pinMode(PIR1,INPUT);
pinMode(SIREN,OUTPUT);
pinMode(statusLED,OUTPUT);
Serial.begin(9600);
SMS.begin(9600);
SMS.println("AT+CNMI=2,2,0,0,0");
delay(5000);
activateSystem(0);
}
void loop() {
unsigned long currentTime = millis();
//If motion is not dected for 5 minutes, turn off the siren.
if(currentTime - latestMovementTime > 300000 && motionCtr>=1){
stopSiren(0);
}
delay(500);
}
void activateSystem(byte manual){
delay(60000); //warm up time for PIR sensor
attachInterrupt(0,motionDetected,RISING);
status = true;
digitalWrite(statusLED,HIGH);
if(manual){
Serial.println("System ACTIVATED by SMS.");
notifyBySMS("System ACTIVATED SMS.");
}else{
Serial.println("System ACTIVATED.");
notifyBySMS("System ACTIVATED.");
}
}
void deactivateSystem(byte manual){
detachInterrupt(0);
status = false;
digitalWrite(statusLED,LOW);
if(manual){
Serial.println("System DEACTIVATED by SMS.");
notifyBySMS("System DEACTIVATED SMS.");
}else{
Serial.println("System DEACTIVATED.");
notifyBySMS("System DEACTIVATED.");
}
}
void motionDetected(){
startSiren("Motion at bedroom door.");
}
void startSiren(String msg){
//Record the time of latest motion dected.
latestMovementTime = millis();
motionCtr++;
Serial.print("Ctr="+motionCtr);
Serial.println(msg);
notifyBySMS(msg);
//Start the siren only if motion is detected 2 times
if(motionCtr==2){
digitalWrite(SIREN,HIGH);
Serial.println("Siren STARTED.");
notifyBySMS("Siren STARTED.");
call(CONTACT1);
// call(CONTACT2);
// call(CONTACT3);
}
}
void stopSiren(byte manual){
motionCtr = 0;
Serial.println("Ctr="+motionCtr);
digitalWrite(SIREN,LOW);
if(manual){
Serial.println("Siren STOPPED manually.");
notifyBySMS("Siren STOPPED manually.");
}else{
Serial.println("Siren STOPPED");
notifyBySMS("Siren STOPPED.");
}
}
void sendSMS(String mobileNumber, String msg){
Serial.println("Sending SMS to "+mobileNumber);
//AT command for text mode of gsm module
SMS.println("AT+CMGF=1");
delay(100);
SMS.println("AT+CMGS=\""+mobileNumber+"\"\r");
delay(100);
// the text you want to send
SMS.println(msg);
delay(100);
// ASCII code of CTRL+Z
SMS.println((char)26);
delay(5000);
Serial.println("SMS sent to "+mobileNumber);
}
void call(String mobileNumber){
Serial.println("Calling..."+mobileNumber);
SMS.println("AT+CMGF=0"); //AT command for PDU mode of gsm module
SMS.println("ATD"+mobileNumber+";");
delay(45000);
SMS.println("ATH");
}
void notifyBySMS(String msg){
sendSMS(CONTACT1,msg);
delay(1000);
// sendSMS(CONTACT2,msg);
// delay(1000);
// sendSMS(CONTACT3,msg);
// delay(1000);
}
I am receiving the SMS from setup()
. But I am not receiving the SMS that I have sent from interrupt routine. Also I am receiving the call only sometime, it is random. I guess this is because I am using delay()
in interrupt routine.
How can I implement such logic without delay()
.
1 Answer 1
As mentioned in the comments Serial won't work in an ISR. Generally, you should do as little as possible in an ISR. Often an ISR will just set a flag to be handled in loop()
You will then need to refactor loop()
to handle the flag set in the ISR. A common method is to use a finite state machine.
-
don't forget to declare the flag volatile!esoterik– esoterik08/02/2018 19:33:44Commented Aug 2, 2018 at 19:33
delay()
both require interrupts in order to work right, but within an ISR, interrupts are already disabled.