Arduino - IR Slotted Optical Speed Sensor

In this tutorial, we are going to learn:

Arduino IR slotted optical speed sensor

About IR Slotted Optical Speed Sensor

The IR slotted optical speed sensor is a small U-shaped module. People also call it a slot sensor, an opto interrupter or a U-shaped IR sensor. It tells Arduino if something is inside its slot or not. With an encoder disc, it can also tell how fast a motor or a wheel turns.

IR Slotted Optical Speed Sensor
Sensor Type slot-type photoelectric (IR LED + NPN phototransistor)
Slot Width 5.9 mm
Operating Voltage 3.3V to 5V DC
Output digital (TTL), LOW when blocked, HIGH when clear
Signal Conditioning built-in Schmitt trigger
Mounting M3 screw holes at both ends
Pins 3 (VCC, GND, OUT)

You can use it for:

  • Measuring motor speed (RPM) with an encoder disc
  • Making a tachometer
  • Counting objects or pulses
  • Measuring distance by counting wheel turns
  • Getting wheel speed feedback on a robot
  • Detecting a limit or a position

Pinout

IR Slotted Optical Speed Sensor Pinout

The IR slotted optical speed sensor has three pins:

  • VCC pin: needs to be connected to VCC (5V, or 3.3V)
  • GND pin: needs to be connected to GND (0V)
  • OUT pin: is a digital output pin. It is LOW when the slot is blocked and HIGH when the slot is clear. This pin needs to be connected to an input pin of Arduino.

The pin order may be different between batches. Please read the labels on your module.

How It Works

How IR slotted optical speed sensor works

One side of the U has an infrared LED. The other side has an NPN phototransistor. They face each other across the 5.9 mm slot.

  • When the slot is empty, the IR light reaches the phototransistor. The OUT pin is HIGH.
  • When an opaque object (a piece of card, or a tooth of an encoder disc) goes into the slot, it blocks the light. The OUT pin is LOW.

The built-in Schmitt trigger makes the output a clean and stable 0 or 1, with no jitter. So we do not need to debounce it in the code.

A few tips:

  • Use opaque objects. A transparent object may not block the IR light well.
  • Some modules from other makers work the other way round. If your sensor says "blocked" when the slot is empty, just swap LOW and HIGH in the first code. The RPM code counts one edge per tooth, so it works either way.

Measuring Speed With an Encoder Disc

An encoder disc is a round plate with slots (holes) near its edge. The common disc for TT gear motors has 20 slots. Fix the disc on the motor shaft or on the wheel, so its teeth pass through the slot of the sensor without touching it.

When the disc spins, each tooth blocks the light for a moment. The OUT pin gives one pulse per tooth. One full turn gives 20 pulses. Arduino counts the pulses in 1 second and then works out the speed:

  • Pulses in 1 second × 60 = pulses in 1 minute
  • Pulses in 1 minute ÷ 20 = turns in 1 minute (RPM)

Wiring Diagram

Connect VCC of the sensor to 5V of Arduino, GND to GND, and OUT to pin 2 of Arduino, as shown in the image below.

Arduino IR Slotted Optical Speed Sensor Wiring Diagram

This image is created using Fritzing. Click to enlarge image

We use pin 2 because it is an interrupt pin on Arduino Uno. The RPM code needs it.

How To Program For IR Slotted Optical Speed Sensor

  • No library needed: the code uses only built-in functions.
  • Define the pin: const int SENSOR_PIN = 2;
  • Set the pin as input with pinMode(): pinMode(SENSOR_PIN, INPUT);
  • Read the state with digitalRead(): int state = digitalRead(SENSOR_PIN);
  • Check the state: if (state == LOW) means something is in the slot. HIGH means the slot is clear.
  • To count fast pulses, use an interrupt. Each time the OUT pin goes from HIGH to LOW (a tooth blocks the slot), Arduino runs a small function: attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), countPulse, FALLING);
  • Keep the counter volatile, because it changes inside the interrupt: volatile unsigned long pulseCount = 0;
  • Every 1 second, turn the pulses into RPM: float rpm = pulses * 60.0 / SLOTS_PER_TURN;

Why use an interrupt? When the motor spins fast, the pulses are very short. If we only check the pin in loop(), we may miss some of them. The interrupt catches every pulse. We use FALLING so each tooth is counted only once.

