# Interrupt fires multiple times

I have a Photo Interrupter which I am using to count the RPM of a motor.

I am incrementing an integer to show the amount of interrupts there have been.

The issue is that there can be several interrupts fired for each time the "beam" of the Photo Interrupter is broken.

I have a 5mm length of plastic which breaks the "beam". If I make the plastic shorter than that, the Photo Interrupter doesn't pick up the break.

I am using the following, very basic code:

int pin = 13;
volatile  int tcnt = 0;
volatile int state = LOW;

void setup() {
Serial.begin(9600);
pinMode(pin, OUTPUT);
}

void loop() {
Serial.println(tcnt);
digitalWrite(pin, state);
}

tcnt = tcnt + 1;
state = !state;
}
• Why can there be several interrupts for each break? Do you know for sure (eg via oscilloscope) that multiple interrupts occur for each break? Also, if you know how many interrupts occur for each break, just divide by that number. – James Waldby - jwpat7 Jul 9 '15 at 5:04
• You appear to be asking a couple of different questions, Why does my interrupt fire multiple times? and Why won't my interrupter detect shorter than 5mm of plastic? I've tried to address both of them below, however, in the future please split them out and ask two separate questions. – Jake C Jul 9 '15 at 5:09
• 1) How many is “several”? 2) How do you know there are several interrupts? You must have some independent means of knowing the motor speed. – Edgar Bonet Jul 9 '15 at 7:39
• @jwpat7, I don't have an oscilloscope however in the Serial Monitor I can see that the interrupt fires in clumps. – Daniel Gee Jul 9 '15 at 9:33
• @JakeC, will do. – Daniel Gee Jul 9 '15 at 9:34

I would recommend adding a comparator with hysteresis so as to get a clean digital pulse, pictured below:

simulate this circuit – Schematic created using CircuitLab

This has the correct values.

I recommend the comparator with hysteresis as the phototransistors are prone to cause issues with interrupts even when used with pul-up/pull-down resistors, thus is as they very the voltage more than give a clean 0/1 digitally.

Here is your code, modified with the addition of RISING and of a 10mS delay.

int pin = 13;
volatile  int tcnt = 0;
volatile int state = LOW;

void setup() {
Serial.begin(9600);
pinMode(pin, OUTPUT);
}

void loop() {
Serial.println(tcnt);
digitalWrite(pin, state);
delay(10);
}

tcnt = tcnt + 1;
state = !state;
}

This method produces very reliable results. It is also accurate with objects moving rapidly because of the interrupt.

I would also say that the problem you have when you use a piece of plastic < 5mm is that the length of the slit in the sensor is 6.0±0.1(seen below). If the plastic is less you probably find that the phototransistor still has enough IR falling on it to allow voltage to flow, but enough to trigger and interrupt. With the comparator you could probably use a smaller piece of plastic and find the voltage swing with a DMM and modify the voltage divider (R1 and R2) to suite the needs.

• Thanks for the advice! I'm going to do some reading on comparators first though! – Daniel Gee Jul 10 '15 at 3:38

Two other possible problems, apart from what Jake C has adressed in his answer are:

1. Hardware bounce

If your signal from the sensor isn't a clean transition from high to low but rather "bouncy" (see image below). The microcontroller will register multiple transitions in the meantime.

Solution to this would be to add a small capacitor (wil slow it down though) or add debouncing code... Best would be to get a "clean" sensor.

2. Floating contact

When I even move my finger close to the wire running to PIN2 the interrupt fires.

That kinda seems like it's a floating contact, where it's not really connected to anything.

This is usually solved by using a pullup/pulldown resistor. Or maybe there is something wrong with the connection.

Also:

Maybe due to the type of sensor?

You should note the part number of the sensor or link a datasheet, so we can see if it's typical behaviour for this type of sensor.

• I've set the pin as a pull up. It does seem like it's a floating contact but I've noticed that when I detach the negative or positive lead, the sensor starts act completely like a floating point. The datasheet for the sensor is at: jaycar.com.au/medias/… – Daniel Gee Jul 9 '15 at 16:24
• I had this issue using buttons as interrupts. Adding a capacitor works like a charm! – Kat Apr 4 '20 at 13:47

As far as it firing multiple times, are you aware that you have the interrupt mode set to CHANGE? This means the interrupt will fire once when something enters the beam, and again when something leaves the beam. You will probably want to set it to RISING or FALLING so that it only fires on one of those events, not both.

As to the not detecting issue I can think of a few reasons why this could be:

1. Your motor is moving so fast that the sensor changes again before it has had the chance to finish the interrupt service routine and reset the interrupt on the pin.
2. The photo interrupter you are using is too slow to report the piece of plastic passing through it. Sensors like this usually indicate a rise time and a fall time, and if it moves through the beam faster than these times it will not register the interruption.
3. The piece of plastic isn't large enough to block the beam. Depending on the photo interrupter, the beam used could be laser like and very narrow, or it could be wide and more like a flashlight. If it is more like the latter, you will need to have enough material present to block enough light to set off the sensor.
• Thanks for the response! I have set the mode to RISING with no luck. The sensor should be fast enough but it seems that the sensor doesn't work well with the pull-up pin. I've set the pin as INPUT_PULLUP but I still get the interrupt firing intermittently. When I even move my finger close to the wire running to PIN2 the interrupt fires. It's like it's not grounded. Maybe due to the type of sensor? – Daniel Gee Jul 9 '15 at 9:31