Limit the power supply of the motor

Hello everyone, thank you in advance for the answers.
In my application I have a pmsm motor powered by a 24V switching power supply. I need to limit the maximum power to 320W (i.e. I need to limit the power supply current to about 13A). However, the power supply current is not measured, only the motor currents are measured.
So, my idea was to consider the power balance:
W of power supply =~ W motor
and limit the motor power accordingly to about 320W.
I would then go and impose a current limit on the motor that varies according to the voltages to be considered in the PID control.
I don’t know if this can be done or are there simpler ways?

If you know the motor currents and the phase resistance, you can estimate the power (P=R*I^2). Your basic consideration that input power roughly equals the power consumed by the motor is usually correct (apart from some losses of course). SimpleFOC also allows you to limit the phase currents, which would be the preferred solution to stay below your limit. Nevertheless it is a good idea to start very low and use a PS with adjustable current limit while you still develop your project.

In another discussion here we mentioned you need to take the PWM into account.
If your motor current is 10A at 10% duty cycle, you are not consuming 10A on the PSU.

Thanks for the reply.
Yes, I also think that I need to consider the PWM by considering the battery current = (vdid + vqiq) / vbat. I would like to implement the power limit by limiting the power of the motor.
Hovewer, do you have any suggestions on how to implement the PSU current controller?

Read the rest of the discussion, you need to multiply by 3/2.

I would try to get the dc current right first.

If I = 3/2 * (vdid + vqiq) / vbat
And P = V*I
Then P = 3/2 * (vdid + vqiq)
I could be simplified to P = 3/2 * vqiq as Id must be 0.
You have to experiment with this. If this works it could be a good addition to SimpleFOC.

Then one method for limiting it is the current chopping, but I am not sure it’s best.
Basically you shut the PWM OFF when above the limit and ON when below the limit :joy:

Hi @Luca90 , welcome to SimpleFOC forums!

The others have already given you some pointers for calculating the bus current from the motor phase currents.
If you arrive at a corrected formula, I’d be glad to put it into SimpleFOC and fix the incorrect DC-current calculation we have now.

Why? Keep in mind that there can be situations where the current is too high, but not passing through the motor, like shoot-through. Why not add some current measurement to the input, then you can be sure you’re acting on real information… a sensor like this: ACS712 20A Ampere Stromensor Range Module Current Sensor Compatible with Arduino costs very little and can be added on externally.

This sounds fairly simple already, but my question is what’s the actual control scheme?

  • is the idea to drive the motor near the limit, or at a specific chosen bus current? - if so I think the SimpleFOC torque dc-current mode would already do this, assuming we correct the formula…

  • or is the idea to run the motor in velocity/angle mode, but to limit the bus current? - I think you can already do this indirectly - by doing the inverse calculation and figuring out the expected bus current for a given Iq limit, and then running the motor in velocity/angle foc_current mode but with the calculated limits.

1 Like

thank you very much for the inputs.
I will check the formula for calculating the bus current.

yes there is an internal measurement in the power supply, but it shuts down the power supply if the current is too high. My idea is to control the motor in velocity/angle mode and limit the bus current so as to prevent the power supply from shutting down by limiting the bus current to a lower value.

I need to control the motor in velocity/angle mode, but especially in the start-up phase, when accelerating, the motor may reach the limit of power that the power supply can provide. At this stage I need to limit the bus current to prevent the power supply from going into protection (=shutting down).
So if I understand, assuming that the formula provided by Candas1 is correct and my power limit, I have:
320W = 3/2 * vqiq
Then I have to limit iq to 213/vq.
Is that what you mean?

Example how it’s done in MESC

You need the experiment, I cannot do it for you.

@runger that would be easy to implement in SimpleFOC

You mean like having a motor.dc_current_limit setting?
Or it would be better perhaps to have a motor.setDCCurrentLimit() function which does the inverse calculation and sets the motor.current_limit accordingly?

I think both are different.
current_limit is more to protect the driver, dc_current_limit would be more about protecting the power supply. So those limits will be different.

We could probably start checking if the dc_current and power using those formulas are accurate enough. Also should this new dc_current be used in the dc_current mode, was the intent the same.
Then we can check how we can limit it.

I tried those formulas myself yesterday:
P = 3/2 * vqiq
Idc = P / vbat

This is only the motor current, so I added the PSU power reading(0.123*26=3.2W) at 0 torque target:
P = 3/2 * vqiq + Pboard
Idc = P / vbat

The calculated I and P were still lower than the ones displayed on the PSU, and the gap was bigger as the current/power increased.
But I guess having incorrect shunt resistance and gains can be a problem for Iq measurement, and the deadtime can impact Vq.

I tried using Iq = 3/2 * vqiq / vbat in dc_current mode for driver the motor, it worked as expected (except the inaccuracy) .

I need to try this on a B-G431B-ESC1.

1 Like

I don’t see how that formula could predict the input power. vqiq is output power (to the rotor, not at the shaft, since the rotor inertia, air resistance, and bearing friction will eat up some torque before it makes it to the shaft). Input power is that plus the mosfet+winding resistance multiplied by total current squared, plus eddy current loss which is probably small enough to ignore in most cases, or at least ignore its scaling and lump it in with a general safety margin. So if I were to hazard a guess at a formula for input power, it would be vqiq + (id²+iq²)*(mosfet_resistance + phase_resistance) + safety_margin

EDIT: Oops, I forgot it’s current squared times resistance, so no square root in the current sum. Which means that even if we assume id=0, we need quadratic formula to do the inverse calculation.
r = mosfet_resistance + phase_resistance
iq²*r + vqiq - power = 0
iq = (-vq ± sqrt(vq² + 4*r*power)) / 2*r
Not sure offhand whether the + or - solution is the one we want or if it will need a branch.

That’s what most of the firmware do, it’s probably just a rough estimate.
Yeah I forgot about the losses, I could just add 5% losses lol.

If I am running my motor with a torque target of 0.4A, I read Vq = 4.1v.
I read 6W and 0.238A on the PSU (3.2W and 0.126A when idle).

3/2 * vqiq = 1.5 * 4.1 * 0,4 = 2.46W
2.46W + 3.2W = 5.66W which means 0.34W is missing

r = 0.008 + 0.1664 = 0.1744
iq²*r = 0.4 * 0.4 * 0.1744 = 0.06976W
5.66 + 0.07 = 5.73 so still 0.27 missing

Probably with load and higher current it would be more significant.

I just want to say I think it may matter how the motor current is measured. With so called inline sensing, the currents out of the inverter terminals to the motor is measured. In that case, the stuff people are saying when it comes the apparent current going to the motor actually being higher than the bus current (due to less than 100% pwm duty cycle and the way the inductors in the motor somehow lead to higher currents) is I guess valid although I’ve never been clear how this works, I assume that current has to go in one leg of the inverter and out another.

However, the b-g431-esc1 board I’ve been using has low side sensing, which actually measures the amount of current that goes to ground. The code base does things in such a way that the peak current is measured more or less in the middle of the PWM pulse, and average current to power ground appears to be calculated. In my experiments the current returned by SimpleFOC functions in this context are basically the bus current, approximately, to the inverter, so not the motor current.