Stm32hwencoder - weird results

Hi all, I’m trying to investigate hwencoder on a nucleo-F411, getting some strange results. Two videos, exact same hardware config, just switching between the standard interrupt encoder code and the hwencoder code and moving the motor by hand. I’ve tried both of the following encoder timer sets (I’m pretty sure they are on the same timer etc). I’ve tried using the HWEnc in closed loop position control and it acts very strange, whereas it was working fine on standard encoder.



Any advice would be much appreciated!
(Standard Encoder)


Why do you need to change pins between tests?
What physical encoder are you using? E.g. CUI, MT6701…
Do you have/need pullups?

Ah sorry, I ran two HWEnc tests but only captured the one, this was to check if a different pin config gave the same results.
Encoder is a linear H9740, it has integrated 2.5k ohm pull ups.


That’s strange, this combination of pins (either one) should work with STM32HWEncoder, and it should work on F411…

Have you figured out yet what the problem is?

What resolution is the encoder set to?

Hi Runger,

No luck on the problem, I’ve had to revert back to software interrupts for now.
I’m hoping to try with a AMT103 to see if I get the same results. I also got myself a G474 so I will try and test this to see if that changes anything.

Resolution is a fixed value at 360 lines per inch, which equates to 17 micron roughly.


It’s a strange problem.

What does this translate to in terms of bits? The timers you’re using would support only <16bits

What’s the clock setup? I guess its standard for the Nucleo board?

Not sure about the bit translation sorry!
Also got me on the clock setup, but as far as I know it is running stock.

But I have made some progress, I tried to reverse the last major commit which was “big simplification to STM32HWEncoder” around 10 months ago and got this result! Checked on both my original encoder and AMT103 and worked great.

Tricky part now is tracking down the culprit! Any ideas?


Actually, that is quite strange, because several people (including myself) are using the refactored code and it’s working.

I’m usually on the dev branch of the library, perhaps there are some more changes there compared to the 2.3.2 released version? I’ll have to check into it.

It’s going to take me a little while due to other projects right now. Let me know if you find out anything, it would be greatly appreciated!

Hey @Zerpoint ,

Watching through the videos it seems tha the angle is actually fine, its the velocity which is very noisny, isn’t that the case?

I’d probably say that the loop with the interrupts is slower than the one with the hardware encoder and that it calls motor.loopFOC() (where the velocity is calculated) less often. That way it calculates the velocity less often and has larger difference in the encoder counts between the calls.
Whereas the hardware encoder calculates the velocity too fast and in some cases it has 0 changes between the two call of the motor.loopFOC().

So there is avariable in the sensor class to force a minimal time between the velocity calculations, it can be set using the min_elapsed_time property of your ecoder class.
By default is 0.1ms.
Try setting it at 1 or 2 ms.
sensor.min_elapsed_time = 0.001; // 1ms

It should make the velocity much better if this is the origin of the issue.

Hi Antun,

Works a charm! So the sweet spot for me was about 0.5ms (captured in video attached).

0.1ms had some noise, but still not as bad as the original videos.

Thank you kindly!

I didn’t actually test if this would affect closed loop control, would a noisy velocity be detrimental to control?


Yeah this would have a lot of influence on the control loop as the velocity is all over the place.
The position and velocity control loops would have hard time to stabilize and would be very noisy, even unstable in some cases.