PIR sensor input

I use multiple pir sensor with ardunio
And the function i want to do is

When I send sms to sim 800 as ON then system start to read pir sensor values and if detect any motion one of them make call

If I send sms as OFF system goes off and dosent make call although sensor detect motion

I want on off sensor reding remotely without using extra switch , but when i upload this code to ardunio uno it start detect motion without motion,

And it also work without on off command i cant understand what is problem please help me to solve this problem

This is the code I tried

#include <SoftwareSerial.h>
const String PHONE1 = "+918830584864xx"; // Phone number 1
const String PHONE2 = "+919876543210xx"; // Phone number 2
const String PHONE3 = "+912345678901xx"; // Phone number 3
#define rxPin 2
#define txPin 3

SoftwareSerial sim800(rxPin, txPin);
int pir_sensor1 = 6; // PIR sensor 1
int pir_sensor2 = 7; // PIR sensor 2
int pir_sensor3 = 8; // PIR sensor 3
bool called = false; // To track if the call has been made
bool systemOn = true; // Flag to indicate if the system is ON (starts as ON)

void setup() {
  pinMode(pir_sensor1, INPUT);
  pinMode(pir_sensor2, INPUT);
  pinMode(pir_sensor3, INPUT);
  Serial.begin(115200);
  sim800.begin(9600);
  Serial.println("SIM800L software serial initialize");
  sim800.println("AT");
  delay(1000);
  sim800.println("AT+CNMI=2,2,0,0,0"); // Enable receiving new SMS notifications
}

void loop() {
  while (sim800.available()) {
    Serial.println(sim800.readString());
    String message = sim800.readString();
    message.trim(); // Remove leading and trailing whitespaces from the received message
    if (systemOn) {
      handleSMS(message);
    }
  }

  // Check if the system is ON
  if (systemOn) {
    // Check if any PIR sensor is HIGH and a call hasn't been made yet
    if (!called && (digitalRead(pir_sensor1) == HIGH || digitalRead(pir_sensor2) == HIGH || digitalRead(pir_sensor3) == HIGH)) {
      Serial.println("Motion detected!");
      Serial.println("calling....");
      delay(1000);
      sim800.println("ATD" + PHONE1 + ";"); // Call the 1st phone number
      called = true; // Set to true to avoid making more calls

      delay(10000); // Wait for 10 seconds (adjust as needed)
      sim800.println("ATH"); // Hang up the current call

      delay(5000); // Wait for 5 seconds before calling the next number
      sim800.println("ATD" + PHONE2 + ";"); // Call the 2nd phone number

      delay(10000); // Wait for 10 seconds (adjust as needed)
      sim800.println("ATH"); // Hang up the current call

      delay(5000); // Wait for 5 seconds before calling the last number
      sim800.println("ATD" + PHONE3 + ";"); // Call the 3rd phone number

      delay(10000); // Wait for 10 seconds (adjust as needed)
      sim800.println("ATH"); // Hang up the current call

      // Reset the 'called' variable to allow making calls again if motion is detected
      called = false;
    }
  }
}

void handleSMS(String message) {
  if (message.equalsIgnoreCase("ON")) {
    Serial.println("System is ON.");
    sim800.println("AT+CNMI=2,2,0,0,0"); // Enable receiving new SMS notifications
  } else if (message.equalsIgnoreCase("OFF")) {
    Serial.println("System is OFF.");
    sim800.println("AT+CNMI=0,0,0,0,0"); // Disable receiving new SMS notifications
  }
}

Hello

Welcome to the worldbest Arduino forum ever.

I suspect that using the b.m. delay() functions blocks the expected real-time behavior of the sketch.

	Line 23:   delay(1000);
	Line 43:       delay(1000);
	Line 47:       delay(10000); // Wait for 10 seconds (adjust as needed)
	Line 50:       delay(5000); // Wait for 5 seconds before calling the next number
	Line 53:       delay(10000); // Wait for 10 seconds (adjust as needed)
	Line 56:       delay(5000); // Wait for 5 seconds before calling the last number
	Line 59:       delay(10000); // Wait for 10 seconds (adjust as needed)

Take a look at the IDE's BlinkWithoutDelay example to design and code a timer() function for your project.

Have a nice day and enjoy programming in C++.

Some PIR sensors take some seconds from power on to stabilise and could, during this time, give false results. From your code, it looks like you expect the PIR sensor to deliver a HIGH when it detects motion and LOW otherwise. Which PIR sensor are you using ?
Once you send an "OFF" command by SMS to the device how are you intending to re-enable it ? It looks like you deactivate the radio module so it cannot respond to further SMS commands.

1 Like

Maybe adding some Serial.print messages to see what values are floating around will help identify where the logic falls over, and why.

2 Likes

Hi @Haritha1995,

welcome to the arduino-forum.
Well done posting your code as a code-section and describing your wanted functionality
in detail.

