FOC Current Mode problem

I’m trying to FOC Current Mode of Torque Control using Arduino Mega Board and BL5057 motor. When I run the code below, the current is too large, and the current gradually decreases and the motor stops running. What’s the problem? Which part should I modify?

#include <SimpleFOC.h>

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

// encoder instance
Encoder encoder = Encoder(2, 3, 512);
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}

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

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

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

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 24;
  driver.init();
  // link driver
  motor.linkDriver(&driver);

  // current sense init hardware
  current_sense.init();
  // link the current sense to the motor
  motor.linkCurrentSense(&current_sense);
  current_sense.gain_b *= -1;
  current_sense.skip_align = true;

  motor.current_limit = 0.5; // amps
  // motor.PID_velocity.limit = motor.current_limit;

  motor.voltage_limit = 5; //V
  // motor.PID_velocity.limit = motor.voltage_limit;


  // 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 = 10;
  motor.PID_current_d.P = 5;
  motor.PID_current_d.I = 10;
  motor.LPF_current_q.Tf = 0.01;
  motor.LPF_current_d.Tf = 0.01;

  // use monitoring with serial 
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);

  // motor.monitor_variables = _MON_CURR_D | _MON_CURR_Q;
  // downsampling
  // motor.monitor_downsample = 100; // default 10

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

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

  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target current using serial terminal:"));
  _delay(1000);

}

void loop() {

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

  // Motion control function
  motor.move();

  // motor.monitor();

  // user communication
  command.run();

}

I don’t know, but what happens if you start with voltage for torque control? I would stick with the examples and get things working in a basic manner before trying to jump in and try something off the beaten track. This stuff is a long way from plug and play, there seems to be a lot of people that think it’s a lot more plug and play than it is.

How is your current sensing set up? Do you have a schematics?

I don’t know… That’s all the code I put up…
The motor worked well when running in torque control voltage mode. There seems to be no hardware problem.

Well, if you have a problem with your current sense, it could cause the motor to stop moving…
Is the current sense embedded on the board? The MEGA does not have this capability, so did you add some sense resistors ?
Do you have an extra PCB for current sensing?

Oh, isn’t it a resistance with the current detection sensor in the SimpleFOCShield? I’m trying to do that. Did I misunderstand anything?

Ah, you didn’t mention you were using the shield.
In that case it is probably fine, the code seems normal to me.

Oh, I’m sorry. I didn’t know I didn’t say that. At first, the motor will run well, but as the current gradually decreases, it will stop in the middle and then operate again. I’ve added and modified some other codes in the code above, is there anything else I should add or modify?

motor.voltage_sensor_align = 1;
motor.voltage_limit = 10;
driver.voltage_limit = 10;

After changing these three values, there is a change in behavior, but I’m not sure yet.

#include <SimpleFOC.h>

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

// encoder instance
Encoder encoder = Encoder(2, 3, 512);
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}

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

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

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

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 24;
  driver.init();
  // link driver
  motor.linkDriver(&driver);

  motor.voltage_sensor_align = 1;

  motor.voltage_limit = 10;
  driver.voltage_limit = 10;
  motor.current_limit = 1; // amps
  // motor.PID_velocity.limit = motor.current_limit;

  // current sense init hardware
  current_sense.init();
  // link the current sense to the motor
  motor.linkCurrentSense(&current_sense);
  current_sense.gain_b *= -1;
  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;

  // use monitoring with serial 
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);

  motor.monitor_variables = _MON_CURR_D | _MON_CURR_Q;
  // downsampling
  motor.monitor_downsample = 100; // default 10

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

  motor.target = 0.2;

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

  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target current using serial terminal:"));
  _delay(1000);

}

void loop() {

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

  // Motion control function
  motor.move();

  // motor.monitor();

  // user communication
  command.run();

}

sorry I want to ask the PID parameters for Arduino UNO/MEGA, but what if the PID settings for the STM32 F401RE board?

In my understanding, the PID parameters are independent of the controller.
They have to suit the motor IMHO

Hi,

PID settings are individual to the setup, and can depend on many factors. The MCU speed is definitely one of them, as it will change the time required for an iteration, and thereby quite significantly affect the result. Generally speaking control is better on faster systems.

Often the loop speed will affect the value you want to use for the LPF constant too.

If the PID setting is not correct, then when it is on but the throttle has not been opened, the motor will be able to move on its own?

Is it possible to run the motor if the closed loop closes, but when I try the current foc mode, the motor cannot move, so I have to set the PID?

Yes, I think we’re already discussing it in the other thread. For foc_current mode you have to tune the current PIDs, but first you should make sure the other, easier modes are working for you.

can I ask about the PID parameters setting instructions?

Example program code maybe

There are some better resources out there and there are some forum posts on this already, on tuning PID controllers. Beware it is a bit laborious and complicated, there are automated systems and there are autotune libraries for Arduino however I was never able to get them working.

what is the name of the library to use if you want to try the Arduino PID autotune?

There are several but it will take some doing to get them working : pid autotune arduino - Google Search

okay, thank you,

and I want to ask, now I have successfully run the closed loop mode voltage, but if we want to change the motor, we have to setting the PP motor, can we replace the motor without resetting the PP motor (to autotune PP)?.

The number of pole pairs is a required input parameter. If you want to discover the PP automatically, this is possible in some applications, if you have an encoder or position sensor, but you’ll have to add the code for it yourself…