Home
General Guide
Register File
Boot Sequence
BLDC Motor FOC
Serial Comm Driver
Flash Driver
NVRAM Driver
RVDT Driver
Renesas
Microchip
Texas Instruments
Analog Devices
Mobile Devices
.NET Tips
Miscellaneous
Contact Us
Forum

 

Brushless DC Motor Field Oriented Control

1. Introduction

 

Is controlling Brushless DC (BLDC) motor mysterious to you? BLDC motor is essentially a three-phase AC motor driven by a DC source, which is converted to three-phase alternating currents supplying to three stator windings of a BLDC motor by an Electronic Control Unit (ECU). In order to drive a BLDC motor smoothly, an ECU shall be designed such that the stator current space vector, which is the sum of the three phase currents, shall be always in the quadrature direction with respect to the rotor and has constant magnitude, irrespective of rotation speed and back EMF frequency. This results in maximum torque and minimum torque ripple. Field Oriented Control (FOC) technology can be used to achieve this goal. In FOC, motor stator currents and voltages are manipulated in the direct-quadrature (d-q) reference frame of the rotor, which means that the stator current feedback must be mathematically transformed from the three-phase static reference frame of the stator windings to the two axis rotating d-q reference frame of the rotor, by using Clarke transform and Park transform, prior to PI processing. Figure 1 shows the stator space vector and its projections on α – β axis and d – q axis respectively.

                                                                                       

Figure 1 - Stator current space vector and its projections on α – β and d – q axes

 

On the contrary, the voltages to be applied to the stator windings must be mathematically transformed from the d-q frame of the rotor to the three-phase reference frame of the stator, by using inverse Park transform and inverse Clarke transform, before they can be used for PWM output. Figure 2 is the diagram of velocity/current control loop using FOC technology. 

 

Figure 2 - Velocity/Current Control Loop Diagram Using FOC Technology

 

Due to the mathematical transformations, a high performance DSP, especially a floating-point type DSP, would be needed. Besides, it is necessary to get the accurate measurement of the rotor position. Some angle feedback device such as resolver along with resolver-to-digital converter (RDC) can be used for that purpose. A 16-bit resolution RDC contributes much greater performance to 12-bit resolution RDC.

The following code shows how to implement Clarke transform, Park transform, inverse Park transform, and inverse Clarke transform.


 

2. Source Code

 

The FOC code consists of four functions, FOC_ClarkeTransform(), FOC_ParkTransform(), FOC_InvParkTransform() and FOC_InvClarkeTransform().

 

2.1. FOC_ClarkeTransform

 

FOC_ClarkeTransform() function converts the three phase currents (Ia, Ib, Ic) from feedback to two-phase currents (Iα, Iβ) according to Clarke Transform theory.

 

/*********************************************************************************************
* Function: FOC_ClarkeTransform
*
* Desc: This function performs Clarke Transform to convert three phase currents
* to alpha / beta domain currents.
*
* Params: FocThreePhaseCurrent currents
*
* Returns: FocTwoPhaseCurrent
*
* Notes: Clarke transform equations:
* Isalpha = Ia
* Isbeta = 1 / sqrt(3) * Ia + 2 / sqrt(3) * Ib
* Ia + Ib + Ic = 0
*
*********************************************************************************************/

FocTwoPhaseCurrent FOC_ClarkeTransform(FocThreePhaseCurrent currents)
{
    FocTwoPhaseCurrent clarkeCurrents;

    // Clarke Transform : convert 3 phase currents to alpha-beta domain currents
    clarkeCurrents.Isalpha = currents.Ia;
    clarkeCurrents.Isbeta = (currents.Ia + currents.Ib * 2) * INV_SQRT3;

    return clarkeCurrents;
}

 

2.2. FOC_ParkTransform

 

FOC_ParkTransform() function converts the two phase currents (Iα, Iβ) from α – β domain to D – Q domain currents (Id, Iq) according to Park Transform theory.

 

/*********************************************************************************************
* Function: FOC_ParkTransform
*
* Desc: This function performs Park Transform to convert two phase currents to DQ domain currents
*
* Params: FocTwoPhaseData currents
*
* Returns: FocDQData
*
* Notes: Clarke transform equations:
* Isd = Isalpha * cos(theta) + Isbeta * sin(theta)
* Isq = -Isalpha * sin(theta) + Isbeta * cos(theta)
*
*********************************************************************************************/

