This technical note addresses a widespread current control technique for three-phase AC currents, which uses a rotating reference frame, synchronized with the grid voltage (dq-frame).

First, the note introduces the general operating principles of vector current control and then details a possible design methodology.

Then, an example of vector current control for a two-level inverter is provided. A possible control implementation on the B-Box RCP or B-Board PRO is introduced for both C/C++ and Simulink/PLECS implementations.

Finally, simulation and experimental results are compared and discussed.

Software resources

  File Modified
File inverter_PlecsViewer_2015a.slx Simulink file, Matlab 2015a with Plecs Viewer Apr 13, 2020 by Gabriel Fernandez
File inverter.slx Original Simulink file, Matlab 2017a and Plecs blockset are required. Apr 13, 2020 by Gabriel Fernandez
File parameters.m Matlab file containing all the parameters of the system. Apr 13, 2020 by Gabriel Fernandez

General principles

In DC applications, conventional PI controllers provide excellent performance, notably minimal steady-state error, thanks to the (almost) infinite DC gain provided by the integral control action. However, in AC applications, PI controllers inevitably present a delayed tracking response, because their gains cannot be set high enough to avoid a steady-state error.

A well-known countermeasure to this shortcoming is the implementation of the PI controller(s) within a rotating reference frame (dq), which allows to “re-locate” the (almost) infinite DC gain at the desired frequency. This technique requires the rotating reference frame to be synchronized with the grid voltage, which is often achieved using a phase-locked loop PLL.

The implementation of PLL techniques is notably addressed in:
- TN103: DQ-type PLL: a standard technique for most applications
- TN104: SOGI-based PLL: a more advanced technique for distorted or unbalanced conditions.

In practice, once the reference frame is established, the use of the Clarke and Park transformations allow projecting all stationery quantities (abc) into direct and quadrature quantities (dq). The control of the AC current becomes therefore transformed into a new control scenario, consisting of two DC currents. Both currents can then be controlled using conventional PI controllers, with zero steady-state error.

Conventional PI-based current control is presented in TN105: Basic PI control implementation.

Inverter current control example

In this note, it is proposed to study the vector current control of a two-level inverter. This example features two state variables, the grid current on the d-axis \begin{array}{l}I_{g,d}\end{array} and on the q-axis \begin{array}{l}I_{g,q}\end{array}.

General Kirchhoff circuit laws allow us to determine the following equations:

\begin{aligned}[c] E_{a} &= R_g I_{g,a} + L_g \frac{di_{g,a}}{dt} + V_{g,a} \\ E_{b} &= R_g I_{g,b} + L_g \frac{di_{g,b}}{dt} + V_{g,b} \\ E_{c} &= R_g I_{g,c} + L_g \frac{di_{g,c}}{dt} + V_{g,c} \end{aligned} \qquad\Longleftrightarrow\qquad \begin{aligned}[c] E_{d} &= R_g I_{g,d} + L_g \frac{di_{g,d}}{dt} -\omega_g L_g I_{g,q} + V_{g,d} \\ E_{q} &= R_g I_{g,q} + L_g \frac{di_{g,q}}{dt} +\omega_g L_g I_{g,d} + V_{g,q} \end{aligned}

In the Laplace domain, this translates into:

\begin{aligned}[c] I_{g,d} = \frac{1}{R_g + s L_g} (E_d - V_{g,d} + \omega_g L_g I_{g,q}) \\ I_{g,q} = \frac{1}{R_g + s L_g} (E_q - V_{g,q} - \omega_g L_g I_{g,d}) \\ \end{aligned}

System-level modeling

A widely-accepted model for the proposed system is shown below. Four distinct parts can be clearly identified.


The inductor is modeled as:

\begin{array}{l}P_1(s) = \displaystyle\frac{K_1}{1+s T_1} \qquad &\text{with} \qquad &\begin{cases}K_1 = 1/R_g \\ T_1 = L_g/R_g \end{cases}\end{array}


