Movement detection alarm using 3 PIR sensors

Hi everyone! My first post to the forum :slight_smile:

I try to make a movement detection alarm using 3 PIR sensors. If you walk from the house and out no alarm is triggered (trigger them in this order; PIR-one, PIR-two, PIR-tre). But if you walk from the street and in, the alarm turnes on (trigger them the other way; PIR-tre, PIR-two, PIR-one).

But I cant figure out how to do this since “time” also is an issue. Any advice how to solve it?

Thanks a lot for any help!

Here’s my code… but it don’t do the job

  const int pinMovement1 = A1;
  const int pinMovement2 = A2;
  const int pinMovement3 = A3;   

  int intrudersDepth = 0;
  
  unsigned long compareWith; 
  
  void AlarmStart()  {
  
  }
  
  void TimerStart()  {  // rest time
        Serial.println("Inside restart 1");
        compareWith = millis;
        compareWith = compareWith + 8000;
        do (millis < compareWith) {
            Serial.println(millis);
            delay(800);
        }
        intrudersDepth = 0;
  }

  void setup ()  {

     Serial.begin(9600); 
  } 

  void loop ()   {

      if (digitalRead(pinMovement1) == HIGH 
       && digitalRead(pinMovement2) == LOW 
       && digitalRead(pinMovement3) == LOW 
       && intrudersDepth == 0) {
              Serial.println( "  First react ");
              intrudersDepth = 1;
              TimerStart();
      }
      if (digitalRead(pinMovement1) == HIGH 
       && digitalRead(pinMovement2) == HIGH 
       && digitalRead(pinMovement3) == LOW 
       && intrudersDepth == 1) {
              Serial.println( "  Second react ");
              intrudersDepth = 2;
              TimerStart();
              AlarmStart();
      }
      if (digitalRead(pinMovement1) == HIGH 
       && digitalRead(pinMovement2) == HIGH 
       && digitalRead(pinMovement3) == HIGH
       && intrudersDepth == 2) {
              Serial.println( "  Third react ");
              intrudersDepth = 3;
              TimerStart();
              AlarmStart();
      }
      Serial.println(intrudersDepth);
      delay(4000);
  }

You didn't say in what way you want "time" to be an issue.

Did you want to reset the sequence if nothing has triggered over some reasonable amount of time?

I would start by recording the time the latest sensor triggered. Then you can check the current time against that time to see if it is time to reset the sequence.

I don't see a need for 3 sensors, maybe you can elaborate.

You need to think about and explain what you want to happen. Someone crosses your sensors, okay, how fast should they make it through them? What if they turn around? Why have you decided on PIR sensors? Have you considered any others or was this the first type of sensor you landed on?

Hi! Thanks for answer and sorry for late reply!

I tought if someone trigger PIR_1 it turns "hot" for a while, and I thought to do this in code is smart since the different PIR's dont know about each other or who was triggered in what kind of order.

If "someone" turn and go away, PIR_1 needs to turn "cold" after some while. But if PIR_2 is triggered when PIR_1 is "hot" the first alarm goes on. If PIR_3 also gets triggered and PIR_2 is "hot" a light turns on and a more intens alarm starts. This was at least my idea.

If the PIR_3 is triggered first, you walk the right way (and no alarm goes of), if PIR_2 is triggered first you are coming from the greenhouse.

So in code I guess I need each PIR to go hot for a while, and when do so check who other is hot and who was it first maybe?

I haven't been able to figure out how the code could look like. Any ideas?

Well yes, I just took PIR switces since they are cheap and 5v.

Any ideas? Sure, start with one PIR and program for it and learn all about how it responds. Then add the second one and program for two, etc.

Paul

If “someone” turn and go away, PIR_1 needs to turn “cold” after some while.

The Arduino has no control over how long it takes the sensor to report “no motion detected” after it reports “motion detected”.

PIR sensors are the wrong kind of sensors for your project.

Hi PaulS.

"The art of getting good answers lies in asking good questions" is true enough, but it is'nt easy to ask good questions when you not able to define you problem, and I see I hade a bad start. The hardware setup is OK, the sensor work OK.

What I was after is how to solve this it C / C++

