Control more BLDC

Currently, I can only control one wheel and using the esp32 with driver8302, the number of pins is almost gone.
But I want to control 4 BLDC motors using hallsensor, which microcontroller should I use to provide enough pins? Or is there any method to control multiple motors?

Usually each motor gets its own dedicated microcontroller. Then use another microcontroller to take user input and communicate to the motor controllers using CAN bus or I2C or servo pulse signals or any other protocol you like.


Thank you. I’m waiting for the stm32f1 circuit to arrive. I’ll try it

With hall sensor you are software-limited to one motor per controller.
The cost for the driver boards is much higher than the ESP32 price, so it actually doesn’t matter.

I think this limitation was resolved in the latest release.

1 Like

Last time I used Esp32S3 to control my 2 bases with only openloop but when I switched to closeloop the gear didn’t run. I think I may not be connecting the pin sensor and Hall sensor components properly.
This time I’m waiting for the stm32 circuit to arrive so I can try it.
I am using simpleFOC version 2.3.2

Some esp32 boards have more pins available than others. Pretty sure you’ll be able to find one that has enough for two closed loop motors.

1 Like

thank you, i am trying stm32f1C8T6

@Khoa_Bach glad you’ve found a suitable mcu. Are you still trying to connect 4 bldcs (with halls) to a single mcu or are you splitting across boards?

If you want someone to check your stmcube pin allocations…

1 Like

This model MCU has only 64kB flash memory - it will be tight to fit SimpleFOC for a single motor, I am not sure you’ll manage to fit 4 motors. I also don’t think the MCU will be fast enough to handle 4 motors.

I can advise strongly against trying to run 4 motors on a single MCU. Even if you manage to find pin combinations that work, it will be difficult from the point of view of the code, and difficult to get the required performance.

And for Hall Sensors, you have to consider the interrupt load caused by 12 interrupt pins firing all the time - I think it will cause problems, at least for higher speeds.

I would strongly urge you to consider an architecture where you have 1 MCU per motor. In this case you can try with the stm32f1C8T6, but actually I would recommend a model with 128kB or more flash memory.

1 Like

thanks i will write the code at the bottom because i am having a problem

I think I’m having a problem with the interrupt pins. Currently I am controlling the 2 front motors. I noticed that when controlling each motor, it rotates, but when running 2 motors, in openloop both wheels rotate, but when running close loop, only 1 wheel rotates. Below is my code:

#include <SimpleFOC.h>
// #include <PciManager.h>
// #include <PciListenerImp.h>
#define pp 15
#define INH_A1 PA8 //PWM_A
#define INH_B1 PA9 //PWM_B
#define INH_C1 PA10 //PWM_C

#define EN_GATE1 PB5
#define M_PWM1 PB4
#define M_OC1 PB3
#define OC_ADJ1 PB6

#define HALLa1 (PA11)// cần thay chân 18 này
#define HALLb1 (PA12)
#define HALLc1 (PA15)
//#define pp 15 //Pole Pairs

#define INH_A2 PB7 //PWM_A
#define INH_B2 PB8 //PWM_B
#define INH_C2 PB9 //PWM_C

#define EN_GATE2 PA0
#define M_PWM2 PA1
#define M_OC2 PA2
#define OC_ADJ2 PA3

#define HALLa2 (PB13)
#define HALLb2 (PB14)
#define HALLc2 (PB15)
// Motor instance
BLDCMotor motor1 = BLDCMotor(pp);
BLDCMotor motor2 = BLDCMotor(pp);

BLDCDriver3PWM driver1 = BLDCDriver3PWM(INH_A1, INH_B1, INH_C1, EN_GATE1);
BLDCDriver3PWM driver2 = BLDCDriver3PWM(INH_A2, INH_B2, INH_C2, EN_GATE2);

// hallsensor instance
HallSensor hsensor1 = HallSensor(HALLa1, HALLb1, HALLc1, pp);
// Interrupt routine initialization
// channel A and B callbacks
void doA1(){hsensor1.handleA();}
void doB1(){hsensor1.handleB();}
void doC1(){hsensor1.handleC();}

