You are on page 1of 13

Project Report

Over All Status:

Finished

Accomplishments:

It is possible to read the position of the motor up to ±15 o accuracy by sending 5 pulses (3 low and
2 high pulses) to the motor.

Risks/Issues:

The amp level of the pulses are not adjusted automatically and should be taken in consideration
before any tests are run.

Project Name Sensorless Rotor Position Estimation for BLDC Motors

Prepared By Ahmet Emre Turkeri

Date 02/06/2020

Reporting Period 09/2019 - 02/2020

Project Manager Andrea Ghirardello / Luca Fazia

This paper explains how the MC_Sensorless(), MC_Step(), MC_AngMan() and


MC_PosMan() functions calculate the angular position of the motor. For the experimental
values BL80M BLDC motor was used.

The Algorithm

During the start-up while startup_cnt value is zero(0) in the MC_ConInt() function
there is a switch case that uses the mot_pos value to give the correct angle of the motor to
found_pos which later is used to write that value to SystemPhase, FluxPhase, Phase_est as
shown below.

else if(0 == startup_cnt)


{
MC_Sensorless();
switch (mot_pos)
{
case _0_DEG: //(1)
found_pos = 0.0f;
break;

case _0_30_DEG: //(2)


found_pos = 0.2617993875f;
break;

...

case _330_360_DEG: //(24)


found_pos = 6.021385913f;
break;
}

SystemPhase = FluxPhase = Phase_est = found_pos;

MC_Step
In MC_Step first pulse is send with the code written below.
// esce da V entra in W ( 0 )
S12AD.ADANSA0.WORD = 0x0004; // w
PORT7.PODR.BYTE = 0x44; // w
//B7
//PORT7.PODR.BIT.B6 = 1; // P76 p051 WL1 MTIOC4D
//PORT7.PODR.BIT.B5 = 0; // P75 p052 VL1 MTIOC4C
//PORT7.PODR.BIT.B4 = 0; // P74 p053 UL1 MTIOC3D
//PORT7.PODR.BIT.B3 = 0; // P73 p054 WH1 MTIOC4B
//PORT7.PODR.BIT.B2 = 1; // P72 p055 VH1 MTIOC4A
//PORT7.PODR.BIT.B1 = 0; // P71 p056 UH1 MTIOC3B
//PORT7.PODR.BIT.B0 = 0; // P70 p057 OVC1 POE0

Later count_w is calculated in,


while((count_w < 50 ) || ((abstotal < LOW_CP) && (count_w < 150)))
{
DELAY1US(1)
++count_w;
S12AD_START
WAIT_S12AD
samplec = AN02_IW1;
total = KADI * (samplec - iwm_off);
abstotal = ((0.0f > total)? -total: total);
}
The number limit of count_w (50-150) does not need to change on different motors.
All that is needed to modify is the limit value of LOW_CP. If count_(u, v, w) values are reading
150, decrease LOW_CP or if you get low values for count_(u, v, w) increase LOW_CP. Keep in
mind that count_(u, v, w) are calculated in the similar principles.

MC_AngMan
After running the tests we have seen that when the rotor position is between 0-180
degrees there is a certain characteristic differences to these values but this characteristic
repeats itself between 180-360 degrees. LOW_CP value is 20.0f. First count_(u, v, w) values
were read on every 15o to get a graph to see how these numbers change as the angle
changes.

With this graph we could see that these numbers can be used in a certain way to
understand the approximate position of the motor.

After discovering the pattern;


In MC_AngMan() function the count_(u, v, w) values are compared to understand
where the results match on the table above. For example if the motor angle is 30 o-60o (4) or
210o-240o (16) the result is always count_v > count_w > count_u or v > w > u. From this
logic;

1) w > u = v 7) v = u > w

2) w > v > u 8) u > v > w

3) w = v > u 9) u > w = v

4) v > w > u 10) u > w > v

5) v > w = u 11) u = w > v

6) v > u > w 12) w > u > v


But there is a small problem here. The "=" needs to be managed because there can
be 4-5 difference to count_(u, v, w) values on the same angle range. Although for 60o (5)
count_w has the value 70 and count_u has the value of 73 they are considered equal.

This can be seen in the code below;


if (-5 < (u-v) && 5 > (u-v))

{...}

