Arduino UNO R4 - IR Slotted Optical Speed Sensor

In this guide, we will learn how to use the IR slotted optical speed sensor with Arduino UNO R4. In detail, we will learn:

Arduino UNO R4 and IR slotted optical speed sensor

Overview of IR Slotted Optical Speed Sensor

This small module has a U shape. People also call it a photo interrupter or an opto interrupter. One arm holds an infrared LED. The other arm holds an NPN phototransistor. They face each other across a 5.9 mm gap. The sensor tells Arduino UNO R4 one simple thing: is the gap empty, or is something inside it?

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)

Common uses:

  • Measure motor speed (RPM) with an encoder disc, like a tachometer.
  • Count objects or pulses.
  • Measure distance by counting wheel turns.
  • Give wheel speed feedback to a robot.
  • Detect a limit or a home position.

Pinout

IR slotted optical speed sensor pinout

The module has three pins:

  • VCC pin: connect to 5V on Arduino UNO R4 (the module accepts 3.3V to 5V).
  • GND pin: connect to GND (0V).
  • OUT pin: digital output, connect to an input pin of Arduino UNO R4.

The pin order can change from batch to batch. Always read the labels printed on your module.

How It Works

How the IR slotted optical speed sensor works

The IR LED shines across the slot all the time.

  • Slot is empty: the light reaches the phototransistor, so the OUT pin is HIGH.
  • Slot is blocked by something opaque (a card, a finger, a tooth of an encoder disc): the light cannot pass, so the OUT pin is LOW.

The built-in Schmitt trigger turns the raw light level into a clean 0 or 1. The signal does not jitter, so you do not need software debounce.

Two small things to know:

  • Clear plastic or glass may let IR light through. Use opaque objects.
  • Some modules from other makers work the other way round. If your board says "blocked" while the slot is empty, just swap LOW and HIGH in the first code. The RPM code counts one edge per slot, so it works with both types.

Wiring Diagram

Only three wires are needed: VCC to 5V, GND to GND, and OUT to pin 2 of Arduino UNO R4. UNO R4 is a 5V board, so 5V power is fine here, and the OUT signal stays at a safe level.

The wiring diagram between Arduino UNO R4 IR slotted optical speed sensor

This image is created using Fritzing. Click to enlarge image

See The best way to supply power to the Arduino Uno R4 and other components.

We use pin 2 because it can run an interrupt. The second code needs this.

How To Program For IR Slotted Optical Speed Sensor

Check if the slot is blocked (polling):

  • Set the pin that connects to the OUT pin as an input:
pinMode(SENSOR_PIN, INPUT);
  • Read the pin. LOW means blocked, HIGH means clear:
int state = digitalRead(SENSOR_PIN);
  • Compare with the last reading, so you act only when the state changes:
if (state != lastState) { // the slot just became blocked or clear }

Count fast pulses (interrupt):

  • Make a counter. Mark it volatile because the interrupt changes it:
volatile unsigned long pulseCount = 0;
  • Write a tiny function that adds one to the counter:
void countPulse() { pulseCount++; }
  • Run that function each time the signal falls from HIGH to LOW (one tooth enters the slot):
attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), countPulse, FALLING);
  • Once per second, copy and reset the counter with interrupts paused, then turn pulses into RPM:
noInterrupts(); unsigned long pulses = pulseCount; pulseCount = 0; interrupts(); float rpm = pulses * 60.0 / SLOTS_PER_TURN;

Why this formula? With a 20-slot disc, one full turn makes 20 pulses. Pulses in 1 second × 60 gives pulses per minute. Divide by 20 and you get turns per minute (RPM).

Arduino UNO R4 Code - Detect Object in the Slot

This sketch checks the OUT pin again and again. It prints a line only when the state changes, and it adds one to a counter each time the slot gets blocked.

/* * This Arduino UNO R4 code was developed by newbiely.com * * This Arduino UNO R4 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-ir-slotted-optical-speed-sensor */ const int SENSOR_PIN = 2; // Arduino UNO R4 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; } }

Detailed Instructions

Follow these instructions step by step:

  • If this is your first time using the Arduino Uno R4 WiFi/Minima, refer to the tutorial on setting up the environment for Arduino Uno R4 WiFi/Minima in the Arduino IDE.
  • Wire the components according to the provided diagram.
  • Connect the Arduino Uno R4 board to your computer using a USB cable.
  • Launch the Arduino IDE on your computer.
  • Select the appropriate Arduino Uno R4 board (e.g., Arduino Uno R4 WiFi) and COM port.
  • Copy the code above and paste it into the Arduino IDE.
  • Click the Upload button to send the code to the Arduino UNO R4.
  • Open the Serial Monitor and set it to 9600 baud.
  • Slide a piece of card (or your finger) into the slot, then pull it out. Do this a few times.
  • Look at the result on the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' 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 R4 WiFi on COM15
2

Each pass makes two lines: one when the card goes in, one when it comes out. No line is printed while nothing changes.

Arduino UNO R4 Code - Measure Motor Speed (RPM)

Polling in loop() is fine for slow objects. A spinning disc is much faster, and loop() could miss some teeth. So this sketch counts pulses with an interrupt on the FALLING edge, which gives exactly one count per tooth. Every second it prints the pulse count and the speed in RPM.

The constant SLOTS_PER_TURN is set to 20. That is the common encoder disc that comes with TT gear motors. If your disc has a different number of slots, change this value.

/* * This Arduino UNO R4 code was developed by newbiely.com * * This Arduino UNO R4 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-ir-slotted-optical-speed-sensor */ const int SENSOR_PIN = 2; // Arduino UNO R4 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"); } }

Set Up the Encoder Disc

  • Fix the encoder disc on the motor shaft or the wheel.
  • Place the sensor so the teeth of the disc pass through the slot.
  • Make sure the disc does not touch the sensor arms.
  • You can spin the disc by hand, or power the motor. The motor needs its own wiring. See the Arduino UNO R4 - DC Motor tutorial for that part.

Detailed Instructions

  • Keep the same wiring as before.
  • Copy the RPM code above and paste it into the Arduino IDE.
  • Click the Upload button.
  • Open the Serial Monitor at 9600 baud.
  • Spin the disc, then let it stop.
  • Watch the speed on the Serial Monitor. Here the motor runs at about 300 RPM:
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' 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 R4 WiFi on COM15
2

Check one line: 100 pulses × 60 ÷ 20 = 300 RPM.

Want to know how far a wheel has moved? Multiply the number of turns by the wheel circumference (π × wheel diameter).

※ NOTE THAT:

  • Keep the interrupt function short. Do not call Serial.print() inside it.
  • Any variable that the interrupt changes must be volatile.
  • Need to sense an object at a distance instead of inside a slot? Try the obstacle avoidance sensor. Need a knob that also gives turn direction? Try the rotary encoder.

Video Tutorial

Function References

※ 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!