But after some codework I think I'm on the right way, by comparing with millis I can make a simple timer saying a variable is "Hot" for a period of time before it goes "Cold". And then I can test to se what other variables is hot and who was it first. The code is not elegant but I think it do the job:

    // 3 different movement sensors goes hot-or-cold

    bool hotOrNot1 = false, hotOrNot2 = false, hotOrNot3 = false;
    unsigned long meashureTime1 = 0, meashureTime2 = 0, meashureTime3 = 0, loopWithMillis = 0;

    class HotOrNot  {
        public:
            void HotOrNotMove1()  {
                if (loopWithMillis >= meashureTime1) {
                    loopWithMillis = meashureTime1;
                    meashureTime1 = meashureTime1 + 12000; // 12 sekunder
                    // Serial.println("inside IF inside class");
                    hotOrNot1 = true;
                } 
                else 
                    hotOrNot1 = false;
            }  
            void HotOrNotMove2()  {
                if (loopWithMillis >= meashureTime2) {
                    loopWithMillis = meashureTime2;
                    meashureTime2 = meashureTime2 + 12000;
                    // Serial.println("inside IF inside class");
                    hotOrNot2 = true;
                } 
                else 
                    hotOrNot2 = false;
            } 
            void HotOrNotMove3()  {
                if (loopWithMillis >= meashureTime3) {
                    loopWithMillis = meashureTime3;
                    meashureTime3 = meashureTime3 + 12000;
                    // Serial.println("inside IF inside class");
                    hotOrNot3 = true;
                } 
                else 
                    hotOrNot3 = false;
            }   
    }; /* --- class HotOrNot end --- */

    void setup(){
        Serial.begin(9600);
    }
    void loop(){

        loopWithMillis = millis();
        
        HotOrNot hotObject; // object til class'en
        
        hotObject.HotOrNotMove1(); // kjøres i hver loop, må trigges av hardware
        hotObject.HotOrNotMove2();
        hotObject.HotOrNotMove3();

        Serial.print("millis: ");           Serial.println(millis());
        Serial.print("loopWithMillis: ");   Serial.println(loopWithMillis);
        Serial.print("meashureTime1: ");    Serial.println(meashureTime1);
        Serial.print("hotOrNot1: ");        Serial.println(hotOrNot1);
        Serial.print("hotOrNot2: ");        Serial.println(hotOrNot2);
        Serial.print("hotOrNot3: ");        Serial.println(hotOrNot3);
        delay(3000);
    }
    bool hotOrNot1 = false, hotOrNot2 = false, hotOrNot3 = false;

I really hate these names. The or not part is implied by the value. isHot1, isHot2, isHot3...

if(isHot1)
   Serial.print("Ouch, I burned myself...");
else
   Serial.print("Cool to the touch...");

What, exactly, is the difference between HotOrNotMove1(), HotOrNotMove2(), and HotOrNotMove3() that couldn't be handled better with one function taking an index and using arrays?

Ha ha, well I try to use names telling what the variables are used for, but shure Hot1 can do the job.

HotOrNotMove 1 2 3 has to be triggered with the movement detector trough: if (digitalRead(pinMovement1) == HIGH) { } and not just run in loop forever.

I'm no C / C++ master (but I'm reading C & Arduino books to increase the level). I understand my code repeating many times with minor changes, and that's not effective (I use classes since I just learn about classes), but if you have a more effective way using arrays please show me an example. This is a problem in most of my code.

    bool hot[3];
    unsigned long meashureTime[3];

void HotOrNotMove(byte index)
{
   if (loopWithMillis >= meashureTime[index])
   {
      loopWithMillis = meashureTime[index];
      meashureTime[index] = meashureTime[index] + 12000; // 12 sekunder
      // Serial.println("inside IF inside class");
      hot[index] = true;
   }
   else
      hot[index] = false;
}

One function, using arrays, not three.

I use classes since I just learn about classes

That’s good, but you need to learn to put the class definition in a .h file, the class implementation in a .cpp file, and to NOT use global variables in the class.

Thanks!

My script tend to be long with quite similar code, så I definitely gone try your example.

Yes indeed, I have read about making librarys, I don't understand everything yet but I think I'm 90% there, so it's on my wish-list :slight_smile: