Boost Converter – Simulink Model Using MATLAB Embedded Function

In this post, I am going to talk about modelling dc-dc power converters using MATLAB’s user defined function block. Doing so saves a lot of time and it’s much more easier as compared to the Buck converter model in which each dynamical equation is implemented using blocks. Doing so is not only time consuming, but tracking back and finding out errors is hard especially when the system becomes larger. In this model, I have used as few blocks as possible.

The Boost converter circuit is shown in fig.1. I have accounted for the parasitic resistance in passive components as well as the ON resistance for active device.

Fig. 1: Boost converter circuit

Inputs the converter model are:

  • Input voltage V_g
  • Voltage control (duty cycle) d
  • Load current i_{out}

Converter outputs:

  • Capacitor voltage v_C
  • Inductor current i_L
  • Output voltage V_{out}
  • Input current I_g

Step 1:

  • Start Simulink either using the MATLAB command window or by clicking the Simulink button on the toolbar
  • Create a new Simulink model file and save it as boost.mdl
  • From the Simulink place 3 instances of constant block located under “commonly used blocks”. Also place a subsystem block as well a scope block.

At this point your model file will look something like fig. 2. Notice that I have renamed the blocks to identify their respective characteristic.

Fig. 2: Initial set up for Boost converter model

Step – 2:

  • Open the Boost converter subsystem block by double clicking on it.

Notice the default connection between in1 and out1. Delete this connection.

  • Add 2 more instances of In1 and 3 more instance of Out1 found under commonly used block
  • Add an instance of subsystem, mux, and demux found under commonly used block
  • Navigate to user-defined functions and add a MATLAB Function block to your model file
  • Go to the continuous library and add 2 instances of integrator block to your model file.

Make the connections as shown in fig.3 and rename your blocks appropriately. Notice that by default mux block has 2 inputs and demux has 2 outputs. This can be changed by double clicking on the respective blocks and changing the number of inputs/outputs

Fig. 3: Boost converter subsystem block

Step – 3:

  • Open the PWM system block, and delete the default connection between In1 and Out1
  • Add a repeating sequence block found under Sources
  • Go to Math library and add a subtract block
  • Finally from the discontinuous library add a relay block and make the necessary connection as shown in fig. 2

Fig. 4: PWM subsystem block

Open the repeating sequence block by double clicking. This block lets you set up switching frequency for the converter as well as the amplitude V_M for the PWM signal. Rather than setting it to some default value, this parameters can be set as variables so that the user has control over changing them for different design.

Fig. 5: Setting parameters in repeating sequence block

Step – 4:

Going back to the user defined function, this is where we will enter the converter state equations. You can refer to the boost converter post to get an in-depth view of how these equations are derived.

When the MOSFET M_1 is on, the behavior of the converter can be captured by the following equations,

v_L = V_g - I_L\left(R_L + R_{on}\right)

i_C = - i_{out}

I_g = i_L

V = v_C - R_{ESR}i_{out}

Similarly, when MOSFET switches off, the equations are

v_L = V_g - I_LR_L - V

i_C = I_L - i_{out}

I_g = i_L

V = v_C + R_{ESR}\left(I_L - i_{out}\right)

Over one switching period T_s, the equations can be combined and represented as follow:

Inductor voltage,

v_L = \left[V_g - I_L\left(R_L + R_{on}\right)\right]*D + \left(V_g - I_LR_L - V\right)\left(1 - D\right)

Capacitor current,

i_C = -i_{out}*D + \left(I_L - i_{out}\right)\left(1 - D\right)

Input current,

I_g = I_L*D + I_L*\left(1 - D\right)

Output voltage,

V = \left[v_C - R_{ESR}i_{out}\right]*D + \left[v_C + R_{ESR}\left(I_L - i_{out}\right)\right]*\left(1 - D\right)

Solving them, the equations simplify to,

v_L = V_g - V\left(1 - D\right) - I_L\left(R_L + R_{on}D\right)

i_C = I_L\left(1 - D\right) - i_{out}

I_g = i_L

V = v_C + R_{ESR}\left[I_L\left(1 - D\right) - i_{out}\right]

The above equations can be entered directly to our MATLAB function. The 5 inputs via mux are stored in an array format. The code should look something as follow:

function y = CCMBoost(u,L,C,RL,Ron,Resr)

% Inputs:
% u = [Vg D iout v_C i_L]
% Parameters:
% L, RL, C, Resr, Ron
% Outputs:
% y = [dv_C/C di_L/L Vo ig]

Vg = u(1);                  % Input voltage
D = u(2);                   % Switch control
iout = u(3);                % Load current
vC = u(4);                  % Capacitor voltage
iL = u(5);                  % Inductor current

dbar = 1-D;

% State equations
Vo = vC + Resr*((iL*dbar) - iout);          % Output voltage
Ig = iL;                                    % Input current
iC = (iL*dbar) - iout;                      % Capacitor current
vL = Vg - (Vo*dbar) - iL*((Ron*D) + RL);    % Inductor voltage

% Output
y = [iC/C vL/L Vo Ig];

