cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 - Timer Innaccuracies - Driving A Servo And The Servo Is Twitching

Matt Roybal
Associate II

Hello, I am using an STM32F103C8T module (blue pill). I am using it to control a servo, which consists of a 20ms window, with a short pulse (1.0ms to 2.0ms). Like this:

0693W00000NspR3QAJ.pngI configured timer 3 like this in CubeMX:

0693W00000NspRDQAZ.pngI am using "HAL_TIM_PeriodElapsedCallback", and here is the code that is driving the servo:

0693W00000NspRSQAZ.pngEverything works for the most part, but the problem is the servo has a slight twitch to it. It twitches fairly consistently about 2 times per second. I connected the oscilliscope to watch the pulse. I can see that the pulse width is not consistant - it has some variance to it:

https://photos.app.goo.gl/2zXpNaN92md5mdMA6

And here I zoomed in on the end of the pulse - you can see it much more clearly:

https://photos.app.goo.gl/2r8uzPqeje9sbSNZ7

Because of the inconsistent width of the pulse, it causes the servo to twitch - basically following the pulse exactly. Here is a video of that:

https://photos.app.goo.gl/eS6NtWFbSuUNP6SJA

Does anyone know what the problem is? My servo driver code is extremely simple and I can't see anything wrong with it. Do I have the timer setup incorrectly, or is it something else? Any help or advice is greatly appreciated, thanks!

4 REPLIES 4

The best solution is to generate the pulse by hardware (i.e. using timer's output, rather than manipulationg a GPIO output in software).

As a minimum, increase given TIM interrupt priority.

JW

Thanks for the response! I checked the NVIC settings for this timer, and it shows both priorities to 0. Does this mean they are already top priority?

0693W00000NsqE0QAJ.png

Maybe. This just means it's clicked so in CubeMX. But even if it's true, you still may have other interrupts of the same priority, resulting in interrupt latencies, so perhaps an easy way might be to decrease those (unless "priority grouping" setting prevents to do this effectively). There may be also other sources of latencies. And, at the end of the day, who knows what mcu exactly your bluepill contains and how does it exactly behave.

The real solution is what I've said above, using hardware i.e. timer for this task.

JW

You're using interrupts.

Put the TIM in a 50 Hz 20 ms continuous operation.

A set the width of each of the channels to your 1-2 ms width.

Perhaps prescale the TIM so the thing clocks at 1 MHz (1us), then a CCR1 setting of 1500 will get you a 1.5 ms top-dead-center signal.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..