PIR Motion sensor code not working well

Hello!
This is my first post here and I am very new to Arduino and programming in general. I am making a school project with 4 motion sensors and Arduino UNO. The problem is that this code works well when there is 2 sensors (obviously have to change it a little then) but when there is 4 sensors it doesnt behave correctly and starts randomly spamming Motion detected and Motion ended sometimes. How do I fix this? Also I never get "Motion detected!On sensors 1,2", so there is always only 1 sensor that detects. Any help would be much appreciated! :slight_smile:

Here is the code(got it online when it was meant for 1 sensor and modified it for 4 sensors):

int ledPin = 13; // choose the pin for the LED
int inputPin = 3; // choose the input pin (for PIR sensor)
int inputPin2 = 4;
int inputPin3 = 5;
int inputPin4 = 6;
int pirState = LOW; // we start, assuming no motion detected
int val2 = 0; // variable for reading the pin status
int val3 = 0;
int val4 = 0;
int val5 = 0;

void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
pinMode(inputPin2, INPUT);
pinMode(inputPin3, INPUT);
pinMode(inputPin4, INPUT);

Serial.begin(9600);
}

void loop(){
val2 = digitalRead(inputPin); // read input value
val3 = digitalRead(inputPin2);
val4 = digitalRead(inputPin3);
val5 = digitalRead(inputPin4);
if (val2 == HIGH && val3 == LOW && val4 == LOW && val5 == LOW) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
if (pirState == LOW) {
// we have just turned on
Serial.println("Motion detected!1");
// We only want to print on the output change, not state
pirState = HIGH;
}
}

else if (val2 == LOW && val3 == HIGH && val4 == LOW && val5 == LOW) {
digitalWrite(ledPin, HIGH); // turn LED ON
if (pirState == LOW) {

Serial.println("Motion detected!2");

pirState = HIGH;
}
}

else if (val2 == LOW && val3 == LOW && val4 == HIGH && val5 == LOW) {
digitalWrite(ledPin, HIGH);
if (pirState == LOW) {

Serial.println("Motion detected!3");

pirState = HIGH;
}
}
else if (val2 == LOW && val3 == LOW && val4 == LOW && val5 == HIGH) {
digitalWrite(ledPin, HIGH);
if (pirState == LOW) {

Serial.println("Motion detected!4");

pirState = HIGH;
}
else if (val2 == HIGH && val3 == HIGH && val4 == LOW && val5 == LOW) {
digitalWrite(ledPin, HIGH);
if (pirState == LOW) {

Serial.println("Motion detected!On sensors 1,2");

pirState = HIGH;
}
}

} else {
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH){

Serial.println("Motion ended!");

pirState = LOW;
}
}
}

You need to post your code in code tags if anyone is going to look at it. This is explained in the how-to-post-to-this-forum threads.

I think your problem may be that the Arduino is not a Power Supply. Try using an external power supply for the PIR and be sure the grounds are connected.

So I am trying to use the EEPROM on my Arduino UNO to count how many times my motion sensors have detected motion, but its not working, the results I got when I made each of the sensors detect motion 2 times where 0 162 0, while they should be 2 2 2, because each sesnor detected movement 2 times obviously. Whats wrong with my code?

/*
 * PIR sensor tester
 */
#include <EEPROM.h>
int ledPin = 13;                // choose the pin for the LED
int inputPin1 = 3;
int inputPin2 = 4;
int inputPin3 = 5;// choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val3 = 0;
int val4 = 0;
int val5 = 0;
int value1 = 0;
int value2 = 0;
int value3 = 0;              // variable for reading the pin status
 
void setup() {
 
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin1, INPUT);
  pinMode(inputPin2, INPUT);      // declare sensor as input
  pinMode(inputPin3, INPUT);
  Serial.begin(9600);
}
 
void loop(){
  EEPROM.write(1,value1);
  EEPROM.write(2,value2);
  EEPROM.write(3,value3);
  val3 = digitalRead(inputPin1);
  val4 = digitalRead(inputPin2);
  val5 = digitalRead(inputPin3);// read input value
  if (val3 == HIGH && val4 == LOW && val5 == LOW) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
    value1 += 1;
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!1");
      // We only want to print on the output change, not state
      pirState = HIGH;
    }
     }
     else if (val3 == LOW && val4 == HIGH && val5 == LOW) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);
    value2 += 1;// turn LED ON
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!2");
      // We only want to print on the output change, not state
      pirState = HIGH;
    }
    }
       else if (val3 == LOW && val4 == LOW && val5 == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);
    value3 += 1;// turn LED ON
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!3");
      // We only want to print on the output change, not state
      pirState = HIGH;
    }
    }
 
  else {
    digitalWrite(ledPin, LOW); // turn LED OFF
    if (pirState == HIGH){
      // we have just turned of
      Serial.println("Motion ended!");
      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
}

value1, 2 and 3 are declared as ints so each require 2 bytes of storage. You are storing them in consecutive bytes of the EEPROM
Do you see the problem ?

Do they need to be ints or could they be bytes ?
If they need to be ints then use EEPROM.put() but space the target location further apart

Have you ruined your EEPROM yet by writing to it on every interation of loop() when it has a lifetime of 100,000 writes to each location

Deciding if valueX needs to be an integer or byte is first business.

Then, if a byte, the eeprom needs to be written with eeprom.update(), and if an int then with eeprom.put(). Both of these methods only write if the data has changed.

Your current code is very dangerous as UKHeliBob has pointed out, and you may want to move your eeprom addresses to some new locations.

There is a problem with your code in that the state change control only covers the printing, but not the value incrment. You will print once, but value will increment for the entire time that the pir sensor reads HIGH.

I think the 162 value might come from these multiple increments.

@andre7171

TOPIC MERGED.
Other post/duplicate DELETED

Continued cross posting could result in a time out from the forum.

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum.

Check the setting on PIR motion sensor. There are two potentiometers and one jumper on it. See How to do setting for PIR motion sensor

I do not know what kind of PIR sensors you are using.

I experiences strange behavior using one PIR sensor that does not have any adjustments for sensitivity.

I used the PIR together with a 4x7 LED display (TM1637 chip). When using a low brightness on the display the PIR sensor behaved OK. When I increased the brightness the PIR sensor was constantly one due to noise from the display.

I fixed this by using de-coupling:

Maybe this can help?

@cattledog
Thanks for the reply, I changed the EEPROM to put, but how do I make it so that when pir sensor reads HIGH it will only change the value once?

how do I make it so that when pir sensor reads HIGH it will only change the value once?

Look at the StateChangeDetection example in the IDE to see how to detect when an input becomes HIGH

Thanks for the help! I couldnt get it to work with the StateChangeDetection example, but I added a delay of 5 sec after the value1 += 1 and this works quite well. Is this safe or do I have to add some safety?

Thank you very much for the help! :slight_smile: The code works good! Sorry for the messy code :smiley:

@cattledog
Thanks for the reply, I changed the EEPROM to put, but how do I make it so that when pir sensor reads HIGH it will only change the value once?

Make sure the count incrementing and EEPROM writing is inside the state change detection code. In @holdingpatterns code it is where there is serial printing on the output change.

I think if you are incrementing the count you want to be in the block where motion is detected, that is where the input becomes HIGH as UKHeliBob says.