Hello,
I’m trying SimpleFOC to replace a classic 6-step BLDC commutation driver for a gimble motor. This motor works very robustly using traditional 6-step commutation tecnique with BEMF. I’ve used it both with a my own prototype controller and with commercial ESC.
In SimpleFOC, The motor “works”. ie It spins, and it works quite well as a servo-positioning system in angle mode, but in velocity mode, speed and torque are nowhere even close to what I get using traditional ESC. I cannot get it to spin faster than ~1K RPM in openloop, or over ~600RPM -in closedloop (I get ~3K with my ESC)… I didn’t measure torque, but with simpleFOC it’s not even close to traditional BLDC with ESC.
Are my expectations right? I thought I read that FOC control would always match or beat traditional commutation?
Controller Arduino Uno (ATMega328P@16Mhz)
Driver: FOCShield v234,
Motor: small 12v 90KV gimbling motor 17 ohm phase resistance,
Sensor: AS5600 in I2c mode
(it isn’t FOCStudio which is holding this back, performance is same without studio)
(attempt to get velocity target past 70 rad/s)
Code:
#include <SimpleFOC.h>
BLDCMotor motor = BLDCMotor(7, 17);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
//InlineCurrentSense current_sense = InlineCurrentSense(0.01f, 50.0f, A0, A2);
// include commander interface
Commander command = Commander(Serial);
void doMotor(char* cmd) { command.motor(&motor, cmd); }
void doTarget(char* cmd) {command.scalar(&motor.target, cmd);}
void doLimit(char* cmd) {command.scalar(&motor.voltage_limit, cmd);}
void setup(){
driver.voltage_power_supply = 12;
Serial.begin(115200);
motor.useMonitoring(Serial);
motor.monitor_variables = _MON_TARGET | _MON_VOLT_Q | _MON_VOLT_D | _MON_CURR_Q | _MON_CURR_D | _MON_VEL | _MON_ANGLE; // monitor target velocity and angle
// link driver
driver.init();
motor.linkDriver(&driver);
// link the motor to the sensor
sensor.init();
motor.linkSensor(&sensor);
motor.voltage_sensor_align = 2;
// contoller configuration based on the controll type
motor.PID_velocity.P = 0.01;
motor.PID_velocity.I = 0.01;
motor.PID_velocity.D = 0;
// velocity low pass filtering time constant
motor.LPF_velocity.Tf = 0.1f;
// angle loop controller
motor.P_angle.P = 10;
// angle loop velocity limit
motor.velocity_limit = 25;
// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// add the motor to the commander interface
// The letter (here ‘M’) you will provide to the SimpleFOCStudio
command.add(‘M’,doMotor,‘motor’);
command.add(‘T’, doTarget, “target”); // ssss space
command.add(‘L’, doLimit, “voltage limit”);
// tell the motor to use the monitoring
motor.monitor_downsample = 0; // disable monitor at first - optional
}
void loop(){
//…
// iterative function setting the outter loop target
motor.loopFOC();
motor.move();
//…
// real-time monitoring calls
motor.monitor();
// real-time commander calls
command.run();
}