Rotary encoder vs magnetic encoder shaking issues

Hello,

I am facing with a shaking issue. My code is pretty simple I will put it below. When I run my motor with an rotary encoder I drive it without any issue. However, since my project need magnetic encoder I should use as5600 or as5048A. With the same code, only encoder part is different, motor runs pretty bad and shaking like the video below. I changed PID, filter but I couldn’t solve the problem. if there was a problem with motor, it shouldn’t work with rotary encoder as well. So I coulnd’t find the problem. Any idea where is the problem?

Thanks for your help.

the video:

the graph:

#include <Arduino.h>
#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor( 7 , 1.75 , 100);
BLDCDriver3PWM driver = BLDCDriver3PWM(33, 26, 14);
InlineCurrentSense current_sense  = InlineCurrentSense(0.01, 5.18, 34, 35, 32);
MagneticSensorI2C magnetic = MagneticSensorI2C(0x36, 12, 0x0E, 4);

float target_velocity = 0;
 Commander command = Commander(Serial);
 void onMotor(char* cmd){ command.motor(&motor,cmd); }
 void onTarget(char* cmd){ command.scalar(&target_velocity, cmd); }
// void onPID_P(char* cmd){ command.scalar(&motor.PID_velocity.P, cmd); }
// void onPID_I(char* cmd){ command.scalar(&motor.PID_velocity.I, cmd); }
// void onPID_D(char* cmd){ command.scalar(&motor.PID_velocity.D, cmd); }
// void onLPF(char* cmd){ command.scalar(&motor.LPF_velocity.Tf, cmd); }

void setup() {


  magnetic.init();
  motor.linkSensor(&magnetic);

  driver.voltage_limit=12;
  driver.init();
  motor.linkDriver(&driver);

  current_sense.linkDriver(&driver);
  current_sense.init();
  motor.linkCurrentSense(&current_sense);

  motor.controller = MotionControlType::velocity;

  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;

//  motor.PID_velocity.output_ramp = 1000; lets use default this time

  motor.LPF_velocity.Tf = 0.01;

  motor.current_limit=2;
  motor.velocity_limit=20;

  Serial.begin(115200);
  motor.useMonitoring(Serial);
  motor.monitor_variables = _MON_VEL;
  motor.monitor_downsample = 500;
  motor.init();
  motor.initFOC();

 command.add('T', onTarget, "target velocity");
 command.add('M',onMotor,"my motor motion");
  // command.add('P', onPID_P, "target P");
  // command.add('I', onPID_I, "target I");
  // command.add('D', onPID_D, "target D");
  // command.add('F', onLPF, "target LPF");  

  Serial.println("Motor ready.");
  _delay(1000);
}

void loop() {

  motor.loopFOC();
  motor.move(target_velocity);
  command.run();
  motor.monitor();

}

The AS5600 encoder is very low end, it’s just a digital potentiometer, and is not appropriate for quality close loop feedback. Please consider fast and high quality encoders such as AS5047 SPI series.

Cheers,
Valentine

I also tried with AS5048A ı forget to mention it.

From the video I cannot see any shaking. Anyways, you probably need to:

  1. Tune the PID.
  2. Make sure your magnet is correctly diametrically magnetized.
  3. Make sure the magnet is securely fastened and centered and the distance to the sensor is correct.
  4. Use a fast MCU such as STM32, Teensy or ESP32.
  5. Use SPI instead of I2C.

Cheers,
Valentine