How to set pid to get smooth motor behavior

Hi:
I have esp32+AS5600_I2C+motor, and get not smooth motor behavior. the pid params is as blow:


My target velocity is about 24 seconds/round(0.26rad/sec), and want the velocity is less than 10% jitter, but now it is more than 100%.
Thank you!

Hi and welcome, @shanli_cai ,

A few ideas to help you:

  1. AS5600 is not the most precise sensor, other magnetic sensor or encoders tend to have better performance. Also I2C is slow (has latency) compared to SPI or encoder pulses.
  2. Position mode tends to be smoother than velocity mode, as velocity is a calculated function of the position, and the timers used on the MCU are not perfectly accurate. Positions are available without a time based calculation, and therefore less error.
  3. Try different LPF values for the velocity. Generally, increasing the LPF (maybe to 0.01 or 0.025?) should make things smoother.

If you don’t mind sharing your code, maybe people have some more ideas. For example, setting the motion_downsample higher tends to improve velocity stability also.

1 Like

Hi runger:
Thank you for your reply!
AS5600 is half price of AS5048_SPI, and we tested with AS5048_SPI, it’s almost the same . Code is here:

#include <SimpleFOC.h>

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);

BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 22);

Commander command = Commander(Serial);
void doMotor(char* cmd) { command.motor(&motor, cmd); }

void setup() {
  I2Cone.begin(19, 18, 400000);   //SDA1,SCL1
  sensor.init(&I2Cone);
  motor.linkSensor(&sensor);
  
  driver.voltage_power_supply = 12.0;
  driver.init();

  motor.linkDriver(&driver);
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  motor.controller = MotionControlType::velocity;
  
  motor.PID_velocity.P = 0.3;
  motor.PID_velocity.I = 27;
  motor.PID_velocity.D = 0.001;
  motor.PID_velocity.output_ramp = 50;
  
  motor.P_angle.P = 20;
  motor.voltage_limit = 12.0;
  
  motor.LPF_velocity.Tf = 0.005;
  motor.velocity_limit = 40;

  Serial.begin(115200);
  
  motor.init();
  motor.initFOC();

  sensor.enableSKF();
  
  command.add('M',doMotor,"my motor");
  motor.useMonitoring(Serial);
  motor.monitor_downsample = 0;
}

void loop() {
  motor.loopFOC();
  motor.monitor();
  motor.move();

  command.run();
}

I need both angle and velocity mode change by up computer.

Hi,

Are you PID values well tuned? It looks reasonable, but if you haven’t tuned it, try lowering velocity_I, increasing the LPF_velocity and maybe increasing the output_ramp?

AS5048 is more expensive, this is true, but the SPI read speeds are also much faster than I2C if you set everything up right…

Hi @runger:
I tested output_ramp with 1000, but the motor rotate back and forth when power on, the big output_ramp is and the rotate speed high of the motor, do you have any ideas?
Now I tuned the pid values like below, and the wave jitter is in 5%, but the motor it self is a litter jitter when touch on it, I think this is due to high value of velocity_p, but low value of velocity_p’s wave jitter is more big than this.