B-G431B-ESC1 + Platform IO : help needed on soft : not driving

Hi everyone,

Been trying to get a STM Discovery board to work with SimpleFOC in sensorless (FOC or openloop) but with very little succes so far.

I’ve gone through the following :

  • Made sure that the discovery / motor / cabling is all good by driving with the STM motor development SDK ==> works a treat but I cannot find my way through the code to add the control functions I want.

  • Then got the whole VScode / PlatformIO out and followed the B-G431B-ESC1: Beginner guide + I2C guide from ultra robotics, added the board template, all the relevant files etc…

  • Managed to get some code compiling uploaded and running ont the board (just managed to get a Hello World through a Serial.println to make sure it was cycling)

===> But that’s pretty much where the fun stops, nothing seem to even drive the FETs, no significant consumption, obviously no motor rotation or even vibration, nothing…

  • Tried different codes and settled on the one below which seemed to be the closest to working… The PID does get processed when I enter it on the terminal but nothing more…

The main.cpp is as follow

#include <Arduino.h>
#include <SimpleFOC.h>
#include
#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

BLDCMotor motor = BLDCMotor(10, .1);
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(1843200);
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();
}

And here’s the platformio.ini :

[env:disco_b_g431b_esc1]
platform = ststm32
board = disco_b_g431b_esc1
framework = arduino
monitor_speed = 115200

build_flags =
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
-D PIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF
; -D PIO_FRAMEWORK_ARDUINO_USB_HIGHSPEED_FULLMODE

lib_deps =
askuric/Simple FOC@^2.3.4
simplefoc/SimpleFOCDrivers@^1.0.8
lib_archive = false

Thanks for the heads up if anything looks weird…

Hopefully your mosfets are still alive… the full motor.voltage_limit is applied at all times in open loop mode, so it should be much lower, like 0.5V or less. Run it with the STM SDK again to make sure the hardware is ok.

Otherwise your code looks like it should work. I’m no good with PlatformIO, but the fact that the constants passed to BLDCDriver6PWM exist and serial communication works means it’s probably set up correctly.

Once you have it running with current sense, the sensorless flux observer is the way to go for velocity control without a position sensor, although it requires some tedious tuning. Start with the kv and resistance values from the motor’s official specs, adjust the inductance until it runs, and then try adjusting the other two as well to see if you can improve it. Usually inductance is in the area of 0.00005.

Hi dekutree64,

Thanks for the feedback !
I’ve just tried and the MOS seem to have survived :slight_smile: The motor is running well under the STM SDK.

Will try running it with the sensorless flux observer you linked even though I have the feeling the problem is coming before that…

Excellent.

Don’t bother with flux observer until you have open loop working. It seems you’re not getting voltage output at all, which is good in this case since it saved your mosfets.

Try running your code again, just with the voltage limit set to 0.5. Add this to make sure it’s actually trying to output varying voltages:

static uint32_t lastPrintTime = 0;
if (millis() > lastPrintTime + 50) {
  lastPrintTime = millis();
  char string[256];
  sprintf(string, "%i, %i, %i\n", (int)(motor.Ua*1000), (int)(motor.Ub*1000), (int)(motor.Uc*1000));
  Serial.print(string);
}

For real-time output it’s generally better to use sprintf like that instead of separate calls to Serial.print for each variable, since multiple calls to Serial slows it down a lot more. But Arduino’s implementation of sprintf does not support floating point, so you have to multiply by 1000 or whatever to get enough visible precision as an integer.

-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
You have to remove that line.