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.

  • \$\begingroup\$ What is the 180deg you are talking about ? \$\endgroup\$
    – Mathieu G.
    Jul 19, 2020 at 12:22

1 Answer 1


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.
  • \$\begingroup\$ Thanks for the fantastic answer. I will play with my implementation and come back with further results. In the meantime, I was also trying to use the first method but I thought that when the motor is locked, what I measure is the stator flux and the rotor flux should be aligned to it, but in the opposite direction. This is the reason I was saying 180° degrees in my question but you suggest that this is not the case. \$\endgroup\$ Jul 20, 2020 at 13:45
  • \$\begingroup\$ Also thanks for the improvement suggestion, I also realized that the offset is indeed different in different directions. I never thought that this might be due friction being different for each direction. It's also interesting that for optimal results the offset should be varied a bit according to the magnitude of the vector. This seems like a linear function and I think it's rather related to field weakening effects. Any comments on that? \$\endgroup\$ Jul 20, 2020 at 13:51
  • \$\begingroup\$ The fact that you are able to adjust the offset with high magnitude vector is because slow rotation speed may not reveal the small error you initially get by "manually" rotating the rotor. The faster you run the motor the more visible is the effect of offset error on speeds in both directions. Am I clear here ? \$\endgroup\$
    – Mathieu G.
    Jul 20, 2020 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.