Idea for sensorless commutation - just track the zero crossings of the current and voltage-in waveforms

Hey guys, Candas1 made some progress on sensorless commutation, A thread for finally figuring out sensorless drive strategies - #19 by Candas1

The central challenge is to take the voltage waveform, and the current waveform, and determine the relative position of the rotor vs the magnetic field produced by the coils in the stator.

This magnetic field can basically be assumed to be determined by the currents in the coils (I guess the magnetic properties of the coils do not insert significant distortions).

So we can use the clarke transform on the current of any 2 phases, at any given instant, to determine the magnetic field produced by the coils, that’s in the bag.

The problem is the rotor. Obviously most systems use a sensor for that.

I read most of the document linked to there, some of it’s not relevant to us.

Got a b-g431-b-esc1 board, got my fan.

I can go ahead and try to see if I can get useful data out of that code that Candas1 posted, but I hesitate to get into all that because I have never really found a solid explanation for exactly what’s going on. One question is what units the flux linkage is in. Also the formulas on line 101 etc SimpleFOC_b-g431b-esc1/src/main.cpp at 9746903f9b0f821a232fcdbcf89330e251f2f376 · Candas1/SimpleFOC_b-g431b-esc1 · GitHub I don’t really understand, and in my experience that’s always cruising for a bruising, and I can’t find any explanations anywhere.

Also am concerned about the mutual inductance between the coils messing things up, this is discussed in the PDF linked to but not really addressed.

I’m thinking if everything is just sine waves (I’ve got a surface magnet type motor and back emf appears to be a nice sine wave on a scope), and the theory is that the current waveform changes phase with respect to the driving voltage waveform (both of which we know), do we really need these calculations to determine what the phase angle between them is?

Why not just track the zero crossings of the two waveforms?

Would this give a measure that stayed constant for a given rotor vs coil-produced magnetic field angle (motor timing), as voltage and RPM changed, do you think? I think it would?

That code is written in platform IO and I don’t know if I’ll be able to get it working under arduino… in other words, a lot of questions. This zero crossing thing seems like it needs to know basically nothing about the motor, which is a problem I always run into. My measurements of the motor characteristics are always off. Also there is a thing called salience which most motors exhibit, where the inductance of the coils changes with the rotor position, that would mess this up.

I think the zero crossing approach would not have this problem?

I know it sounds kind of dumb, but simplify, simplify, right. I mean that paper is great but it always gets incredibly laborious when I try to bake something like that. There is still a lot of stuff that’s pretty uncertain and it would take quite a while to clear it all up and get the actual code hammered out. And then it’s useful basically only for me and almost no one else, these SM type motors are not that common, most motors are plate type, which exhibit significant saliency.

1 Like

So to be clear, I propose that this could give a “normative” measure of motor timing. It won’t return the actual angle between the rotor and the magnetic field produced by the coils (the motor timing). However if the difference between zero crossings of the two waveforms - drive voltage and current - is say 2.1 rads at optimal commutation (which can be determined by other means for any given motor - what I do is run my fan at open loop and adjust the voltage till current is minimized, that happens to be the the point where the motor timing is optimal), then you just use a PID to regulate the RPM or voltage or another parameter such that it’s close to say 2 rads. That extra 0.1 rads is for a little margin against stall. You reduce your efficiency but you get less probability of stall if the load suddenly changes.

One problem is PID oscillations, you can’t have it go to far the wrong way or the motor would stall. Gotta have stall detection and a few other things too for sure. I keep meaning to read up on “beyond the PID” for other regulatory mechanisms that might work. IDK if having a larger gain on one side would help.

For me, I was going to actually regulate voltage, not RPM. RPM just ramps up and down in linear way that I’ve pre-determined. and thus sub-system juices or trims the voltage to keep that motor timing in range of optimal for energy efficiency/overheat defense, and adequately far from stalling.

The only critical thing is that at motor timing angle X our “normative measure” stays the same regardless of RPM and voltage, basically, and it goes up in the right way, and down in the right way, which I think it does. When you are setting up your system, you just test out different timings and set a good one. I noticed this is done anyway during drone motor ESC setup. And they tell you yeah it’s a compromise between margin against stall and energy efficiency. There is the region where the angel is actually more than 90 degrees, they call that field weakening and I don’t know what the point of that is and generally wouldn’t go there… that’s past the point of optimal torque but on the wrong side re approaching stall, which is of course what happens when the timing angle gets too large.

Some of this phase difference is cause by inductance, and some by back emf, but from what I’ve read, not much else. But we can’t always use a clarke transform on the current on any two phases at a moment in time to get the current angle because there are other waveforms like space vector that are important but aren’t sine waves, and again many - I think most - motors don’t actually give a sine wave back emf. 4 zero crossings per oscillation is a reasonable frequency of measurements, I think?

