cancel
Showing results for 
Search instead for 
Did you mean: 

Determine motor speed using encoder

Daniel Boström
Associate II
Posted on February 05, 2018 at 17:09

I am tasked with finding out the speed of a motor using a quadrature encoder interface. As a first step I thought I'd make it as easy as possible and try to determine the time it takes for the encoder counter to count up once. Since I don't have the motor and encoder yet I have tried to simulate the encoder output using a timer (TIM1) on my STM32F303K8 Nucleo (I am running everything on this board atm). I have checked this community and googled other places and found an approaches which I have tried with limited success. I am using the max system clock at 72MHz and the code is generated by STM32CubeMX. This is what I have tried:

Use one timer to simulate encoder output and feed the output to the input of another timer set up as an encoder interface. Then have a third timer trigger an interrupt at a given time interval and check if the encoder has incremented the counter.

TIM1 (Simulated encoder output): 200Hz

0690X00000609c3QAA.png

TIM1 (CH1, CH3) output looks like this (verified with oscilloscope):

0690X00000609btQAA.png

TIM2 (Timer update interrupt with 1us interval): 1MHz

0690X00000609bjQAA.png

TIM3 (Encoder interface):

0690X00000609boQAA.png

Using X4 encoding I expect that the TIM3 counter will be incremented once every 1250us (see picture above). However the times I get using this approach is 61-62us less. This is the ten sampled values I get (there is something in my implementation that gives a value twice as big the first time):

2378, 1189, 1189, 1189, 1188, 1188, 1189, 1189, 1189, 1188

I noticed if I change the speed of TIM2 to half, (Prescaler above is set to 1 instead of 0) and get interrupts every 2us instead then it looks much better:

2500, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1248, 1250

Any ideas why it looks better when I slow down TIM2 to 500KHz? How does one determine the correct prescaler/counter period for the different timers? I am confused, I can see that the results change when i change prescaler etc. but I don't understand how it is all related, now I've just used trial and error. If you need more information let me know.

If there are better approaches to achiving what I want I am all ears. I've seen something about configuring timers in master-slave relationship to solve this but I haven't figured that out yet.

#encoder #timer #motor
6 REPLIES 6
Posted on February 05, 2018 at 18:31

ny ideas why it looks better when I slow down TIM2 to 500KHz?

Maybe because your TIM2 chokes at 72-cycle rate?

Try sampling using TIM2-triggered DMA. There may be better ways, but that should be pretty easy, once you get rid of the idea of clicking in CubeMX and read the TIM and DMA chapters in RM.

JW

henry.dick
Senior II
Posted on February 05, 2018 at 18:50

If you don't care about direction or position, the simplest would be to count the pulses from one of the encoder channels.

Calculating speed from that is fairly simple.

Posted on February 05, 2018 at 18:55

Interrupting at excessively high rates is not desirable. >500 KHz

DMA could do that, and decimate interrupts with a larger buffer of samples.

For measuring pulse widths consider using TIM2 in PWM Input mode, clocking at 72 MHz

From an encoder perspective can you delta the count every 1ms and compute a speed from that.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
henry.dick
Senior II
Posted on February 05, 2018 at 19:09

If you want to simulate an encoder output. You can put a timer into output compare mode. And at match toggle the output compare pins. 

Two output compare match points are a quarter of the period away from each other. This approach once set up requires no mic involvement at all. 

Daniel Boström
Associate II
Posted on February 06, 2018 at 14:09

I don't understand in theory how using DMA to solve this would look, I have never used DMA with timers and the documentation and F3 code sample don't really help as I only see how to generate wave forms using DMA. Anyone care to elaborate on this?

Daniel Boström
Associate II
Posted on February 07, 2018 at 15:00

I changed TIM2 to this:

0690X00000609daQAA.png

This way it will increment the counter once every 1us and then I use the Capture/Compare interrupt of the encoder interface (TIM3) to handle each change of the counter. Here I can check how much time has elapsed using the TIM2 counter and I now get better results:

2500, 1250, 1250, 1250, 1249, 1250, 1250, 1250, 1250, 1250

Given the max speed of the motor I will now get interrupts at most every ~40us instead of every 1us like in my first attempted solution.

Still I will try to figure out a solution using DMA.