Baffling but extremely convenient phenomena that allows stepper motors to be used in e.g. fans easily

I am indeed using a stepper motor to drive a fan, everyone will say it makes no sense but it actually does. The torque to speed ratio is great, the cost of the motors is low, they are easy to get in several sizes, and the buzzing can be eliminated with passive isolation and sine wave drive.

I wrote a driver that uses a current sensor on the power supply side, and optimizes current, to optimize energy efficiency, because I found with 3 phase motors in the past that the point when the so called torque angle i.e. the magnetic field of the stator vs the magnetic field of the rotor (so when open loop and no load, it should be close to zero, with true FOC drive it should be close to 90 degrees) is close to 90 degrees, energy efficiency is also optimal.

Simple, no sensors needed, assuming the fan is not subject to shock or anything. Stall detection I have a plan for, as well as verifying the motor is not moving prior to start up.

There is a voltage ramping thing that increases the voltage to some function of the RPM, basically. The optimizer just adjusts a trim voltage to try to optimize the current.

But here’s the amazing thing. I thought the optimizer was not working, because when I loaded the motor, or adjusted the power supply, the “voltage” commanded by simplefoc did not change much. I.e. motor.voltage_limit, which is used in open loop to set the voltage (it’s not really named quite right in that context, but whatever, because it is not really a limit, it’s always at whatever it’s set to), was not changing.

The current would go up though when I loaded the motor by putting my hand on the shaft etc. Similarly, it would go up, and the energy consumption stayed very nearly the same even when I changed the power supply voltage by turning the knob on the power supply.

I can reduce the power supply voltage from 24 volts down to about 17 volts and it automatically self regulates, with the motor at about 350 RPM, during that experiment. It works fine at 400 rpm.

I cut out the optimizer, by commenting out that code, and the behavior is exactly the same. Somehow, the system is superbly self regulating. I might as well be using a fancy sensor and have a well written FOC drive system or something. It all works great, when the motor is actually just being driven open loop.

An incredibly convenient discovery: a normal stepper motor can be used great to drive actual power producing loads, with no sensor or anything. Just voltage ramping. I can try to get the code up later, I am on the wrong computer right now, but seriously it’s voltage ramping with a minimum voltage i.e an affine function. That’s it. And it’s driving my fan with nearly complete silence, using rubber isolators.

That’s great. I agree you have to forget everything you ever learned about control theory to do it really well. So you have a current controlled voltage source, and how does it know when the voltage is too low ? its using nonlinearity somehow ?

1 Like

No it’s not current controlled, that’s why this is baffling. It’s just literally open loop but the voltage increases when the rpm increases, the voltage is simply a function of the rpm it’s 19*(RPM/rpm_max)+4.5 volts. That’s it! If the voltage was too low it would just collapse into a buzzing mess. but like I said there seems to be plenty of room against that as I can adjust the voltage of the power supply way down and it doesn’t stall. The current increases, power consumed stays relatively constant, instead. It’s not at all what you would expect from open loop.

I have plans to detect stall and also to ensure the motor is not already rotating on startup. To detect stall I plan to just measure the current at a range of rpm and make a polynomial, if the current is too high or too low, it just cuts motor power and the user has to power cycle it.

I don’t understand how the voltage can increase.It’s either the supply voltage or 0. Are you talking about the RMS voltage that simplefoc controls via PWM ?

yes, that’s what I mean. motor.voltage_limit, which is mis-named because it’s not a limit, with open loop that’s the actual de facto rms voltage, well it’s what determines how much current goes through the coils with a given resistance, of course if you actually look at it with an oscope it’s a pwm signal.

This is how im driving the wheels on my rover, the motors will overheat if you leave the voltage limit too high at idle so I ramp it up and down with rpm demanded. I dont zero it so that it will hold position and not roll.

Ok but I’m not sure if my point is coming across. This is open loop. In general we assume that the efficiency is poor, that you need a “torque reserve” and so on. But it turns out that for some reason, a wide range of drive voltages actually gives quite reliable and efficient power production, as good as though they system actually had a sensor. It’s quite something.

The effort involved in making complex current observers and so on is largely useless. You don’t even need a current sensing system. As long as the load is constant, like in a fan. I imagine if the robot, in your case, went over a bump that could cause the motor to stall which would be a problem, so it’s not a great strategy for a robot. But for some applications it’s an incredibly convenient phenomena.

I mean to be fair it would be an even better idea to develop the code for a good current observer as is used in the tmc2209 chips, however I just don’t know how to do that/don’t have time. So it’s very convenient that it is not even necessary in my case.

That is surprising. But after some pondering, I think I see how it works.

As I understand it, with a regular DC motor running on a constant voltage, putting a load on the shaft slows it down, which reduces the back EMF, allowing more current to flow and producing more torque until it reaches an equilibrium speed which is slower than the no-load speed. The increased current increases resistive heating of the coils, but that is in addition to the real work being done moving the load.

SimpleFOC’s open loop mode steps the angle at a constant speed regardless of anything else, so loading the shaft will not reduce the back EMF until it stalls and drops to zero (resulting in a drastic increase in current). Loading it only changes the direction of the magnetic force from radial to tangential. So for a given voltage_limit and target speed, current in the coils should be constant regardless of load, only shifting phase relative to the rotor as the load increases.

The trick is that only the resistive heating is constant. When the magnetic force is radial, it is only force but not work since it isn’t able to move radially, and thus does not consume energy. When loaded, the rotor is dragged back until the tangential force balances the applied load, consuming exactly as much energy as the load requires (or stalling if it needs more than 100% tangential force).

In mathematical terms, power in = power out + losses, and power out = radial force x radial speed + tangential force x tangential speed. Since radial speed is always 0, power goes up as the force becomes more tangential.

So for velocity control, the regular FOC method is just an elaborate way to reduce resistive heating. If motor weight is not a concern, you can just use a big one so heating is negligible and give open loop some headroom to ensure that it doesn’t stall, and power consumption will adapt to the load. Convenient indeed!

1 Like

Nice, I’m a bit under the weather right now but I must study your answer to see if I can also grok how this works.

I made some progress on understanding this. It seems that the key thing is what’s called the power angle characteristic. The key is that the back emf is equal to (flux linkage)(angular speed)(cosine of torque angle), where the “torque angle” is the angle between the magnetic field produced by the stator, and the magnetic field of the rotor. In other words, the angle between where the rotor would be if there was no load, and where it is given the load, uh with one full step being 360 degrees, I mean. So not the physical real world position, but yeah.

So when the motor is loaded more, the back emf goes down, because the torque angle goes up. More current can flow, more torque is produced, the system achieves equilibrium. Boom. A regulatory mechanism.

The thing is when the angle is less than 90 degrees you still get good efficiency, this is what confused me. For some reason it still works great. Also we rarely have that cosine term in mind because we assume a motor has some kind of commutation system. For stepper motors we usually use them at low speed and not for significant mechanical power production. But this is a very handy phenomena to keep in mind. As long as the voltage is sufficiently high the current will actually self regulate to a considerable degree, given a significant RPM. I suppose it probably does not work very well at lower rpm, I haven’t tried it.