IR Object counter help

Hi,
I’m totally new to arduino and looking for some help.

I’m looking to build an IR object counter for a production line. It produces 180 pieces per minute and want the counter to tell me every 60 seconds how many pieces have passed.

That way I can know if the line is running below target speed.

I’ve found this tutorial How to make object counter using Infrared sensor Arduino - YouTube

But I need to adapt it to provide a total every 60 seconds.

Where do I start?
Thanks in advance.

Come back after you've built and tested the thing revealed in the video, preferably in the actual deployment circumstances.

Or when you have problems doing that.

a7

Check out the documentation for millis().. It returns the time since the Arduino started running in milliseconds.

Mark the millis() value when the program starts and count to 6000, that's 60 seconds. Report whatever count you have. Reset the counter to zero, mark the millis() and start again.

Good luck.

const unsigned long REPORT_INTERVAL = (1000 * 60); // seconds
unsigned long timer;

const int IR_PIN = 8;
int counter = 0;


void setup() {

  Serial.begin(9600);
  Serial.println("Starting ...");

  pinMode(IR_PIN, INPUT);

  // mark time
  timer = millis();

}

void loop() {

  // if object is passing sensor
  if ( digitalRead(IR_PIN) == LOW )
  {
    // wait for it to pass
    counter += waitForObject();

  } // if

  // time to report?
  if ( millis() - timer >= REPORT_INTERVAL )
  {
    // print count
    Serial.print("Count = ");
    Serial.println(counter);

    // reset
    counter = 0;
    timer = millis();

  } // if

}

int waitForObject()
{
  // while object is still passing
  while ( digitalRead(IR_PIN) == LOW );

  return 1;

}

Edit: thanks blh64, changed 6 => 60.
Edit 2: interval needs to be unsigned long due to edit 1

Your code reports every 6 seconds...

Thanks all. IR sensor should arrive tomorrow and then i can start playing around.

hi blue eyes,
I tried this code and I get the msg Starting... but it doesn't count. Any idea what I'm doing wrong?
Thanks
Alastair

The only way this code con not report anything is if IR_PIN is constantly LOW. This will cause the program to wait forever inside waitForObject(). May read the value and print it out as a start?

Or work with exactly the relatively simple and proven test example sketch from the video. Make sure you have the Serial Monitor set to 9600.

a7

Edit: thanks blh64, changed 6 => 60.

But 60000 doesn't fit in an int, which only goes to 32767.

Or work with exactly the relatively simple and proven test example sketch from the video.

... which doesn't sit and pick its nose in a while() waiting for the object to move out the way.

Code below is the youtube sketch with a report every minute. Note I used INPUT_PULLUP to test with a button from pin to ground.

Counter = 1
Counter = 2
Counter = 3
Counter = 4
Counter = 5
Counter = 6
    Last minute:6
Counter = 1
    Last minute:1
Counter = 1
Counter = 2
Counter = 3
Counter = 4
    Last minute:4
// https://forum.arduino.cc/index.php?topic=688200
// youtube code with timed reporting
// pin8 has input pullup to test with a button

int ir_pin = 8;
int counter = 0;
int hitObject = false;

unsigned long lastReport;
const unsigned long reportInterval = 60000;

void setup()
{
  Serial.begin(9600);
  pinMode(ir_pin, INPUT_PULLUP);
}

void loop()
{

  int val = digitalRead(ir_pin);

  if ( (val == 0) && (hitObject == false) )
  {
    counter++;
    hitObject = true;
    Serial.print("Counter = ");
    Serial.println( counter);
  }
  else if ( (val == 1) && (hitObject == true) )
  {
    hitObject = false;
  }

  if (millis() - lastReport >= reportInterval)
  {
    Serial.print("    Last minute:");
    Serial.println(counter);
    counter = 0;
    lastReport = millis();
  }
}//loop

Use unsigned long for your time elements.
That is what millis() and micros() return.

With millis(), numbers returned will be from 0 right after a restart, uo to 2^32 - 1 if you run the program for 49+ days.
Then it rolls over back to 0 and keeps on going.

evadne:
... which doesn't sit and pick its nose in a while() waiting for the object to move out the way.

Code below is the youtube sketch with a report every minute. Note I used INPUT_PULLUP to test with a button from pin to ground.

Counter = 1

Counter = 2
Counter = 3
Counter = 4
Counter = 5
Counter = 6
    Last minute:6
Counter = 1
    Last minute:1
Counter = 1
Counter = 2
Counter = 3
Counter = 4
    Last minute:4






// IR Object counter help - Programming Questions - Arduino Forum
// youtube code with timed reporting
// pin8 has input pullup to test with a button

int ir_pin = 8;
int counter = 0;
int hitObject = false;

unsigned long lastReport;
const unsigned long reportInterval = 60000;

void setup()
{
  Serial.begin(9600);
  pinMode(ir_pin, INPUT_PULLUP);
}

void loop()
{

int val = digitalRead(ir_pin);

if ( (val == 0) && (hitObject == false) )
  {
    counter++;
    hitObject = true;
    Serial.print("Counter = ");
    Serial.println( counter);
  }
  else if ( (val == 1) && (hitObject == true) )
  {
    hitObject = false;
  }

if (millis() - lastReport >= reportInterval)
  {
    Serial.print("    Last minute:");
    Serial.println(counter);
    counter = 0;
    lastReport = millis();
  }
}//loop

Thanks Evadne! This is exactly what I was looking for. Only problem is I realised my IR sensor is not digital but analog. I simulated it by pulling the wire in and out of PIN 8 and it works great.

How can I change the code to work with an analog IR sensor? Or can I better buy a digital sensor?

Thanks
Alastair

What actually does the sensor output ?

Did I miss it, give a link to your sensor.

Sharp GP2Y0A21YK IR

You could feed the output into a voltage comparator (LM339) then to a digital input.

However, experiment with feeding the output into the analog input and looking for a ‘reasonable’ trigger level to do whatever.

if(analogRead(A0) > 250)
{
bla bla bla
}