2025-07-23 2:56 AM
I'm using button in the MC_APP_PostMediumFrequencyHook_M1 to stop the motor. When I press the button, the motor enters freewheel mode, so it is not actively braked — it simply coasts down.
Later, when I release the button and increase the potentiometer, the motor starts again via a speed ramp. However, I noticed that the ramp always starts from 0 speed, even though the motor was still spinning due to the freewheel behavior.
As a result, the motor gets "locked" momentarily (due to the controller assuming 0 speed), and then accelerates. This is not the behavior I want. Since the motor never truly stopped (freewheel), I would like the ramp to continue from the current actual speed, not from 0.
How can I make the ramp start from the actual mechanical speed of the motor when restarting after freewheel?
__weak void MC_APP_PostMediumFrequencyHook_M1(void)
{
uint16_t rawValue = RCM_ExecRegularConv(&PotRegConv_M1);
/* USER SECTION BEGIN PostMediumFrequencyHookM1 */
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9))
{
MC_StopMotor1();
//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, 1);
SpeedPotentiometer_M1.IsRunning =false;
}
if(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9))
{
if(rawValue>100)
{
MC_StartMotor1();
}
// HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, 0);
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13))
{
SPDPOT_F(&SpeedPotentiometer_M1, rawValue);
}
else
{
SPDPOT_R(&SpeedPotentiometer_M1, rawValue);
}
}
bool SPDPOT_R(SpeedPotentiometer_Handle_t *pHandle, uint16_t rawValue)
{
bool retVal = false;
#ifdef NULL_PTR_CHECK_SPD_POT
if (MC_NULL == pHandle)
{
/* Nothing to do */
}
else
{
#endif
SpeednTorqCtrl_Handle_t *pSTC = pHandle->pMCI->pSTC;
POT_TakeMeasurement((Potentiometer_Handle_t *)pHandle, rawValue);
SpeednPosFdbk_Handle_t *speedHandle = STC_GetSpeedSensor(pSTC);
if (MCM_SPEED_MODE == STC_GetControlMode(pSTC))
{
if (RUN == MCI_GetSTMState(pHandle->pMCI))
{
if (false == pHandle->IsRunning)
{
pSTC->SpeedRefUnitExt = ((int32_t)SPD_GetAvrgMecSpeedUnit(pSTC->SPD)) * (int32_t)65536;
pHandle->IsRunning = true;
}
if (POT_ValidValueAvailable((Potentiometer_Handle_t *)pHandle))
{
uint16_t potValue = POT_GetValue((Potentiometer_Handle_t *)pHandle);
if ((potValue <= (pHandle->LastSpeedRefSet - pHandle->SpeedAdjustmentRange)) ||
(potValue >= pHandle->LastSpeedRefSet + pHandle->SpeedAdjustmentRange))
{
int16_t currentSpeed = SPD_GetAvrgMecSpeedUnit(speedHandle);
int16_t requestedSpeed = (int16_t)((potValue / pHandle->ConversionFactor) + pHandle->MinimumSpeed);
if (currentSpeed < 0)
requestedSpeed = -requestedSpeed;
int16_t deltaSpeed = requestedSpeed - currentSpeed;
if (deltaSpeed < 0) deltaSpeed = -deltaSpeed;
uint32_t rampDuration = ((uint32_t)deltaSpeed * 1000U) / pHandle->RampSlope;
STC_ExecRamp(pSTC, requestedSpeed, rampDuration);
pHandle->LastSpeedRefSet = potValue;
retVal = true;
}
}
}
else
{
pHandle->IsRunning = false;
}
}
else
{
pHandle->IsRunning = false;
}
#ifdef NULL_PTR_CHECK_SPD_POT
}
#endif
return retVal;
}
To solve this, I tried manually assigning the average mechanical speed to the speed reference like this:
STC->SpeedRefUnitExt = ((int32_t)SPD_GetAvrgMecSpeedUnit(pSTC->SPD)) * 65536;
2025-07-23 6:35 AM
Hi TKara.2,
if you are using the MCSDK6.4.0, you will find the "On The FLy" feature designed for the 6step algorithm. This will allow your motor to restart from a spinning state with no revup phase, as described into the "Six-step Firmware Algorithm" user manual (chapter 5.1.6 Rev-up component and On-the-fly start-up) embedded into the MCSDK Workbench tool.
Please refer to User Manual documentation available through: "Workbench tool">About>Documentations>Documentation>"User manual" tab>"Six-step Firmware Algorithm" link
To enable the feature, you must set the On-the-fly start-up bit into the MCSDK6.4.0 Workbench, and regenerate the project.
Best regards.
Fabrice