Arduino Code - Detect Object in the Slot

The code below does these things:

  • Reads the OUT pin again and again
  • Prints a message only when the state changes
  • Counts how many times the slot is blocked
/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-ir-slotted-optical-speed-sensor */ const int SENSOR_PIN = 2; // Arduino pin connected to the OUT pin of the speed sensor int lastState; // the previous state of the sensor int objectCount = 0; // how many times the slot was blocked void setup() { Serial.begin(9600); pinMode(SENSOR_PIN, INPUT); lastState = digitalRead(SENSOR_PIN); } void loop() { int state = digitalRead(SENSOR_PIN); if (state != lastState) { // the state has changed if (state == LOW) { // LOW = something is in the slot objectCount++; Serial.print("The slot is blocked - count: "); Serial.println(objectCount); } else { // HIGH = the slot is clear Serial.println("The slot is clear"); } lastState = state; } }

Quick Steps

  • Do the wiring as shown in the diagram above.
  • Connect Arduino to PC via USB cable.
  • Open Arduino IDE. Navigate to the Tools menu, select the right board and port.
  • Copy the above code and paste it to Arduino IDE.
  • Click Upload button on Arduino IDE to upload code to Arduino.
  • Open the Serial Monitor (baud rate 9600).
  • Pass a piece of card or your finger through the slot a few times.
  • See the result on Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
The slot is blocked - count: 1 The slot is clear The slot is blocked - count: 2 The slot is clear The slot is blocked - count: 3 The slot is clear
Ln 11, Col 1
Arduino Uno on COM15
2

Arduino Code - Measure Motor Speed (RPM)

The code below does these things:

  • Counts one pulse each time a tooth of the disc blocks the slot (interrupt on the FALLING edge)
  • Every 1 second, works out the speed in RPM
  • Prints the number of pulses and the speed
/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-ir-slotted-optical-speed-sensor */ const int SENSOR_PIN = 2; // Arduino pin connected to the OUT pin of the speed sensor const int SLOTS_PER_TURN = 20; // number of slots (holes) in the encoder disc volatile unsigned long pulseCount = 0; // changed inside the interrupt unsigned long lastTime = 0; // runs every time a tooth of the disc blocks the slot void countPulse() { pulseCount++; } void setup() { Serial.begin(9600); pinMode(SENSOR_PIN, INPUT); attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), countPulse, FALLING); } void loop() { if (millis() - lastTime >= 1000) { // every 1 second lastTime = millis(); noInterrupts(); // read and reset the counter safely unsigned long pulses = pulseCount; pulseCount = 0; interrupts(); float rpm = pulses * 60.0 / SLOTS_PER_TURN; // pulses per second -> turns per minute Serial.print("Pulses: "); Serial.print(pulses); Serial.print(" | Speed: "); Serial.print(rpm); Serial.println(" RPM"); } }

The code uses SLOTS_PER_TURN = 20. If your encoder disc has a different number of slots, change this number.

Quick Steps

  • Fix the encoder disc on the motor shaft or wheel, so its teeth pass through the slot.
  • Keep the same wiring as in the first code.
  • Copy the above code, paste it to Arduino IDE and upload it.
  • Spin the disc by hand, or power the motor. To drive the motor, see Arduino - DC Motor.
  • See the result on Serial Monitor. The example below is a motor spinning at about 300 RPM.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
Pulses: 0 | Speed: 0.00 RPM Pulses: 98 | Speed: 294.00 RPM Pulses: 101 | Speed: 303.00 RPM Pulses: 100 | Speed: 300.00 RPM Pulses: 99 | Speed: 297.00 RPM Pulses: 0 | Speed: 0.00 RPM
Ln 11, Col 1
Arduino Uno on COM15
2

For example, 100 pulses in 1 second gives 100 × 60 ÷ 20 = 300 RPM.

Do you want to find the distance a wheel travels? Multiply the number of turns by the wheel circumference (π × wheel diameter).

If you want to detect an object at a distance (not inside a slot), see Arduino - Infrared Obstacle Avoidance Sensor. If you want to read a knob and its direction, see Arduino - Rotary Encoder.

Video Tutorial

We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

Function References

The Best Arduino Starter Kit

※ OUR MESSAGES