Hello,
I have got a large 10 pole inrunner motor with hall sensors but im really struggling to get it running without it being horrendously loud in closed loop mode.
In open loop it sounds nice and quiet which is pretty much expected as the drivers all seem to be performing well. As soon as I try closed loop FOC in any form I get a 2.6kHz whistling noise which increases proportionally to the current, and there is also a horrible grinding oscillation noise which is proportional to the RPM. There is no mechanical issues with the motor because it works perfectly when driven by a VESC.
Here’s a video of what it sounds like at about quarter speed.
Originally I thought that it could be an issue with the hall sensors, but I’ve since added some strong pull up resistors and the scoped hall sensor signals look fine to me. I’ve also printed the number of interrupts while revolving the motor and everything seems to be in order.
I am using 0.33 milliohm shunt resistors which are crazy small, but thats because I expect around 200 phase amps with this esc. I have since increased this to 1 milliohm to give a better current sense resolution but this didn’t change anything.
I have used this ESC to control a hoverboard motor and a 14 pole outrunner, both of these ran fine and didnt make the same horrendous noise as this big motor, but is still a bit louder than I was expecting from FOC. It sound equally as loud, or slightly louder than a typical trapezoidal controller.
With regards to code, its pretty much the standard example code
#define POLE_PAIRS 5
// Interrupt routine initialization
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PB13, PA9, PB14, PA10, PB15);
LowsideCurrentSense current_sense = LowsideCurrentSense(0.001, 16, PC0, PC1, PC2);
BLDCMotor motor = BLDCMotor(POLE_PAIRS);
void setup() {
Serial3.begin(921600);
SimpleFOCDebug::enable(&Serial3);
sensor.pullup = Pullup::USE_EXTERN;
// initialize sensor hardware
sensor.init();
// hardware interrupt enable
sensor.enableInterrupts(doA, doB, doC);
//Configure and initialise the gate driver
//Normalised dead time with respect to pwm period
driver.dead_zone = 0.05f;
driver.pwm_frequency = 20000;
driver.voltage_power_supply = 20;
driver.voltage_limit = driver.voltage_power_supply * 0.95f;
// driver init
driver.init();
//Enable the TIM1 Break input function for overcurrent protection
configure_TIM1BKIN();
// current_sense.skip_align = true;
// link the current sense to the driver
current_sense.linkDriver(&driver);
// initialise the current sense
current_sense.init();
// link the motor to the sensor
motor.linkSensor(&sensor);
// set motion control loop to be used
motor.torque_controller = TorqueControlType::foc_current;
motor.controller = MotionControlType::torque;
//Set the voltage to be applied during sensor alignment
//This should be as small as possible
motor.voltage_sensor_align = 1;
motor.voltage_limit = 19;
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
motor.LPF_current_q.Tf = 0.05;
motor.LPF_current_d.Tf = 0.05;
// init driver
// link the motor to the driver
motor.linkDriver(&driver);
// link driver and the current sense
// link the motor to current sense
motor.linkCurrentSense(¤t_sense);
// initialize motor
motor.init();
motor.initFOC();
motor.target = 0;
configure_peripheral_gpio();
configure_ADC2();
configure_DMA2();
start_ADC2_DMA();
IWatchdog.begin(1000000);
}
void loop() {
motor.loopFOC();
motor.move();
IWatchdog.reload();
}
Any advice, tips and debugging steps would be hugely appreciated as this is driving me insane
(apologies if i reply slowly, i am about to head to bed)