Hey Anthony,

You can do zero-crossing detection on the motor’s BEMF voltage, that sounds a lot like what you’re proposing. This requires voltage sensing hardware, which many of the drivers used with SimpleFOC don’t have, but some do. And it isn’t FOC in the end - to sense the voltage one of the phases is in high impedance state, which implies block commutation. And BEMF sensing only works when the motor is already turning at a speed sufficient to generate a strong enough BEMF signal. So this means you need another method of control for starting and for slow speeds. It’s also less energy efficient.

So the BEMF control isn’t as versatile as FOC, but it is computationally much less demanding, and can therefore be useful for very high speeds, for example.

Or perhaps I’m not quite understanding you here…

1 Like

The whole flux linkage observer is actually a roundabout way of observing the BEMF continuously. It uses motor parameters and available measurements to calculate what the voltage would need to be in order to get the measured current value. Once you have the BEMF voltages on each phase you can calculate the electrical angle with an atan2 call.

I’m pretty sure the flux linkage parameter is actually just the KV constant with a unit conversion, and has units of webers. The torque constant, in Nm/A, is also the same thing with a different unit conversion.

My experience with the flux observer as currently implemented by Candas is that it’s difficult to get it to reliably start up from zero speed on some motors, even if you start it open loop. I haven’t integrated the same math with my HFI code, but it’s probably approaching time to do that.

1 Like

I think I just need to write out the equations.

I just need to take the equation that gives current for an RL circuit, then take the back emf, add it to the driving voltage (with the phase correct, a phase shift of P).

Suppose we talk about 3 coils in a triangle, with 2 permanent magnet poles i.e. a single pole pair, a bar magnet, basically, sitting on an axle above the 3 coils. And a soft iron core, the magnetic properties of the core are ignored (that seems to be common).

Assume thinking in 2 dimensions, so the fact that the bar magnet is somehow above the coils is ignored.

the back emf is the derivative of the flux through the coils caused by the bar magnet

the net driving voltage across the coils is the driving voltage minus back emf, the voltage generated in the coils by the changing magnetic flux provided by the rotating bar magnet.

The net current waveform through the coils is determined by that RL equation, which I should know but don’t remember. There will be a phase shift of 90 degrees from the voltage but also some from the resistance.

Suppose I graph those with say

Rotation of the rotor is actually counter clockwise, yeah positive rotation is counter clockwise, :P.
Suppose that if the vector points to the right, that’s zero angle. Straight up is 90 degrees.

Because it’s all sine waves, the derivative of one is just 90 degrees phase separation between waveforms. Derivative of sine is cosine, then -sine, then -cosine, then back to sine.

The back emf waveform is 90 degrees ahead of the rotor/flux (the rotor angle i.e. the angle between the magnets and the stator is the “flux angle”). I.e. the waveform of the back emf is shifted to the left of the flux/rotor angle. When the flux is passing through zero, the back emf is at maximal (maximum rate of change of flux is maximal voltage induced).

So, when running open loop with zero load and the coils had zero resistance, and the driving voltage matched to speed, the rotor is aligned with the magnetic field from the coils, the back emf and driving voltages nearly cancel out (180 degrees out of phase). The back emf is the same as the driving voltage, the motor is turning but producing zero power. OK. However the angle of the driving voltage vs the rotor angle would be affected by inductance.

In reality there will still be some power because of the resistance, this would show up on the graph in the current waveform.

When the lag of the rotor is -90 degrees vs the current waveform (which also represents the orientation of the magnetic field produced by the coils), we know that’s the point of maximal efficiency and torque. The back emf is 90 degrees ahead of the rotor, so it’s in phase. Then the back emf and current waveform are in phase. According to the PDF that’s also that’s also known to be the ideal point for maximal torque and efficiency. So things add up. A larger phase diff means the rotor is too far behind (“field weakening” region) and too little is less than ideal in some ways, but being in that region leaves some margin against stall so that’s where we regulate to be in, close to but slightly less than 90 degrees.

So if I just write out the equations as described above, it will quickly become apparent how to derive the phase of the back emf waveform and of course from there the flux/ actual rotor position from the driving voltage and current.

I am thinking this is probably exactly what the Candas1 thing is doing, but we need explanations, too, or we can’t have confidence. I don’t see the resistance factored in there anywhere either and it seems like it must play a role here as it will cause phase shift.

This is different from my zero crossing idea, which I think would not be constant with different drive voltages and is thus not what we want.

These links might help with the math.

In this link, keep in mind that in the laplace domain sF(s) = f’(t), aka that’s how you denote a derivative.

I’m not sure what part you need an explanation of exactly, but if you could be more specific then someone might be able to help you understand.

Sorry this is too much bla bla for me now.
I explained what I did in another thread.

I ported the flux observer from mesc firmware, and I added a like to the documentation here: