Go Down

Topic: trouble writing PIR library (C++) (Read 506 times) previous topic - next topic

Gonzillaaa

Hello I am trying to convert the playground code for detecting presence using PIRs http://www.arduino.cc/playground/Code/PIRsense into a library so I can connect several PIRs together.

I am new to C++ but have followed a few examples. The code compiles but doesn't seem to work as expected. I get readings from two PiRs the first few times but then I only get readings from one of them (the second object initialised). I have the suspicion that objects don't work as I think in C++ and one object is overwriting variables for all, I have declared variables protected but not much luck.

all comments, suggestions much appreciated.
PIR.h
Code: [Select]
#ifndef PIR_H
#define PIR_H

#include "WProgram.h"
#include "inttypes.h"

class PIR
{
   public:
   PIR(int nodeId, int pinId, long pause);
   void initialise();
   void checkStatus();
   
   protected:
   int _nodeId;
   int _pinId;
   unsigned long lowIn;        
   unsigned long start;
   unsigned long end;
   int _pause;

   bool _ready;
   bool lockLow;
   bool takeLowTime;
   
};
#endif


PIR.cpp
Code: [Select]
#include "PIR.h"

/*
*
* The Parallax PIR Sensor is an easy to use digital infrared motion sensor module.
* (http://www.parallax.com/detail.asp?product_id=555-28027)
*
* The sensor?s output pin goes to HIGH if motion is present.
* However, even if motion is present it goes to LOW from time to time,
* which might give the impression no motion is present.
* This program deals with this issue by ignoring LOW-phases shorter than a given time,
* assuming continuous motion is present during these phases.
*/


bool lockLow = true;

PIR::PIR(int nodeId, int pinId, long pause){
_nodeId = nodeId;
_pinId = pinId;
_pause = pause;
}

void PIR::initialise(){

   pinMode(_pinId, INPUT);
   digitalWrite(_pinId, LOW);

   //give the sensor some time to calibrate
   for(int i = 0; i < 30; i++){
       Serial.print(".");
       delay(1000);
   }
   Serial.println("SENSOR ACTIVE");
   _ready = true;
}

void PIR::checkStatus(){
   
   if (_ready == true) {
       
       if(digitalRead(_pinId) == HIGH){
           if(lockLow){  
             //makes sure we wait for a transition to LOW before any further output is made:
             lockLow = false;            
             start = millis()/1000;
             delay(50);
           }        
           takeLowTime = true;
       }
   
       if(digitalRead(_pinId) == 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;                      
                end = (millis() - _pause)/1000;
                Serial.print( _nodeId );
                Serial.print( " " );
                Serial.print( _pinId );
                Serial.print( " " );
                Serial.print( end - start );
                Serial.println();
                delay(50);
              }
      }
   }
}

mike_pa

Hello,

don't use the global variable lockLow, make it a class member instead, othwise this variable is not unique to each sensor!

Mike

Gonzillaaa

Thanks Mike, I tried that but the problem seems to persist. One sensor works more than one doesn't.

Go Up