Arduino RPM Sensor (RPM Meter/Counter With Encoder)

In this tutorial, you’ll learn how to interface Arduino RPM Sensor (Optical Encoder) and use it to build an Arduino RPM Meter/Counter that measures the speed (RPM) of a DC motor.

You’ll also learn multiple techniques for Motor Speed (RPM) Measurement With Arduino & motor encoder (optical encoder). We’ll create an Arduino RPM Meter (Counter) as an example project to practice what we’ll learn in this tutorial.

Table of Contents

  1. Arduino RPM Sensor (Optical Encoder / Photo Interrupter)
    1. Optical Encoder Module Pinout
    2. Photo Interrupter Pinout
  2. Arduino RPM Sensor (Optical Encoder) Interfacing
    1. 1. Arduino RPM Meter Using External Interrupt Pin + Timer Function
    2. 2. Arduino RPM Meter Using External Interrupt Pin + Timer Interrupt
    3. 3. Arduino RPM Meter Using Timer Input Capture Unit
    4. 4. Arduino RPM Meter Using Timer Counter Mode
    5. The Bottom Line
  3. Arduino RPM Meter (Counter) Example Project
  4. Arduino RPM Sensor Wrap Up

Arduino RPM Sensor (Optical Encoder / Photo Interrupter)

Arduino-Motor-Encoder-Optical-Encoder-Photo-Interrupter

The optical encoder sensor is also referred to as a photo interrupter sensor which is widely used in motor control applications. You can typically find many of them in laser printer machines, mobile robots, and many other devices.

The optical encoder can be used to measure the speed of a motor and also the mechanical displacement of the motor-based mechanism regardless of its type (linear, rotary, etc). The figure below shows you an example fixture for an optical encoder sensor with its encoder wheel attached to a small DC motor to measure its speed.

Arduino-Motor-Encoder-Optical-Encoder-Photo-Interrupter-RPM-Sensor
Arduino-Encoder-Optical

During motor rotation, the encoder wheel will block/allow the infrared LED light beam to reach the photo sensor on the other side. Depending on the encoder wheel’s number of windows, we’ll have a certain number of electrical pulses out of the sensor per motor’s shaft complete rotation (revolution).

The encoder wheel shown in the figure above has 20 windows, which means the optical encoder will output 20 pulses/revolution. I’ve got one of these encoder wheels that have 20 windows and will be using it in the example project later on in this tutorial.

It’s worth noting that the more windows in the encoder wheel, the more accurate measurements you’ll get. Especially if you’re using a measurement technique that’s averaging the measured pulses, having more pulses/revolution can be advantageous in that case.

Optical Encoder Module Pinout

This is the pinout diagram for the optical encoder module that you can use with Arduino as a motor encoder to measure its speed or the travel distance of your motor-based mechanism.

It consists of a photo interrupter sensor or a PCB board with power for the IR LED and some signal conditioning and filtering for the phototransistor’s output that goes directly to your Arduino input pin.

Arduino-Motor-Encoder-Optical-Encoder-Photo-Interrupter-Pinout

❕ Note

Note That some optical encoder modules have different pinout orders. You may sometimes find the output pin in the middle or on the left side of the 3-pin header. Anyway, you need to check the module’s pin labeling before powering up your circuit.

Photo Interrupter Pinout

You can use the Arduino Optical Encoder Module or build your own module (circuit) around a low-cost Photo Interrupter Sensor. That you can connect its circuit as shown in the figure below which indicates the photo interrupter sensor’s pinout and typical application circuit diagram.

This is an even lower-cost solution than using the optical encoder module shown earlier and will ultimately give you the same performance as well.

Photo-Interrupter-Sensor-Pinout

Here is an image showing my DIY photo interrupter circuit solution side by side with the optical encoder module. Both are working in the exact same way with very similar performance. While the DIY solution is 6x times cheaper than the optical encoder module’s PCB.

Arduino-Motor-Encoder-Optical-Encoder-Photo-Interrupter-1

???? Also Read
Arduino Motor Encoder (Optical Encoder) Photo Interrupter Tutorial

This tutorial explains how to interface Arduino with a motor optical encoder for motor speed measurement applications. And it gives you some code example projects to practice what you’ll learn.


Arduino RPM Sensor (Optical Encoder) Interfacing

