MKS ESP32 FOC closed loop position control. Osciliations

I am new to foc control and simple foc library. I have been trying to get a closed position control example working with my set up. I am using the MKS ESP32 FOC controller and a AS5047 Encoder comunicating through SPI. I have a 5010 360kv bldc motor with 7pole pairs. I started with the maker Space open loop position control example and it worked fine besides some overheating. Now I am trying to conifgure the simple FOC position angle control(closed loop) example in their github but I am having lots of issues.

Firstly the encoder is returning values from 0 - 12ish in one full revolution. I think it should be in radians so 0-6.28 but I have no clue why it is off. There is also some noise of +/- 0.01 in the readings.

Secondly, when I test with this code or variations of this code the motor starts and moves one quarter rotation normaly but then starts jittering/shaking very fast. The serial input seems to do nothing when I tell it to go to a position. I have tried to tune the pid but with no luck. It seems like no mater what I do the motor just shakes very fast and uncontrolably. I also tried switching the motor wires with no avail. I am really lost and would really appreciate any help.

 * Position/angle motion control example
 * Steps:
 * 1) Configure the motor and magnetic sensor
 * 2) Run the code
 * 3) Set the target angle (in radians) from serial terminal
#include <SimpleFOC.h>

// magnetic sensor instance - SPI
MagneticSensorSPI sensor = MagneticSensorSPI(5, 14, 0x3FFF);

// magnetic sensor instance - MagneticSensorI2C
//MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
// magnetic sensor instance - analog output
// MagneticSensorAnalog sensor = MagneticSensorAnalog(A1, 14, 1020);

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);                               //According to pole pairs of the selected motor, modify the value of BLDCMotor() here
BLDCDriver3PWM driver = BLDCDriver3PWM(32,33,25,22);
// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6,  8);

// angle set point variable
float target_angle = 0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_angle, cmd); }

void setup() {

  // initialise magnetic sensor hardware
  // link the motor to the sensor

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  // link the motor and the driver

  // choose FOC modulation (optional)
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

  // set motion control loop to be used
  motor.controller = MotionControlType::angle;

  // contoller configuration
  // default parameters in defaults.h

  // velocity PI controller parameters
  motor.PID_velocity.P = 0.2f;
  motor.PID_velocity.I = .1;//1
  motor.PID_velocity.D = 0;
  // maximal voltage to be set to the motor
  motor.voltage_limit = 1;

  // velocity low pass filtering time constant
  // the lower the less filtered
  motor.LPF_velocity.Tf = 0.1f;

  // angle P controller
  motor.P_angle.P = 1;//20
  // maximal velocity of the position control
  motor.velocity_limit = 20;//20

  // use monitoring with serial
  // comment out if not needed

  // initialize motor
  // align sensor and start FOC

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

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

void loop() {

  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz

  // Motion control function
  // velocity, position or voltage (defined in motor.controller)
  // this function can be run at much lower frequency than loopFOC() function
  // You can also use motor.move() and set the in the code

  // function intended to be used with serial plotter to monitor motor variables
  // significantly slowing the execution down!!!!
  // motor.monitor();

  // user communication;

I’m running exactly the same issue, on a UNO board and identical results on a SAMD51 board using a SimpleFOC shield 2.0.4. and a HT2205 motor from ali express.

My motor is 7 poles too, resistance is a little low compared to the suggested values (> 10 ohm) but all I need for now is a validation of the working principle of a FOC control over BDLC for position servoing. My AS5048 is wired in PWM mode. I’m getting close to a working (sort of) closed loop if I disable the interrupt mode of the magnetic sensor. I moved to velocity mode without success

I’m partially assuming that the non-interrupt mode of the position sensor reading takes enough time to stabilize the close loop but I’m at loss to get it to work at full speed (I need a high speed closed loop taking advantage of a capable MCU like the SAMD51 - using an adafruit Metro M4)

I double checked the wiring of the motor and tried swapping too. Motor moves fine during init thought it will sometimes not detect movement

When printing the angle, servoing goes apesh$t and angle will keep increasing while shaking and spinning. I have no idea where to start, I tried reducing the control loop or adjusting a little the PID but I’m unsure how. Code is nearly identical as above and pulled almost straight from the examples.

Please don’t use the PWM mode. This is not only limited in the resolution compared to using SPI, and very limited in terms of the speed (max 1kHz), but also will suffer from inaccuracy/discontinuity around the 0 and due to clock inaccuracies.

The AS5048A is a great sensor, and you should use its SPI mode to avoid these problems.

I can’t guarantee it will fix all your problems, but it will be waaaay easier to stabilise and tune your control loops, and you will get much better performance due to the increased bandwidth.

thank you so much. I understand that it generates a lot of IRQs too, which can be counter productive and indeed it gave “some results” when used in polling mode. I’ll give it a try in SPI mode ! Discontinuities could explain it all, it really behaves like phase shifting of PI or 2xPI