HallSensor hsensor2 = HallSensor(HALLa2, HALLb2, HALLc2, pp);
// channel A and B callbacks
void doA2(){hsensor2.handleA();}
void doB2(){hsensor2.handleB();}
void doC2(){hsensor2.handleC();}
//PciListenerImp listenC(hsensor.pinC, doC);
// angle set point variable
//float target_angle = 0;
float target1 = 0.0;
float target2 = 0.0;

void setup() {
// M_PWM - enable 3pwm mode
// OC_ADJ - set the maximum overcurrent limit possible
// Better option would be to use voltage divisor to set exact value

// M_PWM - enable 3pwm mode
// OC_ADJ - set the maximum overcurrent limit possible
// Better option would be to use voltage divisor to set exact value
// initialize sensor hardware
// check if you need internal pullups
//hsensor2.pullup = Pullup::USE_EXTERN;
hsensor1.enableInterrupts(doA1, doB1, doC1);

// hardware interrupt enable
hsensor2.enableInterrupts(doA2, doB2, doC2);

// link the motor to the sensor

// driver config
// power supply voltage [V]

//driver2.pwm_frequency = 20000;

driver1.voltage_power_supply = 36;
//driver1.voltage_limit = 12;

motor1.voltage_sensor_align = 1;

driver2.voltage_power_supply = 36;
//driver2.voltage_limit = 12;

// link the motor and the driver

// aligning voltage [V]
motor2.voltage_sensor_align = 1;

motor1.torque_controller = TorqueControlType::voltage;
motor2.torque_controller = TorqueControlType::voltage;

//motor1.controller = MotionControlType::velocity;
// motor2.controller = MotionControlType::velocity;

//motor2.controller = ControlType::voltage;

//motor1.controller = MotionControlType::velocity_openloop;
//motor2.controller = MotionControlType::velocity_openloop;

//motor.controller = MotionControlType::angle;

// contoller configuration
// default parameters in defaults.h

// // velocity PI controller parameters
motor1.PID_velocity.P = 0.2;
motor1.PID_velocity.I = 1;
motor2.PID_velocity.D = 0.0001f;
// // the lower the less filtered
motor2.PID_velocity.P = 0.2;
motor2.PID_velocity.I = 1;
motor2.PID_velocity.D = 0.0001f;
motor2.LPF_velocity.Tf = 0.04;
motor1.LPF_velocity.Tf = 0.04;

// motor1.PID_velocity.limit = 0.5;

//motor.PID_velocity.limit = 0;

// motor.PID_velocity.I = 50;
// default voltage_power_supply
motor1.voltage_limit = 2;
motor2.voltage_limit = 2;
motor1.velocity_limit = 20; //rad/s
motor2.velocity_limit = 20; //rad/s

// jerk control using voltage voltage ramp
// default value is 300 volts per sec ~ 0.3V per millisecond
// motor1.PID_velocity.output_ramp =500;
// motor2.PID_velocity.output_ramp = 500;

// velocity low pass filtering time constant
//motor1.LPF_velocity.Tf, motor2.LPF_velocity.Tf = 0.01f;

// initialize motor

// align encoder and start FOC
// motor2.zero_electric_angle = 0.00; // rad
//motor2.sensor_direction = Direction::CW; // CW or CCW


// Serial.println(F(“Motor ready.”));
// Serial.println(F(“Set the target angle using serial terminal:”));
// _delay(1000);

void loop() {




There is a problem that I don’t understand. When I control a wheel with the stm32, the wheel makes a sound but it still rotates fine. It seems like this sound is very strange but when I control it with the esp32 it doesn’t exist. When I run openloop the gear also makes noise. sound: pippppp… continuously like a car horn

i get problem when controlling motor 2 when i add this command: hsensor2.enableInterrupts(doA2, doB2, doC2);
then the motor will not run again

You can control 2 motors with a Hall sensor and inline current sensing using a single ESP32 microcontroller. The only restriction is that the motor controller IC needs to work on 3PWM.


You code actually looks ok… which STM32 microcontroller board is it? Is there something special about the pins PB13,PB14,PB15? Are these pins maybe part of a SPI interface or I2C interface on the board you’re using?

i use stm32F1C8T6, With 1 wheel it can still run

Which esp32 do you use?

Its ESP32-WROOM-32D for controlling 2 motors

1 Like

Thank you, I will consider it