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(&, cmd); }

void setup() { 
  // initialize encoder sensor hardware
  // link the motor to the sensor

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  motor.voltage_limit = 6;
  // link driver
  // link the driver to the current sense

  // current sense init hardware
  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
  // align sensor and start FOC

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

  motor.monitor_variables = _MON_VOLT_Q | _MON_CURR_Q;
  motor.monitor_downsample = 100;
  Serial.println("VOLT_Q:0 CURR_Q:0");


void loop() {

  // main FOC algorithm function

  // Motion control function

  // user communication;

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