2018-04-03 02:10 AM
Hi,
I'm using STM32F072RB and a rotary encoder (with 30 dentet) connected to TIM2 in 'encoder mode' and I can see in TIM2->CNT that it is actually counting correctly.
I trying to get an interrupt on each detent rotation but unsuccessfully
To start the encoder in interrupt mode in the main function I'm using:
HAL_TIM_Encoder_Start_IT(&htim2, TIM_ENCODERMODE_TI2);
And the callback:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{ if(htim->Instance == TIM2) counterISR++;}
but the counterISR is not equal to TIM2->CNT.
How to get an interrupt of each detent rotation? or what is the correct way to implement such thing?
Timer 2 init:
/* TIM2 init function */
static void MX_TIM2_Init(void) { TIM_Encoder_InitTypeDef sConfig; TIM_MasterConfigTypeDef sMasterConfig; htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 29; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI2; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 0x0F; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 0x0F; if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } Note: this post was migrated and contained many threaded conversations, some content may be missing.2018-04-03 07:43 AM
The encoder may be bouncing at the pulses boundaries and the filter you set may be insufficient. Try hardware filtering.
Nevertheless, in principle, the encoder when stopped, may oscillate on one of its inputs, that will cause mutliple interrupts, but the counter will correctly stay at one of two succeeding values.
JW
2018-04-03 04:15 PM
Are you using Dials or Knobs ?
Some of us like Dials...
2018-04-03 08:19 PM
Mine go to 11
2018-04-04 01:26 AM
If i remember correctly, you just have to setup an interrupt on the Update event on your timer and then handle it like you would do for any interrupt.
I'm not familiar (at all) with HAL, but this is the event you should look for. (It's triggered on each timer value update)
EDIT : Also, could you tell us the ratio between 'counterISR' and TIM2->CNT ?
2018-04-04 01:59 AM
Thank you I'll check that out
2018-04-04 02:01 AM
I'm using
2018-04-04 02:46 AM
did you make a board for it ?
I'm going to try this one,
2018-04-04 03:34 AM
I don't understand what board are you meaning but I did connect the encoder with a low pass filter as suggested in the datasheet.
2018-04-04 03:39 AM
you mean to set an interrupt on timer overflow?
The ratio between counterISR and TIM2->CNT is not constant, counterISR can move by 1/2/3 while TIM2->CNT move by 1 (constantly) on each step rotation