cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to change the rotation direction of the motor in sensorless mode in some way?

N_1
Associate II

Hello everyone,

I would like to use my setup (using an stm32g431cb) to rotate 3 circle and than rotate 3 circle in the other direction, with 1500 rpm.

Now my motor just doing the rotation in one direction continously. I tried to use the following functions for :

MC_ProgramSpeedRampMotor1(3000,2000);

 MC_StartMotor1();

 HAL_Delay(2000);

MC_StopMotor1();

 MC_ProgramSpeedRampMotor1(-3000,2000);

 MC_StartMotor1();

 HAL_Delay(2000);

MC_StopMotor1();

but I don't exactly know how to use them...

Thanl you!

1 ACCEPTED SOLUTION

Accepted Solutions
Dvorak.Peter
Senior II

" to change the rotation direction in every 3 ms?"

This is not possible with conventional motor.

A voice coil actuator will work at 330 Hz

View solution in original post

4 REPLIES 4
Jack Peacock_2
Senior III

Is this a DC motor driven through an H-bridge? If so to change direction swap the sink and source at the bridge. DC motor direction is controlled by the polarity of the DC power to the motor. Typically an STM32 uses TIM1 to drive the two sides of the H-bridge, using PWM to vary speed and timer compare output polarity to set direction. TIM1 has the additional logic for deadtime when switching direction on the bridge, otherwise you can get a "shoot through" where sink and source are on at the same time on one leg of the bridge.

Jack Peacock

N_1
Associate II

Dear Jack Peacock,

Thank you very much for your nswer. Yes I have DC motor driven through an H-bridge. My TIM1 looks the following:

static void MX_TIM1_Init(void)

{

 /* USER CODE BEGIN TIM1_Init 0 */

 /* USER CODE END TIM1_Init 0 */

 TIM_SlaveConfigTypeDef sSlaveConfig = {0};

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 TIMEx_BreakInputConfigTypeDef sBreakInputConfig = {0};

 TIM_OC_InitTypeDef sConfigOC = {0};

 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 /* USER CODE BEGIN TIM1_Init 1 */

 /* USER CODE END TIM1_Init 1 */

 htim1.Instance = TIM1;

 htim1.Init.Prescaler = ((TIM_CLOCK_DIVIDER) - 1);

 htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;

 htim1.Init.Period = ((PWM_PERIOD_CYCLES) / 2);

 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;

 htim1.Init.RepetitionCounter = (REP_COUNTER);

 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

 {

  Error_Handler();

 }

 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;

 sSlaveConfig.InputTrigger = TIM_TS_ITR1;

 if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;

 sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sBreakInputConfig.Source = TIM_BREAKINPUTSOURCE_COMP1;

 sBreakInputConfig.Enable = TIM_BREAKINPUTSOURCE_ENABLE;

 sBreakInputConfig.Polarity = TIM_BREAKINPUTSOURCE_POLARITY_HIGH;

 if (HAL_TIMEx_ConfigBreakInput(&htim1, TIM_BREAKINPUT_BRK2, &sBreakInputConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sBreakInputConfig.Source = TIM_BREAKINPUTSOURCE_COMP2;

 if (HAL_TIMEx_ConfigBreakInput(&htim1, TIM_BREAKINPUT_BRK2, &sBreakInputConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sBreakInputConfig.Source = TIM_BREAKINPUTSOURCE_COMP4;

 if (HAL_TIMEx_ConfigBreakInput(&htim1, TIM_BREAKINPUT_BRK2, &sBreakInputConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 0;

 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.Pulse = 0;

 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.Pulse = 0;

 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM2;

 sConfigOC.Pulse = 0;

 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)

 {

  Error_Handler();

 }

 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;

 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;

 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;

 sBreakDeadTimeConfig.DeadTime = ((DEAD_TIME_COUNTS) / 2);

 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

 sBreakDeadTimeConfig.BreakFilter = 0;

 sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;

 sBreakDeadTimeConfig.Break2State = TIM_BREAK2_ENABLE;

 sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;

 sBreakDeadTimeConfig.Break2Filter = 3;

 sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;

 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM1_Init 2 */

 /* USER CODE END TIM1_Init 2 */

 HAL_TIM_MspPostInit(&htim1);

}

So how should I change the polarity setup to change the rotation direction in every 3 ms?

I am very new in motor control, you would help me a lot !!

Thank you

Dvorak.Peter
Senior II

" to change the rotation direction in every 3 ms?"

This is not possible with conventional motor.

A voice coil actuator will work at 330 Hz

N_1
Associate II

I have this kind of motor:

https://www.maxongroup.com/maxon/view/content/ECX-Detailsite

With different controller it was possible to do it, probably I said the motor type badly.