cancel
Showing results for 
Search instead for 
Did you mean: 

Editing motor control firmware for Bidirectional control of motor connected to B-G431B-ESC1

rudyard
Associate III

Hello,

In a seperate post I received help allowing my B-G431-ESC1 to accept PWM input from an ESP32 to vary the speed of a 24V hoverboard motor with hall sensors using FOC.

My goal now is to be able to vary the direction of the motor's rotation by varying the PWM.

Given that the acceptable range of values is 1060us to 1860us, I had hoped to be able to do this by having values 1060us to 1460us correspond to rotation in one direction, and the values from 1460us to 1860us correspond to rotation in the opposite direction.

I was unsure of any official documentation on bidirectional control, but i noticed that when using the motor pilot to manually set speeds, I was able to set the speed reference to be both positive and negative. I found a github with a guide on how to implement bidirectional control and after following the steps it mentioned, I found that when the motor driver was viewed on the motor pilot, the speed reference did indeed switch between positive and negative values with the appropriate PWM input.

However, when the speed reference was negative, the motor would attempt to rotate in the positive direction, crash, restart, attempt again, crash again, etc...

I have written this post to ask for help in resolving this issue of the speed reference showing up as negative, but the motor not actually being driven in the correct direction and then also crashing when it attempts to

Or if there were any easier ways to achieve the bidirectional control I described, I would also be very grateful to hear of how I should go about implementing this :)

the modifications I have made are as follows:

  • The following variable has been declared in mc_interface.h as part of the MCI_Handle_t struct
 int16_t hDirection;​
  • The following method has been added to mc_interface.c
__weak void MCI_SetDirection(MCI_Handle_t *pHandle, int16_t hDir)
{
#ifdef NULL_PTR_CHECK_MC_INT
  if (MC_NULL == pHandle)
  {
    /* Nothing to do */
  }
  else
  {
#endif
    pHandle->hDirection = hDir;
#ifdef NULL_PTR_CHECK_MC_INT
  }
#endif
}​
  • The MCI_ExecSpeedRamp() method has been altered, lines 11-18 in this sample were not present originally
__weak void MCI_ExecSpeedRamp(MCI_Handle_t *pHandle, int16_t hFinalSpeed, uint16_t hDurationms)
{
#ifdef NULL_PTR_CHECK_MC_INT
  if (MC_NULL == pHandle)
  {
    /* Nothing to do */
  }
  else
  {
#endif
      if (pHandle->hDirection < 0)
      {
        hFinalSpeed = -hFinalSpeed;
      }
      else
      {
        hFinalSpeed = hFinalSpeed;
      }
    pHandle->hFinalSpeed = hFinalSpeed;
    pHandle->lastCommand = MCI_CMD_EXECSPEEDRAMP;
    pHandle->hDurationms = hDurationms;
    pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED;
    pHandle->LastModalitySetByUser = MCM_SPEED_MODE;

#ifdef NULL_PTR_CHECK_MC_INT
  }
#endif
}​
  • The following If else block has been added to the esc.c file twice, both times before the MCI_ExecSpeedRamp() method is called. The other additions I mentioned were made directly following the github post I linked, but this addition was my attempt at splitting the range of pulse values as i described earlier. After this addition the speed reference would switch between positive and negative as I varied the pulse width about the middle value of 1460us, but the actual rotation did not switch directions.
    	 if(pHandle->Ton_value < (pESC_params->Ton_max + pESC_params->Ton_min)/2 ){
        	 MCI_SetDirection(pMCI[pESC_params->motor], -1);
    	 }
    	 else{
        	 MCI_SetDirection(pMCI[pESC_params->motor], 1);
    	 }​

motor workbench: Version: 6.4.1 Build: 250722.154358
STM32 cubeIDE: Version 2.0.0
STM32 cubeMX: Version 6.16.0

Board: B-G431-ESC1

Motor:

I have been unable to find a spec sheet for this motor, I believe it comes from the zimx hb1 hoverboard. Below is the information I currently have about it.

24V, 5Apk, 15 pole pairs, max RPM 600, 

4 REPLIES 4
STuser2
Senior III

My recommendation would be to first confirm if the motor runs in the reverse direction in the entire range of PWM input without any issues, then you can go for bidirectional control. For the reverse direction try to change as below.

__weak void MCI_ExecSpeedRamp(MCI_Handle_t *pHandle, int16_t hFinalSpeed, uint16_t hDurationms)
{
#ifdef NULL_PTR_CHECK_MC_INT
  if (MC_NULL == pHandle)
  {
    /* Nothing to do */
  }
  else
  {
#endif
    pHandle->lastCommand = MCI_CMD_EXECSPEEDRAMP;
    pHandle->hFinalSpeed = -hFinalSpeed;
    pHandle->hDurationms = hDurationms;
    pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED;
    pHandle->LastModalitySetByUser = MCM_SPEED_MODE;

#ifdef NULL_PTR_CHECK_MC_INT
  }
#endif
}

that is negative of hFinalSpeed and verify if it runs, i assume that as per the ST recommendation you are running in FOC sensor less mode.

 

 

Hello,

I am currently running with STO-PLL as the main sensor with hall sensors as an auxiliary sensor.

I believe I did try this and had the speed references be only negative values, rotate in the same direction as when the values are positive and crash and restart the whole time it was powered. 

I won't be able to work on it today so testing and further responses from me will be delayed. Thank you for the help you have already given and thank you for taking a look into this task :) 

 

EDIT 18/12/2025:

Back working on it for a little bit today, and yeah I tried editing the code as described and it rotates in the same direction as normally and then crashes and restarts continually.

I tried a few different things to fix this but ultimately they didn't work, mainly feel stumped and confused by the fact that the pilot recognises the negative speed reference I supply it.

The current angle I was beginning to explore was editing line 177 in revup_crtl.c

    pHandle->hDirection = -hMotorDirection;

My thinking was that since the revup was defined for a positive direction, if it was made negative, then maybe the opposite of what I was experiencing would happen, i.e. negative speed commands would all come through fine and positive speed commands would rotate in the negative direction, crash, restart, etc... And if that worked then I could have the driver be restarted whenever I needed to switch directions and have the revup occur in the appropriate direction.

Instead what I observed was that with negative speed references, the motor would begin to move in the negative direction, then slow down and begin shaking back and forth very quickly, then crash, then repeat. Then for positive speed references, they operated as normal, in the positive direction with no issues.

Tried some more things but no progress. My next thoughts were to try and alter methods that are more directly powering the motor windings. I tried looking into the mc_tasks_foc.c file but I wasn't sure exactly what to look for and what would actually affect the motor running. I also tried seeing what information I could gather from the registers in the motor pilot but again, not exactly sure what to look for. I did get pictures of the status and fault flag registers. The status register alternates between several states. It starts off idle, enters the start state, briefly enters the run state before reentering the idle state and repeating. A few times it does reach the switch over stage but also seems to crash. The fault register during all of this remains at 0.