I am using a very simple IR sensor (www.velleman.eu/products/view/?id=349823) in order to count the amount of people that pass.
I used a piece of code, but with this it is not just counting each time the beam is interrupted, but keeps on counting while the beam is interrupted.
I have been searchiing the forums but i can;t seem to find a solution, although i think it is such a simple thing.
anybody can help?
willem
int pirPin = 2; //digital 2
int counter = 0;
int state;
int laststate = HIGH;
thanks. It's my first post to the forum, so i am not yet at all used to the formalities.
e.g. your sketch does also not
differentiate between people walking back and forth.
detecting 2 persons simultaneously
slow versus fast people
-I don't mind about people walking back and forth, a passer by is a passer by
-detecting two people simultaneously is something for the future
-slow vs fast: as long as i can count them i am happy.
The problem remains with your adaptation to the code: it starts counting the moment the beam is interrupted, but it keeps on counting till the interruption is gone.
need to find a way to let it count only when the state changes, from HIGH to LOW, and stop counting until another state-change takes place.
The problem remains with your adaptation to the code: it starts counting the moment the beam is interrupted, but it keeps on counting till the interruption is gone.
if state reads HIGH lastState becomes HIGH too, and as long as state reads HIGH the code will not come in the if part again. (it does come in the if part when going from HIGH to LOW so it will probably double your counts)
==> unless you have noise on your line which changes state continuously...
try
void loop()
{
int state = digitalRead(pirPin);
Serial.println(state);
}
what does it do ?
At which distance the PIR switches from LOW -> HIGH ?
and back HIGH -> LOW ?
do you have a type id of the PIR ?
link to datasheet ?
or this one
int pirPin = 2;
int counter = 0;
int laststate = HIGH;
void setup()
{
Serial.begin(9600);
pinMode(pirPin, INPUT);
}
void loop()
{
int state = digitalRead(pirPin);
if (laststate == LOW && state == HIGH) // only count on a LOW-> HIGH transition
{
count++;
Serial.println(count);
}
laststate = state; // remember last state
}
==> unless you have noise on your line which changes state continuously...
i tried your code
and yes, it continuesly changes state when the beam is interrupted.
the uninterrupted state is HIGH, when the beam is interrupted it bounces from HIGH to LOW, that's obviously why it keeps on counting.
the sensor is a velleman pem7d, it is a retroreflective IR sensor.
The URL doesn't seem to be directed to the product details, but to the velleman main website, so i'll quote the stats here:
nominal detection range: 7m
light source: IR LED
working temperature: -20°C to +50°C
power supply: DC 9-15V regulated (adapter included)
total current consumption: < 130mA
standby current: 25mA
IP rating: IP44
output: NPN output
I have found some code examples to get around the debounce, i'll try some of those.
OK, found a debounce code and it seems to work fine: counting each time the beam is interrupted.
probably need to tingle a bit with the delay times, but it seems to work sound.
thanks
//Debounce
//31mar10
//For http://sheepdogguides.com/arduino/
// aht0bounce1.htm
//Note that processing of switch is "blocking"... nothing useful will
// be done until switch is released... but there can be an action
// which happens just after switch pressed.
const int Inp0=13;//connect a momentary switch
//connected to GND to this pin
const int Out0=12;//connect an LED and resistor
//connected to GND to this pin.
//LED is just for a "switch state" indicator
int counter;
void setup()
{
Serial.begin(9600);
pinMode(Inp0,INPUT);
digitalWrite(Inp0,HIGH);//Yes... WRITE to the input pin...#
//This causes the Arduino to "attach" an internal pull up
//resistor to the input pin.
pinMode(Out0,OUTPUT);
digitalWrite(Out0,LOW);//Turn LED off to start with.
};
void loop()
{
if (digitalRead(Inp0)==LOW) {DealWithSwitchPress();};
};
void DealWithSwitchPress()
{
digitalWrite(Out0,HIGH);
delay(100);//Wait while closure-of-switch bounces pass
//
//Put here: Stuff to happen when switch closed
counter++;
Serial.println(counter);
//
while (digitalRead(Inp0)==LOW){;};//do nothing while waiting
digitalWrite(Out0,LOW);
delay(100);//Wait while opening-of-switch bounces pass
//
//Put here: Stuff to happen when switch finishes opening
//
}
are the multiple counts due to reflective differences? possibly due to variations in clothing texture or
folding? requiring the debounce and is the input a schmidt-trigger type?
as i said, i found a solution to the bouncing.
everthing working fine.
now i want to expand, i added a timer, so it returns the amount of pulses in the last 10 seconds
the code looks like this:
#include <SimpleTimer.h>
/*
* SimpleTimerAlarmExample.pde
*
* Based on usage example for Time + TimeAlarm libraries
*
* A timer is called every 15 seconds
* Another timer is called once only after 10 seconds
* A third timer is called 10 times.
*
*/
// There must be one global SimpleTimer object.
// More SimpleTimer objects can be created and run,
// although there is little point in doing so.
SimpleTimer timer;
int counter;
const int Inp0=2;
// function to be called repeatedly
void RepeatTask() {
Serial.println(counter);
Serial.println();
counter =0;
}
// print current arduino "uptime" on the serial port
void DigitalClockDisplay() {
int h,m,s;
s = millis() / 1000;
m = s / 60;
h = s / 3600;
s = s - m * 60;
m = m - h * 60;
Serial.print(h);
printDigits(m);
printDigits(s);
Serial.println();
}
//
// utility function for digital clock display:
// prints preceding colon and leading 0
//
void printDigits(int digits) {
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void setup() {
Serial.begin(9600);
pinMode(Inp0,INPUT);
digitalWrite(Inp0,HIGH);
// timed actions setup
timer.setInterval(10000, DigitalClockDisplay);
timer.setInterval(10000, RepeatTask);
}
void loop() {
// this is where the "polling" occurs
timer.run();
if (digitalRead(Inp0)==LOW) {DealWithSwitchPress();}
}
void DealWithSwitchPress()
{
timer.run();
delay(100);//Wait while closure-of-switch bounces pass
//
//Put here: Stuff to happen when switch closed
counter++;
//
while (digitalRead(Inp0)==LOW){
timer.run();};//do nothing while waiting
delay(100);//Wait while opening-of-switch bounces pass
//
//Put here: Stuff to happen when switch finishes opening
//
}
that works fine, but then i want to add a second sensor, i just expanded the code to this:
#include <SimpleTimer.h>
/*
* SimpleTimerAlarmExample.pde
*
* Based on usage example for Time + TimeAlarm libraries
*
* A timer is called every 15 seconds
* Another timer is called once only after 10 seconds
* A third timer is called 10 times.
*
*/
// There must be one global SimpleTimer object.
// More SimpleTimer objects can be created and run,
// although there is little point in doing so.
SimpleTimer timer;
int counter1;
int counter2;
const int Inp1=2; //counter input
const int Inp2=3;
// function to be called repeatedly
void RepeatTask() {
Serial.print("counter 1: ");
Serial.println(counter1);
Serial.print("counter 2: ");
Serial.println(counter2);
Serial.println();
counter1 = 0;
counter2 = 0;
}
// print current arduino "uptime" on the serial port
void DigitalClockDisplay() {
int h,m,s;
s = millis() / 1000;
m = s / 60;
h = s / 3600;
s = s - m * 60;
m = m - h * 60;
Serial.print(h);
printDigits(m);
printDigits(s);
Serial.println();
}
//
// utility function for digital clock display:
// prints preceding colon and leading 0
//
void printDigits(int digits) {
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void setup() {
Serial.begin(9600);
pinMode(Inp1,INPUT);
digitalWrite(Inp1,HIGH);
pinMode(Inp2,INPUT);
digitalWrite(Inp2,HIGH);
// timed actions setup
timer.setInterval(10000, DigitalClockDisplay);
timer.setInterval(10000, RepeatTask);
}
void loop() {
// this is where the "polling" occurs
timer.run();
if (digitalRead(Inp1)==LOW) {DealWithSwitchPress1();}
if (digitalRead(Inp2)==LOW) {DealWithSwitchPress2();}
}
void DealWithSwitchPress1()
{
timer.run();
delay(100);//Wait while closure-of-switch bounces pass
//
//Put here: Stuff to happen when switch closed
counter1++;
//
while (digitalRead(Inp1)==LOW){
timer.run();};//do nothing while waiting
delay(100);//Wait while opening-of-switch bounces pass
//
//Put here: Stuff to happen when switch finishes opening
//
}
void DealWithSwitchPress2()
{
timer.run();
delay(100);//Wait while closure-of-switch bounces pass
//
//Put here: Stuff to happen when switch closed
counter2++;
//
while (digitalRead(Inp2)==LOW){
timer.run();};//do nothing while waiting
delay(100);//Wait while opening-of-switch bounces pass
//
//Put here: Stuff to happen when switch finishes opening
//
}
And then it counts irregularly, either the first or the second sensor.
I think it has to do with the delay in the debouncing: the moment it is in de debouncing loop of the first sensor, it doesn't get input of the second one.
I am right? and what can i do about it?
one more time, hopefully there is somebody who can help me.
think it has to do with the delay in the debouncing: the moment it is in de debouncing loop of the first sensor, it doesn't get input of the second one.
I am right?
I was not right: it is of course the "while" function
once one sensor is LOW, the code tells it to wait and do nothing, so it also doesn't detect if the second sensor goes low.
this is a problem since i want both sensors to work on different spots at the same time