The measurements of the currents \begin{array}{l}I_{g,abc}\end{array}are generally modeled using a low-pass filter approximation, or they are neglected. The sampling corresponds to a zero-order hold (ZOH) that introduces a lag corresponding to the sampling delay.


The control algorithm consists of two digital PI controllers followed by some basic mathematics operations to compute the duty cycles. The whole algorithm requires a certain amount of computation time, which is modeled as a delay.


The Pulse-Width Modulation (PWM) is also generally modeled as a simple delay.

Tuning and performance evaluation

Different methods are proposed in the literature to determine the parameters of a PI controller. Those methods are well detailed and explained in [1]. In this note, the Magnitude Optimum (MO) will be used.

The goal of the MO is to make the frequency response from reference to the plant output as close to one as possible for low frequencies. The controller parameters are defined accordingly as:

\begin{aligned} &T_n = T_1 \\ &T_i = 2 K_1 T_d\\ & \text{and}\\ &K_p = T_n /T_i \\ &K_i = 1 / T_i \end{aligned}

The parameter \begin{array}{l}T_d\end{array} represents the sum of all the small delays in the system, such as the sampling delay or the modulation delay mentioned above. The product note PN142: Time delay determination for closed-loop control explains how to determine the total delay of the system.

Academic references

[1] Karl J. Åström and Tore Hägglund; “Advanced PID Control”; 1995

B-Box / B-Board implementation

C/C++ code

The imperix IDE provides numerous pre-written and pre-optimized functions. Controllers such as P, PI, PID and PR are already available and can be found in the controllers.h/.cpp files.

As for all controllers, PI controllers are based on:

  • A pseudo-object PIDcontroller, which contains pre-computed parameters as well as state variables.

  • A configuration function, meant to be called during UserInit(), named ConfigPIDController().

  • A run-time function, meant to be called during the user-level ISR, such as UserInterrupt(), named RunPIController().

Implementation example

#include "../API/controllers.h"
PIDController mycontroller_d;
PIDController mycontroller_q;

float Kp = 10.0;
float Ki = 500.0;
float limup = 500;
float limlow = -500;

tUserSafe UserInit(void)
	ConfigPIDController(&mycontroller_d, Kp, Ki, 0, limup, limlow, SAMPLING_PERIOD, 0);
	ConfigPIDController(&mycontroller_q, Kp, Ki, 0, limup, limlow, SAMPLING_PERIOD, 0);
	return SAFE;
tUserSafe UserInterrupt(void)
	//... some code
	Ucd_ref = RunPIController(&mycontroller_d, Igd_ref - Igd) + Vgd - w*L*Igq;
	Ucq_ref = RunPIController(&mycontroller_q, Igq_ref - Igq) + Vgq + w*L*Igd;
	//... some code
	return SAFE;

Simulink implementation

The attached file provides a typical current control implementation.

PLECS implementation

The included file for PLECS also provides a PI controller block. The default PI block of the PLECS library can be used as well.


The vector current control was tested with a grid-connected inverter. A current reference step on both the d-axis and the q-axis was performed in simulation and experimental modes. The following graphs show a comparison between both results:

Small differences can be observed between the simulation and the experimental results, which can be explained by the following facts:

  • In simulation, the variable transformer is not taken into account (modeled). The transformer increases the total inductance between the converter and the grid, which in turn increases the inertia of the system.

  • The EMC filter used to reduce the common-mode current is also not modeled in the simulation.

A ripple can be observed on the grid currents in dq-axis. The frequency of the ripple is 300Hz, or 6 times the output fundamental frequency. This phenomenon can be reproduced in simulation by properly taking into account the effect of the dead-time between the complementary PWM signals. In the imperix CB-PWM block, this can simply be achieved by activating the simulation of dead-times.

The simulation of dead-times allows a slightly better accuracy but significantly slows down the simulation. The following picture shows a comparison between the new simulation and the experimental results:

  • No labels