(Bug Report) When using encoder, the generated code has a few defects - speed calculation is not reliable, no speed reliability check, and no scheme to clear speed feedback fault
(Environment)
MC_SDK 5.Y.3 + STM32CubeMX 6.3.0 with HAL + IAR EWARM 8.5
(Hardware)
custom board based on F446RE + custom power board + Low Voltage BLDC motor with Encoder
(Control Mode)
Speed Control
(What I found)
(1) speed calculation is not reliable
[ ENC_CalcAvrgMecSpeedUnit() in encoder_speed_pos_fdbk.c ]
Encoder direction and UP(overflow/underflow) count are used to calculate the delta.
This algorithm lead, however, to an incorrect result in the following case:
- During speed loop (1msec), assume encoder direction has been up-counting so far
- That is, speed is (+) and delta is (+)
- However, just when ENC_CalcAvrgMecSpeedUnit() is called, encoder direction could be changed to down-counting
- (+)delta and down-counting results in incorrectly adding encoder pulse number
This case can happen when the motor is hunting around zero speed, including encoder alignment.
=============================================================
if ( directionSample == LL_TIM_COUNTERDIRECTION_DOWN ) {
/* encoder timer down-counting*/
OverflowCntSample = ( CntCapture > pHandle->PreviousCapture ) ? 1 : 0;
pHandle->DeltaCapturesBuffer[pHandle->DeltaCapturesIndex] =
( int32_t )( CntCapture ) - ( int32_t )( pHandle->PreviousCapture ) -
( ( int32_t )( OverflowCntSample ) + OFbit ) * ( int32_t )( pHandle->PulseNumber );
}
=============================================================
(2) no speed reliability check
[ TSK_MediumFrequencyTaskM1() in mc_task.c ]
- In case of using encoder
=============================================================
__weak void TSK_MediumFrequencyTaskM1(void)
{
...
(void) ENC_CalcAvrgMecSpeedUnit( &ENCODER_M1, &wAux );
...
case RUN:
MCI_ExecBufferedCommands( &Mci[M1] );
FOC_CalcCurrRef( M1 );
break;
....
}
=============================================================
- In case of using hall sensor
=============================================================
__weak void TSK_MediumFrequencyTaskM1(void)
{
...
bool IsSpeedReliable = HALL_CalcAvrgMecSpeedUnit( &HALL_M1, &wAux );
...
case RUN:
MCI_ExecBufferedCommands( &Mci[M1] );
FOC_CalcCurrRef( M1 );
if( !IsSpeedReliable )
{
STM_FaultProcessing( &STM[M1], MC_SPEED_FDBK, 0 );
}
break;
....
}
=============================================================
(3) no scheme to clear speed feedback fault once happened
[ SPD_IsMecSpeedReliable() in speed_pos_fdbk.c ]
"ENCODER_M1._Super.bSpeedErrorNumber" is incremented to its max(default:3) then generating an alarm, but no state transition or API to reset this value to zero.
