How do you get the speed of an encoder?


New member
We have a project where using a encoder we like to record the speed and position of the encoder and play it back with Teensy 4.1 being used. We are currently using the FreqCount library and the Encoder library which the encoder library get us the position but not the speed. What should we do to get the speed of the encoder as well as be able to record it and playback the movements of the encoder?
You may wish to clarify what you exactly mean by "encoder speed". Is it encoder-ticks-per-second or full revolutions per minute (RPM) or the time between clicks or...?
What type of encoder are you using?
And what will you be using to playback the movements of the encoder? Are you thinking of a stepper motor?

We’re using an incremental rotary encoder with 800ppr, and a stepper motor with 1/4microstepping to have same resolution of 800 steps per rotation.

What we would like to achieve is to record the encoder and then move the stepper motor at same speed,position and direction the encoder was moved.
OK. How many encoder clicks do you expect per second?
Will the encoder be rotated by a human or machine/motor driven?
Just thinking out load here: can we read out out the encoder every 10 or 100 milliseconds, and then record the number of clicks and direction?
Can you elaborate more about your application? I'm trying to get an clearer picture of the constraints and requirements we are dealing with.
How long in seconds/minutes will your recoding be?

You haven't said much about your physical setup or shown your code, so we don't know very much, but I'll take a guess.

Let's say you are turning the encoder shaft by hand. If you turn it clock-wise, you get an increasing count, and if you turn it counter-clockwise, you get a decreasing count. It's an incremental encoder, so it's not really giving you absolute position. It's giving you counts, which is how much it has rotated. If you get 800 counts/per, then after 1 rev you'll be at 800, and if you keep going another rev you'll be at 1600, etc.

Speed is change in position per unit time. Let's assume you read the encoder position every 1 ms (0.001 sec). If the encoder counts at t=0 is X, and counts at time t=1 ms is Y, the change in position is Y-X (counts) and the speed in RPM is ((Y-X)/0.001) * (60/800). If all you want to do is make the stepper motor move the same as the encoder, you don't need speed. You only need the encoder counts. If you are reading the encoder position every 1 ms, you simply compute the change in position since the last read (can be positive or negative), and then command the stepper motor to move the same number of steps. If 1 ms is too frequent, slow it down to every 10 or 100 ms.
The machine consists of an X and Y gantry, with encoder to record what a human did. and steppers to replicate what was done manually.

Ex: human uses the X and Y gantry with a sanding tool.

The human presses a button and starts moving the head of the sanding tool connected to the encoders XY gantry.

Then when the play button is pressed the machine replicates what was done by the human to sand that part automating the process.

Only Position is not enough, since the user will move the head of sander with different acceleration, velocity and position.

At this moment we have the encoder A and B pins connected directly to the Dir and Step pins on the stepper driver and we are able to replicate same movements on another XY gantry but can’t record.
Well, generally speaking there are two ways to measure/compute speed with an encoder. One way is pulse-counting over a given period, which is what FreqCount does for a single input. If you have a quadrature encoder that counts up and down, you would do a delta position/time calculation as I described previously. The other way to measure/compute speed is via period measurement. Instead of counting pulses over a fixed time, you use a timer to measure the period (time) between pulses. If you measure between every successive edge, each measurement would represent 1/PPR revolution, in your case 1/800 rev. The timer would give you the time for that much rotation, and again you can compute the speed = delta position/time. The benefit of period measurement is that you generally get measurements much more frequently and with higher resolution. The FreqMeasureMulti library performs this function, and you can try the example programs. Keep in mind that FreqMeasureMulti generates an interrupt on every pulse, so if your RPM is high, and you have 800 PPR, the interrupt rate can become very high and overwhelm the CPU. I'm guessing the speeds are not too high. Period measurement doesn't include direction, though, so in your case, you at least have to use your Encoder library to get direction, and you can either do pulse counting over some time period, or do period measurement on one channel of the encoder.
This is what we have currently, is this the correct way of going at it or what should we change for it to work.


  • RTS.ino
    1.1 KB · Views: 47
If you want to use both Encoder and FreqMeasureMulti on the same encoder, and the Encoder has A/B signals going to pins 5/6, you would have to jumper one of those to another pin and configure FreqMeasureMulti on that pin. I don't think you can output PWM with frequency as low as 60 Hz, at least not on T4, but I could be wrong about that. If you want to simulate an encoder, search github for the EncSim library. It can produce quadrature signals, and you can loop those back to the two pins for Encoder, and if you're using a breadboard, you can easily connect either A or B to another Teensy pin and configure FreqMeasureMulti on that pin.
Hi Paul and Joe! I’m currently working on the same team with DMZs for these project.

I have watched all Paul YouTube videos and are a big fan of these community.

Regarding the project, we’re trying to make use of the Hardware capabilities instead of software since it can read much faster (Paul video comparison was software 2.4Mhz compared to 65Mhz using hardware).

Would it be possible to read each pulse of the encoder (rising edge falling edge) and get the DeltaTime between each consecutive pulse? And printing these to the serial(or SD card) using a circular buffer to get all pulses printed?

Ex: (using image attached).
One pulse print:
High Level (t1) for “X” time.
Low level (t2) for “Y” time.
And so on.

Or if it starts from a falling edge start reading the Low edge(t2) and then the next high edge (t1) and print same as before.

In the CNC community this is called “record the output of a manual pulse generator MPG” if this helps.

thanks for the support.


  • E1747C78-B34F-4041-AF46-51C3418CA055.png
    12.2 KB · Views: 13
Given that the encoder is 800ppr and max capable readings is at 5000RPM the max frequency should be 66.67Khz

MaxFrequecy= (800pprx5000rpm)\60
Given that the encoder is 800ppr and max capable readings is at 5000RPM the max frequency should be 66.67Khz
It's unnecessary to design for that high frequency/high RPM because your stepper motor will not be able to run that fast. From my experience a NEMA17 stepper will do 10-15 revs per second at best [5000 RPM is ~ 83 RPS].
By the way, you may want to scrutinize the datasheet of your 800ppr encoder because the electrical max output frequency is usually well below the mechanical max revolutions.

That said, I think it's wise to take a small step back and first get some experimental data on what number of clicks we are actually talking about in your physical application.
Just a simple piece of code will give you an idea.
#include <Encoder.h>
Encoder myEnc(5, 6);

void setup() {

void loop() {
  long newPosition =;