Save the MATLAB function. Now we want the parameters be set as variables so that the user can change them. In order to do so, select edit data/ports under tools as shown in fig. 6

Fig. 6: User function parameters

In the next window, select you will find a list of your I/O ports as well as the parameters specified in the function file. Select the input port u and change it’s size to 5 so that it matches the input array.

Fig. 7: Changing data port u property

Also, change the scope of L, C, R_L, R_{ESR}, and R_{ESR} from input to parameter. This can be done simply by clicking on the respective input and selecting parameter from the drop down menu. At the end, your port manager window should look as follow:

Fig. 8: Port/Data Manager

Going back to the Boost subsystem block, you can set up initial conditions for the inductor current and capacitor voltage. In order to do so, open the capacitor integrator block, and type in a variable name under the initial condition field. Do the same for inductor integrator block as well. I have named them as vC_0 and iL_0.

Fig. 9: Configuring initial condition variable

Now, go back to the starting, open the scope block and open the scope parameters. Under general settings for scope parameters, change the number of axes to 4. Then under history uncheck limit data points to last. Click apply and connect the scope inputs to the boost converter outputs.

Fig. 10: Changing scope setting

Fig. 11: Final connections

Right click on the Boost subsystem block, and select mask subsystem. This will open mask editor where you can create a UI for the user to change the boost converter variables and parameters. In the mask editor, click on parameters tab. Then add all the variables via the add button. Make sure that the variable name matches the ones used within the subsystems. Your final mask window should look something as follow,

Fig. 12: Mask editor

Apply your settings and close the editor window. Now if you try and open the Boost converter subsystem block you will see a dialog box as follow,

Fig. 13: Setting parameters

I have set the parameters as follow:

Input voltage: V_g = 12 V

Required output voltage is 30 V. Hence,

Duty cycle, D = 1 - \frac{V_g}{V} = 1 - \frac{12}{30} = 0.6

Load resistance, R = 50 \Omega

Load current, i_{out} = \frac{V}{R} = \frac{30}{50} = 0.6 A

Switching frequency, f_s = 100 kHz

Inductance L = 120 \mu H

Inductor series resistance R_L = 10 m\Omega

Capacitance C = 50 \mu F

Capacitor series resistance R_{ESR} = 1 m\Omega

Switch on resistance, R_{on} = 10 m\Omega

PWM amplitude V_M = 1

Initial inductor current i_L(0) = 1.5 A

This value for inductor current was obtained using the fact that the average inductor current in a boost converter is given by I_L = \frac{V}{\left(1 - D\right)R}

Initial capacitor voltage v_C(0) = 30 V

You can even leave the initial condition set to 0.

Now that all the parameters are configured, its time to simulate and verify that our model produces the expected result. Save your design and go to configure parameters under simulation. I have set the stop time to 100 ms and step size to 1 \mu s.

Fig. 14: Simulation parameter

Now run the simulation. If everything works out properly, then you will get the following result.

Fig. 15: Simulation result

I hope that it all works out for you. In case it didn’t then you can download this file and rename the extension from Boost.pdf to Boost.mdl and re-run the simulation or figure out your error.


Buck Converter – Open Loop Simulink Model

Simulating is a big part of design verification, so this post will deal with creating a model of an open loop synchronous buck converter using MATLAB and Simulink, which can be used to perform transient analysis. The equations governing the operation of a synchronous buck converter shown in fig. 1 are:

\frac{di_L}{dt} = \frac{1}{L}\left(V_g*d - i_L*R_L - v_o\right)

\frac{dv_c}{dt} = \frac{1}{C}\left(i_L - i_o\right)

v_o = v_C + ESR\left(i_L - i_o\right)

Fig. 1: Synchronous Buck Converter

Modelling such a converter using Simulink is quite simple. As shown in fig. 2, the input to model are:

Input voltage,V_g

Duty cycle,d

Load current, i_{load} \left(i_o\right)

Whereas the outputs of the system are:

Voltage across the load, V_o

Inductor current, i_L

Fig. 2: Switching converter model (Fundamentals of power electronics, Robert Erickson)

Simulink Model:

Click my_syncbuck_ol to download the simulink model file, then change the file extension from .pdf to .mdl. From the top level view shown in fig. 3, you can change the values of input voltage, duty cycle, and load resistance according to your system parameters.

Fig. 3: Top Level View

Double clicking on the “Buck converter – open loop” block opens up another window with two more subsystem blocks. Clicking on any of these subsystems will allow you to change their respective parameters. In order to access the underlying lower levels, right click on the block and select “Look under mask” from the menu.

Fig. 4: Mid-level subsystems

  • PWM Subsystem:Allows you to change the switching frequency as well as the amplitude of the PWM ramp signal.

Fig. 5: PWM Subsystem

  • Buck converter Subsystem: Allows you to change the values for inductance and capacitance, along with their parasitic resistances. This is the block where we implement the system equations described earlier.

Fig. 6: Buck Converter Subsystem

Once you have all the parameters setup, you can run the simulation. Fig. 7 shows a screenshot of the simulation result, which can be accessed from the scope block located in the top level view.

Fig. 7: Simulation Result

Continuous Time Periodic Signal