I started analysing your code:

  while (sim800.available()) {
    Serial.println(sim800.readString()); // take received characters out of receivebuffer and print them
    String message = sim800.readString(); // if another string was received in is ready to read out assign the characters to variables message

This means you print the received characters and then these characters are gone.
So the minimum is to change the order of assigning to the string and to print

  while (sim800.available()) {
    String message = sim800.readString(); // assign = stroe characters in variable message
    message.trim(); // Remove leading and trailing whitespaces from the received message
    Serial.println(message); // print what got REALLY stored into variable message

You haven't yet written what microcontroller you use.
Variable-type String does eat up all RAM over time and then starts to corrupt other variables by overwriting their RAM-location.

Me personal I recommend using the SafeString-library which offers almost the same comfort and the name is program. They are safe to use and you don't have to care about boundary checking like with array-of-chars (called "c-string").
@ the c-string fans: have you ever taken the effort to compare how much RAM needs careful and secure array-boundary-checking and how much extra-RAM the SafeString-library needs?

best regards Stefan

1 Like

There are different ways how any kind of serial device can be configured.

  • Sending a carriage return as terminating character
  • Sending a new line as terminating character
  • Sending a carriage return and new line as terminating character
  • Sending no terminating character at all

You should analyse what the exact character-sequence is that your device is sending.
This code is your code with a few changes that will print the received message with a leading "#" and a traing "#" to make visible if there is a terminating character or not.
And to make visible what are the characters that are stored inside your variable message

This is a fundamental and very important debugging technique

#include <SoftwareSerial.h>
const String PHONE1 = "+918830584864xx"; // Phone number 1
const String PHONE2 = "+919876543210xx"; // Phone number 2
const String PHONE3 = "+912345678901xx"; // Phone number 3
#define rxPin 2
#define txPin 3

SoftwareSerial sim800(rxPin, txPin);
int pir_sensor1 = 6; // PIR sensor 1
int pir_sensor2 = 7; // PIR sensor 2
int pir_sensor3 = 8; // PIR sensor 3
bool called = false; // To track if the call has been made
bool systemOn = true; // Flag to indicate if the system is ON (starts as ON)

void setup() {
  pinMode(pir_sensor1, INPUT);
  pinMode(pir_sensor2, INPUT);
  pinMode(pir_sensor3, INPUT);
  Serial.begin(115200);
  sim800.begin(9600);
  Serial.println("SIM800L software serial initialize");
  sim800.println("AT");
  delay(1000);
  sim800.println("AT+CNMI=2,2,0,0,0"); // Enable receiving new SMS notifications
}

void loop() {
  while (sim800.available()) {
    String message = sim800.readString();
    message.trim(); // Remove leading and trailing whitespaces from the received message
    Serial.print("message=#");    
    Serial.print(message);
    Serial.print("#");    
    if (systemOn) {
      handleSMS(message);
    }
  }

  // Check if the system is ON
  if (systemOn) {
    // Check if any PIR sensor is HIGH and a call hasn't been made yet
    if (!called && (digitalRead(pir_sensor1) == HIGH || digitalRead(pir_sensor2) == HIGH || digitalRead(pir_sensor3) == HIGH)) {
      Serial.println("Motion detected!");
      Serial.println("calling....");
      delay(1000);
      sim800.println("ATD" + PHONE1 + ";"); // Call the 1st phone number
      called = true; // Set to true to avoid making more calls

      delay(10000); // Wait for 10 seconds (adjust as needed)
      sim800.println("ATH"); // Hang up the current call

      delay(5000); // Wait for 5 seconds before calling the next number
      sim800.println("ATD" + PHONE2 + ";"); // Call the 2nd phone number

      delay(10000); // Wait for 10 seconds (adjust as needed)
      sim800.println("ATH"); // Hang up the current call

      delay(5000); // Wait for 5 seconds before calling the last number
      sim800.println("ATD" + PHONE3 + ";"); // Call the 3rd phone number

      delay(10000); // Wait for 10 seconds (adjust as needed)
      sim800.println("ATH"); // Hang up the current call

      // Reset the 'called' variable to allow making calls again if motion is detected
      called = false;
    }
  }
}

void handleSMS(String message) {
  if (message.equalsIgnoreCase("ON")) {
    Serial.println("System is ON.");
    sim800.println("AT+CNMI=2,2,0,0,0"); // Enable receiving new SMS notifications
  } else if (message.equalsIgnoreCase("OFF")) {
    Serial.println("System is OFF.");
    sim800.println("AT+CNMI=0,0,0,0,0"); // Disable receiving new SMS notifications
  }
}

best regards Stefan

I think that is the reason of false detect when it turning on, sensor is very low quality and it cost less than1$ thank you

I used ardunio uno board for this project, ican understand what you describe but i dont know how to do it properly because i download few code from internet and mix together as i want , thank you for your reply

I got an idea after read all thes comments if i rewrite code like
I SEND message and it will high a pin of ardunio uno then
I use 3 transistor for pir output then i switch all these transistor with one pin if it is high and aslo detect motion signal go through transistor to ardunio .
Is it wrong , or if I use 3 AND gate and transistor of ardunio pin bias it

As i say i dont know how to code properly so i download some code and mix each other a i want . I wrote this code 42 different ways and check :pleading_face:

This try and error-method will need 7.5 milions years to get the program to output a simple "42" :wink:

Take 42 hours of your precious time to learn programming. As a start I recommend
To work through this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

After that post your actual code-version as a code-section combined with a specific question. In this way you will learn in a way that is taylored to your project.

As a code-writing exercise write a very very simple code that does nothing more than reading in a single PIR-sensor and print the state of the IO-pin to the serial monitor. In this way you will learn how the PIR-sensor behaves.

best regards Stefan

1 Like

I change it like this Ldr control please correct if i wrong please i havent enoug time to complete this project :pleading_face:

#include <SoftwareSerial.h>

const int ledPin = 9; // LED connected to digital pin 9
const int ldrPin = A0; // LDR connected to analog pin A0

int ldrThreshold = 500; // Adjust this threshold value based on your setup

const int pir1Pin = 2; // PIR Sensor 1 connected to digital pin 2
const int pir2Pin = 3; // PIR Sensor 2 connected to digital pin 3
const int pir3Pin = 4; // PIR Sensor 3 connected to digital pin 4

const int callThresholdLow = 100; // Adjust this value based on your setup
const int callThresholdHigh = 800; // Adjust this value based on your setup

SoftwareSerial sim800l(7, 8); // TX pin connected to Arduino pin 7, RX pin connected to Arduino pin 8

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(pir1Pin, INPUT);
  pinMode(pir2Pin, INPUT);
  pinMode(pir3Pin, INPUT);

  sim800l.begin(9600);
  Serial.begin(115200); // Serial monitor baud rate
}

void loop() {
  int ldrValue = analogRead(ldrPin);

  // Check if LDR value is below the threshold and motion is detected
  if (ldrValue < ldrThreshold && (digitalRead(pir1Pin) || digitalRead(pir2Pin) || digitalRead(pir3Pin))) {
    makePhoneCall();
  }

  // Check if an SMS is received
  checkSMS();

  // Wait for a short duration to prevent false detections
  delay(100);
}

void makePhoneCall() {
  // Read the LDR value again to confirm if it's still below the threshold
  int ldrValue = analogRead(ldrPin);

  // Check if LDR value is still below the threshold
  if (ldrValue < ldrThreshold) {
    // Make phone call to 3 numbers
    sim800l.println("ATD+1234567890;"); // Replace +1234567890 with your phone numbers
    delay(3000); // Wait for a few seconds for the call to establish
    sim800l.println("ATH"); // Hang up the call
  }
}

void checkSMS() {
  // Check if there's any data available from the SIM800L module
  while (sim800l.available()) {
    // Read the data from SIM800L module
    char c = sim800l.read();

    // Print the data to the Serial monitor
    Serial.write(c);

    // Check if the received data contains "ON"
    if (c == 'O') {
      if (sim800l.available() && sim800l.read() == 'N') {
        // Turn on the LED
        digitalWrite(ledPin, HIGH);
      }
    }

    // Check if the received data contains "OFF"
    if (c == 'O') {
      if (sim800l.available() && sim800l.read() == 'F' && sim800l.available() && sim800l.read() == 'F') {
        // Turn off the LED
        digitalWrite(ledPin, LOW);
      }
    }
  }
}

As I see it: it is your responsability to organise how and when you finish your project.
The minimum that you can do is describing what your code is doing.

What do you observe what the code does?

The only problem I have is when I try to turn it on and off with a message, the program executes the on message and does not execute the off message. The program does not understand why.

This won’t work well as you consume chars multiple times for the character at the same position and hope for a synchronous communication

I would suggest to study Serial Input Basics to handle this

Say you received OFF
You read the O so the first test is true
You read the F and it’s not N so you exit the first test and enter the second test but here you don’t have FF to read anymore as you already read one of the F

➜ try to run the while loop Manually and see what it does. Note that nothing might be available as the serial communication is slow compared to the read command so you are not sure everything is in the RX buffer

Of course the "program" (=the software as a sequence of numbers stored into flash) is as dumb as the chip.

You: the human beeing are the intelligent one who will learn how to make it work.

I second that. take the example 3 receive with start and endmarker

If you use specific characters that have the function of a start-character and a stop-character the communication will become reliable. (@J-M-L : as you have pms deactivated I write it here: I did not know that I have a personal ghost-corrector. I feel honored :wink: )

And It will be very helpful if you store received data into variables and then print it to the serial monitor to make visible what you received where in your code and what your code is really doing.

best regards Stefan

it "stings the eyes" (as we say in French) from time to time :wink:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.