Break Beam Sensor - Code in a delay or double check?

Fairly new to coding, so bare with me on this one. I'm using a break beam IR sensor to activate a motor. It's a fairly simple code currently. Basically the motor shuts off when the beam is broken and turns on when the beam is not broken.

What I want to play around with is adding a delay for shutting off the motor. There are two methods I'm considering:

  1. Coding in a present delay in milliseconds prior to the motor shutting off.

or

  1. Once the beam is broken, add a delay for a few milliseconds, then check the sensor state for a second time. If the state is the same, so in this case the beam remains broken, then shut off the motor. If the state has changed, and the beam is no longer broken, leave the motor running.

I'm using the motor to drive a sort of marble conveyer belt. With the current basic code I find it doesn't move very consistently since every time the beam is broken the motor shuts off even if just for a split second. I have a feeling the second option will result in a smoother flow but I'm no where close to being able to code it.

Definitely willing to learn if anyone can even just point me in the right direction.

Thanks!

Sounds like you need debounce code, which is commonly used for a switch.
Google "Arduino debounce".
Leo..

Thanks!

This is a great starting point. Hopefully I'll be able to work it into my existing code.

The theory behind it is this:

  1. Read the pin frequently and look for a change.
  2. If there is, wait for x milliseconds and read the pin again.
  3. If it's still the same, then it must be true.

Waiting can be done with a simple delay(), if the code allows you to stop.
Or can be done with non-blocking millis() timing.
Leo..

Makes sense. Right now I'm just using IF and ELSE:

void loop(){
sensorState = digitalRead(SENSORPIN);

// check if the sensor beam is broken
// if it is not, the sensorState is HIGH:
if (sensorState == HIGH) {
// turn LED on:
digitalWrite(LEDPIN, HIGH);
// turn on motor
digitalWrite(dir1, LOW);
digitalWrite(dir2, HIGH);
}
else {
delay(70);
// Turn off LED
digitalWrite(LEDPIN, LOW);
// Turn off motor
digitalWrite(dir1, LOW);
digitalWrite(dir2, LOW);

So basically when the IR sensor is not broken the sensorState is High. The LED for pin 13 turns on and dir1 & dir2 are connected to a DRV8838 motor driver to start the motor. When the IR sensor is broken the sensorState is LOW. I have a slight delay to add a little back pressure to the next marble and then turn off the LED and the motor.

This currently works but it's not consistent. As the marble breaks the IR beam the motor is shut of for a split second even though the marble is just passing by and not actually stopping. What I hope to have happen is when the IR sensor is broken, I will use debounce to wait x milliseconds allowing the moving marble to pass the sensor without stopping the motor.

I've gone through the debounce tutorial using a standard push button. Next step is to get it working with the break beam sensor and then apply it to my code.

You assume that after the delay(70) sensorState is still low, and then turn the motor off.
Not what you want.
You must make sure the pin is still LOW after 70ms, by reading the pin again.
Basic example attached.
Maybe try to code with pin change (not state) and millis().
Leo..

void loop() {
  if (digitalRead(sensorPin) == HIGH) {
    digitalWrite(LEDPIN, HIGH); // LED on
    digitalWrite(dir1, LOW);
    digitalWrite(dir2, HIGH);
  }
  else { // if LOW
    delay(70); // wait before making sure
    if (digitalRead(sensorPin) == LOW) { // if still LOW
      digitalWrite(LEDPIN, LOW); // LED off
      digitalWrite(dir1, LOW);
      digitalWrite(dir2, LOW);
    }
  }
}

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