Counting pulses with photosensor. Counts tens of pulses per FALL or RISE

Hello everybody,

So I do have this photosensor:

At the moment I have problems with photosensor counting too many pulses. When I move my finger to slot it reads 20-1000 pulses. when i move it out it reads less pulses, maybe 2-20.

I have tried to set interrupt to FALLING or RISING edge, but none of this helps. When my encoder wheel (2 RISING edges per rotation) rotates one turn, sensor counts 8 pulses?

E1:This is going to be in car dynamometer. I need to get rpm at least 10 times per second for pid controller.

E2:I stripped all other connected devices from arduino. Still the same problem.

I'm really lost with this. Should I move to another pulse counting way? maybe something like this:

Here is my code (mainly copied and/or modified)

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;
unsigned long revCount;

unsigned long prevDisplayMillis;
unsigned long  displayInterval = 100;

    // variables for the ISR
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;





#include <MobaTools.h>

const byte stepPin = 4;
const byte dirPin = 3;
double rpm;

MoToStepper stepper1( 400, STEPDIR );  // create a stepper instance


#include <TM1637Display.h>
#define CLK A5
#define DIO A4

 TM1637Display display(CLK, DIO);





void setup() {



    isrCount = 0;
    attachInterrupt(0, revDetectorISR, FALLING );


   Serial.begin(38400);  
  display.clear();
  display.setBrightness(7);
  
  stepper1.attach( stepPin, dirPin );
  stepper1.setSpeed( 3600 );              // 30 rev/min (if stepsPerRev is set correctly)
  stepper1.setRampLen( 10); // Ramp length is 1/2 revolution
  stepper1.doSteps(400);
  // stepper1.rotate(1);                    // start turning, 1=forward, -1=backwards                    
}

void loop() {

getIsrData();
    if (millis() - prevDisplayMillis >= displayInterval) {

        
        prevDisplayMillis += displayInterval;
        display.showNumberDecEx(revCount);
       Serial.println(revDuration);
       Serial.println(rpm);
       
      
    }
  

   
}


 void getIsrData() {
    if (newIsrMicros == true) {
        prevRevMicros = revMicros; // save the previous value
        noInterrupts();
            revMicros = isrMicros;
            revCount = isrCount;
            newIsrMicros = false;
        interrupts();
        revDuration = revMicros - prevRevMicros;
       
    }
}

void revDetectorISR() {
    isrMicros = micros();
    isrCount ++;
    newIsrMicros = true;

}

BR Hautamak

That is the equivalent of switch bounce -- multiple transitions, which could be due to poor sensor design, like failure to incorporate hysteresis.

Use of interrupts just makes the problem worse, because to ignore the bouncing you need to incorporate a delay in response.

Which controller are You using?
Pin 0, D0, is Tx or Rx on some controllers.

Why the encoder? The stepper speed is set in Setup. There is no slipp in a stepper. Either it runs the speed assigned or it stops, halts, making noise. Is the interrupter measuring something else then the stepper speed?

To which pin is that interrupt tied on your board?
You should use digitalPinToInterrupt(pin) to convert the Arduino pin number to the related interrupt.

The LM393 has NPN outputs which require a pull-up resistor.

Hello,

I'm attaching it to D2 alias interrupt 0.
Thanks for pointing out. It didn't change anything but may save me from headache in future.

It's pin D2. nano
Encoder is for reading motor rpm. Stepper motor is for controlling dynometer unit. Interrupt worked, but had very much bouncing effect.

jremington, thanks for pointing out the bounce. I set 1ms bounce for interrupt and now it working great. 1ms allows motor rpms up to 10 000.

Thanks for everybody

A photo sensor does not bounce at all.

I don't get it? why does it work after I placed debounce in code?

Now it captures 400 pulses when stepper turns 100 rotations (4 pulses/rotation). No more missed or extra pulses

I see. You fix bad hardware (missing pullups) by software.

I did put pullups on pin2 where i have interrupt attached. However it did not change extra pulses.

Then you have more hardware bugs.

Yes they certainly do. The equivalent of "switch bounce" is multiple transitions, exactly as the OP has described.

They are trivially observed when a slow moving object passes through the beam, especially if hysteresis is not incorporated into the design.

You state that you used your FINGER. Look at the wheel normally used by the sensor. It is photographically created with openings that extremely sharp edges. Your finger has neither and is also mostly transparent to IR light.

Okay, maybe I should be more clear about this. I did test it with my finger but I do also tested it with 3d printed encoder wheels ( different colors).

I will try with sharp edge and see if it's making the difference.

For now, the debounce code is sufficient for this use.

Hautamak

But the sensor used IR light and your colored plastic was transparent to IR light. Do you understand the difference between what we see as visible light and infrared light?

1 Like

It does behave same, even if I try with metal or wood.

It's been my understanding that an optical rotary encoder produces no bouncing. I've never actually used one, but now I wonder if that's true. But I don't see how you would get bouncing with optical sensors. It seems that the receiver should just smoothly transition. Why would that not be true?

Any chance the lines involved in this case are long enough that reflections could be producing multiple triggers? Well, just looking for anything that actually makes sense.

They simply can not bounce. But the subsequent opamp can oscillate during a transition. That's inappropriate circuit design, either a comparator or at least hysteresis should prevent transient oscillations.

A scope could reveal the trouble source easily.

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