I'm driving a 12V brushed DC motor using an A3941 full bridge mosfet driver. The setup is controlled using an STM32F407. Since the A3941's logic inputs need 5V, I'm using a MC74VHCT125A buffer between the STM32 and the driver.
There is also a wireless remote using an nRF24 and its data is parsed by the STM32 as well. Its a simple remote that transmits a 32-byte array. If array[0] = 1, turn the motor CW, if array[0] = 0 then stop the motor. If array1 = 1, then turn the motor CCW and if array1 = 0, then again stop the motor. This partially works and this is where the strange behavior comes into play. When I press the button for CW on the remote, I hear a low whine and the motor does not turn or turns very very slowly. If I press the button for the CCW, it turns but not at the set duty cycle. For the motor to turn, you need to keep pressing the button on the remote. This means that the PWM Start function keeps getting called again and again. If this causing this weird behavior?
Can anyone help me understand what is happening here?
To test if the motors are working properly, I added a small while (1) loop where I turn the motor CW, wait for 2s, stop the motor, reverse the direction and start the motor again, wait for 2s and the stop the motor again. This works just fine without any issues. So I know that the motor driving circuitry works okay.
The functions for turning the motors CW, CCW and OFF are as follows:
void Start_M1_CW(void)
{
HAL_GPIO_WritePin(DIR_M1_GPIO_Port, DIR_M1_Pin, CW); // Sets the direction by setting the Phase pin to 0
HAL_GPIO_WritePin(PWM_L_M1_GPIO_Port, PWM_L_M1_Pin, GPIO_PIN_SET); //PWML = 1. Pg. 9, Table 2 of the datasheet
HAL_GPIO_WritePin(SR_M1_GPIO_Port, SR_M1_Pin, GPIO_PIN_SET); //SR = 1. Pg. 9, Table 2 of the datasheet
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1); // PWMH. 95% duty cycle, 20Khz frequency
Motor_M1.flag = 1; // a simple flag to tell if the motor is ON or OFF
}
void Start_M1_CCW(void)
{
HAL_GPIO_WritePin(DIR_M1_GPIO_Port, DIR_M1_Pin, CCW); // Sets the direction by setting the Phase pin to 1
HAL_GPIO_WritePin(PWM_L_M1_GPIO_Port, PWM_L_M1_Pin, GPIO_PIN_SET); //PWML = 1, Pg. 9, Table 2 of the datasheet
HAL_GPIO_WritePin(SR_M1_GPIO_Port, SR_M1_Pin, GPIO_PIN_SET); //SR = 1. 9, Table 2 of the datasheet
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1); // PWMH. 95% duty cycle, 20Khz frequency
Motor_M1.flag = 1; // a simple flag to tell if the motor is ON or OFF
}
void Stop_M1(void)
{
HAL_GPIO_WritePin(SR_M1_GPIO_Port, SR_M1_Pin, GPIO_PIN_RESET); //SR = 0
HAL_TIM_PWM_Stop(&htim5, TIM_CHANNEL_1); // PWMH = 0
HAL_GPIO_WritePin(PWM_L_M1_GPIO_Port, PWM_L_M1_Pin, GPIO_PIN_RESET); //PWML = 0
Motor_M1.flag = 0;
}
This is the code for operating the motor based on what the remote payload contains. This works fine btw. I can see the button as 0 or 1 while debugging.
void Parse_Remote_Payload(void)
{
//M1 CW
if (nRF24_payload[0])
{
Start_M1_CW();
}
if (!nRF24_payload[0])
{
Stop_M1();
}
//M1 CCW
if (nRF24_payload[1])
{
Start_M1_CCW();
}
if (!nRF24_payload[1])
{
Stop_M1();
}
}