There are so many configurations/techniques that you can use to interface a motor optical encoder with Arduino to measure the motor’s speed (RPM). In this section, we’ll explore each of the possible techniques that you can use to measure a motor’s speed (RPM) using Arduino & motor optical encoder.

Each technique of the following has its pros and cons, it’s up to you “the system designer/programmer” to choose which one fits well your target application needs. Please, be advised that the following techniques list isn’t an exhaustive list of all possible methods that can be used to measure motor RPM with an optical encoder sensor.

1. Arduino RPM Meter Using External Interrupt Pin + Timer Function

The first method is to use an external interrupt pin to trigger an interrupt when the encoder’s output pin state changes. We also use a timer-based function [ micros() ] to measure the encoder output signal’s frequency. Using simple arithmetic we can then calculate the motor’s speed (RPM). Given that the encoder wheel attached to the motor has n windows (my encoder wheel has 20 windows).

Here is the wiring diagram for Arduino with the motor optical encoder sensor. Note that I’m using the INT0 external interrupt pin of the Arduino which is IO pin2.

Arduino-Motor-Optical-Encoder-Wiring-Diagram

Here is a test code example that reads the motor optical encoder sensor, calculates the measured motor RPM, and prints the temperature value to the serial monitor over UART.

Pros

Those are the pros of using the “External Interrupt + Timer-Bases Micros Function” technique:

  • Easy to implement
  • Very high update rate (response time)
  • Very wide measurement range (>0 RPM, absolute zero is not measurable by this technique)

Cons

Those are the cons of using the “External Interrupt + Timer-Bases Micros Function” technique:

  • Prone to noise and random spikes (can be improved by applying a digital filter)
  • Measurement halts if the motor is stopped, you won’t get a “0 RPM” reading (due to no interrupts at stall)
  • Excessive CPU load at high speeds, the CPU will have to handle thousands of interrupts every second

Learn More

It’s Highly Recommended to check out the tutorials below to learn more about Arduino external interrupt pins and timer-based micros() function for precise time measurement applications. Both tutorials are in-depth explaining the topics with a handful of practical code examples to help you get the hang of it.

???? Also Read
Arduino External Interrupts

This tutorial explains the Arduino External Interrupt Pins. You’ll learn everything about Arduino interrupt pins, how to write ISR handlers, interrupt latency, and many other aspects.

???? Also Read
Arduino Micros Tutorial

This tutorial explains the Arduino timer-based micros() function. You’ll learn everything about it, how it works, and how to make the best use of it in time measurement & delay applications with a lot of tips and tricks all the way through.

2. Arduino RPM Meter Using External Interrupt Pin + Timer Interrupt

Another method for motor speed (RPM) measurement with Arduino is to use an external interrupt pin with a timer interrupt that generates a fixed time-interval interrupt signal. This technique mitigates the inability to measure a 0-RPM speed at a motor standstill state which was the case for the previously shown technique in the previous section.

In this technique, we set a hardware timer to fire an interrupt signal at a fixed time interval (let’s say 1 ms). And enable an external interrupt pin to receive the incoming signal from the motor’s optical encoder. For each INTx interrupt, we increment the counter by 1. For each 1ms, in the TMRx interrupt ISR handler, we’ll check how many interrupt ticks have occurred.

Arduino-RPM-Measurement-With-Motor-Optical-Encoder

In this way, we can easily calculate the frequency of the optical encoder’s output signal and use it to calculate the measured motor speed (RPM). This means the motor’s measured speed (RPM) is updated every 1 ms, if you set the timer interrupt interval to be at 1 ms.

Pros

Those are the pros of using the “External Interrupt + Timer Interrupt” technique:

  • Very accurate RPM measurements with fewer fluctuations
  • It can easily measure 0 RPM if the motor is stalled or stopped

Cons

Those are the cons of using the “External Interrupt + Timer Interrupt” technique:

  • Excessive CPU load at high speeds, the CPU will have to handle thousands of interrupts every second
  • The maximum speed that can be measured is limited by the timer interrupt time interval
  • Lower accuracy at high speeds (when INTx interrupt occurs at a rate that’s close to TMRx interrupt interval)
  • A bit more complex to implement and it disrupts any hardware functionality that depends on the hardware timer to be used

Learn More

