Raspberry Pi - IR Slotted Optical Speed Sensor

This tutorial instructs you how to use Raspberry Pi to read the pulses from an IR slotted optical speed sensor with a short Python script. You may also know this part as a photo interrupter or an opto interrupter. It sees when something passes through its narrow gap. With that one signal, the Raspberry Pi can count objects, or it can tell how fast a wheel or a motor shaft turns. In detail, we will learn:

We suggest:

Raspberry Pi and IR slotted optical speed sensor

Hardware Preparation

1×Raspberry Pi 5
1×IR Slotted Optical Speed Sensor
1×Jumper Wires
1×Optionally, Breadboard
1×Recommended: Screw Terminal Block Shield for Raspberry Pi
1×Recommended: Raspberry Pi Prototyping Base Plate & Breadboard Kit

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of IR Slotted Optical Speed Sensor

Look at the module from the side and you will see the letter U. The two arms of the U face each other across a gap that is 5.9 mm wide. One arm holds an infrared LED. The other arm holds an NPN phototransistor. The LED shines across the gap all the time, and the phototransistor watches for that light.

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)

People use this sensor for jobs like these:

  • Measuring the speed (RPM) of a motor that has an encoder disc
  • Building a simple tachometer
  • Counting objects or pulses
  • Measuring distance by counting how many times a wheel turns
  • Giving speed feedback for the wheels of a robot
  • Detecting a limit or a home position

How It Works

IR slotted optical speed sensor how it works

The OUT pin follows the light beam:

  • Empty gap: the infrared light gets to the phototransistor, so OUT stays HIGH.
  • Something opaque in the gap (a piece of card, or one tooth of an encoder disc): the light cannot get across, so OUT drops to LOW.

There is also a Schmitt trigger on the board. It turns the raw signal into a clean 0 or 1 with no jitter at the edges. Because of this, your Python script does not need any debounce code.

Two small things to keep in mind:

  • Clear plastic or glass may let the IR light pass, so the sensor may not see it. Use opaque objects.
  • A few modules from other makers work the other way round. If your module reports "blocked" while the gap is empty, swap LOW and HIGH in the first script. The RPM script counts one edge for each tooth, so it gives the right speed either way.

The IR Slotted Optical Speed Sensor Pinout

IR slotted optical speed sensor pinout

The module has three pins:

  • VCC: This pin must be connected to the voltage supply (3.3V to 5V). On the Raspberry Pi, use 3.3V.
  • GND: This pin must be connected to ground (0V)
  • OUT: This pin sends the digital signal to a GPIO input pin of the Raspberry Pi

※ NOTE THAT:

The arrangement of pins on a module can differ between manufacturers, and even between batches. It is essential to always use the labels printed on the module when working with it. Be sure to take a close look!

Wiring Diagram

The wiring diagram between Raspberry Pi and IR slotted optical speed sensor

This image is created using Fritzing. Click to enlarge image

To simplify and organize your wiring setup, we recommend using a Screw Terminal Block Shield for Raspberry Pi. This shield ensures more secure and manageable connections, as shown below:

Raspberry Pi Screw Terminal Block Shield
  • Sensor VCC pin to Raspberry Pi 3.3V (pin 1)
  • Sensor GND pin to Raspberry Pi GND (pin 6 or any other GND pin)
  • Sensor OUT pin to Raspberry Pi GPIO17 (pin 11)

WARNING

Do not power this sensor from the 5V pin of the Raspberry Pi. The OUT pin goes as high as the VCC voltage. With 5V on VCC, OUT would send 5V into GPIO17, but the Raspberry Pi GPIO pins accept 3.3V only. Powering the sensor from 3.3V keeps the OUT signal safe.

Encoder Disc Setup for Speed Measurement

The second script needs an encoder disc. This is a round disc with slots cut around its edge.

  • Fix the disc on the motor shaft or on the wheel.
  • Mount the sensor with its M3 screw holes, so the edge of the disc runs inside the gap.
  • Check that the teeth of the disc pass through the slot without touching the sensor arms.

You can spin the disc by hand, or you can run the motor. The motor wiring is not part of this page. To drive a motor from the Raspberry Pi, see the Raspberry Pi - DC Motor tutorial.

How To Program for Raspberry Pi to Detect and Count Objects with IR Slotted Optical Speed Sensor

This first script checks GPIO17 again and again in a loop. It prints a line only when the state of the pin changes. Each time the gap becomes blocked, the count goes up by one.

Detailed Instructions

  • Make sure you have Raspbian or any other Raspberry Pi compatible operating system installed on your Pi.
  • Make sure your Raspberry Pi is connected to the same local network as your PC.
  • Make sure your Raspberry Pi is connected to the internet if you need to install some libraries.
  • If this is the first time you use Raspberry Pi, See how to set up the Raspberry Pi
  • Connect your PC to the Raspberry Pi via SSH using the built-in SSH client on Linux and macOS or PuTTY on Windows.
  • Make sure the RPi.GPIO library is installed. If it is missing, install it with these commands:
sudo apt-get update sudo apt-get install python3-rpi.gpio
  • Wire the sensor to the Raspberry Pi as shown in the wiring diagram above.
  • Create a Python script file OpticalSpeedSensor.py and add the following code:
