
Drone ESC motor for buzzer
Preface
The customer noticed DJI powers on with a sound but no buzzer was found in the circuit. They want to use the motor to mimic a buzzer effect. ST’s MCSDK for ESC includes a built-in function for this, so here’s a brief intro to the function that enables a buzzer-like sound during motor startup.
Hardware
Basically, it is the same as a standard motor structure, and no hardware modification is required. The validation reference here is based on ST’s development board B-G431B-ESC1


Sample code

In the new MCSDK Motor Driver, you will find esc.c and esc.h located in your created project folder path.
The motor parameters are configured as follows (note: TIM2 is used for external PWM to control speed, but if unused, it can be removed).
const ESC_Params_t ESC_ParamsM1 =
{
.Command_TIM = TIM2,
.Motor_TIM = TIM1,
.ARMING_TIME = 200,
.PWM_TURNOFF_MAX = 500,
.TURNOFF_TIME_MAX = 500,
.Ton_max = ESC_TON_MAX, /*!< Maximum ton value for PWM (by default is 1800 us) */
.Ton_min = ESC_TON_MIN, /*!< Minimum ton value for PWM (by default is 1080 us) */
.Ton_arming = ESC_TON_ARMING, /*!< Minimum value to start the arming of PWM */
.delta_Ton_max = ESC_TON_MAX - ESC_TON_MIN,
.speed_max_valueRPM = MOTOR_MAX_SPEED_RPM, /*!< Maximum value for speed reference from Workbench */
.speed_min_valueRPM = 1000, /*!< Set the minimum value for speed reference */
.motor = M1,
};
For the sound function, you can directly copy and use the following section. Similarly, the TIM2 part can be removed, and number_beep can be directly set to 1.
#ifdef ESC_BEEP_FEATURE
static bool esc_beep_loop(ESC_Handle_t * pHandle, uint16_t number_beep)
{
TIM_TypeDef * TIMx = pHandle->pESC_params->Motor_TIM;
bool ESC_Beep_loop_STATUS = false;
/* TIMx Peripheral Configuration -------------------------------------------*/
if( pHandle-> start_check_flag == false)
{
pHandle-> start_check_flag = true;
ESC_Beep_loop_STATUS = false;
/* Set the Output State */
LL_TIM_SetAutoReload (TIMx, BEEP_FREQ_ARR);
LL_TIM_CC_DisableChannel (TIMx, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2
| LL_TIM_CHANNEL_CH3 | LL_TIM_CHANNEL_CH1N
| LL_TIM_CHANNEL_CH2N | LL_TIM_CHANNEL_CH3N);
LL_TIM_CC_EnableChannel (TIMx, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2
| LL_TIM_CHANNEL_CH3 );
LL_TIM_EnableAllOutputs (TIMx);
}
{
/* User defined code */
switch (pHandle->beep_state)
{
case SM_BEEP_1:
{
if(pHandle->beep_counter == 0)
{
LL_TIM_OC_SetCompareCH1 (TIMx,BEEP_DUTY);
LL_TIM_OC_SetCompareCH2 (TIMx,BEEP_FREQ_ARR);
LL_TIM_OC_SetCompareCH3 (TIMx,BEEP_FREQ_ARR);
LL_TIM_CC_DisableChannel (TIMx,LL_TIM_CHANNEL_CH2 | LL_TIM_CHANNEL_CH3 );
LL_TIM_CC_EnableChannel (TIMx, (LL_TIM_CHANNEL_CH2N | LL_TIM_CHANNEL_CH3N
| LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH1N));
}
pHandle->beep_counter++;
if(pHandle->beep_counter > BEEP_TIME_MAX)
{
if(number_beep == 1)
{
pHandle->beep_stop_time = 570;
pHandle->beep_state = SM_BEEP_4;
}
if(number_beep == 2)
{
pHandle->beep_num ++;
if(pHandle->beep_num <= 2)
{
LL_TIM_OC_SetCompareCH1 (TIMx,0);
pHandle->beep_state = SM_BEEP_3;
}
else
{
pHandle->beep_stop_time = 410;
pHandle->beep_state = SM_BEEP_4;
pHandle->beep_num = 1;
}
}
if(number_beep == 3)
{
pHandle->beep_num ++;
if(pHandle->beep_num <= 3)
{
LL_TIM_OC_SetCompareCH1 (TIMx,0);
pHandle->beep_state = SM_BEEP_3;
}
else
{
pHandle->beep_stop_time = 270;
pHandle->beep_state = SM_BEEP_4;
pHandle->beep_num = 1;
}
}
pHandle->beep_counter = 0;
}
}
break;
case SM_BEEP_3:
{
if(pHandle->beep_counter == 0)
{
LL_TIM_OC_SetCompareCH1 (TIMx,0);
}
pHandle->beep_counter++;
if(pHandle->beep_counter > 50)
{
pHandle->beep_state = SM_BEEP_1;
pHandle->beep_counter = 0;
}
}
break;
case SM_BEEP_4:
{
if(pHandle->beep_counter == 0)
{
LL_TIM_OC_SetCompareCH1 (TIMx,0);
LL_TIM_OC_SetCompareCH2 (TIMx,0);
LL_TIM_OC_SetCompareCH3 (TIMx,0);
}
pHandle->beep_counter++;
if(pHandle->beep_counter > pHandle->beep_stop_time)
{
pHandle->beep_state = SM_BEEP_1;
pHandle->beep_counter = 0;
esc_reset_pwm_ch(pHandle);
pHandle-> start_check_flag = false;
ESC_Beep_loop_STATUS = true;
}
}
break;
case SM_BEEP_2:
default:
break;
}
}
return (ESC_Beep_loop_STATUS);
}