It’s Highly Recommended to check out the tutorial below to learn more about Arduino Timer Interrupts for precise timing applications. The tutorial below is in-depth explaining the topic with a handful of practical code examples to help you get the hang of it.

???? Also Read
Arduino Timer Interrupts Tutorial

This tutorial will give you more in-depth information about Arduino Timer interrupts and how to set up timer interrupts for periodic events. You’ll also learn how to use our timer code generator for different interrupt types (COMPA, COMPB, and OVF) with multiple code example projects.

3. Arduino RPM Meter Using Timer Input Capture Unit

Another method for motor speed (RPM) measurement with Arduino is to use an internal hardware timer in input capture mode. This is very similar to using an external interrupt pin in conjunction with a hardware timer. However, this technique is superior to the previously explained one due to being friendly to the timer-dependent functionality as it doesn’t disrupt any timer-dependent function, unlike the previous method.

In this technique, we set a hardware timer to enable input-capture interrupt events on the timer input pin. We can set up the ICU to trigger a capture event on every RISING edge on the ICPx pin to measure the optical encoder signal’s frequency.

At the first edge, we’ll save the ICRx register reading into a variable (T1). At the second edge, we’ll save ICRx into (T2). And to get the signal’s period, we just subtract the time stamps as follows: (  T = T2 - T1 ). Just pay attention to timer overflow events because if T2 is smaller than T1, the resulting period (T) will be negative which is not correct. We need to add (  Number of TimerOVF * 65536 ) to T2 to get the correct absolute timestamp difference.

In this way, we can easily calculate the frequency of the optical encoder’s output signal and use it to calculate the measured motor speed (RPM).

❕ Note

In Arduino UNO (Atmega328p) microcontroller, Only Timer1 has an input capture unit (timer mode). Which has an input capture pin (ICP1) that corresponds to Arduino UNO IO pin8.

Pros

Those are the pros of using the “Input Capture Unit” technique:

  • Very accurate RPM measurements with fewer fluctuations
  • Very high update rate (response time)
  • Very wide measurement range (>0 RPM, absolute zero is not measurable by this technique)

Cons

Those are the cons of using the “Input Capture Unit” technique:

  • Excessive CPU load at high speeds, the CPU will have to handle thousands of interrupts every second
  • Measurement halts if the motor is stopped, you won’t get a “0 RPM” reading (due to no interrupts at stall)

Learn More

To learn more about Arduino Input Capture Unit and create a couple of practice projects, you need to check out the tutorial linked below.

???? Also Read
Arduino Input Capture Unit Interrupt Pin Tutorial & Examples

This tutorial will give you more in-depth information about Arduino Timers (in input capture Mode). How to configure Arduino Timers to operate in ICU mode, and what are the use cases & applications for ICU? As well as a couple of practical Arduino code example projects.

4. Arduino RPM Meter Using Timer Counter Mode

Another method for motor speed (RPM) measurement with Arduino is to use an internal hardware timer in counter mode. The timer module in counter mode is configured to have an external pin as the clock source with multiple prescaler options. We’ll use it to count external input pulses and measure the encoder output signal’s frequency by counting its rising or falling edges over a fixed time interval.

In this technique, we set a hardware timer to operate in the counter mode so it counts the input pulses on the Tn pin. And we set another timer to fire a periodic interrupt at a fixed time interval at which we check the counter value of the first timer. In this way, we can easily find out the input signal’s frequency and therefore, calculate the measured motor’s speed (RPM).

The timer module in counter mode can be set to count up each RISING or FALLING edge on the Tn input pin.

STM32 Timers Explained Tutorial Counter Mode Encoder

You can refer to the Arduin UNO Pinout Guide to identify all timer input pins (Tn). Where T0 is the Timer0 input pin and T1 is the Timer1 input pin. In Arduino UNO (Atmega328p), the T0 & T1 pins are Arduino IO pins (4 & 5) respectively. Also note that: the Counter0 register (TCNT0) is 8 bits, while the Counter1 register (TCNT1) is 16 bits.

❕ Note

In Arduino UNO (Atmega328p) microcontroller, Timer2 doesn’t have an input pin so it doesn’t operate in counter mode.

Pros

Those are the pros of using the “Timer in Counter Mode” technique:

  • Very accurate RPM measurements with fewer fluctuations
  • It can easily measure 0 RPM if the motor is stalled or stopped

Cons

