Optimizing the Capabilities of iPower GM5208 with FOC_Current

Hi everyone!!

I am currently using SimpleFOC with iPower GM5208 motor, AS5048A sensor, and the SimpleFOC Board V2.0.4. The objective is for the motor to stay in a certain position while holding a 3D-printed arm. The implementation is shown in the picture below.

The current obstacle I face is that the counter-weight has to be pretty heavy so the frame can be balanced when rotated up and down. In which, the implementation requires the frame to be rotated by hand but still be strong enough to maintain the idle position when not rotated.

For reference, here’s my code:

#include <SimpleFOC.h>

// BLDC motor & driver instance
float target_current = 0;

BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(5, 9, 6, 8);
InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50.0, A1, A3);
MagneticSensorSPI sensor = MagneticSensorSPI(48, 14, 0x3FFF);

void setup() {
// initialize encoder sensor hardware
// link the motor to the sensor

current_sense.skip_align = true;
current_sense.gain_b *= -1;

// driver config
// power supply voltage [V]
driver.voltage_power_supply = 12;
driver.pwm_frequency = 8000;

// link driver

// set the torque control type
motor.phase_resistance = 5.57;
motor.torque_controller = TorqueControlType::foc_current;

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

  motor.PID_current_q.P = 0.01;
  motor.PID_current_q.I= 150;
  motor.PID_current_q.D= 0.00001;
  motor.LPF_current_q.Tf = 0.01;

  motor.PID_current_d.P= 0.01;
  motor.PID_current_d.I = 180;
  motor.PID_current_d.D = 0.00001;
  motor.LPF_current_d.Tf = 0.01; 

  motor.PID_velocity.P = 1.5f;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0.0002f;
  motor.PID_velocity.output_ramp = 1000;
  motor.LPF_velocity.Tf = 0.01;
motor.voltage_limit = 5;
// setting the limits
motor.current_limit = 1.2;

motor.monitor_variables = _MON_CURR_D| _MON_CURR_Q | _MON_VOLT_D | _MON_VOLT_Q | _MON_TARGET | _MON_VEL | _MON_ANGLE;

// initialize motor
// align sensor and start FOC

Serial.println(F(“Motor ready.”));

void loop() {

// main FOC algorithm function

// Motion control function
// user communication

I read in SimpleFOC community and Github discussions that the best and most optimized method to control either Torque, Velocity or Position is through FOC_Current. But unfortunately the torque produced from the motor is unsatisfying. I tried tuning the PID it doesn’t change much but increases the vibration of the motor. I also tried increasing the current_limit, but it doesn’t increase the torque much instead increases the heat.

Please correct me if I’m wrong and all advice or suggestions are gladly accepted.
Thankss a lot in advance

1 Like

Hello @nicolasaw and welcome to the forum.

That’s a really nice setjp you’ve developed. Thank you for sharing.

Unfortunately you have answered your own question. These motors cannot producd the torque you require regardless how much you push them with that board. You have to upgrade the board to handle higher voltage, higher current, and use a gear reducer. It may be good to calculate the dynamic and stall torque required for yr setup beforehand, too, in orderto ensure the forces delivered are sufficient. The general rule is that you need a motor that could deliver stall torque which is 10 times the weight of the arm in order to handle dynamic torque during movements without disrupting the smooth motion. Just adding counterweights will not fix the weak motor / board problem. In fact it makes it worse because the motor needs to push a lot more mass dynamically to move the arm.

Instead of counterweights, you may want to consider spring countertensioners, but thats a really complex mechanical design. Bigger motors, bigger board, gear reducers, countertensioners is your answer.



Thankss for your help and yeah truth to be told, I didn’t really calculate the motor power ratings. Any input for the fastest solution from which you provided? Unfortunately, the deadline is reaching the end and a new motor won’t be accessible anytime soon.

Thanks again in advance


You did not specify which MCU you are using to control the SimpleFOC board. You may benefit from a very fast MCU. Anything closer to or over 100MHz would improve your control loop. I hope you are not running this complex arm using Arduino Nano or some basic Arduino MCU, that’s not nearly enough to produce the computing power required.

I cannot see a fast solution here. If I had to work with your existing setup to make it move, I would fine tune the PID to stay still and not jerk around, and then write extra code to dampen the harmonic oscillations by creating a second bigger loop over the motor loop with S-curves which triggers every 10ms and re-set the target, then slowly try to bring the angle back to the original target angle, then greatly limit the speed to go from one target to another to eliminate any dynamic load as much as possible. Hint: Kalman filtering does miracles. Literally. If it was good for the Apollo Project, it must be good for you, too.

In other words, your current setup will work only if you move the arm VERY slowly to eliminate dynamic feedback and stay under the motor stall torque.

So please add very fast MCU to the list of things to improve. For example, Blue Pill or Nucleo boards (STM32), NXP (Teensy), ESP32, etc.


Hi Valentine, thankss a lot again for your reply

The MCU I am using currently is an ordinary Arduino Mega 2560 and for each motor, they have its own respective SimpleFOC board. I didn’t expect that with a max current of 5A boards aren’t enough to control this kind of load. Is it wise to maybe try increasing the current limit of the motor (currently I’m only using 1.2A)?

Can you help me point out which PID I should tune with? Tuning the Current Q and D doesn’t change much the output, meanwhile tuning the Velocity PID does help but still haven’t found the correct numbers. Am I on the correct track?

Since the frame will be moved most of the time (and not always in a horizontal position, could have an angle), how do I maintain and constantly change the target angle overtime? And if you don’t mind, I would like to learn more as well on how to work on the S-curves (sorry but I’m not really familliar with it).

Thanks again!!


It is extremely difficult to offer constructive advise without closely working with your setup and knowing the end use cases and requirements. These are just general comments.

As I said, you may greatly benefit from a much better MCU.

The current has nothing to do with the board processing power. It has to do with the speed it takes to update the motor FOC loop calculation, not the current it outputs. If you put out 1A or 100A, the computational power required is the same. The higher, the better. To give you an idea how much better, a cheap Nucleo board would get you 10 times (1000%) improvement over the Arduino 2560.

Perhaps? Not sure, but whatever works in your case.

I wish I could help you, however, these are somewhat advanced topics of robotic science, completely outside the field of motor control and scope of this board/forum. You may wait and see if anyone else here is willing to help you, however, I seriously doubt you may find someone. My only advise would be that you ask your academic advisor or professor, or spend time in the library researching the topics (here I’m assuming you are a student).


I will first try changing the MCU, I currently have a Teensy 4.1 in hand, I’ll keep update on what changes it perform.

I will do so as you advise hahaa

Thanks again for your help
*Side note: If any other have some more advices for me, please feel free to share with me.


Check if Teensy has current sensing in the hardwars compatability, I have a feeling there was something about it that there was incomplete support.

I checked the documentation, it seems to support. But I have the trouble the motor isn’t powered currently, but the encoder works fine. Might SimpleFOC board requires 5V in the pin input for it to work since Teensy is sending 3.3V?

You may need 5v. Please check the requirements.

1 Like