FOC current control in wider target current range

Using the following example modified for my setup (SimpleFOCShield 2.0.4+GM4108 with magnetic encoder + Arduino UNO R4 minima), I have tested torque control using FOC currents.

  • When the target current is small, the control seems to be smooth as in the picture.
  • When the target current > 0.08A (voltage_q exceeds 6V), the motor starts to oscillate and rotate reverse as in the video.

Is there any way to stabilize the FOC current control in wider target current range even with driving voltage saturation ?


#include <SimpleFOC.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// encoder instance
MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, 10);

// current sensor
InlineCurrentSense current_sense = InlineCurrentSense(0.01f, 50.0f, A2, A0);

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&motor.target, cmd); }

void setup() { 
  
  // initialize encoder sensor hardware
  sensor.init();
  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  motor.voltage_limit = 6;
  driver.init();
  // link driver
  motor.linkDriver(&driver);
  // link the driver to the current sense
  current_sense.linkDriver(&driver);

  // current sense init hardware
  current_sense.init();
  motor.linkCurrentSense(&current_sense);
  current_sense.gain_a *= -1;  // for SimpleFOCShield v2.0.4
  current_sense.skip_align = true;

  // set torque mode:
  motor.torque_controller = TorqueControlType::foc_current; 
  // set motion control loop to be used
  motor.controller = MotionControlType::torque;

  // foc current control parameters (Arduino UNO/Mega)
  motor.PID_current_q.P = 5;
  motor.PID_current_q.I= 300;
  motor.PID_current_d.P= 5;
  motor.PID_current_d.I = 300;
  motor.LPF_current_q.Tf = 0.01; 
  motor.LPF_current_d.Tf = 0.01; 

  // initialize motor
  motor.init();
  // align sensor and start FOC
  motor.initFOC();

  // add target command T
  command.add('T', doTarget, "target current");

  motor.useMonitoring(Serial);
  motor.monitor_variables = _MON_VOLT_Q | _MON_CURR_Q;
  motor.monitor_downsample = 100;
  Serial.begin(115200);
  while(!Serial);
  Serial.println("VOLT_Q:0 CURR_Q:0");

  _delay(1000);
}

void loop() {

  // main FOC algorithm function
  motor.loopFOC();

  // Motion control function
  motor.move();
  motor.monitor();

  // user communication
  command.run();
}

Just in case, I have tested with motor blocked.
Current control is quite smooth as long as driving voltage is small.
So I think something happens in PIDController when the driving voltage reaches to motor.voltage_limit to counter back EMF.

Finallly I figure out how to solve the problem.
Just reduce motor.voltage_limit to the level where no PID problem happens.
In my case, 6 → 5.2 works.

So my lesson here is to always limit motor.voltage_limit whenever control problem happens.

1 Like