cancel
Showing results for 
Search instead for 
Did you mean: 

Measuring speed with Input Capture Mode.

xpp07
Senior

Hello,

I have the L432KC Nucleo. I'm trying to measure low speeds with a 1 PPR (pulse per revolution) sensor. For low PPRs. using the Period Measurement Method is suggested. If I get the period of the signal, then I can apply the formula:

RPM = 60/(Pulse Period)

It's my first time using input capture mode. This is what I have:

In CubeMx I've set Timer 2, channel 3. My APB2 frequency is 1 MHz. The TIM2 prescaler is 1000 and the counter period is 10000. Everytime a pulse is given, a falling edge occurs. Is everything good so far?

Now, in the code I have:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(htim);
 
  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_IC_CaptureCallback could be implemented in the user file
   */
  if(htim->Instance == TIM2){
	  inputCaptureVal = __HAL_TIM_GetCounter(htim);
	  __HAL_TIM_SetCounter(htim,0);
  }
}

In the while loop I have another variable: counterVal= __HAL_TIM_GetCounter(htim2);

I'm kind of lost. Is this the right way to get the period? I would appreciate any guidance.

5 REPLIES 5

Wouldn't the capture event load CCR3 with the value of CNT at the event?

I would tend to use PWM Input mode where CH1/CH2 would provide a Period and Duty value, and reset the count.

The other method is to have the counter in a maximal mode ie ARR=0xFFFFFFFF for a 32-bit TIM, and then subtract the last value of CCR3 from the current to get a delta ticks measurement. This would have less issues with latency.

In maximal mode you can use uint32_t a, b, delta; where delta = b - a; for all values.

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

Is this routine okay?

// PWM Input Mode 
void  HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
if(htim->instance == TIM2) {
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
//if CH1 is rising
IC1Value = HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_1); //Read CH1 value
TIM->CNT=0 // Reset count
Period = IC1Value;
}
}
}

Khouloud GARSI
Lead II

Hi @XP.1acheco​ ,

I really advise you to refer to "TIM_InputCapture" and "TIM_PWMInput" examples provided under STM32L4 Cube package:

STM32Cube_FW_L4_V1.13.0\Projects\NUCLEO-L432KC\Examples\TIM

The examples are well explained and will help you to understand how to use the timer peripheral under the Input capture and PWM input mode.

Khouloud.

xpp07
Senior

Hi @Khouloud GARSI​  Thank you. I was looking into the PWM Input Example:

Does the count reset automatically? As I'm interested in measuring the pulse period to find the speed, the only essential line is

uwIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); Right?

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  {
    /* Get the Input Capture value */
    uwIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
 
    if (uwIC2Value != 0)
    {
      /* Duty cycle computation */
      uwDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1)) * 100) / uwIC2Value;
 
      /* uwFrequency computation
      TIM2 counter clock = (RCC_Clocks.HCLK_Frequency) */
      uwFrequency = (HAL_RCC_GetHCLKFreq())  / uwIC2Value;
    }
    else
    {
      uwDutyCycle = 0;
      uwFrequency = 0;
    }
  }
}

Khouloud GARSI
Lead II

Hi @XP.1acheco​ ,

The answer is YES for the two questions.

Khouloud.