cancel
Showing results for 
Search instead for 
Did you mean: 

Measure the speed rotation by using TIM in encoder mode

SMusc.1
Associate III

hello, I ask for the following clarification: I am using a two-channel encoder, A and B, and I want to estimate the rotation speed of the encoder shaft as precisely as possible. I started setting the TIM2 in encoder mode.
My encoder generates 1200 pulses per revolution.
I called the function:

 
HAL_TIM_Encoder_Start_IT(&htim2, TIM_CHANNEL_ALL);

and :
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
counter = __HAL_TIM_GET_COUNTER(htim);
}


which increases the counter variable every time a channel A (and B) get a variation (rising/falling edge settable from CUBE IDE).
At one full revolution of the encoder, with my settings of frequency = 160 MHz, Ps =0 and ARR = 4800, the counter variable starts at zero and goes to the value 4800 at each full revolution, then goes back to zero, and so on (all visible via serial on my laptop by using Putty software). My question is: how can I estimate the rotation speed? I have read a lot of information about this but I am still confused. Any advice?

14 REPLIES 14

 

 


@SMusc.1 wrote:

I correct myself. Every time I rotate the shaft of my encoder, using the function:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
}

 

>>Every time I rotate the shaft of my encoder, using the function:<<

This means: each time you move your encoder, an interrupt is fired. This means the MCU is busy handling all the interrupts generated by the encoder tics. Put a counter variable into that callback function, increment it on every call and check in "live expressions" how often it fires.

this is a not a good solution. I need the encoder function active as is now but i need the internal interrupt to calculate the time, ex. every 1 ms and count how many count generate the mouvment of encoder to calculate later on, the speed of the encoder. So i need this:

1) the function encoder calculate the count at every mouvment of the encoder shaft (now is working fine this)

2) one internal interrupt that at every 1 ms, is generated automatcly and regardless of the encoder channel

In this way, if I rotate the encoder shaft faster I will have more pulses and therefore knowing the time I can calculate the speed with which the encoder shaft moves. 

so at each interrupt of the internal timer I go to read how many pulses the encoder has generated and I can therefore be able to calculate the instantaneous speeds at every millisecond. In theory I should do it as fast as possible but if for now I can do it at every millisecond I'm already happy. If it is not possible to do this I will have to buy another board from another manufacturer that gives me the possibility of having multiple interrupts and without interference between them. Any suggestions?

The problem is here, that you are using the hardware wrong and expect different results. Additionally you don't want to listen to the advice how to do it right but insist in using your incorrect approach. No hardware in the world can fix that. You'll have to look between your ears to solve that.

As long as you are unwilling to re-think your concept and gain some deeper understanding about the hardware you want to work with, noone can help you. This is not a hardware / HAL issue. What we see here is a user issue.

hi, i dont understand how you are helping me. I need some timer working independently from external interrupts because I have to acquire a time that only a timer scheduled at every exact time can give me. I don't understand the help you are giving me, you say to do many things but they are not feasible because if I do them they do not work for the reasons I explained to you. Let me understand with real examples as I have explained and written the functions that I use for my purpose.

Good morning Sir, I followed your advice but with external interrupt active as :

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

any other timer interrupt callback in below function:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

it is frozen and not recalled. So the last ST comunity posts that talking on me that I am using wrong hardware is not right. I repeat again that when ever the external interrupt called from N°1 function I wrote above, all the other interrupt requests are frozen and I cant measure any time setting any other timer. Please what other solutions can there be?