Slotted photo interrupter

A slotted optical switch on its small board (the KY-010), with an encoder wheel to spin through the slot.

Aliases: photo interrupter, optical endstop, speed sensor, slot sensor.

An infrared LED in one arm of a U, a phototransistor in the other, and a gap between them. Anything opaque in the gap cuts the beam. It is how a printer finds home, how a robot car counts wheel turns, and how a class measures the speed of a fan.

Pins

Pin What it does
SIG Printed S. LOW while the beam gets through, HIGH while something is in the slot.
VCC Printed +. Supply, 3.3 V or 5 V.
GND Printed -. Ground.

Properties

slots is how many slots the encoder disc has, 20 by default: the black disc that comes with two-wheel robot chassis.

While it runs

The slider spins the wheel through the slot, 0 to 600 RPM. The card beside it is a piece of cardboard: click it to push it into the slot, and again to pull it out. The beam drawn across the gap is lit while light gets through.

Counting the wheel

Every slot is one pulse on SIG, so

RPM = pulses a second x 60 / slots

Count rising edges with an interrupt and read the count once a second:

volatile unsigned int pulses = 0;
void countSlot() { pulses++; }

void setup() {
  attachInterrupt(digitalPinToInterrupt(3), countSlot, RISING);
}

What the model gets right

Blocked is high. The board puts a 10 k pull-up on the phototransistor's collector. Light turns the transistor on and pulls SIG low; blocking the beam lets the pull-up take it high.

The saturation voltage. From the Everlight ITR9608 datasheet, the class of part on these boards: at least 0.5 mA of collector current with the LED on, and 0.4 V at most across the transistor at that current. Beam through, SIG sits at 0.4 V.

The edge time. The sheet's rise and fall time is 15 µs, and SIG follows the beam 15 µs late. A slot that passes faster than that is not seen cleanly on the real part either.

The wheel. Slots and spokes are the same width, so the beam is open half of each slot period. A stopped wheel rests on a slot, with the beam through.

What it does not model

Ambient light, partial blocking, and the LED current.

Common mistakes

Reading it the wrong way around: HIGH means blocked.

Counting in loop() with digitalRead. At a few hundred RPM a 20-slot wheel makes pulses a few milliseconds long, and a loop that also prints misses them; use an interrupt.

See it in action

Heat, magnet and wheel counts a 20-slot wheel on pin 3 and prints the RPM. Open it at /templates.