STM32_12.TestEnkoderSerwo

Encoder to Servo Test Bench

Test bench connecting encoder to servo. The firmware uses STM32F411CEU6 timer encoder mode and servo PWM for precise position control.

STM32F4CHALEncoderServoTimer PWM

Project facts

  • Repository: STM32_12.TestEnkoderSerwo
  • Board / area: STM32F411CEU / TIM encoder + PWM servo
  • Category: Motion control
  • Status: Public repository

Technical description

  • The code starts PWM on TIM10 and encoder mode on TIM4, then repeatedly reads the TIM4->CNT counter.
  • Servo range is defined by START_POSITION and END_POSITION, making the PWM calibration explicit.
  • percentToServoPosition() maps the input value to a servo position and setServoPosition() updates the PWM compare register.
  • The firmware uses two STM32 timers in different roles: TIM4 works as the encoder input and TIM10 generates servo PWM.
  • The main loop reads the encoder counter, scales the input value and updates the servo position through the timer compare register.

What happens in the code

Selected key mechanisms from the project code. This is not a full repository dump, but an analysis of the parts responsible for the main firmware logic.

  • The main operation mechanism is based on reading the TIM4->CNT counter from the encoder and transforming it into an appropriate servo position.
  • The percentToServoPosition() function converts the encoder value to a PWM pulse for the servo, using START_POSITION and END_POSITION constants.
  • The setServoPosition() function updates the timer compare register of TIM10, which results in the correct servo position.
  • The code implements a simple logic to transform encoder pulses into servo position without additional control.
  • Using TIM4 in encoder mode allows precise tracking of the shaft movement, while TIM10 generates appropriate PWM pulses for the servo.

Key code excerpts

The code is shortened to the parts that matter for understanding the project.

Transforming encoder value to servo position

Core/Src/main.c
uint16_t percentToServoPosition(bool mode, uint16_t percent)
{
	uint16_t ret =0;

	float div = (percent/100.0f);
	if(mode)
		ret =START_POSITION + div * (END_POSITION -  START_POSITION);
	else
		ret =END_POSITION - div * (END_POSITION -  START_POSITION);

	return ret;
}

The function transforms the encoder value to an appropriate servo position. Values are scaled within the range from START_POSITION to END_POSITION, enabling precise servo position control.

Setting servo position

Core/Src/main.c
void setServoPosition(uint16_t position)
{
	__HAL_TIM_SET_COMPARE(&htim10,TIM_CHANNEL_1, position);
}

The function sets the servo position by updating the timer compare register of TIM10. The value passed to the function is directly the PWM pulse value.

Main control loop

Core/Src/main.c
__HAL_TIM_SET_COMPARE(&htim10,TIM_CHANNEL_1, START_POSITION);
  uint16_t servoPosition = 0;
  while (1)
  {
		pulse_count = TIM4->CNT; // przepisanie wartosci z rejestru timera
		positions = pulse_count/4; // zeskalowanie impulsow do liczby stabilnych pozycji walu enkodera

		servoPosition = percentToServoPosition(true, pulse_count);
		setServoPosition(servoPosition);
  }

The main loop reads the encoder counter, scales the value and sets the appropriate servo position. The value is transformed by the percentToServoPosition function and set by setServoPosition.