cancel
Showing results for 
Search instead for 
Did you mean: 

Encoder mode with input capture ?

goktug
Associate

I want to measure speed of motor precisely with encoder pulses and for that I saw this topic

https://community.st.com/s/question/0D50X00009fDstgSAC/can-you-combine-encoder-and-input-capture-both-from-the-same-pin

@Werner D�hn​  @akosodry​ 

and from what I understand here , encoder mode internally triggering another input capture timer

My questions is ;

my encoder has 360 line but multiplex by 4 because of two channel ,so it becomes 1440 puls for one revolution.

I get 1440 puls from timer 4->CNT register but captured2 value from tim5 callback function give 360 puls is it correct ? or is it missing someting ?

and also my rpm measurement range 10-100 RPM so I'm deal with very low frequencies and I'm okay with any suggestions for precise speed measurement in that frequencie range.

Thanks in advance for any solution

/* USER CODE BEGIN 0 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
  {
	  PPMValue_Prev = PPMValue;
	  PPMValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
      PPM = (PPMValue >= PPMValue_Prev) ? (PPMValue - PPMValue_Prev) : (UINT16_MAX - PPMValue_Prev + PPMValue);
    
      captured2++;
 }
}
 
  MX_GPIO_Init();
  MX_TIM4_Init();
  MX_TIM5_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);
  HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_1);
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
int i = 0;
int a=0;
  while (1)
  {
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
	  i = TIM4->CNT;
	  a=TIM5->CCR1;
HAL_UART_Transmit(&huart2, (uint8_t*)txData, sprintf(txData, "%d\t%d\t%d\t%d\t%d\r\n", a,i,PPM,captured,captured2), 500);
 
  }
  /* USER CODE END 3 */
 
 
 
/* TIM4 init function */
static void MX_TIM4_Init(void)
{
 
  TIM_Encoder_InitTypeDef sConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
 
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 0;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 1-1;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter = 5;
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC2Filter = 5;
 
 
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  
 
}
 
/* TIM5 init function */
static void MX_TIM5_Init(void)
{
 
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_SlaveConfigTypeDef sSlaveConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_IC_InitTypeDef sConfigIC;
 
  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 84-1;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 0xffff-1;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 
 
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 
 
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
  sSlaveConfig.InputTrigger = TIM_TS_ITR2;
  
 
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_TRC;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
 

2 REPLIES 2

> I get 1440 puls from timer 4->CNT register but captured2 value from tim5 callback function give 360 puls is it correct

I don't use Cube and am not going to decipher your code, but if you set encoder to increment on both edges of both signals (TIMx_SMCR.SMS=0b011), it "sees" four time more edges when the encoder is turned in one direction all the time, than the slave timer's counter, which counts only on one signal's rising edge.

JW

thank for your reply , my problem is both channels activated and both channels rising edge in TIM4 so in this scenario TIM4 counter is successfully measure 1440 puls (it means 100% resolution of encoder) but same time TIM5 captured callback just triggered 360 puls (I manually turn motor wheel one revolution)

but after read your reply , I set tim4 both channels and both edge and tim4 counter "TIM4->CNT value which doesn't seem to count up or down consistently."

the same issiue happened in here (https://community.st.com/s/question/0D50X00009XkdsT/tim4-in-encoder-mode-nucleo-f767zi)

but tim5 callback counter increased 720 puls in one revolution it's like joke !?

(by the way my setup board is stm32f407vgtx)

thanks.