Sensorless BEMF reading with B-G431-ESC1

I am currently using the B-G431-ESC1 to drive a sensorless BLDC motor. I have the motor running well in an velocity open loop, but I need to run the motor in a closed loop. From my understanding I need to use BEMF as feedback but don’t know how to actually get the BEMF values and then what to do with those values afterwards. Is there a different way to do a sensorless closed velocity loop? Does anyone have any pointers as to how to get the BEMF values and what to do with them afterwards?

I have attempted to configure the ADC using the STM32 library but was unsuccessful. If that is the path to take are there any pointers there?

This is my current code:


#include <Arduino.h>
#include <SimpleFOC.h>
#include <string>
#include "stm32g4xx_hal.h"

//local variable definitions
float target = 0.0;     // used to change currently tested variable
int spinIt = 1;         // iterator for the startup
int spinItSpeed = 1500; // rate of the startup, higher = slower
float radPerSec = 0;    // driver the motor speed
int mxRads = 0;         // max motor speed
int outIt = 0;          //used for communication rate iteration

//Set up the motor and driver, motor is 7 pp, .12 phase resistor, and 1400KV 
BLDCMotor motor = BLDCMotor(7, .12, 1400);
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);

/*controls the motor using the UART. 
-g starts the motor and revs up to 300 rad/s, 
-s stops the motor, 
-and entering a number sets the P in pid to that number
  -(currently not useful, but implemented for later tuning)
*/
void serialControl(){
  static String received_chars;
  while (Serial.available())
  {
    char inChar = (char)Serial.read();
    received_chars += inChar;
    if (inChar == '\n')
    {
      float num = received_chars.toFloat();
      if(received_chars == "s\n"){
        radPerSec = 0;
        mxRads = 0;
        received_chars = "";
        Serial.println("Stopping Motor.");
        break;
      }
      else if(received_chars == "g\n"){
        radPerSec = 0;
        mxRads = 300;
        received_chars = "";
        Serial.println("Starting Motor.");
        break;
      }
      else{
        target = num;
        Serial.print("PID.P = ");
        Serial.println(target);
        received_chars = "";
      }    
    }
  }
}

void setup()
{

  //initializes the psu and driver
  driver.voltage_power_supply = 14.8;
  driver.init();

  motor.linkDriver(&driver);
  motor.voltage_limit = 14.8;
  motor.velocity_limit = 2212;

  //Sets up openloop FOC
  motor.controller = MotionControlType::velocity_openloop;
  // set FOC modulation type to sinusoidal
  motor.foc_modulation = FOCModulationType::SinePWM;


  motor.init();

  motor.initFOC();

  
  Serial.begin(115200);
  delay(1000);

}


void loop()
{
  //starts the motor moving at radPerSec
  motor.loopFOC();
  motor.move(radPerSec);
  //this loop controls the rate at which the motor speeds up
  if (spinIt%spinItSpeed == 0 && radPerSec<mxRads){
    radPerSec++;
    spinIt = 1;
  }
  else{
    spinIt++;
  }

  //motor.PID_velocity.P = target;
  
  serialControl();
}


It’s not using the BEMF sensing but maybe you can try the flux observer I ported as a simplefoc sensor, I tested it on a hoverboard motor with this example project.

I am actually working on a unified current sense driver for stm32 that let’s you sample any other pin easily, it works but I still have a list of things to do there.
Here you can see I added the BEMF pins already.
If I remember well you need to do this in the main loop to get the values:

_readADCVoltageLowSide(A_BEMF1, currentSense->params);

But I haven’t tried to use it for sensorless, you should probably calibrate the 0 offset for each phase. I am not sure if this is meant for 6 step communation only, or you can do a clarke transform and use atan2 to get an angle.

That’s meant for 6 step, iirc. You only get an interesting value by reading the voltage of a phase when it’s half bridge is in high-z mode, otherwise it’ll just read psu voltage or ground.

OK so other than 6 step it could be interesting for tracking when the motor is not driven only.