Strange troubles with closed Loop Mode - Any suggestion to find the problem?

Hi folks !! Hapy new year !!

After some months keeping my SimpleFoc project on the project stack, I decided too try again and
restart again with a new configuration, back to the basics. So i’ve been working on a new setup using the following:

  • MCU: Arduino Mega 2560 REV3
  • Motor: GM5208-12 [15Ω Phase resistance, Config: 12N14P]
  • Driver: SimpleFocShield 1.3.3
  • Magnetic Sensor: AS5048A (SPI interface)
  • IDE: PlatformIO

My code is:

#include <SimpleFOC.h>

#define MOSI_ENC 51 // Blue
#define MISO_ENC 50 // Green
#define CLK_ENC 52  // Orange
#define CS_ENC 53   // Yellow

#define INH_A 12
#define INH_B 11
#define INH_C 10
#define ENA_GATE 8

// motor instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, ENA_GATE);

MagneticSensorSPIConfig_s AS5047A_SPI_Config{
    .spi_mode = SPI_MODE1,
    .clock_speed = 10000000,
    .bit_resolution = 14,
    .angle_register = 0x3FFF,
    .data_start_bit = 13,
    .command_rw_bit = 14,
    .command_parity_bit = 15};

MagneticSensorSPI sensor = MagneticSensorSPI(AS5047A_SPI_Config, CS_ENC);

// instantiate the commander
Commander commander = Commander(Serial);
void doMotor(char *cmd) { 
  commander.motor(&motor, cmd); 

void setup(){
  // use monitoring with serial
  Serial.println("Starting Motor configuration ....");

  // initialize magnetic sensor hardware
  // link the motor to the sensor
  // driver config
  driver.voltage_power_supply = 20;
  // set motion control loop to be used
  motor.controller = MotionControlType::velocity_openloop;
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  // set control loop type to be used
  // contoller configuration based on the control type
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  motor.LPF_velocity.Tf = 0.2;
  motor.P_angle.P = 20;
  // angle loop velocity limit
  motor.velocity_limit = 10;
  motor.voltage_limit = 20;
  // initialize motor

  commander.add('M', doMotor, "my motor");

  Serial.println("Motor ready.");
  _delay(1000); = 10;

void loop(){

This is my Platformio.ini:

platform = atmelavr
board = megaatmega2560
framework = arduino
monitor_speed = 115200
lib_deps = 
	askuric/Simple FOC@^2.2.3

When I test the magnetic sensor in isolation the readings seem perfect adding 2 Pi each turn I give to the motor shaft and without any noise.

This is the output after initialization with the full sketch:

MOT: Monitor enabled!
Starting Motor configuration ....
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: OK!
MOT: Zero elec. angle: 4.18
MOT: No current sense.
MOT: Ready.
Motor ready.
10.0000 12.0000 10.0000 6.0935
10.0000 12.0000 10.0000 0.8449
10.0000 12.0000 10.0000 1.8829
10.0000 12.0000 10.0000 2.9200
10.0000 12.0000 10.0000 3.9554
10.0000 12.0000 10.0000 4.9930

My setup works perfectly, very smoothly both in OpenLoopVelocity mode and in
OpenLoopPosition mode.

However, when I change to OpenLoopVelocity and OpenLoopAngle,… things get weird :frowning:

Some times simple stop moving quietly and other times starts slightly vibrating without moving. This is what is shown after executing the MC1 to change to Closed Loop Velocity:

20.0000 12.0000 20.0000 0.4662
20.0000 12.0000 20.0000 2.5351
Warn: \r detected! 
20.0000 12.0000 13.9292 2347.0766
20.0000 12.0000 7.2132  2347.0405
20.0000 12.0000 3.7746  2347.0385
20.0000 12.0000 1.9817  2347.0397
  • Does anyone know where the problem could be or give some indication of how to solve it or continue investigation eje root of the problem?
  • Could it be due to the tuning of the coefficients of the PIDs?
  • Any clues to figure out where the problem might be?

Any suggestion is welcome :grinning:

Hey @JorgeMaker ,

With PlatformIO, you need a

lib_archive = false

in your platformio.ini.
See if that helps any…

1 Like

Hi @runger Tanks for you answer… I tested your suggestion adding lib_archive = false but it seems that does not make any difference :roll_eyes:

Ok, that’s strange because this option is needed in PlatformIO…

Yes, in fact another user recently reported here that the PID tunings changed quite a bit when they upgraded the library - the PID was more “aggressive” and the values had to be tuned down IIRC… we figured it was due to improved performance (faster loop speed).

Looking at the signals of the phases in the oscilloscope (INH_A, INH_B, INH_C) I observe a behavior that I think is strange but I don’t know what it could be due to.

When I go to closed loop in one of the phases there is no PWM signal .If I go back to open loop mode, everything works correctly and PWM signals are produced in each of the phases.

Any strategy on how to tune the PID parameters?

Well if you are missing a phase signal then it can’t work right!
I can see in the code you’ve posted you are using different pins, but is there any reason the sensor pins could be interfering with the PWM pin?

Also, IIRC Antun recently made some fixes to the ATMega code, not sure if it was for the mega…
Yes, I just checked on GitHub and there are several changes to the ATMega2560 code on the dev branch… maybe you should try with that?

For the PID tuning, I have the following I plan to put in the docs somewhere. But all the phases have to be working first:

To tune the PID values there are different methods, including formal math-based ones that you could look up on the internet or in the literature and follow. But here is a simple “ad hoc recipe” that works in many cases:

First question to look at: is the closed loop torque-voltage mode working well? That needs the sensor, but not the PID tuning. So if this mode is working as expected, it means the sensor and sensor alignment are working, and the basic motor parameters (like pole count!) are correct.

Then try closed loop velocity. For this you tune the velocity PID. One method can be:

  • in closed loop torque-voltage mode, set up some output in a way that doesn’t affect motor performance but allows you to track the actual and target velocity (e.g. use the Arduino Serial plotter or just plain serial output. You can see the section on monitoring in our docs for one way to log this data)

  • Once logging is working to your satisfaction, switch to velocity mode

  • set P,I,D to 0, and slowly raise P, in small steps of 0.05 or 0.1 until you get oscillations, e.g. until the velocity oscillates near to or around the target value. Then take it back until there are no oscillations.

  • then raise I in small steps until the velocity tracks the target value well.

  • D can usually be left at 0

  • try different speeds and maybe loads on the motor, and see if the behaviour is good.

If closed loop velocity is working well, closed loop position usually works well too, without much difficulty. Start with an angle P value between 1 and 20, and see how that behaves, try some lower or higher values until you get a good tracking of the position without too much “jitter” when settling into position.

1 Like

Thanks for your detailed explanation. I will check it hoping yo solve the issue :slight_smile: