Baffling problem with torque mode, and pole pair checks

The voltage-based torque control calculation is a dead simple use of Ohm’s law, in the controller switch statement in BLDCMotor::move: voltage.q = target*phase_resistance + voltage_bemf (which is then constrained to voltage_limit)
And voltage_bemf comes from another straightforward calculation before the switch statement: voltage_bemf = shaft_velocity/KV_rating/_RPM_TO_RADS

Note: Apparently q-axis is the useful torque and d-axis is useless squeezing of the rotor, backward from what I said in my previous post… I will edit that.

Probably :slight_smile: But I did the same thing when I thought it was hopeless trying to get my hall sensors to produce smooth motion.

Another thing that occurred to me is that your power supply protection may be causing problems under-volting the buck converter and CPU/gate driver power. Results from any tests that trip the protection should probably be disregarded.

Yes, results from the times when too much current was drawn are not figuring too prominently here, fortunately.

It works ok if I make a program that accelerates and then runs, and then I adjust the power supply until a reasonable current is consumed. Seems to be quiet. So open loop produces a reasonably smooth waveform, which is a start… and the angle sensor does work, I just have to patch together these pieces somehow without messing things up…

Hey, quick question as I try to implement the above approach: the docs all say the relative angle for mechanical position of the rotor and the electrical angle should be 90 degrees.

I assume I multiply the mechanical angle of the rotor - detected sensor angle minus the zero electrical angle (to compensate for the random installed position of the sensor’s magnet relative to the rotor’s magnets) - by seven (7 pole pairs for this motor), then go modulo division of that figure by 2pi. That should give me the “mechanical angle” in terms of the position of the magnets between the poles? In radians.

And then add 90 degrees i.e. pi/2 radians, to give the desired electrical angle in simplefoc?

I’m trying to write a simple program that starts the motor in open loop mode, checks the mechanical angle (as described above) and then immediately checks the electrical angle using simplefoc’s methods/functions. I assume no practical time delay between these two measurements. I do this ten times per second. Then I calculate the difference.
Then I do some very basic PID controller stuff with floating point numbers, also every tenth of second or so, to adjust the open loop velocity, in order to regulate the difference between the two angles to pi/2.

Thus, I close the loop, but in a way that allows for much higher RPM. It is not suitable for other kinds of motion, but it should work for a fan. Reversing direction, and acceleration will be tackled after getting this going.

Does that make sense? I don’t quite see why this 90 degrees angle gives optimal torque. One thing I can do is run it in open loop mode and print out the relative angle, then adjust the power supply to reduce current flow, until efficiency is optimal (which is at the same point that current is minimal and yet the fan keeps turning), or rather just before (so I have a little safety margin against the motor “skipping steps”, same as a stepper motor would). I can verify experimentally that my assumptions/this wisdom about the angle being 90 degrees is correct. Pretty clownerific I know, compared to actually understanding the math, but none of the articles I can find about FOC want to actually answer on the ground questions like this.

You can’t change the acceleration too fast or it will loose track and the pid controller will take a while to reduce the velocity and get the fan turning again, but that’s fine. I can implement acceleration logic in the master microcontroller, the raspberry pi pico. Or I could implement it later, or maybe even just set the PID controller gains accordingly. I know to do integral wind up limits and stuff with the controller logic. It will be a pain to tune the pid, I will have to compile and recompile it with different values because I don’t know enough C to make efficient work of getting the values over serial or whatever. Whatever.

This video, and also episode 8 from this series, can be helpful without diving too much into the math.

Are you still on the lepton?

Thanks :slight_smile:
No, I switched to the b-G431B-ESC1 to get things working because the serial port works and I have enough memory to do things, and compilation is much faster for some reason. After I get it working I will try to switch to the Lepton and see if I can at least use the boards I have bought, or if it is incapable of running the sketch due to speed or memory limitations.

No problem, that video series as a whole helped me to understand a lot about these motors. They are really pretty interesting.

For tuning it might be worthwhile to just load a dummy program that gets you into serial commander and then do tuning through the studio, then take those parameters back to your real program.

I could never get the studio thing working, I will probably just print the values to serial and use the graphing thing in arduino.
hm the question which I had and still have after watching that is how this works in a multi pole motor. In the example shown of course it works, but in a multi pole motor you cannot do the same things.

Basically, if you move the motor open loop, there is at any given instance the equilibrium shaft angle, i.e. the angle the shaft would come to rest at if there were no other forces on it. This is the same as the magnetic angle. Except if you have a 7 pole motor the rotor can be in 7 different positions, so we can more sensibly talk about the relative distance between each of these 7 positions. Let’s call this the modulo mechanical position.

So supposing we are driving the motor with a 3 phase sine waveform, one 360 degrees trhough the waveform gives a step of 1/7 of a rotation.

However given the geometries it does not appear that making the electrical sine wave 90 degrees out of phase with the modulo mechanical position will lead to optimal torque as it would in that video. In other words, his simplifications make the question remain unanswered. It’s not clear what the optimal point along the waveform the electrical signals is, relative to the modulo mechanical position. I don’t know if it is 90 degrees in the case of a multi pole motor.

