0

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().

asked Jul 3, 2018 at 14:55
3
  • 1
    Never use Serial in an interrupt! Commented Jul 3, 2018 at 14:59
  • 1
    Serial and delay() both require interrupts in order to work right, but within an ISR, interrupts are already disabled. Commented Jul 3, 2018 at 15:20
  • Have the interrupt set a flag (boolean variable). Then in the loop, check that flag, do your actions and reset the flag. Using delay, serial, and softwareserial inside the ISR is not adviced. Commented Jul 3, 2018 at 15:30

1 Answer 1

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.

answered Jul 3, 2018 at 15:35
1
  • don't forget to declare the flag volatile! Commented Aug 2, 2018 at 19:33

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.