Wiring 3 PIR Motion Sensors in Parallel Problem HC-SR501

Hi guys,

I have created a motion sensor array containing 3 PIR sensors, which links to a windows form application on my computer via the USB connection.

The c# windows form works fine and accepts the correct data in from the serial port and turns a picture from green, which signals no motion, to red, when motion is detected, for each individual sensor.

Here is link to my youtube video when I only had 2 sensor present to give you idea of what the software looks like, its changed slightly since then and has now 3 sensors:

It records the time motion was activated, if its ongoing, and then records the time the motion ended based on what the Arduino is printing to the serial port for each sensor.

When motion is detected and the pins in the HIGH state, the Sensors print the following to the serial and read into the windows form and action taken accordingly dependent on what the string is equal to it reads:

Sensor 1 prints “md\n”
Sensor 2 prints “md2\n”
Sensor 3 prints “md3\n”

When motion is no longer ongoing and the pins in the LOW state, the Sensors print the following to the serial:

Sensor 1 prints “nomd\n”
Sensor 2 prints “nomd2\n”
Sensor 3 prints “nomd3\n”

I have 3 PIR sensors wired in Parallel on a breadboard shown in the circuit diagram and photos attached.

My Problem
Using the Serial port, I can see what the problem is.

Basically If Sensor 3 which is at the end of the circuit detects motion, while its motion is still ongoing, if sensor 1 or 2 detects motion, it prints to the serial port without delay.

However If motion is detected at the same time on Sensor 2 (in the middle of the circuit) and on sensor 3 (at the end of the circuit) at exactly the same time, then Sensor 3 will output its serial print text first and not Motion sensor 2’s text as well.

However while motion is ongoing on sensor 3, waving anything in front of motion sensor 2 will not trigger it to print to the serial, however if while motion 3’s sensor is still ongoing movement, waving something in front of motion sensor 1 will cause it to trigger. Then once sensor 3 and sensor 1 have finished their output, it sometimes fires sensor 2’s serial print after these have finished.

It seems if sensor 2 and 3 detect motion at the exact same time its going to the end of the circuit and almost working backward with a delay only happening for the sensor in the middle of the circuit.

Anybody any ideas what is happening or how to fix this? Not sure if its the wiring or code etc.

Have tried introducing delays, pauses, changing jumpers on the PIR sensors but still get the exact same problem., length of pause to check HIGH and LOW states of sensors but am at a loss.

Any help would be greatly appreciated.

Arduino Code:

long unsigned int calibrationTime = 10;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;    
long unsigned int lowIn1;   
long unsigned int lowIn2;   

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 1000;  
long unsigned int pause1 = 1000;  
long unsigned int pause2 = 1000;  

boolean lockLow = true;
boolean lockLow1 = true;
boolean lockLow2 = true;

boolean takeLowTime;  
boolean takeLowTime1;  
boolean takeLowTime2;

int pirPin = 8;    //the digital pin connected to the PIR sensor's output
int pirPin2 = 7;
int pirPin3 = 6;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(pirPin2, INPUT);
  pinMode(pirPin3, INPUT);
  digitalWrite(pirPin, LOW);
    digitalWrite(pirPin2, LOW);
      digitalWrite(pirPin3, LOW);
  //give the sensor some time to calibrate
  //Serial.print("calibrating sensor \n");
 //   for(int i = 0; i < calibrationTime; i++){
 //     Serial.print(".");
      //delay(500);
//      }
//    Serial.println(" done\n");
//    Serial.println("SENSOR ACTIVE\n");    
//
}

////////////////////////////
//LOOP
void loop(){

//MOTION SENSOR ONE =============================================
     if(digitalRead(pirPin) == HIGH){       
       if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.print("md\n");
         //Serial.print(millis()/1000);
         //delay(50);
         }         
         takeLowTime = true;
       }

     if(digitalRead(pirPin) == LOW){             

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("nomd\n");      //output
           //Serial.print((millis() - pause)/1000);
           //delay(50);
           }
       }

//MOTION SENSOR ONE END =============================================

//MOTION SENSOR TWO =============================================
        if(digitalRead(pirPin2) == HIGH){       
       if(lockLow1){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow1 = false;            
         Serial.print("md2\n");
         //Serial.print(millis()/1000);
         //delay(50);
         }         
         takeLowTime1 = true;
       }

     if(digitalRead(pirPin2) == LOW){             

       if(takeLowTime1){
        lowIn1 = millis();          //save the time of t                                                                                                                                                                          he transition from high to LOW
        takeLowTime1 = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow1 && millis() - lowIn1 > pause1){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow1 = true;                        
           Serial.print("nomd2\n");      //output
           //Serial.print((millis() - pause)/1000);
           //delay(10);
           }

//MOTION SENSOR TWO END =============================================


//MOTION SENSOR THREE =============================================
    if(digitalRead(pirPin3) == HIGH){       
       if(lockLow2){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow2 = false;            
         Serial.print("md3\n");
         //Serial.print(millis()/1000);
         //delay(10);
         }         
         takeLowTime2 = true;
       }

     if(digitalRead(pirPin3) == LOW){             

       if(takeLowTime2){
        lowIn2 = millis();          //save the time of t                                                                                                                                                                          he transition from high to LOW
        takeLowTime2 = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow2 && millis() - lowIn2 > pause2){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow2 = true;                        
           Serial.print("nomd3\n");      //output
           //Serial.print((millis() - pause)/1000);
           //delay(10);
           }
           
       }
       
//MOTION SENSOR THREE END =============================================
}
}

Motion Sensor breadboard.JPG

It's time to start working with arrays so that you only need to debug one section of code rather than three. If you want to wait for a set interval before taking an action then it's very similar to debouncing a button.

Have a look at these:

https://www.arduino.cc/reference/en/language/variables/data-types/array/

Trying to write the same code 3 times is a very common source of errors, which is why it's bad practice. Instead, us Martin mentioned, use arrays and loop over your sensors. Also, if you're combining conditions in an if(), make sure you properly bracket them.

So instead of

if(!lockLow1 && millis() - lowIn1 > pause1)

use

if((!lockLow1) && ((millis() - lowIn1) > pause1))

as this might sometimes lead to unexpected behaviour.

Hi guys thanks for the advice am going to get back into this as unfortunately earlier in the year suffered a mini stroke but am hoping to pick it up again, will take a look at these articles thanks :slight_smile: