Speed limit because of FOC?

I have a 1 pole pair BLDC motor, rated current 2A, rated voltage 24V, no load speed is 15,000RPM. power supply is as motor spec, rated current 3A.
I am using nucleo L432KC as the controller, it’s Cortex M4 @80MHz.
I don’t have inline current sense, so I use voltage as the torque control type. I noticed that in Angle control and Velocity control, I can’t reach speeds higher than 450 rad/sec which is 4300RPM.
I need 10,000RPM. the motor is not connected to any load. Shaft is free to spin, current measured externally at this 450 rad/sec speed is 0.5A. the voltage measured on the FOC studio at this speed is 4. I measure with voltmeter and I get 8.5V AC.

driver.voltage_power_supply = 24;
motor.voltage_limit = 24.0;
motor.velocity_limit = 1000;

Is it because of the limitation of using voltage mode for the torque control? (because I don’t have inline current sense, only low side which is not supported by SimpleFOC)


EDIT ==> strangely, increasing the current limit to 3A increases the speed to apprx 680 rad/sec.
However, it is more than the motor’s rated current which is not good.
And then, some other thing happens after a couple of seconds, the current rises to 2-3.5A and the motor decelerates to a stop while still consuming this current constantly!
I really don’t know what is going on here… My only command was M900 at velocity mode

1 Like

Hi, and welcome to SimpleFOC!

Two separate issues. Firstly, the speed:

  1. Yes, the 80MHz CPU speed will eventually limit the max RPM. The frequency of the control loop executing loopFOC() function will determine the maximum speed you can attain since you’re not updating the phase currents faster than this.

  2. You’re using closed-loop mode, the speed at which you can obtain sensor data will probably be the limiting factor. To update the phase currents to a new value you also need new sensor values on which to base the calculations. If the sensor is not fast enough, or the sensor-read speed is not fast enough this will also limit your max. velocity.

  3. 680rad/sec is quite fast for FOC control with SimpleFOC! :smiley: You’re doing well. Probably if you upgrade to a faster MCU you might make it to 10000RPM, if your sensor is fast enough.

  4. If you increase the current, the speed can increase because the motor will move a little more between each iteration of loopFOC().

Second, the “stopping problem”:

This is a separate issue, I think. It is a known bug with magnetic sensors - are you using a magnetic sensor? If so, this problem will be fixed in the next release of the library.

Thank you runger, yes the MA730 is able to reach speeds of 60,000RPM and still maintain its characteristics (according to MPS) so I am not worried about it.
What I do worry about, is the BUG of the high current consumption and stopping abruptly. Yes the MA730 is the magnetic sensor. Is there any way you can share how I can solve this bug? or what lines of code can I change in the library? This is really important. Thanks!

Unfortunately the change will not be contained to just a few lines.

For today, I can suggest the following: you can take a look here: https://github.com/simplefoc/Ardunio-FOC-drivers/blob/master/src/encoders/as5048a/PreciseMagneticSensorAS5048A.cpp
This class will not have the problem, but it is for the AS5048A sensor. Maybe you can copy & modify it for MA730.

I will try to implement the fix within the library ASAP, and report back to you here.

1 Like

thank you runger, I will try to implement it for the MA730

I had about the same requirements when I stumbled upon SimpleFOC.
I downloaded the code and had a look at it, and then thought “this will not work”.
Because when studying what FOC is, I realised what needs to be done.
You can brute-force the motorspeed to anything you want by just using a faster cpu, but the thing is SimpleFOC is not that efficient.
You need a hardware solution, a microcontroller that is designed for motor-control.
What SimpleFOC does is all software-based.
At the core is a loop that reads a position-sensor and calculates the required voltages for getting to the next position.
But by the time it has done so, the rotor-position has advanced so much that the current is no longer generating maximum torque ( which is the single goal of FOC ).
You could compensate for this delay in software, but when you have to do so you might as well use the faster 6-step commutation algorithm.

Are you telling me 80Mhz MCU is not enough to calculate 1 motor’s voltages in real time?

It would be more than enough in other situations. It is just that SimpleFOC was designed for controlling gimbal motors at low speeds. It is not an ESC. ESC’s do better at high speeds.
What you want to do dictates the software you will need and if that software doesn’t exist then you have to write it yourself or adapt something that almost meets your needs.

It’s more than enough :slight_smile: but it depends on what speed you want to go…

Different sensors have different timings - and don’t forget that even if a sensor can do 60000RPM, you might be reading it via SPI at 1MHz, and this will limit the speed at which the MCU can get data from the sensor.

And the MCU, depending on its speed and whether there is an ALU for floating point accelleration, will require different amounts of time for computing the phase currents in the loopFOC function, and the target values in the move() function.

So on an 80MHz MCU, just as an example, maybe you can expect 3kHz on the main loop? So you won’t be able to update the motor’s currents more than 3000x per second. For a 7 pole motor, there are 7 electrical revolutions per turn, and you probably want to hit at least 6 updates (really, more) per electrical revolution, so that’s minimum of 42 updates per turn - 3000updates/s at 42 per turn makes for 71 turns/second, or 4260RPM maximum motor speed for this example MCU…

I’m sure the control theory experts have a much clearer and better way of looking at this, but this is how I think about it.

Thanks runger, my motor has only 1 pole pair (2 poles)
I need to reach 14,000 RPM (1465 rad/ sec)
my encoder is the MA730
How can I decrease the number of updates necessary to achieve this speed?
although technically with 3Khz, 6 updates per turn (6X1), 3000/5 = 500 revs/ sec which is more than 2 times of what I need… right?

Hey, yes, with such a motor it becomes easier, I think!

Do you have access to a logic analyser or oscilloscope? If so, you could time your main loop precisely: I use some unused output pin, toggle this pin in the main loop before the call to loopFOC() and before the call to main(). Then I can see the frequency of the loop in the logic analyser:

In this way you could check your main loop speed, and also check how long the sensor reads are taking, etc… then you will know if it is a MCU speed problem, or due to some other issue (like sensor lag, back EMF, etc…)

Hi Runger
thank you for your offer. it looks quite logical.
Right now I have a strange behavior:
I am using voltage mode as my torque controller. I measure the current externally.
I can reach -1400 rad/sec (CCW direction) , current draw is approx 0.8A (motor is rated for 2A max)
oddly, I had to set the current limit at 4.5A to reach this speed. the higher the current limit, the faster I can go. (velocity limit is 1600, voltage limit is 6V)
in CW direction, I reach 1400 but the current draw is doubled! I measure 1.6A!
same settings. this is very weird.

I need more current to rotate CW than CCW?

Any ideas why this could happen? There is nothing connected to the shaft, the motor is new, and free to spin in any direction.


One explanation can be a (small) misalignment on the motor electrical zero. This would explain the asymmetrical error.
You could test this by modifying the electrical zero found during alignment by a small amount in either direction, and seeing if this improves the behaviour.

This is expected, of course. The more amps, the faster the motor can go. At some point the marginal gains begin to decrease because of the back-EMF.