Those are the cons of using the “Timer in Counter Mode” technique:

  • The maximum speed that can be measured is limited by the timer interrupt time interval
  • A bit more complex to implement and it disrupts any hardware functionality that depends on the hardware timer to be used

Learn More

For more examples and demonstrations of Arduino Timers (Counter Mode), it’s highly recommended to check out its dedicated tutorial linked below. It’ll give you more information, code examples, and applications for Arduino Timers in Counter Mode.

???? Also Read
Arduino Counter Timer Mode Tutorial & Code Examples

This tutorial will give you more in-depth information about Arduino Timers ( in Counter Mode). How to configure Arduino Timers to operate in Counter mode, and what are the use cases & applications for Counter Mode? As well as a couple of practical Arduino code example projects.

The Bottom Line

This wasn’t an exhaustive list for all possible techniques that you can use to measure the optical encoder sensor’s output frequency to measure the motor’s speed (RPM). There are so many other routes that you may also consider taking. Every method has its own pros and cons, it’s up to you “the system designer/programmer” to decide which is the best fitting solution for yor applications’ needs.


Arduino RPM Meter (Counter) Example Project

In this example project, we’ll use Arduino with Motor Optical Encoder (Photo Interrupter) to measure the speed of a DC Motor (RPM – Revolutions Per Minute). As described earlier, I’ll be using an external interrupt pin & the micros() function to measure the output signal’s frequency of the optical encoder.

Then, we can easily calculate the motor’s speed (RPM) using the measured signal’s frequency and the number of windows in the encoder wheel (20).

???? Also Read
Arduino I2C LCD 16x2 Interfacing Tutorial & Library Examples

This is the ultimate guide for Arduino I2C LCD 16×2 interfacing and library functions explanation. It’ll guide you through everything you’d need to interface Arduino with an I2C LCD display.

Code Example

Here is the complete code listing for this example.

Code Explanation

First of all, we should include the Wire.h library for I2C communication and the LiquidCrystal_I2C.h library for the I2C LCD control.

Then, we’ll define the encoder’s external interrupt input pin. We’ll also create an instance of the I2C_LCD class, and define some variables to be used in the motor RPM speed measurement & conversion process.

INT0_ISR()

This is the interrupt handler function for the INT0 external interrupt pin which is connected to the optical encoder. In this function, we’ll start the time measurement by taking a timestamp using the micros() function and save it into the variable (T1) at the first rising edge.

At the second rising edge’s interrupt event, we’ll also take another timestamp and save it into the (T2) variable. Now, the encoder signal’s period is (T = T2-T1). This is the end of the measurement cycle, and the flag is reset again to repeat the measurement cycle on the next rising edge interrupt event.

setup()

in the setup() function, we’ll initialize the I2C LCD module and turn ON its backlight. We’ll also set the encoder pin as input and enable interrupts on RISING edge events on that pin as well.

loop()

in the loop() function, we’ll take the latest time measurement, convert it to frequency, and calculate the measured motor’s speed (RPM). Which is then written to the LCD screen every 250ms.

Testing Results

Here is a demo video for testing this project on my Arduino UNO board.


Parts List

Here is the full components list for all parts that you’d need in order to perform the practical LABs mentioned here in this article and for the whole Arduino Programming series of tutorials found here on DeepBlueMbedded. Please, note that those are affiliate links and we’ll receive a small commission on your purchase at no additional cost to you, and it’d definitely support our work.

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting my work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports our community.


Arduino RPM Sensor Wrap Up

To conclude this tutorial, we can say that you can easily interface Arduino RPM Sensor based on a photo-interrupter (optical encoder) to measure the motor’s speed (RPM). The Arduino optical encoder (photo-interrupter) sensor interfacing can be achieved by so many techniques as we’ve discussed in this tutorial.

If you’re just getting started with Arduino, you need to check out the Arduino Getting Started [Ultimate Guide] here.

And follow this Arduino Series of Tutorials to learn more about Arduino Programming.

???? Also Read
Getting Started With Arduino Programming For Beginners

This is the ultimate guide for getting started with Arduino for beginners. It’ll help you learn the Arduino fundamentals for Hardware & Software and understand the basics required to accelerate your learning journey with Arduino Programming.

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

2 thoughts on “Arduino RPM Sensor (RPM Meter/Counter With Encoder)”

Leave a Comment