Currrent/torque control in open-loop velocity mode

Hello FOC Experts,
I am successfully running a BLDC motor in MotionControlType::velocity_openloop mode.
It runs at a very constant speed and is quiet. So far so good. What I am not able to figure out is:
How can I control the current (or PWM duty cycle) that goes into this motor? Is there a method in this library to reduce the PWM duty cycle by a percentage or a factor?
Thanks much in advance!

Hi @bm8000,

Without any current sensing, you cannot measure/control the actual current.

You can use the motor.voltage_limit to set an upper bound on the voltage (and thus the PWM duty cycle). For higher ohm motors and low velocities, this will well approximate limiting the current. You can also set the motor.phase_resistance and motor.current_limit to limit things in the same way, but using amps as the unit.

For better results, especially at higher speeds or with more dynamic, lower ohm motors, you will need FOC control, i.e. a position sensor, and ideally also current sensing.

Hi Runger,
Thanks much for your reply! I am experimenting with using a 3-phase BLDC motor as a synchronous motor with a precise RPM that is not dependent on a PID mechanism.
For start-up I want to run it with a high torque, and once it is running reduce the torque/current to half the initial value.
Does the ratio between voltage_power_supply and voltage_limit essentially define the duty_cycle in open_loop? In other words, if I set voltage_power_supply to 12V and voltage_limit to 6V the duty cycle will be 50%?
Thanks much in advance!


It’s a little more complicated…

driver.voltage_limit acts in exactly the way you describe - setting it to 6V on a 12V driver.voltage_power_supply will limit the maximum PWM duty cycle to 50%.

motor.voltage_limit actually limits the Q axis voltage (see our “theory corner” in the documentation for more on this).

And the actual voltage set depends on the point in the commutation pattern. The open-loop code essentially commands a sinusoidal commutation waveform to each phase, regardless of the actual rotor position (since it has no sensor). So the actual voltages commanded (e.g. duty cycles) will vary up and down in a sine-wave pattern.

Synchronous operation will require writing custom timing code that switches the coils at set time intervals rather than switching based on the rotor position. However that is very easy to do, so you may not even want to use SimpleFOC, but just write your own firmware from scratch.

For startup, use low switching frequency and low PWM duty, and gradually ramp up so the motor has time to move before the coils switch on to the next state, and doesn’t burn up from drawing massive current with full voltage at low speed. This is how stepper motors are run on 3D printers and CNC machines (although most stepper drivers have current limiting, which would eliminate the need to ramp up the PWM duty).