How to Interface an External MCU with B-G431B-ESC1 Discovery Kit for High Precision BLDC Motor Control using SimpleFOC?

How to Interface an External MCU with B-G431B-ESC1 Discovery Kit for High Precision BLDC Motor Control using SimpleFOC?**

Hello everyone,

I’m working on a high-precision BLDC motor control project and I need some guidance on interfacing an external microcontroller unit (MCU) with the B-G431B-ESC1 Discovery kit. My goal is to leverage the SimpleFOC library for fine-tuned motor control.

Here are the details of my setup:

  • BLDC Motor: Hoverboard motor "
  • MCU: ( ESP32)
  • Motor Driver: B-G431B-ESC1 Discovery kit
  • Control Library: SimpleFOC

Questions:

  1. Connection: What is the best way to connect my external MCU to the B-G431B-ESC1 Discovery kit? Are there specific pins or interfaces (e.g., UART, I2C, SPI) that are recommended for this setup?
  2. Power Considerations: How should I manage the power supply for the external MCU and the B-G431B-ESC1 Discovery kit? Should they share a common ground, and what precautions should I take to avoid power-related issues?
  3. Communication Protocol: Which communication protocol is most suitable for sending control signals from the external MCU to the B-G431B-ESC1? Are there any libraries or examples that could simplify this process?
  4. SimpleFOC Integration: How can I configure SimpleFOC to work seamlessly with the external MCU and the B-G431B-ESC1? Are there any specific configurations or settings within SimpleFOC that I need to be aware of?
  5. Precision Control Tips: What are some best practices or tips for achieving high-precision control of the BLDC motor in this setup? Are there any additional sensors or feedback mechanisms that would enhance the precision?

Additional Context:

  • I have intermediate experience with MCU programming and basic knowledge of motor control.
  • I have already successfully run basic motor control tests using the B-G431B-ESC1 and an onboard MCU.

Any advice, example projects, or resources that you can share would be greatly appreciated!

Thank you!

I was thinking the same if it is possible to do it. Seems like no one has done it.

trying to do the same here but don’t know what code to upload where, do I upload all the simplefoc code to the esp32 and leave the B-G431B blank and send commands from the esp32 or upload some code to the B-G431B and some to the esp32, I can upload all the simplefoc code to the B-G431B and use my AS5600 connected to it and get it working fine, but that can’t be the way to go because I would need to upload the same code to both but then you can’t use motor1 motor2 and so on in your config. it’s got me pretty confused; I was gonna just upload the same config on both B-G431B’s then from esp32 just send each one a serial command, but can’t figure out how to setup that Commander to separate each one. Anyone with time interested in helping to explain how to set this up?

If I understand correctly you are trying to control G431 (may be more than one) with one Esp32?

The SimpleFOC is for G431 single motor control. You need to write your own code for Esp32 to send control signals to G431, and G431 will use SimpleFOC to control the motors. In other words, the Esp32 will contain your custom code which has nothing to do with the G431 motor control, it’s your own control such as what speed, or angle, voltage and current to use to control the motor, send those to the G431 using I2C or some other protocol, and write your custom code inside the G431 loop to read the I2C (or other) control signal from Esp32, and make SimpleFOC control the motor. The AS5600 is connected to the G431. If you control two motors, you need two G431, two AS5600->G431 and one Esp32 connected to G431 on the I2C. You cannot use one Serial from Esp32 to control two motors unless you use two serial lines to the two G431. Serial is only point to point. However, I2C can use multiple addresses and devices.

Am I making sense here?

Cheers,
Valentine

I think I have things sorted out now, sorta. I’ve uploaded the first code for each motor to each G431 controller with one change, one motor is “A” while the other is “B” then from my esp32, I send the second code

#include <Arduino.h>
#include <SimpleFOC.h>

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);

BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PC13, PA9, PA12, PA10, PB15);

//float target_velocity = 0;
unsigned long time_stamp = 0;
double temp = 0;

Commander command = Commander(Serial);

void doMotor(char* cmd) { command.motor(&motor, cmd); }

void printTemp() {
  if(millis()-time_stamp > 1500) {
    temp = map(analogRead(A_TEMPERATURE),0,1024,-49,125);
    Serial.print("TempC: "); Serial.println(temp);
    time_stamp = millis();
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(A_TEMPERATURE, INPUT);

  //SimpleFOCDebug::enable(&Serial);

  sensor.init();
  motor.linkSensor(&sensor);

  driver.voltage_power_supply = 14.25;
  driver.init();

  motor.linkDriver(&driver);
  motor.controller = MotionControlType::velocity;
  //motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

   // velocity PI controller parameters
  motor.PID_velocity.P = 0.055f; // 0.055f
  motor.PID_velocity.I = 5.2f; // 5.5f
  motor.voltage_limit = 2.5;
  motor.PID_velocity.output_ramp = 1000;
  motor.LPF_velocity.Tf = 0.005f;

  motor.useMonitoring(Serial);
  motor.init();
  motor.initFOC();

  char motor_id = 'B';
  motor.monitor_start_char = motor_id;
  motor.monitor_end_char = motor_id; 
  
  command.add(motor_id,doMotor,"motor");
  command.verbose = VerboseMode::machine_readable;
  
  Serial.println(F("Motor ready."));
  _delay(1000);
}

void loop() {
  //printTemp();
  motor.loopFOC();
  motor.move();
  motor.monitor();
  command.run();
}

Esp32 code as a test.

void setup() {
  Serial.begin(115200);
}

// TEST -- send a random velocity over serial to each motor every 2 seconds
void loop() {
  int velocity_a = random(0, 31);
  int velocity_b = random(0, 31);
  Serial.print("A"); Serial.println(velocity_a);
  Serial.print("B"); Serial.println(velocity_b);
  delay(2000);
}

this works so I can send commands to each motor separately over serial, however I don’t know how or if I can send the same command simultaneously to each motor yet, or if this will work when i get into sending more stuff long term. If you know a better way I’d be glad to hear your thoughts, because I don’t know if this would be a bad way to do it or not. Thanks

Serial protocol is not the right choice. What you are doing is using the transmit as a pseudo-broadcast, however, the fact that this is working over a single line is just a hack byproduct of the way serial is handled.

Use I2C or canbus, and do a broadcast message, embedding both motor commands inside, then each motor will parse out only the part they need.

Problem with broadcast is you don’t know who received it and what they did.

IRL for real-time control you need either a star topology with dedicated lines or very high comm speed and density channel such as ethercat.

Cheers,
Valentine

aw ok I see, I’ve never worked with canbus and my AS5600 is already using the i2c on each ESC, can I split that? I believe I have a couple TCA9548. it would need to get the data from the two AS5600 sensors plus provide communication to both of the G431B ESC’s. like I said though, I’m very new to all this. I originally tried with a Nucleo F446RE and couldn’t figure out the canbus stuff so I gave up, there’s not many resources online for my level of programming sadly. thanks for providing me with the info and getting me straightened out before I tried to hack my way through all that.

G431B ESC is the wrong choice for what you need. It’s OK to get you started to understand the limitations, though. But for what you want you need a dedicated driver board. the G431B ESC is a drone propeller motor drive designed to do one thing only : spin a propeller at high speed.

Cheers,
Valentine