Logical approach to tuning. Help please

I have been reading for several days now and can’t seem to find what I need. Perhaps my question is too basic. Currently, I am unable to get any predictable response from my setup. It just won’t do what I ask and seems to have a mind of it’s own.

What I have is an attempt to duplicate the Reaction Wheel Inverted Pendulum project. I am using an Emax GB4114 gimbal motor, ESP32 controller, AS5600 sensors. The motor is attached to the reaction wheel and both are suspended from the pendulum.

I also have the SimpleFOCStudio working (need help here too. IE, how to use it).

What my motor WILL do:
Loading the open_loop_velocity_example with voltage limits set to 4. (it got hot at six so being cautious). It will run both CW and CCW up to 15 rads/s. At values less than about 9, it is rough running and only begins to smooth out above 10. Values over 15 and it just stops and shakes. It will not start and any value over 3. To reach 15, I must start at 1 and increment by 1 until 15.

The open_loop_position_example. The motor will move…sorta. I tried values from -6 to +6, increments of 1. It will move a random distance in a random direction. positive values do not always create motion in the same direction, nor do negative values.

The angle control for magnetic sensor. The test probably could use more voltage. If I help it start, it seems to move correctly but jitters after reaching it’s target position.

Velocity control using encoder. This would run up to +/- 40 if I helped it start although values above 25 did not seem to change the speed.

I feel like I must get the motor to start reliably on it’s own in either direction and run relatively smooth with enough torque to make this experiment work. So starting with a basic script seems logical. Which one would be best or one from scratch? Since I cannot find very much information on how to use the Studio, I am unsure what it can and cannot do. Can it change modes and override what was programmed via the “control loop mode” window? If so, where should I start? Select PID also has four choices, which one. What does the jogging control do? It inserts and instruction of Target:xx … Does it’s function change with the control loop mode? It could mean move one rad or a velocity of one rad/s…I can’t tell.

Here is a simple code that might work as a test program (if the Studio can provide the what and how):

#include <SimpleFOC.h>

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(11,10.9,42);
BLDCDriver3PWM driver = BLDCDriver3PWM(16,17,18,19);
Commander command = Commander(Serial);
void doMotor(char* cmd) { command.motor(&motor, cmd); }

void setup() {
  driver.voltage_power_supply = 14.8;
  motor.voltage_limit = 6;


  motor.monitor_downsample = 0; 

void loop() {

Try removing the phase resistance and the motor KV rating and run de closed loop with the sensor. It should be easier to tune.

To get good results the phase resistance value and the KV rating need a bit of tuning. In most cases phase resistance provided usually stays the same as the measured/datasheet one. The KV rating in my experience needed to be raised to about 120%-170% of the datasheet one.

If you’re using the phase resistance and the KV rating simpleofc library will estimate the current the motor is consuming based on them and will make it respect
motor.current_limit variable. You can change it using the commander MLC.

If you don’t provide the phase resistance and the KV rating simpleofc will not estimate the current and it will work only with voltages. So it will respect your motor.voltage_limit, you can change this one with MLU in the commander.

Thank you Antun. I will try that. Following on, is there any sort of guide for SimpleFOCStudio? Especially what does the jogging control do and does it’s function change if the “Modes” change? Of the four PID classes? What is a good approach to using those?

I just found this post from Jorge:

Knowing what the “jog” button is trying to do helps me understand what should be happening. Bear in mind, my test system does not work yet so knowing what the motor is being asked to do is key in troubleshooting.

Perhaps add this note to the Studio readme? (thank you for your work Jorge!)

We have extensive documentation in our docs site: https://docs.simplefoc.com/

But the tuning question is one that is often asked. Here are some pointers:

Values that affect tuning and motor performance include:

  • Voltage limits! A motor that is receiving too much current will be hard to impossible to tune, and will probably burn the motor or the driver hardware if left too long. Make sure voltage limits are set in a sensible way. Note that you can set a separate limit for the alignment phase of the motor initialisation! During the alignment, the motor is run in open loop mode, so current consumption can sometimes be larger than during closed loop control. If you can, use PSU where you can set a current limit. Take precautions to protect your hardware.

  • Motor pole count - while this does not matter too much in open loop mode, it has to be set correctly in closed loop mode. Setting the pole count incorrectly often results in no motion, very erratic motion, and often much noise developed by the motor

  • Sensor values - the sensor values have to be correct (e.g. vary smoothly between 0 and 2∏ radians as you turn the motor a full physical revolution). Use our sensor test code (or write your own) to check the sensor before using it for closed loop mode.

  • Motor KV and phase resistance values. Make sure you’re getting good results in open loop mode and closed-loop torque-voltage modes. The phase resistance can be set as per the datasheet, but the KV value often has to be set higher than stated in the datasheet to get good results. You can also leave these values unset if they’re giving you trouble.

  • LPF time constant. The velocity low pass filter time constant should be set as low as possible to get fast updates from the sensor, but high enough that the velocity is smooth.

  • Loop time. This one is really important, as the loop time determines the time resolution with which you can control the motor. Ideally it should be considerably higher than 1kHz (e.g. 1000 loop iterations per second), a value of 10kHz or more is really good. Values below 2kHz will result in quite degraded performance. The loop time has a big influence on the maximum speed you can achieve on the motor, and the smoothness of control.

  • PID values - these need tuning, see below.

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)
  • 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.

Best write up yet! Thank you Runger!

1 Like

Hi @Keshka sorry for the late response. You are totally right this functionality was added to the SimpleFOCStudio but never was not documented so it can cause some doubts about how it behaves. Just updated the README.md file to include it. Thanks for the suggestions :slight_smile:


1 Like