""" This Raspberry Pi code was developed by newbiely.com This Raspberry Pi code is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-ir-slotted-optical-speed-sensor """ import RPi.GPIO as GPIO import time SENSOR_PIN = 17 # GPIO17 (pin 11) connected to the OUT pin of the speed sensor GPIO.setmode(GPIO.BCM) GPIO.setup(SENSOR_PIN, GPIO.IN) last_state = GPIO.input(SENSOR_PIN) object_count = 0 # how many times the slot was blocked try: while True: state = GPIO.input(SENSOR_PIN) if state != last_state: # the state has changed if state == GPIO.LOW: # LOW = something is in the slot object_count += 1 print("The slot is blocked - count: {}".format(object_count)) else: # HIGH = the slot is clear print("The slot is clear") last_state = state time.sleep(0.001) except KeyboardInterrupt: pass finally: GPIO.cleanup()
  • Save the file and start the script with this command:
python3 OpticalSpeedSensor.py
  • Slide a piece of card, or your finger, into the gap and pull it out again. Do it a few times.
  • Check the results on the terminal.
PuTTY - Raspberry Pi
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

The terminal stays quiet while nothing changes. A new line shows up only at the moment the gap gets blocked or becomes clear again. The script keeps watching until you press Ctrl + C keys in the terminal. It then cleans up the GPIO pin before it exits.

How To Program for Raspberry Pi to Measure Motor Speed (RPM) with IR Slotted Optical Speed Sensor

When a disc spins fast, the pulses come very quickly. A simple loop like the one above could miss some of them. So this script asks RPi.GPIO to watch the pin in the background with GPIO.add_event_detect(). Each FALLING edge (the moment a tooth blocks the gap) calls a small function that adds one to a counter. In this way, each tooth gives exactly one count.

Once per second, the script reads the counter, sets it back to zero, and works out the speed:

  • One full turn of a 20-slot disc gives 20 pulses.
  • Pulses in 1 second × 60 = pulses in 1 minute.
  • Pulses in 1 minute ÷ 20 = turns in 1 minute, which is the RPM.

The value 20 is stored in SLOTS_PER_TURN. That is the slot count of the common encoder disc sold with TT gear motors. If your disc has a different number of slots, change this constant.

Detailed Instructions

  • Do the same preparation as in the first example: SSH into the Raspberry Pi, install RPi.GPIO, and keep the same wiring.
  • Put the encoder disc in place, as shown in the encoder disc setup above.
  • Create a Python script file OpticalSpeedSensorRPM.py and add the following code:
""" This Raspberry Pi code was developed by newbiely.com This Raspberry Pi code is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-ir-slotted-optical-speed-sensor """ import RPi.GPIO as GPIO import time SENSOR_PIN = 17 # GPIO17 (pin 11) connected to the OUT pin of the speed sensor SLOTS_PER_TURN = 20 # number of slots (holes) in the encoder disc pulse_count = 0 # runs every time a tooth of the disc blocks the slot def count_pulse(channel): global pulse_count pulse_count += 1 GPIO.setmode(GPIO.BCM) GPIO.setup(SENSOR_PIN, GPIO.IN) GPIO.add_event_detect(SENSOR_PIN, GPIO.FALLING, callback=count_pulse) try: while True: time.sleep(1) # count pulses for 1 second pulses = pulse_count # read and reset the counter pulse_count = 0 rpm = pulses * 60 / SLOTS_PER_TURN # pulses per second -> turns per minute print("Pulses: {} | Speed: {:.2f} RPM".format(pulses, rpm)) except KeyboardInterrupt: pass finally: GPIO.cleanup()
  • Save the file and start the script with this command:
python3 OpticalSpeedSensorRPM.py
  • Spin the disc by hand, or turn on the motor.
  • Check the results on the terminal. The lines below come from a motor that turns at about 300 RPM:
PuTTY - Raspberry Pi
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

Unlike the first script, this one prints a line every 1 second (from the time.sleep(1) line), even when the disc is not moving. In that case, it shows 0 pulses and 0.00 RPM. The readings keep coming until you press Ctrl + C keys in the terminal. The script then cleans up the GPIO pin and stops.

Additional Knowledge

Slotted Optical Sensor vs Obstacle Avoidance Sensor vs Rotary Encoder

All three parts send pulses or ON/OFF signals to the Raspberry Pi, so they are easy to mix up. Let's compare what each one is made for:

IR Slotted Optical Speed Sensor IR Obstacle Avoidance Sensor Rotary Encoder
What it senses an object inside a 5.9 mm gap an object in front of it, a few centimeters away how far and which way a knob is turned
How it senses light beam across the gap is blocked reflected infrared light two signals out of step with each other
Best use RPM, counting, wheel turns, home position detecting obstacles for robots user input knob
Tells direction no no yes

Evidently, the slotted optical sensor is the right pick when the moving part can pass through its gap and you need speed or an exact count. If the object stays outside, use the obstacle sensor. If a person turns a knob and the direction matters, use the rotary encoder.

Choosing the Number of Slots on the Encoder Disc

Let's compare a disc with few slots and a disc with many slots:

  • More slots give more pulses per turn. The RPM value gets finer steps, and it reacts better at low speed. With 20 slots and a 1-second window, each extra pulse changes the result by 3 RPM (60 ÷ 20).
  • Fewer slots give fewer pulses per second. This is easier for the Raspberry Pi to follow when the motor is very fast, but the result moves in bigger steps.

Whatever disc you use, write its real slot count into SLOTS_PER_TURN. Otherwise the RPM value will be wrong.

Measuring Distance from Wheel Turns

If the encoder disc turns together with a wheel, you can also find out how far the wheel has rolled:

  • Wheel circumference = π × wheel diameter
  • Distance = number of turns × wheel circumference
  • Number of turns = total pulses ÷ SLOTS_PER_TURN

For example, a wheel with a diameter of 65 mm rolls about 204 mm in one turn. So after 10 turns, it has moved about 2 meters.

Video Tutorial

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!