I was under the impression that because the pole pairs are arranged symmetrically, that you can kind of think of them as each an individual d-q coordinate space (in which case you can apply the simple model for the bar magnet, like in the video). @runger probably has a better idea and I would love to learn a bit more about this.

FWIW, I had a very similar symptom caused by a pushfit 3d-printed (PLA) magnet mount which (I surmise) was getting looser as the motor heated up. Fixed by reprinting in ASA.

Well, I’m not any kind of expert in motor physics, but I can’t 100% follow @Anthony_Douglas plan. It sounds a bit like adding unnecessary complications on top of open loop mode.

Regardless of whether you are doing open loop or closed loop control, you have to update the phase currents at a fairly high frequency. I think I posted a fairly long piece on that before, but the sine waves (or whatever commutation waveform you’re using) don’t just happen - they are generated by the MCU, by setting the PWM levels on the pins controlling the 3 phase drivers, and they need to be updated many times per second to produce something that looks like a sine-wave at the output.

Now in open loop control, you just output this commutation waveform, and trust that the motor will follow it. Depending on the motor’s KV rating, the voltage used, the frequency of the commutation (e.g. the speed) and the load on the motor, the motor will follow this waveform “more or less closely”. E.g. in open loop mode, this waveform will sometimes be too fast for what the motor wants, or too slow, and the commutation and what’s actually happening in the motor’s magnets will be always somewhat “out of sync” - so open loop mode is less efficient, much of the energy put into the commutation will be wasted in processes that don’t contribute to rotational torque.

In closed loop control, the commutation is adjusted each iteration step to match the motor’s actual position. So it might look a lot less than the open loop sine wave, but it will be much closer to what the motor needs in that moment. And therefore it is much more efficient.

But this efficiency depends on the constant updates - it’s not like in open loop mode the position just “drifts away” from where it should be, and can be adjusted once per second to restore efficiency. Open loop is less efficient because it’s not constantly adjusting to the rotor position.
If you were to do 1 closed loop adjustment every second, and open loop the rest of the time, the efficiency would not improve in any measurable way, since only 1/a few thousand control steps would be efficient, and the rest would all be inefficient.

So I think you can save yourself the effort of doing this complicated correction you describe, and just use open loop mode from the beginning…

1 Like

I can’t 100% picture this.

I would think of it more like a continuous space - if the motor has only 1 PP like in the video, then the electrical angle and physical angle space are the same - if the motor has more pole pairs, then the physical rotation contains multiple electrical rotations, but it is still a continuous coordinate system.

The coordinate system of the electrical phases can be transformed into the D-Q coordinate system, but that’s more the mathematical model - as the video explains, you can also just think of it in terms of the magnetic fields. The goal is to keep the magnetic field generated by the stator’s electro-magnets at 90° to the magnetic field of the rotors permanent magnets.

So as the rotor turns, you have to keep adjusting the electro-magnets to keep their field 90° ahead of the rotor.

The D-Q axis comes into it when you do the mathematics of how to accomplish all this. It is much easier to deal with current or voltage vectors in the D-Q space than to deal with the three phase voltages/currents directly. In the D-Q space the D-axis vector is aligned with the rotor position, and the Q-axis is therefore 90° ahead of it. So you can compute a voltage vector along the Q axis and reverse transform this back into the phase voltages which you have to set to the phases.

Our “theory corner” in our documentation has a much better explanation of all this than I can give :smiley:

1 Like

That’s a recipe for insanity :slight_smile: PID tuning is time consuming and frustrating even in the best of circumstances. The values can be extremely sensitive. Do whatever it takes to get fast communication working, such as the quick and dirty method I posted before where you type a capital letter and a number in the Arduino IDE serial monitor to change a variable, and lowercase letter to print the current value.

void SerialComm()
{
  switch(Serial.read())
  {
  case 'K': motor.KV_rating = Serial.parseFloat(); Serial.print("Set ");
  case 'k': Serial.print("KV_rating "); Serial.println(motor.KV_rating); break;

  case 'F': motor.LPF_velocity.Tf = Serial.parseFloat(); Serial.print("Set ");
  case 'f': Serial.print("LPF_velocity.Tf "); Serial.println(motor.LPF_velocity.Tf); break;
  case 'P': motor.PID_velocity.P = Serial.parseFloat(); Serial.print("Set ");
  case 'p': Serial.print("PID_velocity.P "); Serial.println(motor.PID_velocity.P); break;
  case 'I': motor.PID_velocity.I = Serial.parseFloat(); Serial.print("Set ");
  case 'i': Serial.print("PID_velocity.I "); Serial.println(motor.PID_velocity.I); break;
  case 'D': motor.PID_velocity.D = Serial.parseFloat(); Serial.print("Set ");
  case 'd': Serial.print("PID_velocity.D "); Serial.println(motor.PID_velocity.D); break;

  case 'A': motor.P_angle.P = Serial.parseFloat(); Serial.print("Set ");
  case 'a': Serial.print("P_angle.P "); Serial.println(motor.P_angle.P); break;
  }
}

As for the commutation stuff, multi-pole motors are still driven the same way, 90 electrical degrees ahead of where the rotor would naturally settle to. But it certainly is confusing trying to comprehend the magnetic interactions with all the stator poles and magnet poles and coils wound in different directions.

1 Like