Calculating angular velocity using incremental encoder data

I’m trying to measure the angular velocity of a rotating shaft using an encoder.
An encoder delivers the angular position at certain time.

If the time is known you can in theory calculate the angular velocity by dividing the difference in position by the difference in time between two measurement.

The issue I have is easy to understand in the following example:

  • The encoder has a resolution of 1 degree.
  • The polling rate is 10Hz.
  • The shaft rotates with 11 degree per seconds.
    The measurement will looks something like that:
    time | position | speed
    0 | 0 |
    0.1 | 1 | 10
    0.2 | 2 | 10
    0.3 | 3 | 10
    0.4 | 4 | 10
    0.5 | 5 | 10
    0.6 | 6 | 10
    0.7 | 7 | 10
    0.8 | 8 | 10
    0.9 | 9 | 10
    1.0 | 11 | 20
    1.1 | 12 | 10

The issue is that you never get the real velocity, obviously with a running median you can get the real velocity, but you get some lag.

I need to measure measure the angular velocity difference between two axis driven by a combustion engine on both side of a coupling to assess of the fitness of said coupling. The shaft will rotate at about 6000[RPM]. The sampling rate is about 10kHz and we want to analyze multiple rotation to make the data is consistent.

At first I tried to implement different filters, but here again there is a lag. Then I tried to implement a fit, which works fine for short measurement, but if the change in velocity is too frequent the function quickly diverges.
Then I tried to cut the data in sub segment and use a fit for each segment, this works fine except that the junction between segment still has a discontinuity.

I tried to find a fit function where I could force the function to go through a specific point to avoid discontinuity, but I have not been able to find such a function.
Does someone know of such a function or an alternative method for this problem?

1 Like

I have used an Alpha beta filter for this in the past. Simpler than a Kalman filter but does need some tuning to trade off lag and smoothness.

An even better solution is to capture the time of the encoder edge transitions (for example with a microcontroller timer capture peripheral) rather than sampling the counter. This data will still need to be fed to a filter, but having the edge timing is a big improvement.

1 Like

Thanks for the input.
Capturing the time might be the better option indeed. I’m going to try that one.
My knowledge in filter is limited, I would if possible avoid to implement a filter myself. Is there a good and fast Julia package implementing an alpha beta filter?

Well, you can only reach a very small time lag

  • if you have an accurate time stamp of each reading
  • if you have a high sampling rate.

There should be no need to average multiple rotations if you you have the correct sensing hardware that records the exact time stamps of at least the bit transitions.

I finally could test the solution with the timer in a real application.
It worked really fine.
Almost no filtering needed. A simple Butterworth FFT filter gave me near perfect results.
Thanks a lot.

2 Likes