FocDQCurrent FOC_ParkTransform(FocTwoPhaseCurrent currents, float theta)
{
    FocDQCurrent dqCurrent;
    SineCosineData posMotor;

    //get sine and cosine values of the motor position
    posMotor = FOC_GetPosSineCosine(theta);

    //Park Transform : phase alpha-beta frame currents to DQ frame currents
    dqCurrent.Isd = currents.Isalpha * posMotor.Cosine + currents.Isbeta * posMotor.Sine;
    dqCurrent.Isq = currents.Isbeta * posMotor.Cosine - currents.Isalpha * posMotor.Sine;

    return dqCurrent;
}

 

2.3. FOC_InvParkTransform

 

FOC_InvParkTransform() function performs inverse Park transform of voltages in D-Q domain (Vd, Vq) to voltages in α – β domain (Vα, Vβ). Vd and Vq shall be obtained from current PI module.

 

/*********************************************************************************************
* Function: FOC_InvParkTransform
*
* Desc: This function performs inverse Park Transform to convert DQ voltages to two phase voltages
*
* Params: FocTwoPhaseData currents
*
* Returns: FocDQData
*
* Notes: Inverse Park transform equations:
* Vsalpha = Vsd * cos(theta) - Vsq * sin(theta)
* Vsbeta = Vsd * sin(theta) + Vsq * cos(theta)
*
*********************************************************************************************/
FocTwoPhaseVoltage FOC_InvParkTransform(FocDQVoltage dqVolts, float theta)
{
    FocTwoPhaseVoltage twoPhvolts;
    SineCosineData posMotor;

    //get sine and cosine values of the motor position
    posMotor = FOC_GetPosSineCosine(theta);

    //inverse Park Transform: phase alpha-beta frame voltages to DQ frame voltages
    twoPhvolts.Vsalpha = dqVolts.Vsd * posMotor.Cosine - dqVolts.Vsq * posMotor.Sine;
    twoPhvolts.Vsbeta = dqVolts.Vsd * posMotor.Sine + dqVolts.Vsq * posMotor.Cosine;

    return twoPhvolts;
}


 

2.4. FOC_InvClarkeTransform

 

FOC_InvClarkeTransform() function performs inverse Clarke transform to decode the sector number and normalized voltages (Va, Vb, Vc) of commutation that are used to determine PWM duty cycles.

 

/*********************************************************************************************
* Function: FOC_InvClarkeTransform
*
* Desc: This function inverses Clarke transform to decodes sector number and Va, Vb, Vc
*
* Params: FocTwoPhaseVoltage twoPhVolts
*
* Returns: InvClarkeData
*
* Notes: Inverse Clarke transform equations:
* Va = Vsbeta
* Vb = (sqrt(3) * Vsalpha - Vsbeta) / 2
* Vc = (-sqrt(3) * Vsalpha - Vsbeta) / 2
*
*********************************************************************************************/
InvClarkeData FOC_InvClarkeTransform(FocTwoPhaseVoltage twoPhVolts)
{
    FLOAT32 halfVsbeta, halfSqrt3Vsalpha;
    INT32 sector;
    InvClarkeData invData;

    // compute Vsalpha / 2 = Vsalpha * 0.5
    halfVsbeta = twoPhVolts.Vsbeta * 0.5;


    // compute Vsalpha * (sqrt(3)/2) = Vsalpha * 0.8660254
    halfSqrt3Vsalpha = twoPhVolts.Vsalpha * 0.8660254;

    // compute Va, Vb, Vc
    invData.Va = twoPhVolts.Vsbeta;
    invData.Vb = halfSqrt3Vsalpha - halfVsbeta;     //Vb = ((sqrt(3)Vsalpha - Vsbeta ) / 2
    invData.Vc = -halfSqrt3Vsalpha - halfVsbeta;    //Vc = (-(sqrt(3)Vsalpha - Vsbeta ) / 2

    //decode sector number
    sector = 0;

    if (invData.Va > 0.0)
    {
        sector = 1;
    }

    if (invData.Vb > 0.0)
    {
        sector += 2;
    }

    if (invData.Vc > 0.0)
    {
        sector += 4;
    }

    return invData;
}

 

3. Source Code Download

 

The FOC complete source code can be downloaded here.

 

    ES_FOC.c

    ES_FOC.h