Electronic – BLDC Motors: Calculating the offset between rotor flux angle and rotary encoder Measurement

brushless-dc-motormotorsensor

I am using an AS5147 Rotary Sensor to measure the position of a BLDC Motor. The motor is a 11 pole BLDC/PMSM. I have my own inverter circuit and right now doing a look up table based Space Vector PWM scheme to drive the motor.

For the sake of simplicity, lets assume the encoder gives me degrees (0-360, electrical not mechanical) and based on the measurement, i check my look up table (lets assume it also has 360 values, representing 1 cycle) and depending on the direction i want to drive, i get the duty cycles at the index [EncoderPosition +/- 90 ]. If i want to add a bit of field weakening, i add a few degrees.

This approach gives satisfactory results but what i described above is only valid if what I get from the rotary encoder is actually the rotor flux angle. As far as I've understood the encoder is not synchronized to the rotor flux and just gives me a measurement that has a constant offset to it.

Currently, i am finding this offset by just playing around and trying different values and this 1 SE post suggests that its not that important but for my current implementation that doesn't do current measurement, it really seems to affect the performance.

I tried to automate finding this offset by locking the motor to some position – with an arbitrary index from the look up table, take the measurement from the encoder and get the difference between them and use this as a software parameter. I was a bit lost with this approach since to my understanding, the look up table index represents the stator flux (that i generate) and the encoder measurement should represent (rotor flux + 180), since when the motor is locked, the rotor flux locks itself in the opposite direction of the stator flux. My idea was doing

Offset = (ChosenLookUpTableIndex + 180) – EncoderMeasurement

where (ChosenLookUpTableIndex + 180) is the rotor flux angle when the motor is locked.

I also had other problems such as different motor power cable orderings giving different offsets, some of them not even constant.

I would like to ask if there is a proper way to calculate this offset rather then experimenting with it.

Best Answer

Your initial idea is correct. I will make the assumption that you have a function that runs the Space Vector Machine and that takes 2 input arguments: the stator angle and the magnitude of the stator vector you want to apply. Here is what I suggest to you to solve your problems :

Motor phase sequence not always the same :

Main idea: Feed the SVM with an angle ramp and a positive amplitude to see if rotor turns in the right direction.

  1. Connect your phases the way you want on your motor controller;
  2. Remove any load on the rotor;
  3. Launch a first procedure that manually ramp the SVM's angle at a slow and desired speed, with a constant positive vector amplitude. It will generates a rotary stator vector and the rotor magnetic field will align with it (some friction could make them not perfectly aligned, but you do not care here). If speed is low enough, magnitude high enough (but not too high to avoid excessive current) you should see the rotor spinning;
  4. According to the direction of rotation, you can determine if the phase sequence is the good one, or if 2 phases have been switched. Keep in mind that a circular permutation of all the phases will not reverse the speed, but it will "add" 120 deg to your offset. But you don't mind because you will automatically compute the offset.
  5. If the direction is not the good one, switch duty cycles of 2 phases (let's say A and B) just before the SVM will apply them.
  6. Save this information in some Flash memory to use it after a reboot.

Automatically compute the offset (1st method)

Main idea: Feed the SVM with a 0 angle and look at the AS5147 measured angle to find the offset Alignement of the rotor direct axis and the stator a axis.

  1. Feed the SVM with a 0 angle and a positive constant amplitude. To find the right amplitude value, do some tests. Increase it until the rotor is locked and hard to turn by hand. Be careful not to drive too much current;
  2. The rotor field will align with the stator field along the a axis of the (a,b,c) reference and the AS5147 value will be your offset.

This method will not be extremely accurate because of friction but it will give you a good estimation of the offset.

Automatically compute the offset (2nd method)

Main idea: Feed the SVM with an angle ramp and look at the AS5147 measured angle to find the offset SVM angle ramp in both direction to remove effects of friction

  1. Manually ramp the SVM angle in one direction (the same ramp as for phase sequence detection will be ok);
  2. Each time the SVM angle is 0, add the AS5147 output to a variable. Do it a couple of motor turns and compute the mean of this value at the end of the sequence;
  3. Do it again but in the opposite direction;
  4. With the assumption that friction has the same effect in both direction, one value will be your offset+friction and the other will be your offset-friction. Sum them up and take the half of it and you will have a quite good offset value.

Bonus to improve the offset calculation

Here is how you should use the previous offset:

  1. Get AS5147 value;
  2. Subtract to it the offset previously computed and then you have the rotor position in the (a,b,c) reference. (Example: a raw value of "Offset" degrees given by the AS5147 will tell you that you are on the A-axis of (a,b,c) reference (0 deg));
  3. Without field weakening, and with no phase compensation due to torque and speed (only a simple open loop control with no Vd), you now feed your SVM with this angle +/- 90deg (Vq) to make the motor turn in one direction or the other.
  4. Apply a pre-defined vector magnitude to the SVM and measure the speed;
  5. Apply the opposite pre-defined magnitude and measure the speed;
  6. Decrease or increase the offset on the fly to make both speeds match.