else if (-5 < (u-w) && 5 > (u-w))

{...}

else if (-5 < (v-w) && 5 > (v-w))

{...}
MC_PosMan
MC_PosMan() function sends two pulses with opposite directions and by comparing
these two values understands the direction of the rotor. The direction of the two pulses
differ depending on the mot_ang value as seen below.

if ((2 == mot_ang) || (3 == mot_ang) || (4 == mot_ang) || (5 == mot_ang))

// esce da W, entra in U
while((count_u < 50 ) || ((abstotal < HIGH_CP) && (count_u < 200)))

// esce da U, entra in W
while((count_wu < 50 ) || ((abstotal < HIGH_CP) && (count_wu <
200)))

else if ((1 == mot_ang) || (7 == mot_ang) || (10 == mot_ang) ||


(12 == mot_ang))

// esce da U, entra in V
while((count_v < 50 ) || ((abstotal < HIGH_CP) && (count_v < 200)))

// esce da V, entra in U
while((count_uv < 50 ) || ((abstotal < HIGH_CP) && (count_uv <
200)))
else if ((6 == mot_ang) || (8 == mot_ang) || (9 == mot_ang) ||
(11 == mot_ang))

// esce da V entra in W
while((count_w < 50 ) || ((abstotal < HIGH_CP) && (count_w < 200)))

// esce da W entra in V
while((count_vw < 50 ) || ((abstotal < HIGH_CP) && (count_vw <
200)))

The necessary comparisons are done in the if statements respectively. These three
graphs show the resuts of the count_(u, v, w,wu,uv,vw) values on their respective positions
to better explain the reason for the comparisons. The HIGH_CP value is 47.0f.

1) if ((2 == mot_ang) || (3 == mot_ang) || (4 == mot_ang) || (5 == mot_ang))


2) else if ((1 == mot_ang) || (7 == mot_ang) || (10 == mot_ang) ||
(12 == mot_ang)

3) else if ((6 == mot_ang) || (8 == mot_ang) || (9 == mot_ang) ||


(11 == mot_ang))

For example if we get (2) for the mot_ang value, count_u and count_wu values are
compared. If count_u is bigger than count_wu the angle must be 0o-30o (2) and if count_wu is
bigger than count_u the angle must be 180o-210o (14) as seen in the graph. This can be seen
in the code as;
if (2 == mot_ang) //0-30
{
if (count_u > count_wu)
{
mot_pos = 2;
}
else if (count_wu > count_u)
{
mot_pos = 14;
}
}
Mot_ang Comparison Mot_pos
u > wu 2
2
wu > u 14

u > wu 3
count_u 3
wu > u 15
count_wu
u > wu 4
4
wu > u 16

u > wu 5
5
wu > u 17

uv > v 1
1
v > uv 13

uv > v 7
7
count_v v > uv 19

count_uv v > uv 10
10
uv > v 22

v > uv 12
12
uv > v 24

vw > w 6
6
w > vw 18

vw > w 8
8
count_w w > vw 20

count_vw vw > w 9
9
w > vw 21

w > vw 11
11
vw > w 23

Same principle applies to other cases. The reason for having different directions is
after looking at the results of the all six pulses we chose the best direction of the three to
compare the results. We also do not send any unneeded pulses. After the comparisons we
get a mot_pos value.
Keep in mind that one of the count_u, count_v or count_w values will be
overwritten in this function.
MC_PosMan() function has the same principle that is in MC_Step() and
MC_AngMan() functions combined. This means that while modifying the code for a
different motor we can change the HIGH_CP in the same way explained in MC_Step for
LOW_CP.

Conclusion
Now that we have the mot_pos value, as explained in the start with the switch case
we can assign the corresponding number to its angle and write that value to SystemPhase,
FluxPhase and Phase_est for the startup of the motor.
Angle of the Rotor mot_ang mot_pos

0 1 1

0-30 2 2

30 3 3

30-60 4 4

60 5 5

60-90 6 6

90 7 7

90-120 8 8

120 9 9

120-150 10 10
150 11 11

150-180 12 12

180 1 13

180-210 2 14

210 3 15

210-240 4 16

240 5 17

240-270 6 18

270 7 19

270-300 8 20

300 9 21

300-330 10 22

330 11 23

330-360 12 24

You might also like