Counter problem

Hi all
I have built an infrared light barrier. It is connected with "sensePin".
I want the Arduino to count objects passing the barrier.

The problem:
The program I have, counts while an object is passing the barrier.
That means if the object need a lot of time to pass, the counter will display a high number.

My try to solve:
I said the arduino to wait until the object passed, after it added 1. Pseudocode:

add 1;
write number on the display;

while(object in the barrier)
do nothing;

The arduino stopped to count after 1 object passed the barrier. =(

Thank you for helping!

[//* * Tastendrücke zählen */   
#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,10,7,6,5,4); //Pins für Disply werden festgelegt

//ir
int sensePin= 1;    //Anschluss Fototransistor
int ausloeser= 13;  //Ausloeser um 1 weiter zu zaehlen
int senseValue;     //Wert des analogen Signals


int switchPin = 1;       // Schalter ist mit Pin 1 verbunden 
int val;                   // Variable für den Pin Zustand 
int buttonState;           // Variable für den letzten Schalterzustand 
int buttonPresses = 0;      // Wie oft ist der Schalter gedrückt   

void setup() 
  { pinMode(switchPin, INPUT);             // Schalter-Pin ist Input   
  Serial.begin(9600);                     // Start der seriellen Kommunikation mit 9600bps 
  buttonState = digitalRead(switchPin);     // Anfangszustand lesen 
  lcd.begin(16,4);
  lcd.setCursor(0,0);
  lcd.print("100% i.O.  Dobry");


}     

void loop()
{ senseValue = analogRead(sensePin);

   if (senseValue < 50) 
   {       // Der Zustand des Schalters hat sich verändert 
          
  
    buttonPresses++;               // Inkrementieren der Variablen buttonPresses 
  
    Serial.print("Schalter wurde "); 
    Serial.print(buttonPresses); 
    Serial.println(" gedrueckt");
   lcd.setCursor(0,1);
   lcd.print (buttonPresses);
     } 
   
  
  }]

Where do you set buttonPresses back to zero for the next one?

I can reset the counter by pushing the reset button on my arduino.

Oh yes? And does it work after that for the next object?

You need to detect transitions - something is in front of the sensor now but was not last time, or nothing is in front of the sensor now but was last time. Take action (count the object) only when a transition occurs. It is up to you to decide which transition to count.

Detecting transitions means that you need to keep track of the state/value last time.

I tried it already with a structure like this (code). But i can't us edge detection because the sense value of the infrared receiver is changing every milisecond.

[/void loop() {
  // read the pushbutton input pin:
  buttonState = analogread(sensePin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState <50) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
  
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  ]

But i can't us edge detection

Nonsense. You have some threshold now that says "there is an object in front of the sensor". When that threshold is exceeded, an edge happened.

because the sense value of the infrared receiver is changing every milisecond.

Explain, please. How MUCH does the value change?

The value changes maximum 2.

The value changes maximum 2.

So, you have a big jump when an object passes in front of the sensor, then a little jitter while it is there, and then a big drop when the object is no longer in front of the sensor?

right!

Instead of:

if (buttonState != lastButtonState) {

You could do something like:

if (abs (buttonState - lastButtonState) > 2) {

That detects a change, which is more than 2.

Yes this works. :slight_smile: Thanks a lot Nick Gammon and everyone else.