PIR sensor help part counter

Hello,

I am attempting to use motion detection to increase the count on an LCD screen. Right now, the count is increasing whether there is motion or not. I want it so that every time there is motion detected I would like to add one to variable count which is then displayed on the LCD. The serial monitor seems to be working correctly, with a 1 being displayed when motion is detected otherwise being a zero. I am doing this on tinkercad until my Arduino Mega arrives.

#include <Keypad.h> //libraries
#include <Adafruit_LiquidCrystal.h>

static int count = 0; //variable used as first number
Adafruit_LiquidCrystal lcd_1(0);
const byte ROWS = 4;
const byte COLS = 4;
int sensorStatus = digitalRead(13);
bool blinking = false;

	void partLoc(){
  		lcd_1.setCursor(7,1);
		}

	void fabLoc(){
  		lcd_1.setCursor(11,0);
		}
  
	void clearScreen(){
  		lcd_1.print("     ");
		}

	void countUp(){        
  		++count;
    	partLoc();
    	clearScreen();
        partLoc();
    	lcd_1.print(count);
  	for (int i = 0; i <= 16; i++) {
    	blinking=false;
        lcd_1.setCursor(i,1);
      	}
  		}

	void countDown(){
  		if(count!=0){
        	--count;
       		partLoc();
    		clearScreen();
        	partLoc();
    		lcd_1.print(count);
          	partLoc();
          	lcd_1.print(count);
        for (int i = 0; i <= 16; i++) {
    		blinking=false;
        	lcd_1.setCursor(i,1);
      		}
      		}
    	}
    	
  

char hexaKeys [ROWS][COLS] ={
  			{'1','2','3','A'},
  			{'4','5','6','B'},
  			{'7','8','9','C'},
  			{'*','0','#','D'}
			};

byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);



void setup()
{
  Serial.begin(9600);
  pinMode(13,INPUT);
  lcd_1.begin(16, 2);
  lcd_1.print("Fab Cell #");
  lcd_1.setCursor(0,1);
  lcd_1.print("Part #");
  lcd_1.setCursor(11,0);
  lcd_1.blink();
}



void loop(){
  
  int sensor = digitalRead(13);
  Serial.println(sensor);
  
  char customKey = customKeypad.getKey();
  
  if (blinking){
    lcd_1.blink();
  	}
  
  if (sensor=HIGH){
    countUp();
    delay(100);
  	} 
  
  
  
  //Switchcase Statements

  switch (customKey){
    
    case 'C':
      countUp();
      break;

    case 'D':
      countDown();
      break;

    case '*':
      fabLoc();
      clearScreen();
      fabLoc();
      blinking = true;
      break;		
  	}

  // Allows button input from buttons 0 - 9
	if ((customKey>='0') && (customKey <= '9')){
  		lcd_1.print(customKey);
		}
  
  //When A is pressed it clears the blinking and "confirms" the number
  	if (customKey=='A'){
      	for (int i = 0; i <= 16; i++) {
    		blinking=false;
        	lcd_1.setCursor(i,0);
      		}
    	for (int i = 0; i <= 16; i++) {
    		blinking=false;
        	lcd_1.setCursor(i,1);
      		}
  		}
  
  //When B is pressed the count resets
  	if (customKey=='B'){
    	count=0;
    	partLoc();
    	lcd_1.print(count);
  	for (int i = 0; i <= 16; i++) {
    	blinking=false;
        lcd_1.setCursor(i,1);
      	}
  }
}


  if (sensor = HIGH)

Should be ==

You have to know when the sensor stops detecting motion in order to know when it detects it the next time. The same object may be in the detection field for some period of time. A very poor system design.

I am very new to arduino code, how do you recommend I fix this problem.

Fix it by determining when the PIR turns off, again. Then you should be back at the original condition. There is the problem, of course, when the PIR is sensing motion when the program begins when power is first applied. So the very first thing to do in you program is to be sure the PIR is off before beginning your normal logic.

What you see in the serial monitor is

0
0
0
0
1
1
1
1
1
0
0
0

etc.
loop is looping all code inside function loop() is repeated
including these lines

  if (sensor = HIGH) {
    countUp();
    delay(100);
  }

which should be

  if (sensor == HIGH) { // DOUBLE equalsign for comparing
    countUp();
    delay(100);
  }

double

equal-sign

==

Even with a double-equal-sign it does not yet work. You are checking for input IS HIGH

What you need is state-change-detection.
When does the input change from LOW to HIGH

best regards Stefan

2 Likes

I am using a PIR sensor to make an object counter. What I am realizing is that when there is an object in the range of the sensor, the sensor will repeatedly give off a one signal. Ideally, I would want it to read a singular one but I am unsure of how to do that. The issue I am having is that I am linking the count to the PIR sensor directly. In other words, every time I have a high output, which is multiple times in an instance (when ideally it would be once), the count goes up, which results in a count that is higher than the number of times an object passes through. Any help is appreciated thanks!

Have a look at external interrupts.

1 Like

Not sure how interrupts are going to help, but maybe look at the state-change detection example in the IDE

A PIR sensor uses change in passive IR with time. So, it typically is used to detect people or other IR sources. I'm glad you are able to detect objects with it.

Could you please post a link to the sensor you are using?
Since they detect change, they will typically have a time out period that is adjustable. This prevents re-triggering.

The way I understood the question is the the output of the PIR is read
in the loop several times for the same "detection",
Of course I may be wrong.

int counter;
const byte pir_pin = 2;
volatile byte state = LOW;
void detected() {
  state = HIGH;
}
void setup() {
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(pir_pin), detected, RISING);
}

void loop() {
  if (state == HIGH) {
    counter++;
    Serial.println(counter);
    state = LOW;
  }
}

Hi,
how about posting schematic?

1 Like

Rubbish!

And interrupts are not an appropriate way to solve that; proper coding is.

Mind you, I grant you a clever trick using the "RISING" function. :thinking:

Problem is, we are not at all sure what "every time I have a high output, which is multiple times in an instance" is supposed to mean.

It is convenient that the PIR output (given the sensor has an logic output, not a relay contact) has no "bounce" as a bouncing output would totally wreck your interrupt concept! :grin:

As @cncnotes points out, PIR sensors deliberately have a persistent output over a specific time as what they are actually detecting is an oscillating signal as the target moves over zones of the Fresnel lens. It would not be appropriate to signal each oscillation in any case.

If @jonathanmm is having a problem with the PIR output remaining high over successive cycles of the loop(), then the answer is to set a flag at the first pass and only increment the count when the flag was not previously set - at that first pass. The flag is then cleared when the PIR output goes low.

But I suspect that is not the entire problem. If an "instance" refer to the continuing presence of an object (a warm one in the case of PIR), then he needs some way of discerning whether it is the same object which is moving (thus re-triggering the PIR) but has not gone away; that is a whole different matter. He would have to consider a simple time delay - how long each object is likely to stay (moving) around as against the delay before a new object arrives.

1 Like

I am using a PIR sensor to make an object counter. What I am realizing is that when there is an object in the range of the sensor, the sensor will repeatedly give off a one signal. Ideally, I would want it to read a singular one but I am unsure of how to do that. The issue I am having is that I am linking the count to the PIR sensor directly. In other words, every time I have a high output, which is multiple times in an instance (when ideally it would be once), the count goes up, which results in a count that is higher than the number of times an object passes through. Any help is appreciated thanks!

@jonathanmm,

I have deleted one of your multiple topics on this subject and merged the other 3. I've given you a ban from posting until next week to give you time to familiarise yourself with the forum instructions:

If you continue to post the same question in multiple topics your ban will be permanent.

Thank you.

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