Continuous time signals are basically analog signals, which occur all around us in nature. Even though most of the signal processing is done in digital domain these days, we still need to convert the output waveform back to continuous time analog signals for the human beings to perceive them.

In this post, I am going to describe how we can use MATLAB to approximate a continuous time periodic signal using exponential Fourier series. Although, bear in mind that, for a Fourier series to exists, the signals must satisfy certain criteria, which might be discussed in upcoming posts.

The general form of an exponential Fourier series is,

Let’s assume that we wish to approximate the periodic signal shown in fig. 1 which has a period of 2.

Fig. 1

First of all, lets determine the expression for computing the co-efficients of the FS. We know that the period of the square wave is T = 2 sec. So,

The above expression for X_k will be useful to compute the co-efficients of the Fourier series. So, let’s go ahead, and see how we can use MATLAB to approximate x_t.


% Approximating a periodic square wave using exponential fourier series

clear all; clc; clf;

N = 8000;                   % # of sample pts
T = 2;                      % Period of x(t)
Wo = 2*pi/T;                % Fundamental freq.
Ts = 0.001;                 % Sampling period
t = 0:Ts:(N-1)*Ts;          % Time vector

x_t = zeros(1,N);           % Initializing
K = 5;                      % # of terms in FS

for k = -K:1:K;
  W = k*Wo;
     if k == 0
        X_k = 0;
        X_k = [1/(i*2*pi*k)]*[exp(-i*2*pi*k) - 2*exp(-i*pi*k) + 1];
  x_t = x_t + X_k*exp(i*W*t);

x_t_real = real(x_t);

plot(t, x_t_real);
grid on;
title('Approximation of a periodic waveform using exponential FS')

The waveform generated is,

Fig. 2: Square wave approximation with 5 terms

Obviously, this doesn’t appear to be a perfect square wave. There are squiggles at places where we expect a constant amplitude of 1 or -1. Even the transition at the point of discontinuity does not appear to be a perfect vertical line, rather it has some slope, implying a delay such as that of a ramp function. Bear in mind, that an approximation can be as good as our model, and that the chance of approximating a perfect square wave in this case is next to zero. So, the obvious question which might arise is that what can we do to have a better approximation?

The answer to this question is a simple one. All we need to do is consider more terms while approximating the signal. As we increase the number of terms (change K in the script), the approximation appears to get better and better, and this is shown in fig 3.

Fig. 3: Approximation (clockwise) K = 5, 10, 50, 25

As we can observe from the above plots, when we increase the number of terms in our FS, the approximation appears to get much better. Although, we still notice that the squiggles at the jump discontinuity still persists. This is something known as Gibbs Phenomenon, which will be discussed in one of the upcoming posts.

Now that we have looked at some of the aspects of the exponential FS, let’s see what’s going on in the MATLAB script shown above.

clear all; clc; clf;

N = 8000;                   % # of sample pts
T = 2;                      % Period of x(t)
Wo = 2*pi/T;                % Fundamental freq.
Ts = 0.001;                 % Sampling period
t = 0:Ts:(N-1)*Ts;          % Time vector

This part of the code defines all the required parameters to compute the FS co-efficients and approximate x(t). This part of the code be compared to variable declaration and initialization blocks found in Java or C++. For our approximation, we will be taking N samples of x(t) at every Ts second for the entire length. Hence, we will have T/Ts samples for each period.

x_t = zeros(1,N);           % Initializing
K = 5;                      % # of terms in FS

for k = -K:1:K;
  W = k*Wo;
  if k == 0
     X_k = 0;
     X_k = [1/(i*2*pi*k)]*[exp(-i*2*pi*k) - 2*exp(-i*pi*k) + 1];
  x_t = x_t + X_k*exp(i*W*t);

x_t_real = real(x_t);

plot(t, x_t_real);
grid on;
title('Approximation of a periodic waveform using exponential FS')

The declaration of x(t) creates a row vector of N elements, with each element initialized to zero. Let’s take a look at the crazy looking FOR loop. The very first statement in the FOR loop, k = -K:1:K, declares the condition for which the loop is valid. For K = 5, the first iteration of the loop starts at k = -5. At the end of each iteration, the value of k is incremented by 1. At the end of the last iteration, k equals the number of terms in approximation.

One might think, that the approximation is 11 terms and not 5 terms as indicated by the value of K. So what the heck is going on? Just remember that an exponential FS is a complex series, and like all complex quantities, each term in an exponential FS has a complex conjugate. The terms on the negative side are just conjugate components to their counterparts on the positive side. Moreover, the term related to k = 0, can be though of as the DC Offset, with respect to the time axis in this case. If X_k were to be a different than 0 for k = 0, then the waveform would have be simply shifted up for X_k > 0, and shifted down for X_k < 0. For this particular example, I have used 0 DC offset, so that the output is centered around the x-axis.

Obviously, this is not the only we in which we can approximate the periodic waveform. There are plenty of algorithms which one might explore. Rather than deriving the expression for the co-efficient by hand, we can just use the built in MATLAB integration function and embed that in the scripting file.

By eprimes Posted in MATLAB