0% found this document useful (0 votes)
39 views226 pages

Digital Control of Power Converters Using Arduino and an STM32

This document is a guide on implementing digital control algorithms for power converters using STM32 microcontrollers and Arduino. It covers topics such as digital control theory, control algorithm design, and practical tutorials with code examples to aid understanding. The book is aimed at students and professionals interested in applying digital control techniques in power electronics systems.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views226 pages

Digital Control of Power Converters Using Arduino and an STM32

This document is a guide on implementing digital control algorithms for power converters using STM32 microcontrollers and Arduino. It covers topics such as digital control theory, control algorithm design, and practical tutorials with code examples to aid understanding. The book is aimed at students and professionals interested in applying digital control techniques in power electronics systems.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 226

Digital Control of

Power Converters Using


Arduino and an STM32
Microcontroller

This concise and accessible guide equips readers with the knowledge
and skills needed to implement digital control algorithms to design effi-
cient and reliable power converters using STM32 microcontrollers.
Through this book, Majid Pakdel covers a range of topics including
digital control theory, switching converters theory, the design and imple-
mentation of control algorithms (such as proportional–integral–deriva-
tive and advanced digital control techniques), programming of STM32
microcontrollers, and interfacing with power electronics components.
He also provides step-­by-­step tutorials and code examples to help read-
ers understand and implement the concepts in their own projects.
Readers will gain a deep understanding of digital control techniques in
power converters, learn how to program STM32 microcontrollers for
control applications, and be able to design and implement their own
digital control algorithms in power electronics systems. The practical
examples provided in the book will help readers apply the knowledge
gained to real-­world projects and improve their skills in developing digi-
tal control systems.
The information within is useful for young professionals and stu-
dents aiming at experimental implementation on a microcontroller
platform of a control algorithm for power converters. To fully benefit
from the practical examples demonstrating digital controller imple-
mentation on the STM32, readers should have a solid understanding of
power switching converter topologies, modeling, and control.
Majid Pakdel earned a bachelor’s degree at Amirkabir University
of Technology in 2004, a master’s degree at Isfahan University of
Technology in 2007, a PhD in electrical power engineering at the
University of Zanjan in 2018, and a further master’s degree in AI and
robotics at Malek Ashtar University of Technology in 2023.
Digital Control of
Power Converters
Using Arduino and an
STM32 Microcontroller

Majid Pakdel
Designed cover image: Microcontrollers, PCB electrical boards, semiconductor micro-
chip technology computers machine, circuit electronics concept hardware pi chip, neat
vector illustration of electronic technology component; Shutterstock.
MATLAB® and Simulink® are trademarks of The MathWorks, Inc. and are used with per-
mission. The MathWorks does not warrant the accuracy of the text or exercises in this book.
This book’s use or discussion of MATLAB® or Simulink® software or related products does
not constitute endorsement or sponsorship by The MathWorks of a particular pedagogical
approach or particular use of the MATLAB® and Simulink® software.
First edition published 2025
by CRC Press
2385 NW Executive Center Drive, Suite 320, Boca Raton FL 33431
and by CRC Press
4 Park Square, Milton Park, Abingdon, Oxon, OX14 4RN
CRC Press is an imprint of Taylor & Francis Group, LLC
© 2025 Majid Pakdel
Reasonable efforts have been made to publish reliable data and information, but the
author and publisher cannot assume responsibility for the validity of all materials or the
consequences of their use. The authors and publishers have attempted to trace the copy-
right holders of all material reproduced in this publication and apologize to copyright
holders if permission to publish in this form has not been obtained. If any copyright
material has not been acknowledged please write and let us know so we may rectify in
any future reprint.
Except as permitted under U.S. Copyright Law, no part of this book may be reprinted,
reproduced, transmitted, or utilized in any form by any electronic, mechanical, or other
means, now known or hereafter invented, including photocopying, microfilming, and
recording, or in any information storage or retrieval system, without written permission
from the publishers.
For permission to photocopy or use material electronically from this work, access ​w ww.​
copyright.​com or contact the Copyright Clearance Center, Inc. (CCC), 222 Rosewood
Drive, Danvers, MA 01923, 978-750-8400. For works that are not available on CCC
please contact [email protected]
Trademark notice: Product or corporate names may be trademarks or registered trade-
marks and are used only for identification and explanation without intent to infringe.
ISBN: 978-1-032-89038-8 (hbk)
ISBN: 978-1-032-89137-8 (pbk)
ISBN: 978-1-003-54135-6 (ebk)
DOI: 10.1201/9781003541356
Typeset in Minion
by SPi Technologies India Pvt Ltd (Straive)
Contents

Preface, vii

Chapter 1   ◾    Digital Control with Arduino 1


1.1 INTRODUCTION 1
1.2 ADVANTAGES OF DIGITAL CONTROL 2
1.3 OVERVIEW OF THE Z-TRANSFORM 7
1.4 DISCRETIZATION OF CONTINUOUS-
TIME SYSTEMS 14
1.5 ARDUINO IMPLEMENTATION OF
DISCRETE-TIME SYSTEMS 19
1.6 DIGITAL FEEDBACK CONTROL ALGORITHM 35
1.7 DIGITAL CONTROLLER DESIGN (SIX STEPS) 40
1.8 DC MOTOR SPEED CONTROL 49

Chapter 2   ◾    Theoretical Overview of the Buck


Converter 81
2.1 BUCK CONVERTER DESIGN 81
2.2 THE CONTROLLER DESIGN WITH OCTAVE 107

v
vi   ◾    Contents

Chapter 3   ◾    Digital Control Implementation of the


Buck Converter 118
3.1 HARDWARE OUTLINE 118
3.2 FIRMWARE PERIPHERAL
INITIALIZATION WITH CUBEMX 121
3.3 MANUAL FIRMWARE INITIALIZATION 124
3.4 FIRMWARE IMPLEMENTATION OF
VOLTAGE CONTROL 129
3.5 FIRMWARE IMPLEMENTATION OF
CURRENT CONTROL 134
3.6 AVERAGE CURRENT MODE CONTROL
OF THE BUCK CONVERTER 139

Chapter 4   ◾    Digital Control Implementation with


PLECS 150
4.1 INTRODUCTION 150
4.2 DESIGNING A CLOSED-LOOP
CONTROLLER IN PLECS AND MATLAB 151
4.3 CODE GENERATION FOR THE STM32
NUCLEO-G474RE IN PLECS 165
4.4 REVIEW OF SMALL SIGNAL ANALYSIS
TOOLS FOR CONTROLLER DESIGN
IN PLECS 179

REFERENCES, 208

INDEX, 209
Preface

In recent years, power converters have become an integral part of


modern electronics, providing efficient and reliable energy con-
version for a wide range of applications. With the advancement
of digital control technology, there is a growing interest in using
microcontrollers such as Arduino and STM32 to implement con-
trol algorithms for power converters.
This book aims to provide a comprehensive guide to under-
standing and implementing digital control of power converters
using Arduino and STM32 microcontrollers. It covers the funda-
mental principles of the design and implementation of control
algorithms, and practical examples of real-­world applications.
Whether you are an electrical engineering student, researcher,
or practicing engineer, this book will help you develop the neces-
sary skills to design and implement digital control systems for
power converters. Through a combination of theoretical concepts
and hands-­on examples, you will gain a deep understanding of
the principles and techniques required to successfully implement
digital control systems in your own projects.
The author hopes this book will serve as a valuable resource for
anyone interested in learning about digital control of power con-
verters using Arduino and STM32 microcontrollers. Happy read-
ing and happy experimenting!

vii
CHAPTER 1

Digital Control with


Arduino

1.1 INTRODUCTION
In this chapter, we’ll be showing you how you can design and
implement a digital controller on the Arduino to control or regu-
late a continuous-­time system. First, we’ll start off by discussing
the advantages of using digital control as opposed to the tradi-
tional analog control and will then briefly go over the Z-­transform
and discretization of continuous-­time systems. Then we’ll move
on to the six steps for designing and implementing a digital con-
troller on the Arduino and lastly, we’ll finish with designing a
digital controller for a direct current (DC) motor speed control
system. So, this chapter outline is as follows:

• Advantages of digital control


• Z-­Transform
• Discretization of continuous-­time systems (Tustin’s method)
• Implementation of discrete systems on the Arduino

DOI: 10.1201/9781003541356-1 1
2   ◾    Digital Control of Power Converters

• Digital controller design (Six steps)


• DC motor speed control example: obtaining the transfer
function
• DC motor speed control example: controller design
• DC motor speed control example: Arduino implementation

Now keep in mind like we said in this chapter’s description this is


not an introductory course on signal processing or controls. If
this is your first-­time hearing words such as Laplace and
Z-­transforms or sampling stability, then you should first seek out
this information elsewhere. This chapter is a practical tutorial
series made to bridge the gap between the theory and practice of
discrete-­time systems and control theory. Again, our goal is to
give you the tools needed to design a controller, how you will inte-
grate this into your design is 100% your responsibility to figure
out. Therefore, the disclaimer for this chapter is as follows.

• This is NOT an introductory course on LINEAR SYSTEMS,


CONTROL THEORY, DIGITAL SIGNAL PROCESSING,
ELECTRONICS, ETC.
• This is a practical tutorial course that will allow students,
engineers, and hobbyists to apply their known theoretical
knowledge of control theory and discrete-­time systems.
• We will not hold ourselves responsible for any explanation
of the basic fundamentals of linear systems and signals,
Arduino coding, and basic electronics. It is required you
have some exposure to these topics coming into reading this
chapter. So, let’s get on with this chapter.

1.2 ADVANTAGES OF DIGITAL CONTROL


Before we discuss why digital control is useful, let’s take a look at
analog control or continuous-­time controllers. Here we have a
Digital Control with Arduino   ◾    3

FIGURE 1.1 Analog or continuous-­time control system.

system block diagram of a control system where C(s) is our analog


controller driving our plant, P(s), to a desired set point as shown
in Figure 1.1.
Now decades ago, even sometimes today C(s) was designed
using purely discrete analog components typically consisting of
operational amplifiers. Therefore, we can say the traditional feed-
back systems (decades ago) relied on analog controllers or com-
pensators for closed-­ loop control. Whereas electronic-­ based
systems, they were mainly done using op-­amps. A good example
of this is a switch mode power supply topology known as the buck
converter as depicted in Figure 1.2.

FIGURE 1.2 The buck converter (step-­down converter) as an electrical


example.
4   ◾    Digital Control of Power Converters

A buck converter is a power electronic device whose job is to


step down the input voltage to a desired output voltage to supply
power to all sorts of electronic loads. The output voltage is
sensed through H(s) and compared to a desired output voltage
to then generate an error signal. This error signal is then fed to
our controller or C(s) which generates and sends a continuous
control voltage signal to the pulse-­w idth modulation (PWM)
driver driving the plant. The buck converter is duty cycle con-
troller with the relation Vo = D × Vi, where D varies between 0
and 1. The feedback controller C(s) drives the PWM duty cycle
value to keep the error at zero. However, let’s not overlook how
it operates. The point we’re trying to make is that this system is
entirely analog controlled as there is no digital or discrete cou-
pling between the blocks. Now if we take a look at the controller
C(s), we can see that it’s a type II compensator made out of just
one op-­a mp and a few resistors and capacitors as illustrated in
Figure 1.3.
The inverting and non-­inverting inputs of the op-­amp are effec-
tively the summing junction as seen in the feedback control system
blocks. Again, don’t get too caught up with understanding what’s
happening. The takeaway is that the analog control systems rely

FIGURE 1.3 The type II compensator (adds two poles and one zero into
control loop).
Digital Control with Arduino   ◾    5

only on analog components for their controller implementation


made entirely out of analog components, forming a 100% continuous-­
time coupled control loop and thus there are no time delays, sam-
pling delays, and quantization errors and they are also easier to
analyze and design using classical control techniques such as root
locus or Bode plot analysis. Now that’s all great. However, again
why use digital control if analog controls seem so sufficient? Well
with the use of analog control come some disadvantages. First,
they’re mainly composed of discrete analog components so if you
wanted to tweak your controller or play around with various
designs, this would mean physically replacing the components which
is inconvenient if the components are soldered onto a board or not
immediately available. Second, the passive components such as
resistors and capacitors degrade and vary in value over time and
temperature and thus the transfer function of your controller is
never fixed, and the worst-­case scenario is that if they are somehow
damaged due to environmental temperatures, their values could
have drifted so far off that they cause the controller to go unstable.
Some systems incorporate multiple control loops so the more con-
trollers there are the more space is required on a circuit board, and
this can lead to bulkier designs and also increase the costs of the
implementation. Some systems are also time variant or non-­linear
such that they require an adaptive or a non-­linear controller. So,
the controller’s parameters will change in accordance to the varia-
tion of the system in order for the control loop to stay stable or
robust. However, this is not possible with analog controllers
because the parameters set by discrete components are hard wired
and fixed. Therefore, the disadvantages of analog/continuous-­time
controllers are summarized as the following:

• Since they’re composed of analog components (resistors,


capacitors, op-­amps, etc.), the parameters are fixed.
• Analog components degrade over time and temperature, thus
causing the overall transfer function to vary unintentionally.
6   ◾    Digital Control of Power Converters

• Some feedback systems require multiple control loops at


high orders; this leads to requiring more board space and
bulky designs (multiple op-­amps and passives), and overall
higher cost.
• For systems whose dynamics are time-­ variants or non-­
linear, an adaptive or a non-­ linear controller may be
required, and this is very difficult to achieve using discrete
analog components considering the components are hard-­
wired (soldered) and fixed before deployment.

So, if we go from an analog control scheme to a digital control


scheme, you’ll notice that we introduce a couple of new blocks.
Unlike in the analog control scheme, the feedback signal is now
sampled discreetly and fed into a microcontroller and then after
the error signals are generated, a discrete control algorithm con-
verts its error signal to a control signal which then leaves a micro-
controller to drive the plant as shown in Figure 1.4.
The C(z) is our discrete equivalent of our analog controller
C(s) and can be implemented through firmware or embedded
code and therefore we can easily adjust the coefficients that
define the discrete transfer function C(z) and thus have more
flexible control over our feedback system’s behavior. So here are
the main advantages of digital control. The first advantage is that
it allows a designer or a control engineer to readily adjust the

FIGURE 1.4 The digital control scheme blocks.


Digital Control with Arduino   ◾    7

control parameters through firmware which is inexpensive, saves


time, and provides a flexible degree of tuning. Second, since digi-
tal controllers are typically implemented on a controller or
microprocessor, they take up less board space and allow you to
implement multiple control loops and add various features such
as saturation or hysteresis with just a few lines of code, and, last,
they allow for adaptive or non-­linear control laws for systems
that are time varying or non-­linear in their transient or steady-­
state behavior. Therefore, the advantages of digital control can be
summarized as follows:

• Allows the designer or control engineer to readily adjust the


controller’s parameters via firmware – inexpensive, saves
time, and provides a flexible degree on tuning.
• Since digital controllers are typically implemented on a
microcontroller or microprocessor, they take up less board
space, allowing you to implement multiple control loops and
add various features such as saturation and hysteresis with
just a few lines of code.
• Allows for adaptive or non-­linear control laws for systems
that are time variant or non-­linear in their transient or
steady-­state behavior.

So, this was just a brief motivation for why you should learn to
implement digital controllers and their advantages over analog
controllers. The rest of this chapter will focus on bridging the gap
between the theory and the practical implementation in much
greater detail.

1.3 OVERVIEW OF THE Z-­TRANSFORM


In this section, we will be briefly looking over the Z-­transform and
its role in the digital controller’s implementation. In continuous-­
time feedback systems, we represent our controller’s transfer func-
tion C(s) in the s-­domain which is obtained by taking the Laplace
8   ◾    Digital Control of Power Converters

FIGURE 1.5 The Laplace transform of the controller.

transform of the impulse response c(t), where s is a complex num-


ber, σ + jω, and ω = 2πf. The famous Laplace transform, L{}, takes
a signal or system in the time domain and brings it to its complex
frequency-­domain representation. Doing so, it converts differen-
tial equations to algebraic expressions and the convolution opera-
tion does multiplication and helps make analyzing systems easier
as equations below and as shown in Figure 1.5.
+∞


C ( s ) = c ( t ) e − st dt
−∞
(1.1)

U (s)
C (s) = (1.2)
E (s)

where C(s) is the Laplace transform of c(t), U(s) is the control out-
put, and E(s) is the error input.
In other words, it makes analyzing linear systems and designing
controllers a lot easier. In the continuous-­time or analog-­domain,
the controller C(s) is derived from a differential equation that
describes the dynamics of the physical system where in most cases,
it is the dynamics of an electrical analog circuit. For example, the
type II compensator used for power supply regulation has the fol-
lowing transfer function as shown in Figure 1.3:

Ve ( s ) 1 + C1R2 s
C (s) = = − (1.3)
Vout ( s ) ( 2 1 1C3 ) s + R1C1C3R2 s2
R C + R
Digital Control with Arduino   ◾    9

To get the transfer function, we can apply the Kirchhoff’s


Current Law (KCL) on the red node in Figure 1.3. The inverting
and non-­inverting inputs of the ideal op-­amp should have equal
voltage, and the current flowing to the inverting point of ideal op-­
amp is equal to zero; therefore, the red node voltage is also equal
to Vref as depicted in Figure 1.3:

Vref − Ve Vref − Ve V V − Vout


+ + 0 + ref + ref =0 (1.4)
1 1 R R
+ R2 4 1
C3 s C1s

 
Ve  1  V
|Vref =0 → Ve  C3 s + =− out (1.5)
Vout  1  R1
 + R2 
 C1s 

Ve 1 + C1R2 s
|Vref =0 = − (1.6)
Vout ( R2C1 + R1C3 ) s + R1C1C3 R2 s2

Now don’t worry too much about how this compensation was
derived. Just understand the concept as understanding the spe-
cific controller is way beyond the scope of this chapter. So, we
cross multiply the terms, so that they are written as such:

−Vout ( s )(1 + C1=


R2 s ) Ve ( s ) ( (R C + R C )s + R C C R s )
2 1 1 3 1 1 3 2
2
(1.7)

Then, after taking the inverse Laplace transform or in other


words going back to the time domain, we get the following dif-
ferential equation:

dVout ( t ) dVe ( t ) d 2Ve ( t )


−Vout ( t ) − C1R2 =( R2C1 + R1C3 ) + R1C1C3 R2
dt dt dt 2
(1.8)

Now keep in mind that when we take the Laplace transform or


the inverse Laplace transform, you don’t actually have to solve in
10   ◾    Digital Control of Power Converters

the integrals. You just look at the Laplace transform table pro-
vided. So, this differential equation (1.8) is what describes physi-
cally the relationship between the input and the output of the
compensator. Now this dynamic is implemented using discrete
components such as op-­amp resistors and capacitors. So, how do
we implement this type of dynamic digitally on a microcontroller
for example? In order to answer that, we must briefly go over the
Z-­transform. Just like how the Laplace transform puts a continu-
ous signal in terms of its ‘s’ or its complex frequency domain. The
Z-­transform puts a discrete or digitized signal in terms of a ‘z’ or
complex frequency domain or ‘z’ is equal to ‘e’ the power of ‘sT’
(esT). Now, C(z) is the Z-­transform of c[k], where c[k] is a discrete-­
time signal sampled at our sampling time, T, as illustrated in
Figure 1.6.
So, the Z-­transform is essentially the discrete version of the
Laplace transform and it follows similar properties of the Laplace
transform and it is a mathematical operation that takes a discrete-­
time signal and converts it to its complex frequency-­ domain
representation:

C (z ) = ∑c k  z
k =0
−k
(1.9)

Where z= esT
Most importantly it converts convolution in the discrete-­time
domain to multiplication in the complex frequency domain.

FIGURE 1.6 The Z-­transform.


Digital Control with Arduino   ◾    11

FIGURE 1.7 The Z-­transform as a Laplace transform for discrete signals


sampled at T.

The Z-­transform is essentially the ‘Laplace transform’ for discrete


signals sampled at a fixed sample rate T as given in the following
equations and is shown in Figure 1.7:

c n  = e n  ∗ u n  → C ( z ) = E ( z )U ( z ) (1.10)

c ( t ) = e ( t ) ∗ u ( t ) → C ( s ) = E ( s )U ( s ) (1.11)

It is also essential to know the mapping between the s-­plain


and the z-­plane which comes from the following expression:

z = e sT (1.12)

s= σ + jω (1.13)

Now σ is a real component and ω is the imaginary component.


It is apparent from this formula that the left half plane of the s-­
plane maps to inside the unit circle as shown in Figure 1.8, where
a point can be represented by its magnitude, eσT, and its angle, ωT,
as represented in the following equation:

= = eσ T e jω=
z e sT T
eσ T ∠ωT (1.14)

So, if there was a point on the origin of the s-­plane, it would


map to 1 on the real axis of the z-­plane since the magnitude is 1
12   ◾    Digital Control of Power Converters

FIGURE 1.8 Mapping between s-­plane and z-­plane.

and the angle is 0, and if we were to move further negative in the


real s-­plane, this would correlate to moving closer to the origin
of the z-­plane However, if we move to the right of the s-­plane,
this would correlate to a magnitude greater than 1 and, thus, we
would be outside the unit circle, and since we also have an
imaginary component, the angle is non-­zero. Now, if we keep
the imaginary component the same and move the real compo-
nent to the left half-­plane, we will find ourselves back inside the
unit circle in the z-­plane, and, however, the angle will remain
the same as represented in equations below and as shown in
Figure 1.8:

z = e sT |s =0 = 1∠0o (1.15)

=z e sT=
|s0 (e σT
)
 1 → 0∠ωT (1.16)

z= e sT |s >=0 (eσ T > 1)∠ωT (1.17)

This is too crucial to the digital controller design process but


it’s good to know how the routes match between the Laplace and
the Z-­transform. A stable system should have all its poles within
the unit circle. A pole outside the unit circle would indicate an
Digital Control with Arduino   ◾    13

FIGURE 1.9 Closed-­loop feedback diagram of digital control.

unstable system. So, taking a look at our closed-­loop feedback dia-


gram, a controller C(z) is now digital and is represented in the
z-­domain preceding it as a sampler which is sampling at a sam-
pling time of TS and after it comes our zero-­order hold (ZOH)
block. We’re just theoretically bringing our discrete signal back to
the continuous-­time domain to drive the plant as illustrated in
Figure 1.9.
Now, we’ll go more into both of these blocks in later sections of
this chapter. So, let’s say we’ve designed C(z), that is great. Now
how do we implement this? To answer that let’s say C(z) equals the
following transfer function which you can clearly see relates are
discrete error input E(z) and our controller’s discrete output U(z)
as below equation:

U ( z ) b0 + z −1b1 + z −2b2 +…+ z − M bM


=
C (z ) =
E ( z ) a0 + z −1a1 + z −2a2 +…+ z − M aM
(1.18)

Now, if we cross multiply the turns, we get the following


expression:

U ( z ) (a0 + z −1a1 + z −2 a2 +…+ z − M aM )


= E ( z ) (b0 + z −1b1 = + z −2b2 +…+ z − M bM ) (1.19)

Now if we distribute U(z) and E(z) on the respective sides of the


equation and then we take the inverse Z-­ transform of the
14   ◾    Digital Control of Power Converters

expression, or in other words going back to the discrete-­time


domain, we get the following difference equation:

1
{ }
Z −1 X ( z ) =
2π j ∫ X ( z ) z n −1
dz (1.20)

a0u n  + a1u n − 1 + a2u n − 2  +…+ a M u n − M 


= b0e n  + b1e n − 1 + b2e n − 2  +…+ bM e n − M  (1.21)

This is called a difference equation which is essentially the dis-


crete version of the differential equation and this equation is what
is coded and used to develop the code in the firmware to imple-
ment a digital controller in a real-­time system. Now, notice the ‘a’
and ‘b’ coefficients in front of each discrete-­time term in the dif-
ferential equation case. These had to be using resistors and capaci-
tor values because this is a difference equation and they can be
implemented digitally. So, these coefficients can simply be adjusted
in the code. Therefore, as the title of this section indicates, this is
a very brief overview of the Z-­transform; in the later sections, we
will dive much deeper into making intuitive sense out of it and
you’ll see where it’s relevant in the digital controller design
process.

1.4 DISCRETIZATION OF CONTINUOUS-­TIME
SYSTEMS
In this section, we’ll be going over the discretization of analog or
continuous-­time systems using Tustin’s method. Whenever we
have a pure continuous-­time feedback loop with the continuous-­
time plant, sensor, and controller, we design our controller, C(s),
using classical control techniques as shown in Figure 1.1. The two
most popular techniques being root locus and the frequency
response or, Bode plot analysis. Using the root locus, we observe
how close loop poles move in the s-­plane as a function of the gain
Digital Control with Arduino   ◾    15

of our control or C(s). Using the frequency response analysis


technique, we observe the Bode plot of the entire feedback loop
and check the gain and phase margins to assess the stability and
the transient performance. So, if a continuous-­time control or
C(s) is designed using these classical control techniques, how do
we go about designing a digital controller, C(z), to drive a
continuous-­time plant such as a power supply, a motor, or a
heater system. The best way to derive a digital controller is to first
derive a continuous controller C(s) that can appropriately drive
our plant and then knowing that z equals e to the sT (z = esT), we
can convert controller transfer function, C(s), to a discrete con-
troller or C(z) such that it mimics the continuous-­time control-
ler’s behavior in the discrete/digital domain in regard to its
frequency response as you can see in Figure 1.4. So essentially
our goal is to design C(z) such that its frequency response matches
closely with C(s) frequency response. So, let’s say we have a sys-
tem or plant that we want to control with feedback and we design
the following continuous-­time controller or controller C(s) that
has a pole in −5 and zero at −1 as represented in the following
equation:

s +1
C(s) =
s+5 (1.22)

So, we know that z equals e to the sT as below:

z = e sT (1.23)

If we arrange in the equation the ‘s’ as a function of ‘z’, we get


that s equals a natural logarithm of z over T, therefore, we have the
following equation:

ln ( z )
s= (1.24)
T
16   ◾    Digital Control of Power Converters

So, substituting for ‘s’ in C(s), we get C(z) that equals natural
logarithm of ‘z’ over T plus 1 over natural logarithm of ‘z’ over T
plus 5 as follows:

ln ( z )
+1
C (z ) = T (1.25)
ln ( z )
+5
T

This equation is suddenly a non-­linear equation due to the nat-


ural logarithm term and therefore we cannot take the inverse
Z-­transform of this, hence, we cannot work with this equation.
So, what we’ll need to do instead is approximate z equals e to the
sT (esT) as a first-­order linear equation. There are many approxi-
mation methods that have been proposed but one in particular
does a better job than the rest, and that’s Tustin’s method which is
also known as a bilinear transformation as given in the following
equations:

Euler′s method : z= e sT ≈ 1 + sT (1.26)

1
z e sT ≈
Backward difference := (1.27)
1 − sT

T
1+ s
Tustin′s method ( bilinear transformation ) : z =
e sT ≈ 2
T
1− s
2
(1.28)

Now, if we map the left half plane of the s-­plane to the z-­plane
using each of these approximations, you can see that Euler’s
method and the backward difference methods map very poorly in
comparison to Tustin’s method as illustrated in Figure 1.10.
Digital Control with Arduino   ◾    17

FIGURE 1.10 Mapping of the left-­hand s-­plane (Re{s}< 0) to the z-­plane


(unit circle).

Therefore, using Tustin’s method, the mapped z-­plane for val-


ues Re{s} < 0 matches the closest to the original z-­plane of z = esT.
So, if we want our digital controller’s frequency response to match
very closely to the frequency response of our continuous-­time
controller, it is in our best interest to go with Tustin’s method. So,
if we rearrange this new approximation of ‘s’ as a function of ‘z’,
we get that ‘s’ equals 2 over T times Z minus 1 over Z plus 1 as the
following equation:

T
1+ s
z= e sT
≈ 2 → s= 2 z − 1 (1.29)
T T z +1
1− s
2

If we now substitute for ‘s’ and C(s) and, for example, set the
sampling time T to be 0.02 seconds, we get the following z-­domain
transfer function:

2 z −1
s +1 s=
C (s) = T z +1 (1.30)
s + 5 T sampling time = 0.02 seconds
( )
18   ◾    Digital Control of Power Converters

0.9619z − 0.9429
C (z ) = (1.31)
z − 0.9048

This transfer function C(z) is the discrete equivalent to the


continuous-­time transfer function C(s). Now we can use MATLAB
to verify that their frequency responses match close enough. So,
let’s verify with MATLAB that C(z) has similar frequency response
as C(s). We’ll use the code below, where the first code line is
declaring our continuous-­time transfer function C(s) and then to
get the discrete transfer function C(z), reuse the ‘c2d’ function
with the method set to ‘tustin’ and the sampling time, Ts, set to
0.02.

C_s = tf([1 1],[1 5]); %% C(s) is the transfer



function
Ts = 0.02; %% Sampling time is 0.02 s

C_z = c2d(C_s,Ts,’tustin’);  %% Discretizing C(s)
using Tustin’s
method
bode(C_s); %% Plotting the frequency

response C(s)
hold on;
bode(C_z); %% Plotting the frequency

response C(z)

Then, we’re plotting the Bode plots for both C(s) and C(z) on
the same plot to see how they overlap. Now after running the code
on MATLAB, we will get the figure showing the frequency
responses of both C(s) and C(z), and they are matched very closely
with one another as shown in Figure 1.11.
Although they do not perfectly align, in our case of designing a
digital controller that behaves like the continuous one, it’ll do just
fine. Hopefully, this section gave you enough information to know
how to discretize a continuous-­time system. In the next section,
we will look into how a digital system like the one derived here is
implemented in code on the Arduino Integrated Development
Environment (IDE).
Digital Control with Arduino   ◾    19

FIGURE 1.11 The Bode diagram of C(s) and C(z).

1.5 ARDUINO IMPLEMENTATION OF
DISCRETE-­TIME SYSTEMS
In this section, we will go over to see how you can implement a
discrete-­time system on the Arduino. Now we’re going to step
back from any discussion about feedback control and just see how
we can implement any arbitrary discrete-­time system on a micro-
controller so let’s say we have a second-­order system, H(s), that we
wish to discretize as below:

20
H (s) = 2
(1.32)
s + 2.5s + 20

Now, if we apply a step input for this system which we can sim-
ulate with MATLAB using the following code we can observe how
the output behaves and we get a very typical under-­damped
second-­order response as shown in Figure 1.12:
20   ◾    Digital Control of Power Converters

FIGURE 1.12 The step response of second-­order continuous-­time sys-


tem, H(s).

H_s = tf([20],[1 2.5 20]);


step(H_s);

We can also observe the frequency response of the system using


the ‘bode’ function on MATLAB by the following code:

H_s = tf([20],[1 2.5 20]);


bode(H_s);

In the Bode plot as depicted in Figure 1.13, we will have a natu-


ral or resonance frequency of about 4.07 rad/s.
So, it’s a pretty slow and low bandwidth system and because we
want to discretize this to implement on Arduino, we use the ‘c2d’
function on MATLAB as shown in the previous section and we
Digital Control with Arduino   ◾    21

FIGURE 1.13 The frequency response of the system, H(s).

set the method to ‘tustin’ and the sampling-­time to T which is


equal to 0.1 seconds as the following code:

H_s = tf([20],[1 2.5 20]);


T = 0.1;
H_z = c2d(H_s,T,’tustin’);

This is the discrete transfer function we get as the equation


below:

2 z −1
s= 2
= ( s ) T z + 1 0.042372z + 0.08475z + 0.04237 (1.33)
H ( z ) H=
T = 0.1sec z − 1.61z + 0.7797

We’ll call this discrete-­system, H(z), and if we plot the transient


response of both the analog and digital systems, you can see that
22   ◾    Digital Control of Power Converters

FIGURE 1.14 The transient response of both the analog and digital
systems.

their responses line up with each other as shown in Figure 1.14,


and the MATLAB code is as below:

H_s = tf([20],[1 2.5 20]);


T = 0.1;
H_z = c2d(H_s,T,’tustin’);
subplot(2,2,1);
step(H_s);
subplot(2,2,2);
step(H_z);
subplot(2,2,[3,4]);
step(H_z, H_s);

Also, if we plot the frequency responses of both systems, we can


see that they line up relatively well with some error at the higher
frequency as shown in Figure 1.15, and it should be said that when
Digital Control with Arduino   ◾    23
FIGURE 1.15 The frequency response of both the analog and digital systems.
24   ◾    Digital Control of Power Converters

it comes to design the controllers and digitizing systems, it isn’t


necessary that you get a controller that behaves exactly 100% like
its analog equivalent.
The following MATLAB code is used for plotting the frequency
responses of both systems:

H_s = tf([20],[1 2.5 20]);


T = 0.1;
H_z = c2d(H_s,T,’tustin’);
subplot(2,2,1);
bode(H_s);
subplot(2,2,2);
bode(H_z);
subplot(2,2,[3,4]);
bode(H_z, H_s);

The goal is to design a controller that will robustly control the


open-­loop system. Now, we want to write this transfer function in
its causal form with the following equation:

0.04237 z 2 + 0.08475z + 0.04237


H (z ) = (1.34)
z 2 − 1.61z + 0.7797

So, because it’s a second-­order system, we divide the numerator


and the denominator by z2 to get the following causal expression:

Y ( z ) 0.04237 + 0.08475z −1 + 0.04237 z −2


=
H (z ) =
X (z ) 1 − 1.61z −1 + 0.7797 z −2
(1.35)

Then as before we cross multiply the terms to separate X(z) and


Y(z) as below:

( )
Y ( z ) 1 − 1.61z −1 + 0.7797 z −2
(
= X ( z ) 0.04237 + 0.08475z −1 + 0.04237 z −2 ) (1.36)
Digital Control with Arduino   ◾    25

Y ( z ) − Y ( z )1.61z −1 + Y ( z ) 0.7797 z −2
= X ( z ) 0.04237 + X ( z ) 0.08475z −1 + X ( z ) 0.04237z −2 (1.37)

Also, after distributing X(z) and Y(z) on both sides, respec-


tively, and then taking the inverse Z-­transform to go back to the
discrete-­time domain, we get the following expression:

y n  − 1.61 y n − 1 + 0.7797 y n − 2 


= 0.04237 x n  + 0.08475x n − 1 + 0.04237 x n − 2  (1.38)

What you’ll notice over and over again is that z-­1 raised to the
−1 correlates to the previous sample from one discrete-­time step
ago and that z-­2 raised to the −2 correlates to the sample from two
discrete-­time steps ago. So, we then take our prior output terms
and move them over to the right side as the following equation:

=
y n  0.04237 x n  + 0.08475x n − 1 + 0.04237 x n − 2 
+ 1.61 y n − 1 − 0.7797 y n − 2  (1.39)

Now, we have a difference equation that is causal, meaning that


its output only relies on the current and the previous input and
output values. So, now let’s go and implement this difference
equation on the Arduino and see it in action. We’ll first start off or
we do know the script by first declaring variables and we’re setting
our sampling time to T equals 100 which is one hundred millisec-
onds or 0.1 seconds in this case. We will then create two variables
called last_time and current_time, which we’ll use to keep a con-
stant sample time interval, 0.1 seconds, in every iteration, and
then we’ll have to declare our input and output variables for stor-
ing the current and previous values as given by the following code:

//Declaring variables
int T = 100; /
/sampling time in milliseconds
(T = 0.1s)
26   ◾    Digital Control of Power Converters

unsigned long last_time;


unsigned long current_time;
float x; //x[n]
float y; //y[n]
float x_1; //x[n-­
1]
float y_1; //y[n-­
1]
float x_2; //x[n-­
2]
float y_2; //y[n-­
2]

Also, for our void setup function which runs only once at the
beginning of the program, we set all our variables to zero since we
want our system response to have a zero initial condition in order
to mimic a step response, we’ll have to generate a unit step func-
tion which is done here in the code below and the waveform of
x[n] is illustrated in Figure 1.16:

//Test Input Discrete Step Signal


vaoid x_input(){
if(current_time == 1000){ //After 1000ms or 1
second, step x[n] from 0 to 1
x = 1.0;
}
}

FIGURE 1.16 Testing the input step signal.


Digital Control with Arduino   ◾    27

The if statement condition is that once the elapsed time has


reached 1000 milliseconds or 1 second, the input x[n] should be
equal to 1. So essentially, we’re going from x equals 0 to x equals 1,
the moment we reach 1 second. Here, as illustrated in the code
below, is the main void loop where we use a millis() function to
keep track of the current elapsed time in milliseconds. We then
compute the delta time or time difference between the current
time and the previous time, and once this delta time value reaches
our sample time of 0.1 seconds, we execute the if statement and
then we save our current time as the last time.

//Main Loop
void loop() {
current_time = millis(); //stores the program

running time(ms)
int delta_time = current_time - last_time; //

computes ΔT
if (delta_time >= T) { //when ΔT = T, read

input x[n] and compute y[n]
elapsed_time = elapsed_time + T/1000.0; //

compute elapsed time in seconds
x_input(); //obtain input x[n]
y = 0.0424*x + 0.0848*x_1 + 0.0424*x_2 +

1.61*y_1 - 0.7797*y_2;
x_2 = x_1;
 //store x[n-­
1] as x[n-­
2] for
next iteration
y_2 = y_1;
 //store y[n-­
1] as y[n-­
2] for
next iteration
x_1 = x;
 //store x[n] as x[n-­
1] for
next iteration
y_1 = y;
 //store y[n] as y[n-­
1] for
next iteration
last_time = current_time; //restarts ΔT or

delta_time back to 0
}
}
28   ◾    Digital Control of Power Converters

This method allows us to have artificial control over our


sample time interval despite the higher sampling frequency of
the Arduino’s ADC. So, in our ‘if ’ statement, we will include
our step input function, x_input, and then our difference equa-
tion. Notice that this line of code is exactly the one we derived
before in Equation (1.31), and then lastly, we store the current
values as the previous or delayed values for the next iteration,
and there you have it as you can see in the above code. That is
all you need to implement a discrete-­ t ime system on the
Arduino. Let’s run this code on the Arduino IDE and monitor
the input and the output. So here, we have the Arduino code we
just discussed.

float T = 100.0;
unsigned long last_time;
unsigned long current_time;
double elapsed_time;
double x;
double y;
double x_1;
double y_1;
double x_2;
double y_2;
void setup() {
Serial.begin(9600);
x = 0.0;
y = 0.0;
x_1 = 0.0;
y_1 = 0.0;
x_2 = 0.0;
y_2 = 0.0;
}
void loop() {
current_time = millis();
int delta_time = current_time - last_time;
if (delta_time >= T) {
elapsed_time = elapsed_time + T/1000.0;
x_input();
Digital Control with Arduino   ◾    29

y = 0.0424*x + 0.0848*x_1 + 0.0424*x_2 +



1.61*y_1 - 0.7797*y_2;
x_2 = x_1;
y_2 = y_1;
x_1 = x;
y_1 = y;
Serial.print(elapsed_time);
Serial.print(" ");
Serial.println(y);
last_time = current_time;
}
}
void x_input() {
if (current_time == 1000) {
x = 1.0;
}
}

One neat thing about the Arduino IDE is that you can moni-
tor any value on the Serial Plotter, so we’ll want to monitor the
step input x and the output y and see how they behave; hence,
from Tools menu, we select the Serial Plotter option. So, let’s run
the program as shown in Figure 1.17, we’re getting the slow

FIGURE 1.17 The slow under-­damped response with Arduino IDE’s


Serial Plotter.
30   ◾    Digital Control of Power Converters

under-­damped response that we expected but in order to verify


that this result is theoretically correct, let’s confirm it with
MATLAB Simulink.
We’ll first create a discrete transfer function block and type in
the numerator and denominator coefficients in Equation (1.34),
and then we’ll set the sample time to 0.1 seconds as depicted in
Figure 1.18.
Next, we’ll add the step input block which will step up from 0
to 1 at 1 second with sample time equal to 0.1 seconds as illus-
trated in Figure 1.19.
Then lastly, we’ll add a scope to plot and observe the output and
the input and run a 10-­second simulation as shown in Figure 1.20.

FIGURE 1.18 Setting the discrete transfer function parameters.

FIGURE 1.19 Adding the step input block.


Digital Control with Arduino   ◾    31

FIGURE 1.20 Adding a scope and running the simulation.

FIGURE 1.21 The discrete transfer function step response in scope.

From the scope, we can see that this is what we expect from the
theoretical model of our discrete transfer function as shown in
Figure 1.21.
Now we want to compare this with the implementation result.
So, we’ll need to monitor the time and output data, so that we can
create a two-­dimensional variable on MATLAB. Now going back
32   ◾    Digital Control of Power Converters

to the Arduino, compile and then upload the program from the
Tools menu, we can use the Serial Monitor to display the values
numerically. By running the program, you can see the elapsed
time and output columns on the Serial Monitor.
Currently, we have completed the initial steps. Next, we will
copy the values up to 10 seconds into Notepad++ and then import
them into MATLAB. To do this, we will create a data variable that
includes both the time and output data. Additionally, we will insert
a row above the time value of 0.1 and set it to 0, as we want to
include a row for time zero (time = 0 s), as illustrated in Figure 1.22.
After that, we do rename the data variable as Output_Data as
shown in Figure 1.23.
Then, we use the From Workspace block from Sources in
Simulink to plot the experimental output data and then use a
scope to view this signal alongside the theoretical step input.
Therefore, we do double click on the From Workspace block and
set Data as Output_Data and Sample time to 0.1 seconds as
depicted in Figure 1.24.

FIGURE 1.22 Creating a data variable that contains time and output
data and adding a row above time 0.1 s.
Digital Control with Arduino   ◾    33

FIGURE 1.23 Renaming the data variable as Output_Data.

FIGURE 1.24 Setting the From Workspace block properties.

Then we connect it to a scope to compare the theoretical and


experimental results, and if we were to plot the theoretical simu-
lated output against the implementation output, we can see that
they lie almost exactly on top of one another as shown in Figures
1.25 and 1.26, respectively.
34   ◾    Digital Control of Power Converters

FIGURE 1.25 Theoretical simulated output against the implementation


output.

FIGURE 1.26 Exact overlap of theoretical simulated output and imple-


mentation output.
Digital Control with Arduino   ◾    35

This goes to show that you can use the Arduino or any micro-
controller to implement a difference equation or discrete-­time
system. So now that we’re confident that we can implement a
discrete-­time system in the real time. Let’s move on to discussing
how we can implement the feedback control algorithm on the
Arduino.

1.6 DIGITAL FEEDBACK CONTROL


ALGORITHM
In this section, we’ll build upon what we learned in the previous
section and now discuss how to implement feedback control
structure on the Arduino. So, in the last section, we learned how
to implement a discrete-­time system such as C(z) in this case as
shown in Figure 1.4. However, how do we code up the feedback
control algorithm so that we can use an Arduino in a control loop
to digitally regulate a continuous-­time plant? Or, how do we
implement the digital control scheme inside the dashed line as
shown in Figure 1.4? In Figure 1.27, you’ll see the portion of the
feedback loop we wish to implement digitally and, in the code
below, you’ll see the main loop block that we discussed in the

FIGURE 1.27 Digital implementation for the portion of the feedback


loop.
36   ◾    Digital Control of Power Converters

previous section for implementing the controller transfer func-


tion, C(z), as the following equation:

U ( z ) b0 + b1z −1 + b2 z −2 +…+ bm z −m
=
C (z ) =
E ( z ) 1 + a1z −1 + a2 z −2 +…+ an z −n
(1.40)

void loop() {
current_time = millis(); //stores the program

running time(ms)
int delta_time = current_time - last_time; //

computes ΔT
if (delta_time >= T) { //when ΔT = T, read

input x[n] and compute y[n]
sensed_output(); //obtain a current sample,

output_y[n]
e = setpoint – output_y; //e[n] = setpoint

- output_y[n]
u = -a_1*u_1-­… -a_n*u_n + b_0*e + b_m*e_m;

//C(z)
u_n = u_(n-­
 1); //store u[n-­
(n-­
1)] as
u[n-­
n] for next iteration
e_m = e_(m-­
 1); //store e[n-­
(m-­
1)] as
e[n-­
m] for next iteration
. . .
u_1 = u;
 //store u[n] as u[n-­
1]
for next iteration
e_1 = e;
 //store e[n] as e[n-­
1]
for next iteration
last_time = current_time; //restarts ΔT or

delta_time back to 0
}
}

So, let’s work our way from the feedback path, so, if you take a
look at the ‘if’ statement in the code, you’ll notice that it in itself is
the sampler as it only executes every sample time of T. So, for
example, if T equals one second, then the code inside the ‘if’ state-
ment will iterate or update every one second. That being said if we
Digital Control with Arduino   ◾    37

call a function which may be declared somewhere else in the script


and reads in some discrete or analog sensed output data and if we
place that in the ‘if’ statement, then we’re artificially sampling the
output signal every T second. So, this code so far takes care of the
sampling block. Next, we take our sensed output and then sub-
tract it from a set point or a desired output to generate an error
signal and this is done by doing a simple subtraction. Although
we don’t show it here, the variables we’re introducing are declared
at the beginning of the script. So, after we’ve obtained our error,
we want to generate a control single to drive our plant. So next we
implement the controller as a difference equation where the error
e is our input and u is our control output. Here in the above code,
we have it written as a pseudo code for the fallen transfer function
with ‘a’ and ‘b’ coefficients in Equation (1.30). If you notice this is
exactly the same implementation we covered in the previous sec-
tion. Nothing is different about the way it is implemented; all
that’s different is what we’re feeding in as our input and getting
back as our output. The difference equation structure is exactly
the same. So, that is all, and this is all you need to implement the
feedback control structure as shown in Figure 1.4. Now, you may
wonder what is a zero-­order hold (ZOH) block for as you can see
in Figure 1.4, and why did we include it? Well let’s step back and
assess its theoretical function if we have a continuous signal, x(t),
and pass it through a sampler which samples every T second, then
we theoretically end up with the discrete signal, x[n]. Now, what
the zero-­order hold (ZOH) block does is hold the sample value for
T seconds so that we get a staircase looking version of the continu-
ous signal as depicted in Figure 1.28.

FIGURE 1.28 The zero-­order hold (ZOH) block operation.


38   ◾    Digital Control of Power Converters

FIGURE 1.29 The impulse function is used only for theoretical deriva-
tion and analysis.

So, how do we implement a ZOH block? The answer is we don’t


have to. It’s already intrinsically part of the firmware or code.
Keep in mind that this signal x[n] does not exist in our physical
reality and it is simply a mathematical representation of a sampled
signal. Nowhere, inside the microcontroller, you will find a signal
where the value only shows up in for testimony at the beginning
of the sample period and then suddenly disappearing in between.
This kind of representation is only useful for theoretical or math-
ematical analysis. The same goes for the impulse function, as
illustrated in Figure 1.29.
They only exist for theoretical derivation and analysis purposes.
Therefore, all the variables in the ‘if (delta_time >= T) {}’ state-
ment are held constant for the entire T sampling period and only
change or update in the next iteration. So, the ZOH block is intrin-
sically present in the void loop() function, it is not a function we
implement and it’s not something we have to implement directly.
Again, the reason we include the sampler and the ZOH block in
our diagram is because they mathematically and theoretically rep-
resent what is happening to our signals and they are a model rep-
resentation of what is happening to our signal, theoretically. So,
there you have it and that is all you need to implement the follow-
ing control structure as represented in the above code, and you can
also see in Figure 1.30.
Digital Control with Arduino   ◾    39
FIGURE 1.30 Arduino code for implementing the control structure block diagram.
40   ◾    Digital Control of Power Converters

So, now that we are in most of the theory out of the way. In the
next few sections, we’ll dive into the design step process and even-
tually demonstrate this process using a DC motor speed control
example.

1.7 DIGITAL CONTROLLER DESIGN (SIX STEPS)


In this section, we’ll be going over the six design steps you can use
to design a digital controller to control your continuous-­time sys-
tem, so, here are the six design steps.

1. Obtain the plant’s transfer function, P(s)


2. Choose an approximate sampling time, T
3. Design controller, C(s), while taking into account the effects
of ZOH/sampling
4. Use bilinear transform/Tustin’s method to discretize C(s) to
C(z)
5. Take the inverse Z-­transform of C(z) to obtain the difference
equation
6. Implement the difference equation on the Arduino and run
the system!

We want to let you know that this step-­by-­step procedure isn’t the
only way to go about designing a digital controller. This is just a
method that makes sense to us and hopefully will make intuitive
sense to you. So, the first step is to obtain the continuous-­time
transfer function of the system you wish to control and we will
refer to this transfer function as P(s). Now this step is very open
ended because there are many ways to obtain a transfer function
of an open-­loop system. For example, the method used to obtain
the transfer function of a power supply will differ from the method
used to obtain the transfer function of a DC motor or a heater
Digital Control with Arduino   ◾    41

system. So, for now, we’ll assume you know what the open-­loop
transfer function is for the system you want to control. There’s
plenty of literature and papers out there. We’ll show you how to
get the transfer function of a quad-­copter DC motor, heater sys-
tem, power supply, etc. In the coming section, we’ll be demon-
strating this step for a DC motor but it is your job to figure out the
transfer function of the system you wish to control. So, let’s say
you have your open-­loop transfer function. So, the next step is to
choose the sampling frequency or sampling time for your digital
controller. So, there is actually no clear-­cut method or equation to
choose a sampling frequency or sampling time. If you Google
this, you’ll see that there are several ways to go about choosing a
sampling time. However, Tustin’s method works better when the
sampling frequency (1/T) is much higher than the Nyquist fre-
quency. So, what is the Nyquist frequency? Nyquist frequency (fn)
is the minimum sampling frequency needed to prevent introduc-
ing aliasing or introducing distortion/error in your closed-­loop
system. The Nyquist frequency is defined as being strictly twice
the bandwidth of your open-­ loop system as the following
equation:

Tbw
fn ≥ 2 × f bw or Tn ≤ (1.41)
2

But like we said Tustin’s method works better when the sam-
pling frequency is much higher than the Nyquist frequency. So,
as a rule of thumb is preferable to use a sampling frequency
that’s 5–10 times faster than the bandwidth (f bw) of your open-­
loop system. The bandwidth of your system is typically defined
as being the frequency at which the gain of your system is about
3 dB is less than the DC gain. So, the bandwidth frequency or 3
dB frequency is essentially the point where the DC gain begins
to roll off, especially at 3 dB below the DC gain. So, in order to
find the bandwidth of your system, it is required to know the
42   ◾    Digital Control of Power Converters

FIGURE 1.31 The bandwidth frequency or 3 dB frequency.

transfer function so that you may plot the Bode plot and locate
this minus 3 dB point on the magnitude graph as shown in
Figure 1.31.
Next, we move on to design the controller, C(s). So, as we
mentioned in the earlier section when needing a digital control-
ler, it’s much easier to design it as a continuous mode controller
and then discretize it to implement it digitally. So, we got the
open-­loop transfer function P(s) and we’ve chosen our sampling
frequency so can we start the controller, C(s), design process
yet? No, we cannot because we’ll be designing a continuous-­
time controller using continuous-­time design methods such as
root locus or the frequency response analysis, we need to take
into account the continuous-­time effects the sampling and the
ZOH function will have in the control loop as depicted in
Figure 1.32.
If we take a continuous-­time signal x(t) and pass it through the
sampler and the ZOH block, we get the expected continuous
staircase signal which we’ll call xS(t), and if we were to overlap
these signals in time you can see the hold delay, and it’s
discontinuous-­time hold delay that we wish to model and include
in our control loop before designing our controller as illustrated
in Figure 1.33.
Digital Control with Arduino   ◾    43
FIGURE 1.32 The continuous-­time effects of ZOH/sampling in the transmission loop.
44   ◾    Digital Control of Power Converters

FIGURE 1.33 Approximate transfer function to model the hold delay.

So, we want an approximate transfer function, model this hold


delay which we’ll call GZOH(s), that will relate an original
continuous-­time signal x(t) to its ZOH reconstructed signal xs(s)
as shown in Figure 1.33. So, let’s briefly derive GZOH(s). If we pass a
continuous-­time signal x(t) through a sampler, we get the follow-
ing sample signal x*(t), which we can mathematically represent
with the following equation:
+∞

x (t ) x (t )
= ∗
∑δ (t − kT )
k =−∞
(1.42)

If we take a Laplace transform of x*(t), we get the following


expression:
+∞

{ ( s ) T1 X  s − j 2Tπ k 
(t ) X=
 x= ∗
} ∗
∑ (1.43)
k =−∞
 

Now driving this specific equation is beyond the scope of this


chapter. So just take our word for it that this is the Laplace trans-
form of x*(t) as shown in Figure 1.34.
So, if we were to pass x*(t) through the ZOH block, we get xS(t).
However, xS(t) can be mathematically represented as a convolution
Digital Control with Arduino   ◾    45

FIGURE 1.34 Brief derivation of GZOH(s) – Part 1.

between x*(t) and a function we’ll call g(t) where g(t) is the follow-
ing rectangular function:

g (t ) = u (t ) − u (t − T ) (1.44)

If we took the Laplace transform of g(t), we get that G(s) equa-


tion as below:

1 e − sT 1 − e − sT
{ }
 g (t ) =
G ( s ) =−
s s
=
s
(1.45)

Again, T is the sampling period, as depicted in Figure 1.35.

FIGURE 1.35 Brief derivation of GZOH(s) – Part 2.


46   ◾    Digital Control of Power Converters

Now we know from our linear signals and systems funda-


mentals that the convolution in the time domain translates to
multiplication in the frequency domain so we can express
x*(t) convolves with g(t) as X*(s) multiplied by G(s) which gets
us xs(s), which is mathematically expressed as the following
equations:

{ }
x ∗ (t ) 
= g ( t ) x s ( t )  → X ∗ ( s=
) G ( s ) Xs ( s ) (1.46)

+∞
1  2π k 
∑ Xs − j
T k =−∞  T 
G(s) =
Xs ( s ) (1.47)

Now of this expression, if we take a closer look at the periodic


train function, we only really care about the band-­limited compo-
nent which in itself is simply X(s) or the Laplace transform of our
original continuous-­time signal x(t). Therefore, realistically we
only care about band-­limited component (k = 0), which is simply
X(s). So, we can equate the periodic train function to just X(s) as
illustrated in Figure 1.36.
Thus, our expression has been simplified to the following
equation:

1
X ( s )G ( s ) = X s ( s ) (1.48)
T

FIGURE 1.36 Brief derivation of GZOH(s) – Part 3.


Digital Control with Arduino   ◾    47

We know that G(s) equals to Equation (1.45). So, substituting


this we get the following transfer function that relates the stair-
case function xS(t) to our original continuous-­time signal x(t):

Xs ( s ) 1 − e − sT
(1.39 ) , (1.36 ) → X (s)

sT
(1.49)

So, GZOH(s) is approximately equal to the following equation:

1 − e − sT
GZOH ( s ) = (1.50)
sT

So, this is the transfer function block that models the hold delay
in the continuous-­time domain as shown in Figure 1.37.
Now, we’ll take this block and we’ll place it in the closed-­loop,
and now we can finally go ahead and design C(s) while taking into
account the continuous-­time effects of the discrete parts. Therefore,
we can now design C(s) using classical design techniques because
we accounted for the discrete effects in our control loop as depicted
in Figure 1.38. The closed-­loop transfer function now looks like
the following equation:

Y (s) C (s)P (s)


= (1.51)
R(s) 1 + C ( s ) P ( s ) GZOH ( s ) H ( s )

FIGURE 1.37 Modeling the hold delay in the continuous-­time domain.


48   ◾    Digital Control of Power Converters

FIGURE 1.38 Adding the hold delay block in the closed-­loop.

Now, after designing the continuous-­time controller C(s), we


want to discretize it using Tustin’s method (bilinear transforma-
tion). So, knowing that the sampling time is T and knowing that
we’re going to use Tustin’s method we get the following z-­domain
transfer function:

2 z −1
s=
C (s) T z +1 = C (z ) (1.52)
T = chosen sampling time

U ( z ) b0 + z −1b1 + z −2b2 +…+ z − M bM


=
C (z ) =
E ( z ) a0 + z −1a1 + z −2a2 +…+ z − M a M
(1.53)

From our transfer function equation, (1.53), we cross multiply


the terms as below:

(
U ( z ) a0 + z −1a1 + z −2a2 +…+ z − M aM )
(
= E ( z ) b0 + z −1b1 + z −2b2 +…+ z − M bM ) (1.54)

Next, we take the inverse Z-­transform aka going to discrete-­


time domain, doing so; we end up with a different equation of our
controller that relates our error input to the controller output as
the following expression:
Digital Control with Arduino   ◾    49

a0u n  + a1u n − 1 + a2u n − 2  +…+ a M u n − M 


= b0e n  + b1e n − 1 + b2e n − 2  +…+ bM e n − M  (1.55)

Once we’ve got that we can go straight to implementing it on


the Arduino, and this is the code for the feedback control struc-
ture that we discussed in the previous section, and that is it. Those
are all the preliminary steps needed to design and implement a
simple digital controller for your system. In the last few sections,
will apply these six steps to design a digital controller for a DC
motor speed control system.

1.8 DC MOTOR SPEED CONTROL


1.8.1 System Modeling
In this section, we’re going to dive into designing a digital feed-
back control system to regulate the speed of a real DC gearmotor.
The block diagram of the control loop is shown in Figure 1.39.
In this case, we will have the PWM motor driver block after the
ZOH block and the plant P(s) is the DC gearmotor, H(s) is the
encoder, and output is the velocity (θ ( t )) in rad/s. We want to
implement the rotary encoder that is used to acquire the motor
speed which then gets sampled by the Arduino as a discrete signal
which we’ll call output speed. We then compare it with a desired
speed variable to generate an error signal, e. This error signal then
goes through our controller C(z) which again is implemented as a

FIGURE 1.39 The block diagram of the control loop.


50   ◾    Digital Control of Power Converters

FIGURE 1.40 The schematic of the setup.

difference equation to generate a control signal. This control signal


is realized as a PWM signal that comes out of the Arduino and
goes into the PWM motor driver. The motor driver imposes an
input voltage on the gearmotor to bring the actual speed, θ ( t ),
toward desired speed and thus we have our feedback loop. Here in
Figure 1.40 is the apparatus for the DC motor control system. We
have our Arduino Mega 2560 which is acting as our digital con-
troller followed by a PWM motor driver which drives our gearmo-
tor. Our motor conveniently has a built-­in encoder that sends
pulses data to where do we know which contains an algorithm to
convert this data to an output speed value. The motor driver
receives this power from the DC power supply and the real output
voltage is set to 12 volts. The schematic of the setup is depicted in
Figure 1.40.
So, we want to design a digital controller to effectively regulate
the speed of this DC gearmotor. So, the following are the six-­step
procedures as discussed in the previous section.
Digital Control with Arduino   ◾    51

1. Obtain the plant’s transfer function P(s)


2. Choose an approximate sampling time T
3. Design controller C(s) while taking into account the effects
of ZOH/sampling
4. Use bilinear transform/Tustin’s method to discretize C(s) to
C(z)
5. Take the inverse Z-­transform of C(z) to obtain the difference
equation
6. Implement the difference equation on the Arduino and run
the system!

Our first task is to obtain the approximate transfer function of our


DC gearmotor. So, in order to do that we must drive a transfer
function based on the electro-­mechanical system model of a
generic DC motor as illustrated in Figure 1.41.
Therefore, in order to design a speed control system for this
gearmotor using classical control techniques, we must first derive
its transfer function, P(s), using an equivalent system model that
approximately models its dynamics. Now running out all the
physics for the mathematical model derivation is beyond the scope
of this chapter. So, we’ll go straight into the transfer function of

FIGURE 1.41 The DC motor transfer function – Part 1.


52   ◾    Digital Control of Power Converters

this model that relates the input voltage, V(s), to the output speed,
θ ( s ) , as the following equation [4]:

θ ( s ) sθ ( s ) K  rad / s 
=
P (s) = =
V (s) V (s) ( Js + b )( Ls + R ) + K  V 
2 
(1.56)

where J (kg.m2) is the moment of inertia of the rotor, b (N.m.s) is


the motor viscous friction constant, K is equal to the electromo-
tive force constant (Ke(V/rad/s)) or motor torque constant (Kt(N.m/
Amp)), R(ohm) is the electric resistance, and L(H) is the electric
inductance. From Figure 1.41, we can derive the following govern-
ing equations based on Newton’s second law and Kirchhoff’s volt-
age law:

Jθ + bθ = K t i = Ki (1.57)

di
L + Ri =V − K eθ =V − Kθ (1.58)
dt

By applying the Laplace transform to Equations (1.57) and


(1.58), we will have the following equations:

( Js + b ) sθ ( s ) =
KI ( s ) (1.59)

( Ls + R ) I ( s=) V ( s ) − Ksθ ( s ) (1.60)

By eliminating I(s) from Equations (1.59) and (1.60), we get the


open-­loop transfer function in Equation (1.56). Now, if you wish
to see where we got this transfer function from, you can find the
detailed derivation in the link provided in [4]. So, the five param-
eters of the DC motor transfer function are as below as shown in
Figure 1.42.
Digital Control with Arduino   ◾    53

FIGURE 1.42 The DC motor transfer function – Part 2.

J is the rotor’s moment of inertia (kg.m2)


b is the motor’s viscous friction constant (N.m.s)
K is the electromotive force or motor torque constant (V/rad/s)
R is the electric resistance (Ω)
L is the electric inductance (H)

So, now the big question is how do we find these values for our
gearmotor? Well, if you’re lucky all this information can be avail-
able on the motor’s data sheet. However, almost 99% of the time
this is never the case, so, we’ll have to somehow figure out these
values using our tools and our intuition. So, let’s try to figure out
K, now K is the electric motor force or torque constant. This is
essentially the DC gain that relates our input voltage to our output
speed in radians per second (rad/s). Now, according to the data
sheet, the nominal speed at the rated voltage of 12 volts is 220
RPM now, 220 RPM can also be expressed as 23 rad/s since we
have:

2π ( rad )
220 RPM =
220 × ≈ 23rad / s (1.61)
60 ( s )
54   ◾    Digital Control of Power Converters

So, dividing 12 V by 23 rad/s, we get an approximate constant of


about 0.52 V/rad/s. Now what about the resistance? Now luckily, we
have an LCR meter which can measure electrical resistance of
complex impedance. So, if we probe across the leads of the motor,
we can get an approximate value of the internal resistance. Now
the resistance and the inductance actually vary with the angle of
the rotor. But again, we’re just looking for an approximate value.
So, for now, we’ll just say that the resistance is around 4.4 ohms.
Now using the same meter which is capable of measuring induc-
tance values at several frequencies we measure the inductance to be
around 6.3 mH, at an applied low frequency of 100 Hertz. So far,
we’ve gotten three values down, great, but now how do we go about
finding J and b. Now, unless we have some very expensive precision
tests’ apparatus, finding even the approximate values for these
parameters is quite difficult. Luckily, MATLAB Simulink has a
parameter estimation feature in the optimization toolbox. The
design optimization toolbox comes with a parameter estimation
tool, where the user can estimate the parameters of a simulated
model of their system using real measured input and output data.
So, the first step to use a tool is to create a Simulink model
based on the differential equations that describe the dynamics of
the system or to create a linear model that captures the dynamics
of a DC motor (Equation 1.56 or Equations 1.59 and 1.60) as
shown in Figure 1.43.

FIGURE 1.43 The Simulink model based on dynamic equations.


Digital Control with Arduino   ◾    55

Now, if you’ve never played with Simulink or modeled on


Simulink, we highly suggest that you get exposed to it because it’s
very useful for control design and simulating real-­time systems.
There are plenty of tutorials all over YouTube and Udemy on mod-
eling using MATLAB Simulink, so we won’t be discussing that
here as it’s beyond what this chapter focuses on. The second step is
to obtain the input and output data we want to use. So, in this
Arduino script, we’ve created a test input signal that will vary the
input voltage applied to the motor in a step-­like fashion and will
want to monitor the elapsed time, the applied input and the out-
put speed.

int sampling_time = 50;


unsigned long previous_time, current_time;
float encoder_count = 0;
boolean encoder_A, encoder_B;
byte state, statep;
float previous_angle, current_angle = 0;
float motor_speed = 0;
float supply_voltage = 12;
float elapsed_time = 0;
const int pwm_output = 7;
float control;
void Encoder_State(){
encoder_A = digitalRead(3);
encoder_B = digitalRead(2);
if ((encoder_A == HIGH) && (encoder_B == HIGH))

state = 1;
if ((encoder_A == HIGH) && (encoder_B == LOW))

state = 2;
if ((encoder_A == LOW) && (encoder_B == LOW))

state = 3;
if ((encoder_A == LOW) && (encoder_B == HIGH))

state = 4;
switch (state)
{
case 1:
56   ◾    Digital Control of Power Converters

{
if (statep == 2) encoder_count-­
-;
if (statep == 4) encoder_count++;
break;
}
case 2:
{
if (statep == 1) encoder_count++;
if (statep == 3) encoder_count-­
-;
break;
}
case 3:
{
if (statep == 2) encoder_count++;
if (statep == 4) encoder_count-­
-;
break;
}
default:
{
if (statep == 1) encoder_count-­
-;
if (statep == 3) encoder_count++;
break;
}
}
statep = state;
}
void get_speed(){
current_angle = (encoder_count*360.0)/(1632.67);
motor_speed = 0.01745*((current_angle

- previous_angle)/0.05);
previous_angle = current_angle;
}
void step_input(){
control = 0;
if (current_time >= 2000 && current_time <=

6000){
control = 12;
}
Digital Control with Arduino   ◾    57

if (current_time > 6000 && current_time <=



10000){
control = 6;
}
if (current_time > 10000 && current_time <=

14000){
control = 8;
}
if (current_time > 14000){
control = 0;
}
}
void setup(){
Serial.begin(9600);
previous_time = millis();
pinMode(2,INPUT);
pinMode(3,INPUT);
attachInterrupt(digitalPinToInterrupt(2),
Encoder_State, CHANGE);
attachInterrupt(digitalPinToInterrupt(3),
Encoder_State, CHANGE);
encoder_A = digitalRead(3);
encoder_B = digitalRead(2);
if ((encoder_A == HIGH) && (encoder_B == HIGH))

statep = 1;
if ((encoder_A == HIGH) && (encoder_B == LOW))

statep = 2;
if ((encoder_A == LOW) && (encoder_B == LOW))

statep = 3;
if ((encoder_A == LOW) && (encoder_B == HIGH))

statep = 4;
pinMode(pwm_output, OUTPUT);
}
void loop() {
current_time = millis();
int delta_time = current_time - previous_time;
if (delta_time > sampling_time){
elapsed_time = current_time/1000.0;
58   ◾    Digital Control of Power Converters

step_input();
get_speed();
analogWrite(pwm_output,(control/
supply_voltage)*255.0);
Serial.print(control);
Serial.print(" ");
Serial.print(elapsed_time);
Serial.print(" ");
Serial.println(motor_speed);
previous_time = current_time;
}
}

Let’s run the script and then from Tools menu, we select the
Serial Monitor option. Now we’ll take 15 seconds rows of data and
then on MATLAB, we’ll create 7 data variables that contain R, L,
K, J, b, and also, the measured Input_Data and Output_Data
which the first column is the elapsed_time and the second col-
umn is control and motor_speed, respectively, as depicted in
Figure 1.44.
Now, before the estimation tool can run, we’ll need to use some
initial values for all the parameters. So earlier we approximated
what K, R, and L could be. So, that’s what we’ll be using for their
initial values as illustrated in Figure 1.45.

FIGURE 1.44 Creating variables that contain the measured data.


Digital Control with Arduino   ◾    59

FIGURE 1.45 Obtaining parameter values.

However, for b and J, we’ll just pick some random values to


begin with (J = 0.001, b = 0.1). Now, we are opening up the
Simulink, and the file containing our motor model.
We’ll go to the apps tab and then open up parameter estimator.
From this window, we want to create a New Experiment. Next, we
want to pull the measured Output_Data and Input_Data from the
workspace and then we want to select the parameters (Select
Parameters), since we wish to estimate all those five parameters
(J, K, L, R, and b). Therefore, we select all of them and click on the
OK button.
Now, in order to get more realistic parameter estimation, we
want to set the Min and Max boundaries so that the tool doesn’t
vary any parameters too far from a realistic value. So, we’ll set the
Min and Max for K, R, and L to what we think they could be, and
because we don’t know b and J, we’ll leave its max alone but we’ll
want to set the minimum value to zero because realistically none
of these parameters should ever go negative as below.

J = 0.001, Minimum = 0, Maximum = Inf


K = 0.52, Minimum = 0.47, Maximum = 0.54
L = 0.0063, Minimum = 0.006, Maximum = 0.007
R = 4.4, Minimum = 3.8, Maximum = 5
b = 0.1, Minimum = 0, Maximum = Inf
60   ◾    Digital Control of Power Converters

Now, if you click on Plot button in that window, you should see the
measured input voltage and output speed data we got from the
Arduino.
Now let’s click on the Estimate button, you can see that the tool
is running some sort of optimization algorithm to curve fit the
simulation output to the measured output and it’s doing this by
iterating and varying the parameters. Now, once we’ve come to a
close enough fit, the tool stops estimating and our parameter val-
ues should have automatically been updated by clicking on the
Exp icon in Experiments sub-­window.
Now, using the following script as given below, we can get the
approximate transfer function for our DC gearmotor as the fol-
lowing equation:

0.47
P (s) = 2
(1.62)
3.425e − 5s + 0.01859s + 0.2211

J = 0.004893;
b = 5.8147e-­
5;
K = 0.47;
R = 3.8;
L = 0.006999;
num = K;
den = [J*L,(J*R)+(b*L),(b*R)+(K^2)];
sys = tf(num,den);

So, step 1, which is obtaining the plant’s transfer function P(s), is


complete. So, let’s stop here for now, until now, we’ve gotten an
approximate transfer function. In the next section, we’ll move on to
selecting an appropriate sampling time and design your controller.

1.8.2 Controller Design
In this section, we will continue the controller design process for
DC motor speed control example. So, we dedicated the previous
section to obtaining an approximate transfer function for DC
gearmotor which is shown in Figure 1.46.
Digital Control with Arduino   ◾    61

FIGURE 1.46 Obtaining an approximate transfer function for DC


gearmotor.

So, moving on to step 2, we must find a sampling time, T, for


our control loop. So, as we discussed a couple of sections ago, the
sampling frequency should be at least 5–10 times higher than the
bandwidth of the open-­loop system, P(s). Using the following
MATLAB code, we can obtain the Bode plot for our system.

s = tf(‘s’);
P_s = 0.47/(3.425e-­
5*s^2 + 0.01859*s + 0.2211);
bode(P_s);
grid on;

From observing the magnitude plot, we can see that the DC


gain is around 6.55 dB and the bandwidth of the system is at the
frequency 3 dB below the DC gain, so, moving down 3 dB below,
we get to 3.55 dB and the frequency at this gain 12.1 rad/s or 1.93 Hz.
So, the bandwidth of our system is 1.93 Hz or around 2 Hz. So,
we’ll multiply this by 10 and arrive at a sampling frequency of 20
Hz which correlates to a sampling time of 50 milliseconds as
shown in Figure 1.47 and equation below:

1 1
T= = = 0.05seconds (1.63)
f 20
62   ◾    Digital Control of Power Converters
FIGURE 1.47 Choosing a sampling time, T.
Digital Control with Arduino   ◾    63

FIGURE 1.48 The continuous-­time block diagram for our control loop.

So now that, we have our sampling time and step 2 is complete.


Now let’s move on to designing a continuous-­time controller C(s),
as shown in Figure 1.48, which is the continuous-­time block dia-
gram for our control loop and here after C(s) we have a PWM driver
block with gain of 1, the P(s) is the transfer function of DC gearmo-
tor obtained in the previous section, and H(s) is the transfer func-
tion of encoder with the gain of 1. Because the encoder is simply
providing pulse count data that is to be interpreted by the Arduino
as a speed value in rad/s, we can just set the encoders transfer func-
tion, H(s), as a gain of 1, so we have the following equation:

H (s) = 1 (1.64)

So, this is our closed-­loop transfer function that relates a set


point to our output speed as the following equation:

θ ( s ) C (s)P (s)
R (s)
Gθ= = (1.65)
R ( s ) 1 + C ( s ) P ( s ) GZOH ( s ) H ( s )

Also, knowing that each H(s) is equal to 1, Equation (1.54), we


get the following expression:

θ ( s ) C (s)P (s) C (s)P (s)


(s)
Gθ R= = =
R ( s ) 1 + C ( s ) P ( s ) GZOH ( s ) 1 + T ( s )
(1.66)

T ( s ) = C ( s ) P ( s ) GZOH ( s ) H ( s ) (1.67)
64   ◾    Digital Control of Power Converters

FIGURE 1.49 Adding explicit transfer functions for P(s) and GZOH(s).

With T(s), is being our loop gain. Here as depicted in Figure


1.49 is a closed-­loop block diagram except with the explicit trans-
fer functions shown for P(s) and GZOH(s).
Therefore, the explicit transfer functions for GZOH(s) are given
in the following equation:

1 − e − sT
GZOH ( s )
= = , T 0.05sec (1.68)
sT

Now, it’s quite apparent that designing a controller from this


point can be quite difficult because GZOH(s) has an exponential
term and therefore it’s irrational. We should approximate GZOH(s)
further to a rational function to make the control design easier for
MATLAB. The control design tools in MATLAB tend to work
more nicely with the rational transfer functions as opposed to
transfer functions that have exponential terms in them. So, using
an approximation technique known as the Pade approximation,
the exponential term can be approximated as a rational function
with ever-­increasing orders of precision, so the higher the order,
the better the approximation as the equation below:

1 1  1   1  4  1  5
1 +   x +   x2 +   x3 +   x +  30240  x ...
Pade Appr. : e x = 2 9  72   1008   
1 1 2  1  3  1  4  1  5
1−  x +  x −  x +   x −  30240  x ...
2 9  72   1008   
(1.69)
Digital Control with Arduino   ◾    65

Now, of course, doing this by hand is impractical but luckily


MATLAB has a function (available with Control System Toolbox)
called pade(sys,n) with sys = transfer function, n = approximation
order, which if you give it the irrational transfer function and a desired
order n, it will output the approximate rational transfer function. So,
using the following MATLAB script, we can obtain the following
rational transfer function for GZOH(s) and we’ll call that GZOHP(s):

40s 3 + 960000s
GZOHP ( s ) =
s 4 + 240s 3 + 24000s 2 + 960000s (1.70)

T = 0.05; %sampling time T = 0.05 seconds


s = tf(‘s’);
G_zoh = (1-­
exp(-s*T))/(s*T); %original ZOH/
sampling delay transfer function
G_zohp = pade(G_zoh,3); % 3rd order approximation

So now that, we know that both P(s) and GZOHP(s) are rational
and we can go ahead and design C(s) as shown in Figure 1.50.
Now, for controlling the speed and position of a DC motor,
typically a proportional integral (PI) controller is used in the
industry and most conventional DC motors have their output
speed regulated using a PI controller as the following equation:

Ki
C (=
s) K p + (1.71)
s

FIGURE 1.50 The rational transfer functions for P(s) and GZOHP(s) in
the control loop.
66   ◾    Digital Control of Power Converters

So now, we can design C(s) using classical control techniques such


as root locus, frequency response analysis, or some other complicated
control design method but look at the transfer function we’re dealing
with in total they make up a six-­order system. Now if you want to do
root locus or frequency response analysis on a six-­order system, you
can. However, we think it’s a lot more convenient to use the control
design tools that are available with MATLAB. Now luckily because
we’re designing a controller that’s a part of the proportional integral
derivative (PID) family, we can use the pidTuner(sys) app that’s avail-
able with the control system toolbox and the code is as below.

T = 0.05; %sampling time T = 0.05 seconds


s = tf(‘s’);
P_s = 0.47/(3.425e-­5*s^2 + 0.01859*s + 0.2211);
%DC gear motor’s transfer %function P(s)
G_zoh_s = (1-­exp(-s*T))/(s*T); %ZOH/Sampling’s
continuous-­
time effect transfer function G_zoh(s)
G_zohp_s = pade(G_zoh_s,3); %3rd order Pade
approximation of G_zoh(s)
sys = P_s*G_zohp_s; %total open-­ loop gain
pidTuner(sys); %launch PID Tuner App on MATLAB

We declare our transfer functions P(s) and GZOHP(s) and then


we multiply them to get the total effect of open-­loop transfer func-
tion. Then we store it in a variable which we’ll call ‘sys’ which is
short for system. We then call the pidTuner(sys) function with
‘sys’ being the input argument. Now, before we run the script, we
want to set some design requirements. We would like the settling
time for the output transient to be less than 2 seconds. The over-
shoot and undershoot to be under 5% of the steady-­state value and
the steady-­state error to be less than 3% of the steady-­state value.
So, the design requirements are:

• Settling time less than 2 seconds


• Overshoots and undershoots should be under 5%
• Steady-­state error should be less than 3%
Digital Control with Arduino   ◾    67

So now let’s run the script, so the PID tuner raptured open up
automatically and by default it seems like it chose a PI controller
on its own, and what you see now is a step response of the closed-­
loop system’s output and upon the top that are sliders that we can
use to adjust the response time and transition behavior such that
it meets our criteria, and on the bottom right should be the Kp and
the Ki gain values that it correlates to. So, we’ll play around with
this plot until we think it looks good. So, this response seems to
work and if we click on the Show Parameters tab, we can see the
gain values, the settling time, overshoot percentage, and the sta-
bility margins as depicted in Figure 1.51.
So far, they all meet our criteria and we think we’ll go with this
design, so, this is our continuous-­time PI controller with Kp that is
equal to 0.427 and Ki is equal to 5.114 and we have the following
equation:

Ki 5.114
C (s) = K p + = 0.427 + (1.72)
s s

FIGURE 1.51 Clicking on the Show Parameters tab.


68   ◾    Digital Control of Power Converters

FIGURE 1.52 Complete design of continuous-­time control loop.

So now that, we have got our continuous-­time controller, and


step 3 is complete as illustrated in Figure 1.52.
Now, we have to discretize it using Tustin’s method by running
the following MATLAB script that contains a c2d function with
the method set to Tustin.

T = 0.05; %sampling time T = 0.05 seconds


s = tf(‘s’);
C_s = 0.427 + (5.114/s); %continuous-­ time
controller C(s)
C_z = c2d(C_s,T,’tustin’); %discretized
controller C(z)

We get the following discrete transfer function C(z), and we


divide the numerator and the denominator by ‘z’ to get it into his
causal expression as the equation below:

U ( z ) 0.5548z − 0.2991 0.5548 − 0.2991z −1


=
C (z ) =
E (z ) z −1
=
1 − z −1
(1.73)

So now, step 4 is complete and now we have to take the inverse


Z-­transform to get the difference equation. Now we take C(z)
from Equation (1.73) which relates our error E(z) to our control
signal U(z) and cross multiply the terms and, after distributing,
Digital Control with Arduino   ◾    69

we then take the inverse Z-­transform to get a difference equation


as the following equations:

(
U ( z ) 1= ) (
− z −1 E ( z ) 0.5548 − 0.2991z −1 ) (1.74)

U ( z ) − U ( z ) z −=
1
E ( z ) 0.5548 − E ( z ) 0.2991z −1 (1.75)

Z {}−1
(1.64 )  → u n  − u=
n − 1 0.5548e n  − 0.2991e n − 1
(1.76)

Then we bring all the delayed input and output terms to the
right side as the equation below:

u n = u n − 1 + 0.5548e n  − 0.2991e n − 1 (1.77)

Now, we’ve obtained the controller’s difference equation that


relates our discrete error signal e[n] to our discrete control output
u[n]. So now, step 5 is complete. Now, all we have to do is to imple-
ment the controller on the Arduino and see the closed-­loop speed
control in action and we’ll do this in the next section.

1.8.3 Arduino Demonstration
In this final section, we’ll finally implement the digital controller
designed in the previous section to regulate the speed of our DC
gearmotor. So, we dedicated the last two sections to completing
steps 1–5. Now all that remains is implementing the controller on
the Arduino to demonstrate the closed-­loop control. However,
before we go ahead and code up the script, we are going to first
simulate this control structure to see what type of behavior we
should expect. Shown here in Figure 1.53 is the Simulink block
diagram for our closed-­loop feedback system. Notice that there’s a
saturation block after the controller. Now what does this block
will do is to limit the control signal to be within the bounds of
70   ◾    Digital Control of Power Converters

FIGURE 1.53 The Simulink block diagram for our closed-­loop feedback
system.

0–12 volts and that’s because our real power supply for our PWM
driver is set to 12 volts.
Also, because the control signal of 12 V correlates to a PWM
duty cycle of 100% so it’s inherently the maximum voltage we can
apply. So, a good way to test the feedback system is by stepping the
desired set point to a few speed values and observing how well the
output speed tracks the set point. So, using the staircase signaling
block, we create the set points signal where every four seconds, the
set point changes abruptly to a few different values and we’re
observing the plots for the desired set point and the measured
speed as shown in Figure 1.53. Let’s run the file, while observing
the plot, you can see that it tracks the set point speed very well and
it also meets our design right here in regard to the settling time,
overshoot, and steady-­state error as shown in Figure 1.54.
So, in simulation, our results look good. Now, let’s go imple-
ment this exact same test on the Arduino setup. So, here is the
Arduino script.
Digital Control with Arduino   ◾    71

FIGURE 1.54 Plot of tracking the set point speed.

int T = 50; // sampling time T = 50ms


unsigned long previous_time, current_time;
// variables to hold time values
float encoder_count = 0; // initialize encoder
count to 0
boolean encoder_A, encoder_B;
byte state, statep;
float previous_angle, current_angle = 0;
// set current and previous angle //values to 0
float output_speed = 0; // initialize
output speed to 0
float supply_voltage = 12; // the supply
voltage for our PWM motor driver //is 12V, so we
set this to 12
float elapsed_time = 0;
float setpoint; // declare setpoint variable
float e, e_1, u, u_1 = 0; // delcare e[n],
e[n-­
1], u[n], and u[n-­1]
72   ◾    Digital Control of Power Converters

const int pwm_output = 7; // label digital


pin 7 as the PWM output
void Encoder_State(){ // this function is
used for encoder pulse counting
encoder_A = digitalRead(3);
 // read pulse
data from encoder’s pin A
encoder_B = digitalRead(2);
 // read pulse
data from encoder’s pin B
if ((encoder_A == HIGH) && (encoder_B == HIGH))

state = 1;
if ((encoder_A == HIGH) && (encoder_B == LOW))

state = 2;
if ((encoder_A == LOW) && (encoder_B == LOW))

state = 3;
if ((encoder_A == LOW) && (encoder_B == HIGH))

state = 4;
switch (state)
{
case 1:
{
if (statep == 2) encoder_count-­
-;
if (statep == 4) encoder_count++;
break;
}
case 2:
{
if (statep == 1) encoder_count++;
if (statep == 3) encoder_count-­
-;
break;
}
case 3:
{
if (statep == 2) encoder_count++;
if (statep == 4) encoder_count-­
-;
break;
}
default:
{
Digital Control with Arduino   ◾    73

if (statep == 1) encoder_count-­
-;
if (statep == 3) encoder_count++;
break;
}
}
statep = state;
}
void get_speed(){
current_angle = (encoder_count*360.0)/(1632.67);
// 1632.67 is the total //number of counts per
revolution. Because it’s a 48 CPR encoder and a
34.1 //gearmotor, you multiply 48 x 34.1 =
1632.67
output_speed = 0.0175*((current_angle - previous_

angle)/0.05); // 0.0175 rad/s = 1 degree.
The formula is essentially calculating theta_dot
// or dteta/dT, where dT = 0.05, is the sampling
time in seconds
previous_angle = current_angle;
}
void step_setpoint(){ // a stair-­
case setpoint
input signal to test the //transient response of
the control loop
setpoint = 0;
if (current_time >= 4000 && current_time <=

8000){
setpoint = 5;
 // after 4 seconds,
setpoint = 5 rad/s for 4 seconds
}
if (current_time > 8000 && current_time <=

12000){
setpoint = 20;
 // setpoint = 20 rad/s
for 4 seconds
}
if (current_time > 12000 && current_time <=

16000){
setpoint = 12;
 // setpoint = 12 rad/s
for 4 seconds
}
74   ◾    Digital Control of Power Converters

if (current_time > 16000){


setpoint = 0;
}
}
void setup(){
Serial.begin(9600);
previous_time = millis();
pinMode(2,INPUT);
 // set digital pin 2
as an input
pinMode(3,INPUT);
 // set digital pin 3
as an input
attachInterrupt(digitalPinToInterrupt(2),
Encoder_State, CHANGE);
attachInterrupt(digitalPinToInterrupt(3),
Encoder_State, CHANGE);
encoder_A = digitalRead(3);
encoder_B = digitalRead(2);
if ((encoder_A == HIGH) && (encoder_B == HIGH))

statep = 1;
if ((encoder_A == HIGH) && (encoder_B == LOW))

statep = 2;
if ((encoder_A == LOW) && (encoder_B == LOW))

statep = 3;
if ((encoder_A == LOW) && (encoder_B == HIGH))

statep = 4;
pinMode(pwm_output, OUTPUT);
 // set pwm_
output or pin 7 as the PWM signal’s output pin
}
void loop() {
current_time = millis(); // store the elapsed
time in milliseconds
int delta_time = current_time - previous_time;
// calculate the delta //time or time difference
in milliseconds
if (delta_time > T){ // if the time
difference is equal to 50 ms, execute the if
statement. Doing so, keeps a consistent sampling
interval of //50ms
Digital Control with Arduino   ◾    75

elapsed_time = current_time/1000.0; // stores



the elapsed time in seconds
step_setpoint();
 // call out desired
setpoint speed signal
get_speed();
 // obtain our output_
speed signal in rad/s
e = setpoint - output_speed;
 // calculate
the error e[n]
u = u_1 + 0.555*e - 0.299*e_1;
 // calculate
the control signal u[n], this is our difference
equation derived from C(z)
if (u >= 12.0){
 // if statement is used to
saturate the control signal value between 0(V)
and 12(V)
u = 12;
}
else if(u <= 0){
u = 0;
}
analogWrite(pwm_output,(u/supply_voltage)*255.0);
// maps the control signal values linearly to
PWM duty cycle %’s. 0 - 12 correlates to 0%
- 100%.
u_1 = u;
 / store u[n] --> u{n-­1] for next
iteration
e_1 = e;
 // store e[n] --> e{n-­1] for next
iteration
Serial.print(elapsed_time);
 // Serial print
the elapsed time(s) and the output_speed or
measured speed(rad/s)
Serial.print(" ");
Serial.println(output_speed);
previous_time = current_time;
 // store
current_time --> previous_time for next loop
iteration
}
}
76   ◾    Digital Control of Power Converters

You can see that the controller is implemented as a difference


equation as we expected inside the void loop function. You can
also see that we’ve declared an input set point function (step_set-
point) that mimics the input set point signal from the simulation.
We’ve also included some code to saturate or limit the control
output between 0 and 12. So, let’s monitor the set point signal and
the measured output speed on the Serial Plotter and observe the
DC gearmotor’s behavior as depicted in Figure 1.55.
So, it seems to be working as expected. You’ll notice that there’s
a lot of noise in the measured output. This is mainly due to the
noise in the encoder speed measurement, but again it’s very mini-
mal and the overall transient and steady-­state performance is
pretty good. With built-­in encoders, we don’t really expect them

FIGURE 1.55 Observe the DC gearmotor’s behavior on the Serial


Plotter.
Digital Control with Arduino   ◾    77

to have very precise or noiseless performance, but overall, this


control structure works and does exactly what we expected it to.
So, we did the MATLAB Simulink simulation, and then we did
the Arduino implementation on the real DC gearmotor. So now,
let’s compare the two results with one another and see how closely
they match or mismatch. We’ll modify our Arduino script to out-
put the elapsed time and the output speed and collect 17 seconds
with the data using the Serial Monitor.
Then on MATLAB, we’ll create a variable called Measured_
Speed and enter in two columns of that, this elapsed time (column
1) and measured output speed (column 2) data as shown in
Figure 1.56.

FIGURE 1.56 Creating a variable string with this measured output


speed data.
78   ◾    Digital Control of Power Converters

FIGURE 1.57 Feeding data from the workspace and plot against the
simulated data – Part 1.

Then on Simulink, we’ll feed this data to From the Workspace


block and fill in its Data as Measured_Speed and set the Sample
time as 0.05 and plot on the scope against the simulated output
data and the simulated set point as shown in Figures 1.57 and
1.58, respectively.
As shown in Figure 1.59, the theoretical result and measured
result match very well with the exception of the noise on the mea-
sure data and you can see that even the transient parts of the mea-
sure data match pretty close with the simulated data.
So, this comparison proves three things. First, the transfer
function we approximated for our actual DC gearmotor was a
good enough approximation to use for our controller design step
Digital Control with Arduino   ◾    79
FIGURE 1.58 Feeding data from the workspace and plot against the simulated data – Part 2.
80   ◾    Digital Control of Power Converters

FIGURE 1.59 Comparison of the theoretical result and measured result.

process. Second, the closed-­loop control structure on Simulink is


a very accurate simulation of the real physical closed-­loop system,
and, third, the six-­step controller design process is theoretically
and practically a sound method to use to design a simple digital
controller for your continuous-­time system, so that is all.
CHAPTER 2

Theoretical Overview
of the Buck Converter

2.1 BUCK CONVERTER DESIGN


In this chapter, we will cover the basic design of a buck converter
and implement closed-­loop control for it. This system has both
voltage and current sensors. We do not dive deeply into theoretical
analysis of buck converters, because this book is practically ori-
ented. So, we will not consider the derivation of the buck converter
equations and we will just present them. The schematic of the basic
buck converter is shown in Figure 2.1.
We have an input voltage, VIN, a MOSFET, Q, a diode, D, an
inductor, L, a capacitor, C, and a resistive load. The load can be
active, for example, a battery or other type of loads, but in this
case, a resistor has been used for analysis. We have also the output
current, Io, inductor current, IL , and output voltage, Vo. The
parameters of the buck converter which are constant and designed
for a particular case are listed in Table 2.1.

DOI: 10.1201/9781003541356-2 81
82   ◾    Digital Control of Power Converters

FIGURE 2.1 The schematic of basic buck converter.

TABLE 2.1 Parameters of the Buck Converter


Parameters Values

Vin 24 V
Vout 16 V
Iout( = iL) 2.133 A
Rout 7.5 Ω
∆VO, pk − pk 0.02 Vout
∆IL, pk − pk 0.1 Iout
rESR 3 mΩ
rL 300 mΩ
Vfwd 1.15 V
Vds, sat 0.075 V
L 200 μH
C 40 μF
fsw 100 kHz

For the sake of analysis, we choose the inductor current ripple to be


10% of inductor current, using the following equations for duty cycle,
D, and inductor, L, we get the duty cycle and inductance values:

Vfwd  iL rL  Vout
D  0.7094 (2.1)
Vin  Vfwd  Vce,sat
Theoretical Overview of the Buck Converter   ◾    83

L
Vin  Vce,sat  iL rL  Vout   D  243.3  H (2.2)
I L , pk  pk f sw

Because of the size of the inductor, we choose the inductor L to


be 200 μH and let the inductor current ripple to be 15% of induc-
tor current. Additionally, the output voltage ripple, which is 2% of
the output voltage, and the actual capacitor value (40 μF) signifi-
cantly exceed the calculated value for capacitor C (0.83 μF), as
shown in the following equation:

I L , pk  pk
C  0.83  F (2.3)
8Vo, pk  pk f sw

Then we have the following small signal transfer function


which is crucial in designing the buck converter [5]:

i o  s  1  sCrESR  Vin  Vfwd  Vds,sat 



d  s   LCR  LCrESR  s 2   CRrL  CrESR rL  CRrESR  L  s  rL  Rout
(2.4)

We should note that these equations cannot be used to other


converters. Also, the output voltage to duty cycle small signal
transfer function is as below:

v o  s  Rout 1  sCrESR  Vin  Vfwd  Vce,sat 



d  s   LCR  LCrESR  s 2   CRrL  CrESR rL  CRrESR  L  s  rL  Rout
(2.5)

Notice that the parasitic parameters, that is, equivalent series


resistance of capacitor and inductor resistance, are denoted by rESR,
84   ◾    Digital Control of Power Converters

and rL respectively. If we substitute the parameters in Table 2.1 in


the above equations, we will have the following relations:

i o  s  3.009  106 s  25.07


 (2.6)
d  s  6.003  10 s  0.0002912s  7.801
8 2

v o  s  2.257  105 s  188.1


 (2.7)
d  s  6.003  10 s  0.000291s  7.801
8 2

For designing a PI controller for current control loop or voltage


control loop, we can use MATLAB. In the previous chapter, we
used MATLAB functions (pidTuner and c2d tools) for designing a
digital PID controller for our control loop. To design a PI control-
ler for the current control loop using MATLAB, the following code
can be applied:

s = tf(‘s’);
Gid = (3e-­6*s+25.07)/(6e-­8*s^2+0.000291*s+7.801);
pidTuner(Gid);

By executing the above code, the PID tuner window is popped up.
We select the type of controller as PI and its form as Standard and
then regulate the Response Time and Transient Behavior sliders to
get desired Step Plot. Then, if we click on Show Parameters button, we
can see our controller parameters. Finally, we click on the Export
button and give it a name for our PI controller. In this case, we chose
‘Cont’ as its name and click on the OK button as shown in Figure 2.2.
Now, in the command window, if we type the name (‘Cont’)
and then press the Enter key, you can get the controller transfer
function as the following equation:

 Kp 
 

Gc  s   K p  1 
1 
 K   Ti   3.11 105  120.5 (2.8)
 p
 Ti s  s s
Theoretical Overview of the Buck Converter   ◾    85

FIGURE 2.2 The PID tuner window.

K p  3.11 105 , Ti  2.58  107 (2.9)

If you want to implement analog controller using op-­amp, the


above equation is enough. However, for use in a digital controller,
the following substitutions must be applied (Tustin’s method):

s
2  z  1 2 1  z

 1
 (2.10)

Ts  z  1 Ts 1  z 1 
where TS is the sampling time and is chosen as 100 μs, so we have:

 Ts  z  1 
Gc  z   K p 1 
 2Ti  z  1 
 
K p  z  1  K pTs  z  1 /  2Ti 

 z  1 (2.11)


 K p  K pTs /  2Ti  z  K pTs /  2Ti   K p
z 1
0.0061z  0.006

z 1
86   ◾    Digital Control of Power Converters

0.006z 1  0.0061
Gc  z   (2.12)
z 1  1

We can also use the c2d function in MATLAB to get the


discrete-­time transfer function from Gc(s) using the following
code in the command window as depicted in Figure 2.3.

c2d(Cont,100e-­6,’tustin’)

Correlating the equation above with the standard form, we will


have the following equation:

B3 z 3  B2 z 2  B1z 1  B0 yn
Gc  z    (2.13)
 A3 z 3  A2 z 2  A1z 1  1 en

FIGURE 2.3 The PI controller transfer function in continuous-­and


discrete-­time domain.
Theoretical Overview of the Buck Converter   ◾    87

=
A1 1,=
B0 0.0061, B1 = 0.006 (2.14)

The equivalent equation is given as follows:

yn  A3 yn3  A2 yn2  A1 yn1  B3en3  B2en2  B1en1  B0 en


(2.15)

To design a PI controller for voltage control loop, the same as


the current control loop, we can use pidTuner and c2d tools in
MATLAB. To design a PI controller for the voltage control loop
using MATLAB, the following code can be applied.

s = tf(‘s’);
Gvd = (2.257e-­5*s+188.1)/(6e-­8*s^2+0.000291*s
+7.801);
pidTuner(Gvd);

By executing the above code, the PID tuner window is popped


up. We select the type of controller as PI and its form as Standard
and then regulate the Response Time and Transient Behavior slid-
ers to get desired Step Plot. Then, if we click on Show Parameters
button, we can see our controller parameters. Finally, we click on
the Export button and give it a name for our PI controller, in this
case, we chose ‘Cv’ as its name and click on the OK button as
shown in Figure 2.4.
Now, in the command window, if we type the name (‘Cv’) and
then press the Enter key, you can get the controller transfer func-
tion as the following equation:

 Kp 
 
 1   Ti  16.05
Gc  s   K p  1    Kp   4.14  106  (2.16)
 Ti s  s s
88   ◾    Digital Control of Power Converters

FIGURE 2.4 The PID tuner window.

K p  4.14  106 , Ti  2.58  107 (2.17)

If you want to implement analog controller using op-­amp, the


above equation is enough. However, for use in a digital controller,
the following substitutions must be applied (Tustin’s method):

s
2  z  1 2 1  z

 1
 (2.18)

Ts  z  1 Ts 1  z 1 
where TS is the sampling time and is chosen as 100 μs, so we have:

 Ts  z  1 
Gc  z   K p 1 
 2Ti  z  1 
 
K p  z  1  K pTs  z  1 /  2Ti 

 z  1 (2.19)


 K p  K pTs /  2Ti  z  K pTs /  2Ti   K p
z 1
0.00081z  0.0008

z 1
Theoretical Overview of the Buck Converter   ◾    89

FIGURE 2.5 The PI controller transfer function in continuous-­and


discrete-­time domain.

0.0008z 1  0.00081
Gc  z   (2.20)
z 1  1

We can also use the c2d function in MATLAB to get the


discrete-­time transfer function from Gc(s) in the command win-
dow, with the code below as depicted in Figure 2.5.

c2d(Cv,100e-­6,’tustin’)

Correlating the equation above with the standard form, we will


have the following equation:

B3 z 3  B2 z 2  B1z 1  B0 yn
Gc  z    (2.21)
 A3 z 3  A2 z 2  A1z 1  1 en
90   ◾    Digital Control of Power Converters

=
A1 1,=
B0 0.00081, B1 = 0.0008 (2.22)

The equivalent equation is given as follows:

yn  A3 yn3  A2 yn2  A1 yn1  B3en3  B2en2  B1en1  B0 en


(2.23)

In continuous conduction mode (CCM), we keep the inductor


current ripple very low (usually lower than 20%). We select the
inductor, L, lower than the calculated value in Equation (2.2), for
practical reasons. Now, we are going to introduce another method
for controller design. Here, we are going to set the controller as
simple as possible. We use the phase margin to design the control-
ler. So, we set up the phase margin that we wanted and designed the
controller to meet that phase margin at a specific crossover fre-
quency. The crossover frequency in control systems refers to the
frequency at which the magnitude of the open-­loop transfer func-
tion is equal to 1 or 0 dB. The switching frequency, on the other
hand, refers to the frequency at which a switching device (such as a
transistor in a power converter) turns on and off. There is no direct
relationship between the crossover frequency and the switching
frequency in control systems. These are two separate concepts that
relate to different aspects of a system. However, the choice of
switching frequency in a power converter can indirectly affect the
crossover frequency of the control system that is regulating the
converter. For example, a higher switching frequency in a power
converter may allow for faster response times in the control system,
which could potentially impact the crossover frequency. Ultimately,
the crossover frequency is determined by the design of the control
system itself and is not directly tied to the switching frequency. In
this case, the crossover frequency is chosen to be fc = 2 kHz. So, for
the current controller, we have the following equations:

s  jc  j2 f c  j12566.4 (2.24)


Theoretical Overview of the Buck Converter   ◾    91

i o  j12566.4 
 2.6    6.236  114.6 (2.25)
d  j12566.4 

Gain = 6.236 (2.26)

Phase  114.6 (2.27)

The following equations are used to determine the compensa-


tion required to do that we specify a phase margin in crossover
frequency and calculate the required compensation phase:

PM  59 (2.28)

crossover  comp  180  PM (2.29)

comp  PM  crossover  180 (2.30)

 
comp  59  114.6  180  6.4 (2.31)

We usually choose phase margin between 40 and 60 degrees.


However, we do not want the system to be unstable, so we have
selected higher phase margin in this case which is 59 degrees. If
the compensator phase is positive, you will need a lead-­lag com-
pensator. If the compensator phase is negative, you will need a lag
compensator, which in this case is a PI controller. Using the above
equations, a lag compensator is adequate, so the PI compensator is
of the form:

 
Gc  s   K p  i  1  (2.32)
 s 
92   ◾    Digital Control of Power Converters

  
Gc  jc   K p  i  1  (2.33)
 jc 

 
Gc  jc    tan 1  i  (2.34)
 c 

 
6.4   tan 1  i  (2.35)
 c 

 
i  c  tan 6.4 (2.36)

 
i  12566.4  tan 6.4  1409.55 rad / s (2.37)

The value for Kp is found using the following equations:

2
 i  1 1
Gc  jc   K p     1  Gain  6.236 (2.38)
 c

1 / 6.236
Kp   0.159 (2.39)
 tan 6.4   1
2


Since, in the crossover frequency, the gain of compensated sys-


tem should be equal to 0 dB or 1. Therefore, the controller transfer
function is of the form:

   1409.55  224.12
Gc  s   K p  i  1   0.159   1   0.159 
 s   s  s
(2.40)
Theoretical Overview of the Buck Converter   ◾    93

We will have the identical crossover frequency for voltage con-


trol loop as well. The following equations are applied for the volt-
age controller. At 2 kHz, the following info is obtained:

s  jc  j2 f c  j12566.4 (2.41)

v˘o  j12566.4 
 2. 7   ˘
 46.79  114.6 (2.42)
d  j12566.4 

Gain = 46.79 (2.43)

Phase  114.6 (2.44)

The following equations are used to determine the compensa-


tion required to do that we specify a phase margin in crossover
frequency and calculate the required compensation phase:

PM  59 (2.45)

crossover  comp  180  PM (2.46)

comp  PM  crossover  180 (2.47)

 
comp  59  114.6  180  6.4 (2.48)

We usually choose phase margin between 40 and 60 degrees.


However, we do not want the system to be unstable, so we have
selected higher phase margin in this case which is 59 degrees. If
the compensator phase is positive, you will need a lead-­lag com-
pensator. If the compensator phase is negative, you will need a lag
94   ◾    Digital Control of Power Converters

compensator, which in this case is a PI controller. Using the above


equations, a lag compensator is adequate, so the PI compensator is
of the form:

 
Gc  s   K p  i  1  (2.49)
 s 

  
Gc  jc   K p  i  1  (2.50)
 jc 

 
Gc  jc    tan 1  i  (2.51)
 c 

 
6.4   tan 1  i  (2.52)
 c 


i  c  tan 6.4o  (2.53)

 
i  12566.4  tan 6.4  1409.55 rad / s (2.54)

The value for Kp is found using the following equations:

2
 i  1 1
Gc  jc   K p     1  Gain  46.79 (2.55)
 c

1 / 46.79
Kp   0.021 (2.56)
 tan 6.4   1
2

Theoretical Overview of the Buck Converter   ◾    95

Since, in the crossover frequency, the gain of compensated sys-


tem should be 0 dB or 1. Therefore, the controller transfer func-
tion is of the form:

   1409.55  29.6
Gc  s   K p  i  1   0.021  1   0.021 
 s   s  s
(2.57)

We can use Google Colab for Bode plots of closed-­loop current


and voltage control with PI controllers designed by MATLAB pid-
Tuner tool and phase margin-­based frequency response calcula-
tions. Google Colab is a free cloud-­ based Jupyter notebook
environment that allows users to write and execute Python code
in a browser. It provides access to free GPU and TPU resources,
making it a popular choice for data scientists and machine-­
learning researchers to work on computation-­ intensive tasks.
Google Colab also allows for easy sharing and collaboration on
projects, the Google Colab code is as below.

!pip install control


%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from control.matlab import *
Gid = tf([3e-­6, 25.07],[7.33e-­8, 0.0002912,
7.801])
Gvd = tf([2.257e-­ 5, 188.1],[7.33e-­
8, 0.000291,
7.801])
print("Gid = ", Gid)
print("Gvd = ", Gvd)
Gid = <TransferFunction>: sys[0]
Inputs (1): [‘u[0]’]
Outputs (1): [‘y[0]’]
96   ◾    Digital Control of Power Converters

3e-­06 s + 25.07
----------------------------------
7.33e-­
08 s^2 + 0.0002912 s + 7.801
Gvd = <TransferFunction>: sys[1]
Inputs (1): [‘u[0]’]
Outputs (1): [‘y[0]’]
2.257e-­
05 s + 188.1
---------------------------------
7.33e-­
08 s^2 + 0.000291 s + 7.801

The above codes are used for printing the transfer functions of
Gid and Gvd as given in Equations (2.6) and (2.7). The code below
is used for the Bode plot of Gid as illustrated in Figure 2.6.

w = np.logspace(1,5)
mag,phase,omega = bode(Gid,w)
plt.tight_layout()

FIGURE 2.6 The Bode plot of Gid.


Theoretical Overview of the Buck Converter   ◾    97

The Gci_mat is the transfer function of current controller


obtained by the pidTuner tool of MATLAB as given in the code
below.

Gci_mat = tf([3.11e-­5, 120.5],[1, 0])


print("Gci_mat = ", Gci_mat)
Gci_mat = <TransferFunction>: sys[3]
Inputs (1): [‘u[0]’]
Outputs (1): [‘y[0]’]

3.11e-­
05 s + 120.5
------------------
s

The feedback loop transfer function is the product of the plant


and controller transfer functions and the following code is used
for the Bode plot of it as shown in Figure 2.7.

FIGURE 2.7 The Bode plot of Gpci_mat.


98   ◾    Digital Control of Power Converters

FIGURE 2.8 The Bode plot of Tpci_mat.

Gpci_mat = Gid*Gci_mat
w = np.logspace(1,5)
mag,phase,omega = bode(Gpci_mat,w)
plt.tight_layout()

The closed-­loop transfer function and the code for the Bode
plot of it are depicted in Figure 2.8.

Tpci_mat = Gpci_mat/(1+Gpci_mat)
w = np.logspace(1,5)
mag,phase,omega = bode(Tpci_mat,w)
plt.tight_layout()

The Gci_pm is the transfer function of current controller obtained


by the phase margin calculations as given in the code below.

Gci_pm = tf([0.159, 224.12],[1, 0])


print("Gci_pm = ", Gci_pm)
Theoretical Overview of the Buck Converter   ◾    99

Gci_pm = <TransferFunction>: sys[10]


Inputs (1): [‘u[0]’]
Outputs (1): [‘y[0]’]

0.159 s + 224.1
---------------
s

The feedback loop transfer function is the product of the plant


and controller transfer functions and the following code is used
for the Bode plot of it as shown in Figure 2.9.

Gpci_pm = Gid*Gci_pm
w = np.logspace(1,5)
mag,phase,omega = bode(Gpci_pm,w)
plt.tight_layout()

FIGURE 2.9 The Bode plot of Gpci_pm.


100   ◾    Digital Control of Power Converters

FIGURE 2.10 The Bode plot of Tpci_pm.

The closed-­loop transfer function and the code for the Bode
plot of it are depicted in Figure 2.10.

Tpci_pm = Gpci_pm/(1+Gpci_pm)
w = np.logspace(1,5)
mag,phase,omega = bode(Tpci_pm,w)
plt.tight_layout()

The code below is used for the Bode plot of Gvd as illustrated in
Figure 2.11.

w = np.logspace(1,5)
mag,phase,omega = bode(Gvd,w)
plt.tight_layout()
Theoretical Overview of the Buck Converter   ◾    101

FIGURE 2.11 The Bode plot of Gvd.

The Gcv_mat is the transfer function of current controller obtained


by the pidTuner tool of MATLAB as given in the code below.

Gcv_mat = tf([4.14e-­6, 16.05],[1, 0])


print("Gcv_mat = ", Gcv_mat)
Gcv_mat = <TransferFunction>: sys[42]
Inputs (1): [‘u[0]’]
Outputs (1): [‘y[0]’]

4.14e-­
06 s + 16.05
------------------
s

The feedback loop transfer function is the product of the plant


and controller transfer functions and the following code is used
for the Bode plot of it as shown in Figure 2.12.
102   ◾    Digital Control of Power Converters

FIGURE 2.12 The Bode plot of Gpcv_mat.

Gpcv_mat = Gvd*Gcv_mat
w = np.logspace(1,5)
mag,phase,omega = bode(Gpcv_mat,w)
plt.tight_layout()

The closed-­loop transfer function and the code for the Bode
plot of it are depicted in Figure 2.13.

Tpcv_mat = Gpcv_mat/(1+Gpcv_mat)
w = np.logspace(1,5)
mag,phase,omega = bode(Tpcv_mat,w)
plt.tight_layout()

The Gcv_pm is the transfer function of current controller


obtained by the phase margin calculations as given in the code
below.

Gcv_pm = tf([0.021, 29.6],[1, 0])


print("Gcv_pm = ", Gcv_pm)
Theoretical Overview of the Buck Converter   ◾    103

FIGURE 2.13 The Bode plot of Tpcv_mat.

Gcv_pm = <TransferFunction>: sys[50]


Inputs (1): [‘u[0]’]
Outputs (1): [‘y[0]’]

0.021 s + 29.6
--------------
s

The feedback loop transfer function is the product of the plant


and controller transfer functions and the following code is used
for the Bode plot of it as shown in Figure 2.14.

Gpcv_pm = Gvd*Gcv_pm
w = np.logspace(1,5)
mag,phase,omega = bode(Gpcv_pm,w)
plt.tight_layout()

The closed-­loop transfer function and the code for the Bode
plot of it are depicted in Figure 2.15.
104   ◾    Digital Control of Power Converters

FIGURE 2.14 The Bode plot of Gpcv_pm.

FIGURE 2.15 The Bode plot of Tpcv_pm.


Theoretical Overview of the Buck Converter   ◾    105

Tpcv_pm = Gpcv_pm/(1+Gpcv_pm)
w = np.logspace(1,5)
mag,phase,omega = bode(Tpcv_pm,w)
plt.tight_layout()

As you can see in Bode plots in Google Colab for closed-­loop


current and voltage control using MATLAB pidTuner tool, and
phase margin calculations, the designed PI controller for current
and voltage control loops is stable. For further analysis, we can
compare the operation of designed PI controllers in MATLAB
Simulink. As illustrated in Figure 2.16, we are going to compare
the step or transient response of closed-­loop current and voltage
control with PI controllers designed by MATLAB pidTuner tool
and phase margin calculations.
The results of transient response of current and voltage control
loops with PI controllers designed by MATLAB pidTuner tool and
phase margin calculations are plotted on the scopes as shown in
Figures 2.17 and 2.18, respectively.

FIGURE 2.16 Comparing the transient response of current and voltage


control loops with PI controllers designed by MATLAB pidTuner tool
and phase margin calculations.
106   ◾    Digital Control of Power Converters

FIGURE 2.17 The step response of current control loop (up: MATLAB,
down: Phase Margin).

FIGURE 2.18 The step response of voltage control loop (up: MATLAB,
down: Phase Margin).
Theoretical Overview of the Buck Converter   ◾    107

Although the PI controllers with both methods are stable, how-


ever, the PI controllers designed by pidTuner tool of MATLAB
have better transient response than phase margin calculations.
Therefore, we will use the PI controllers designed by pidTuner tool
of MATLAB.

2.2 THE CONTROLLER DESIGN WITH OCTAVE


In this section, we are going to discuss about how to obtain
the digital controller coefficients for designing closed-­loop
buck converter controllers using STM32 microcontroller. To
do that, we can also apply the Octave software for designing
the PI controller, using phase margin calculations. Therefore,
you should first initialize the buck converter parameters as the
code below.

%clear all
pkg load control
s = tf(‘s’);
%Initialization of converter parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Vin = 24;
Vo = 16;
Io = 2.133;
Ro = Vo/Io;
fsw = 100000;
rL = 300e-­ 3;
rESR = 3e-­ 3;
Vds = 0.075;
Vfwd = 1.15;
iL = Io;
D = (Vfwd + iL*rL + Vo)/(Vin - Vds + Vfwd);
L = 200e-­6;
C = 40e-­6;
delta_iL = 0.1 * iL;
delta_Vo = 0.02 * Vo;
%L >= (Vin - Vds - iL*iL - Vo)*D/(fsw*delta_iL);
%C >= delta_iL/(8*delta_Vo*fsw);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108   ◾    Digital Control of Power Converters

The parasitic values are inductor resistance, rL, equivalent series


resistance of capacitor, rESR, saturation voltage of MOSFET, Vds, and
forward voltage drop of diode, Vfwd, which have very little effect on
output of the system, but it is useful to include them in practice. All
of the commands in Octave can be executed in MATLAB as well.
Then we initialize the crossover frequency which is very important
in controller design. In power supply design, we mostly focus on
crossover frequency of the converter frequency response. So, in
power supply design, we are focusing on frequency-­domain. If you
choose the crossover frequency high, your converter will be very
sensitive and it will respond basically to anything. So, we here do
not focus on disturbances, however, we will mostly focus on robust-
ness, so, if we change the set point, it will not affect the stability of
the converter. We define crossover frequencies for current and volt-
age separately as given in the following code.

%Initialization of the crossover frequency


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wc_i = 2*pi*2000;
fc_i = wc_i/(2*pi);
wc_complex_i = wc_i*1i;
wc_v = 2*pi*2000;
fc_v = wc_v/(2*pi);
wc_complex_v = wc_v*1i;
targ_PM_deg_i = 59;
targ_PM_deg_v = 59;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

The codes for small signal output current to duty cycle and out-
put voltage to duty cycle transfer functions are as below.

%Small Signal Transfer Functions


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Output Current to Duty Cycle beginning
Theoretical Overview of the Buck Converter   ◾    109

GIoD_num = (1+s*C*rESR)*(Vin - Vds + Vfwd);


GIoD_den = (L*C*Ro + L*C*rESR)*s^2 + (C*Ro*rL
+ C*rESR*iL + C*Ro*rESR + L)*s + rL + Ro;
GIoD = (GIoD_num/GIoD_den);
%Output Current to Duty Cycle ending
%Output Voltage to Duty Cycle beginning
GVoD_num = (1+s*C*rESR)*(Vin - Vds + Vfwd)*Ro;
GVoD_den = (L*C*Ro + L*C*rESR)*s^2 + (C*Ro*rL +
C*rESR*rL + C*Ro*rESR + L)*s + rL + Ro;
GVoD = (GVoD_num/GVoD_den);
%Output Voltage to Duty cycle ending
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

The realization of complex small signal output current to duty


cycle and output voltage to duty cycle transfer functions at the
crossover frequency is represented in the following code.

%Transfer functions to realize the gain and


phase at crossover frequency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Output Current to Duty Cycle gain_phase
beginning
g = wc_complex_i;
GIoD_num_g = (1+g*C*rESR)*(Vin - Vds + Vfwd);
GIoD_den_g= (L*C*Ro + L*C*rESR)*g^2 + (C*Ro*rL
+ C*rESR*rL + C*Ro*rESR + L)*g + rL + Ro;
GIoD_g= (GIoD_num_g/GIoD_den_g);
%Output Current to Duty Cycle gain_phase ending
%Output Voltage to Duty Cycle gain_phase beginning
g = wc_complex_v;
GVoD_num_g = (1+g*C*rESR)*(Vin - Vds + Vfwd)*Ro;
GVoD_den_g = (L*C*Ro+ L*C*rESR)*g^2 + (C*Ro*rL +
C*rESR*iL + C*Ro*rESR + L)*g + rL + Ro;
GVoD_g = (GVoD_num_g/GVoD_den_g);
%Output Voltage to Duty Cycle gain_phase ending
110   ◾    Digital Control of Power Converters

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

The code required for current and voltage controller design is


given as follows.

%Current Controller design begin


i_gain = abs(GIoD_g);
i_phase = angle(GIoD_g)*(180/pi);
targ_PM_rad_i = targ_PM_deg_i*(pi/180);
phase_comp_i = targ_PM_rad_i - (i_phase*(pi/180))
- pi;
fi_i = fc_i * tan(-1*phase_comp_i);
Kpi = (1/i_gain)/sqrt((fi_i/fc_i)^2 + 1);
wi_i = fi_i*2*pi;
%Current Controller design ends
%Voltage Controller design begin abs (GVOD_g);
v_gain = abs(GVoD_g);
v_phase = angle(GVoD_g)*(180/pi);
targ_PM_rad_v = targ_PM_deg_v*(pi/180);
phase_comp_v = targ_PM_rad_v - (v_phase* (pi/180))
- pi;
fi_v = fc_v * tan(-1*phase_comp_v);
Kpv = (1/v_gain)/sqrt((fi_v/fc_v)^2 + 1);
wi_v = fi_v*2*pi;
%Voltage Controller design ends

The codes for current and voltage controller transfer functions


and also current and voltage closed-­loop transfer functions are
illustrated below.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Gci = Kpi*(wi_i/s + 1);
Gcv = Kpv* (wi_v/s + 1);
%Gc1 = 1;
Ti = Gci*GIoD;
Tv = Gcv*GVoD;
Theoretical Overview of the Buck Converter   ◾    111

%Create a figure to hold the plots


%figure;
%Plot Bode plot for the system
%bode(Ti);
%bode(Tv);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

The following codes are used for calculating gain and phase
margins using closed-­loop transfer functions.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Calculate gain and phase margins
[gain_margin, phase_margin, crossover_
frequencies, phase_crossover] = margin(Ti);
%Display Current Bode Plot the results
fprintf(‘Current, Gain margin: %.2f dB\n’,
20*log10 (gain_margin));
fprintf(‘Current Phase margin: %.2f degrees \n’,
phase_margin);
fprintf(‘Current Crossover frequencies: %.2f
rad/s\n’, crossover_frequencies);
fprintf(‘Current Phase at crossover: %.2f
degrees\n’, phase_crossover);
[gain_margin, phase_margin, crossover_
frequencies, phase_crossover] = margin(Tv);
%Display Voltage Bode Plot the results
fprintf(‘Voltage Gain margin: %.2f dB\n’,
20*log10 (gain_margin));
fprintf(‘Voltage Phase margin: %.2f degrees\n’,
phase_margin);
fprintf(‘Voltage Crossover frequencies: %.2f
rad/s\n’, crossover_frequencies);
fprintf(‘Voltage Phase at crossover: %.2f
degrees\n’, phase_crossover);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112   ◾    Digital Control of Power Converters

For converting controller transfer functions from continuous


to digital mode or from s-­domain to z-­domain, we use the sam-
pling time of 100 μs as follows.

Gi_d = c2d(Gci, 100e-­


6);
Gv_d = c2d(Gcv, 100e-­
6);

So, in this case, the duty cycle is updated every 100 μs. We run
the program and go to the command window and get current and
voltage closed-­loop gain and phase margins with current and
voltage controllers with and without current and voltage control-
lers and then get the controllers transfer functions in z-­domain as
below.

>> loop_design_octave
Current, Gain margin: Inf dB
Current Phase margin: 59.06 degrees
Current Crossover frequencies: NaN rad/s
Current Phase at crossover: 12563.57 degrees
Voltage Gain margin: Inf dB
Voltage Phase margin: 58.94 degrees
Voltage Crossover frequencies: NaN rad/s
Voltage Phase at crossover: 12569.17 degrees
>> Gci
Transfer function ‘Gci’ from input ‘u1’ to output

0.1594 s + 225.5
y1: ----------------
s
Continuous-­time model.
>> Gcv
Transfer function ‘Gcv’ from input ‘u1’ to output

0.02127 s + 30.16
y1: -----------------
s
Continuous-­time model.
Theoretical Overview of the Buck Converter   ◾    113

>> Gi_d
Transfer function ‘Gi_d’ from input ‘u1’ to
output …
0.1594 z - 0.1369
y1: -----------------
z - 1
Sampling time: 0.0001 s
Discrete-­time model.
>> Gv_d
Transfer function ‘Gv_d’ from input ‘u1’ to
output …
0.02127 z - 0.01825
y1: -------------------
z - 1
Sampling time: 0.0001 s
Discrete-­time model.

These z-­domain transfer functions are actually what we want


to use in our codes. The ‘Io’ value in the initialization of converter
parameters at the beginning does not affect so much on the
designed robust system. So, the output current set point could be
changed in the firmware as you like in the reasonable range and it
will not make the system unstable. As mentioned before, we will
use the PI controllers obtained by pidTuner tool of MATLAB;
however, we can also use the PI controllers gained from phase
margin calculations by Octave programming. The whole code in
Octave software is as below.

%clear all
pkg load control
s = tf(‘s’);
%Initialization of converter parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Vin = 24;
Vo = 16;
Io = 2.133;
Ro = Vo/Io;
114   ◾    Digital Control of Power Converters

fsw = 100000;
rL = 300e-­ 3;
rESR = 3e-­ 3;
Vds = 0.075;
Vfwd = 1.15;
iL = Io;
D = (Vfwd + iL*rL + Vo)/(Vin - Vds + Vfwd);
L = 200e-­6;
C = 40e-­6;
delta_iL = 0.1 * iL;
delta_Vo = 0.02 * Vo;
%L >= (Vin - Vds - iL*iL - Vo)*D/(fsw*delta_iL);
%C >= delta_iL/(8*delta_Vo*fsw);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Initialization of the crossover frequency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wc_i = 2*pi*2000;
fc_i = wc_i/(2*pi);
wc_complex_i = wc_i*1i;
wc_v = 2*pi*2000;
fc_v = wc_v/(2*pi);
wc_complex_v = wc_v*1i;
targ_PM_deg_i = 59;
targ_PM_deg_v = 59;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Small Signal Transfer Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Output Current to Duty Cycle beginning
GIoD_num = (1+s*C*rESR)*(Vin - Vds + Vfwd);
GIoD_den = (L*C*Ro + L*C*rESR)*s^2 + (C*Ro*rL +
C*rESR*iL + C*Ro*rESR + L)*s + rL + Ro;
GIoD = (GIoD_num/GIoD_den);
%Output Current to Duty Cycle ending
%Output Voltage to Duty Cycle beginning
GVoD_num = (1+s*C*rESR)*(Vin - Vds + Vfwd)*Ro;
GVoD_den = (L*C*Ro + L*C*rESR)*s^2 + (C*Ro*rL +
C*rESR*rL + C*Ro*rESR + L)*s + rL + Ro;
Theoretical Overview of the Buck Converter   ◾    115

GVoD = (GVoD_num/GVoD_den);
%Output Voltage to Duty cycle ending
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Transfer functions to realize the gain and
phase at crossover frequency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Output Current to Duty Cycle gain_phase
beginning
g = wc_complex_i;
GIoD_num_g = (1+g*C*rESR)*(Vin - Vds + Vfwd);
GIoD_den_g = (L*C*Ro + L*C*rESR)*g^2 + (C*Ro*rL
+ C*rESR*rL + C*Ro*rESR + L)*g + rL + Ro;
GIoD_g = (GIoD_num_g/GIoD_den_g);
%Output Current to Duty Cycle gain_phase ending
%Output Voltage to Duty Cycle gain_phase
beginning
g = wc_complex_v;
GVoD_num_g = (1+g*C*rESR)*(Vin - Vds + Vfwd)*Ro;
GVoD_den_g = (L*C*Ro+ L*C*rESR)*g^2 + (C*Ro*rL +
C*rESR*iL + C*Ro*rESR + L)*g + rL + Ro;
GVoD_g = (GVoD_num_g/GVoD_den_g);
%Output Voltage to Duty Cycle gain_phase ending
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Current Controller design begin
i_gain = abs(GIoD_g);
i_phase = angle(GIoD_g)*(180/pi);
targ_PM_rad_i = targ_PM_deg_i*(pi/180);
phase_comp_i = targ_PM_rad_i - (i_phase*(pi/180))
- pi;
fi_i = fc_i * tan(-1*phase_comp_i);
Kpi = (1/i_gain)/sqrt((fi_i/fc_i)^2 + 1);
wi_i = fi_i*2*pi;
%Current Controller design ends
%Voltage Controller design begin abs (GVOD_g);
v_gain = abs(GVoD_g);
116   ◾    Digital Control of Power Converters

v_phase = angle(GVoD_g)*(180/pi);
targ_PM_rad_v = targ_PM_deg_v*(pi/180);
phase_comp_v = targ_PM_rad_v - (v_phase*
(pi/180)) - pi;
fi_v = fc_v * tan(-1*phase_comp_v);
Kpv = (1/v_gain)/sqrt((fi_v/fc_v)^2 + 1);
wi_v = fi_v*2*pi;
%Voltage Controller design ends
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Gci = Kpi*(wi_i/s + 1);
Gcv = Kpv* (wi_v/s + 1);
%Gc1 = 1;
Ti = Gci*GIoD;
Tv = Gcv*GVoD;
%Create a figure to hold the plots
%figure;
%Plot Bode plot for the system
%bode(Ti);
%bode(Tv);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Calculate gain and phase margins
[gain_margin, phase_margin, crossover_
frequencies, phase_crossover] = margin(Ti);
%Display Current Bode Plot the results
fprintf(‘Current, Gain margin: %.2f dB\n’,
20*log10 (gain_margin));
fprintf(‘Current Phase margin: %.2f degrees \n’,
phase_margin);
fprintf(‘Current Crossover frequencies: %.2f
rad/s\n’, crossover_frequencies);
fprintf(‘Current Phase at crossover: %.2f
degrees\n’, phase_crossover);
[gain_margin, phase_margin, crossover_
frequencies, phase_crossover] = margin(Tv);
%Display Voltage Bode Plot the results
Theoretical Overview of the Buck Converter   ◾    117

fprintf(‘Voltage Gain margin: %.2f dB\n’,


20*log10 (gain_margin));
fprintf(‘Voltage Phase margin: %.2f degrees\n’,
phase_margin);
fprintf(‘Voltage Crossover frequencies: %.2f
rad/s\n’, crossover_frequencies);
fprintf(‘Voltage Phase at crossover: %.2f
degrees\n’, phase_crossover);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Gi_d = c2d(Gci, 100e-­
6);
Gv_d = c2d(Gcv, 100e-­
6);
CHAPTER 3

Digital Control
Implementation of
the Buck Converter

3.1 HARDWARE OUTLINE
In this chapter, we are going to discuss about the hardware we will
use to implement the buck converter controller. We will utilize
the STM32 Nucleo-­G474RE board and it is connected to the main
converter board as shown in Figure 3.1.
We have actually an AC–DC converter that converts single
phase 230 Vac to 24 Vdc and that is an input to the system. In the
main converter, we have an auxiliary power supply and, of course,
we have an inductor coil, and on the right-­hand side of it, we have
a diode and on the left-­ hand side, there is a Metal-­ Oxide-­
Semiconductor Field-­ Effect Transistor (MOSFET) and the
MOSFET is significantly over sized and it does not require a heat
sink, but the diode requires a heat sink. Then we have the output
of the main converter and the resistive load is connected to the
output. There are four 10 μF parallel capacitors and also we have
an inductor that serves outgoing current to the output and it
118 DOI: 10.1201/9781003541356-3
Digital Control Implementation of the Buck Converter   ◾    119

FIGURE 3.1 The buck converter controller implementation.

comes after the capacitors. Also, we have a shunt current-­sensing


resistor next to the inductor. There is another shunt current-­
sensing resistor of the main inductor. On the top right-­hand side,
we have a voltage sensor for the output. There is also a MOSFET
driver in this case and we usually use bootstrap MOSFET driver
for this particular application but we have not used it in this main
converter board because they have some drawbacks, so, we use an
isolated MOSFET driver. The converter is not considered isolated
since the ground of input and output are the same. However, it
helps go to any duty cycle we want. Next to the MOSFET driver,
there is a power supply for it. It is a very common converter for
this application. The STM32 Nucleo-­G474RE board has high-­
resolution PWM and timer modules which are very useful in
power electronics applications. The codes provided can be used
120   ◾    Digital Control of Power Converters

FIGURE 3.2 The schematic of buck converter and its controller.

on other STM32 microcontrollers as well. The buck converter and


its controller schematic using the STM32 Nucleo-­G474RE devel-
opment board are depicted in Figure 3.2.
We have two current sensors and two voltage sensors in the
schematic. The input voltage and current sensors are not used in
this system. However, the output voltage and current sensors are
utilized. We have also two input and output inductor current sen-
sors and we can switch between them. We have used HCPL-­3120
as the MOSFET driver. There is an auxiliary power supply,
LM2596S, which generates 5 V at the output and its maximum
input voltage is 28 V. There is also a power supply, B0515S, exclu-
sively for the MOSFET driver which converts 5 V–15 V. The only
deviation from traditional buck converter is that there is an out-
put inductor, 10 μH, which is an outgoing for the next section of
buck converter, for the load basically. We have also connections
from buck converter board to the STM32 Nucleo-­ G474RE
Digital Control Implementation of the Buck Converter   ◾    121

development board. The current sensor amplifier IC is INA180


from Texas Instruments Incorporated (TI).

3.2 FIRMWARE PERIPHERAL INITIALIZATION


WITH CUBEMX
In this chapter, we are going to initialize the firmware periph-
erals to program the buck converter controller which is STM32
Nucleo-­G474RE development board. To get started, you should
note that the initialization is done using CubeMX software and it
is done easily and already available with that. Therefore, we open
the STM32CubeMX and under File tab, we create a New Project.
In the Board Selector tab and in the Commercial Part Number,
we do type NUCLEO-­G474RE and select it in the bottom window
and click on the Start Project button. In the popped-­up window,
we click on the Yes button to initialize all peripherals with their
default mode to load the IOC and rendering UI. We select the
Clock Configuration tab, the maximum clock frequency is 170
MHz. You can use pre-­scaler to reduce the clock speed. However,
in this case, we want to get maximum PWM resolution to real-
ize the closed-­loop control, so the maximum clock frequency
is perfect. Then we go to the Project Manager tab, we do copy
and paste the project directory in the Project Location also select
a name, that is, BUCK_CONTROL in the Project Name. Then
select STM32CubeIDE as Toolchain/IDE. We do not need to
change anything in the Tools tab. Then we go back to the Pinout
& Configuration tab. The STM32 microcontroller is capable of
doing many tasks and we are going to initialize what is actually
needed for the system. We start with the System Core and go to
the DMA; however, before using DMA, the DMA is actually can
be used in conjunction with the ADC and in the most conve-
nient way in closed-­loop controller is done by DMA. Then, in the
ADC1 Mode and Configuration window, we set IN1 and IN2 as
single-­ended.
Then, we go back to the DMA and click on the Add button and
select ADC1 item and choose Circular as Mode and Word as
122   ◾    Digital Control of Power Converters

Data Width. We do not discuss deeply any available peripherals,


so we only consider peripherals as initialization perspective.
Then we go back to the ADC1 Configuration window and in the
Parameter Settings tab, we select independent mode for Mode,
synchronous clock mode divided by 4 for Clock Pre-­scaler, ADC
12-­bit resolution, Data Alignment is not important, scan conver-
sion mode is disabled, end of sequence conversion since we have
two ADC channels, continuous conversion mode is enabled, and
DMA continuous requests is enabled. In the ADC_Regular_
ConversionMode part, we do enable regular conversions and
oversampling is disabled. In the number of conversions, we
choose 2 since we have 2 channels and for the sampling time of
Channel 1, we select the maximum cycle, because it actually
makes sure that the system is much stable so we sacrifice the sam-
pling time to get much stability, so the Rank 1 is completed. We
do the same settings for Rank 2 and Channel 2. Then we come
back to the scan conversion mode in ADC_Settings part and you
can see that is enabled now. We leave the other settings unchanged
for ADC1. The next one is actually the timers. So, we go to the
TIM1 in Timers section and this is specifically for PWM signal
generation. We choose Internal Clock for Clock Source and select
PWM Generation CH1 for Channel 1. You have not inversed out-
put, so you select CH1 and not CH1N where its polarity is
inversed relative to CH1 and you can see the TIM1_CH1 is actu-
ally in the pin PC0 in this case. In the Configuration window and
Parameter Settings tab, we choose Counter Mode as Up and we
select No Division in Internal Clock Division (CKD) for maxi-
mum resolution, also we do enable the auto-­reload preload and
you do not need to worry about the Break and Dead Time
Management, it will play the role in the synchronous buck, boost
or half-­bridge converters and you need to consider the dead time
management in those aspects. However, in this case, we will
focus on Pre-­scaler and Counter Period. The Counter Period and
Pre-­scaler are from 0 to 65535 (216 − 1). The following equations
can be used in this case:
Digital Control Implementation of the Buck Converter   ◾    123

FCLK
FPWM  (3.1)
 ARR  1   PSC  1

FCLK
ARR  1 (3.2)
 PSC  1   FPWM 

The Auto Reload Register (ARR) or Counter Period value is


equivalent to the compare value and PSC is the Pre-­scaler value.
In this case, we assume the PWM frequency is 100 kHz and the
clock frequency is 170 MHz. If, for example, the PSC is equal to 1,
from Equation (3.2), we can calculate ARR which is 849. The next
one is the timer interrupts, remember that in Chapter 2, to gener-
ate the digital controller coefficients, we selected the timer inter-
rupts to be 100 μs which means its frequency is actually 10 kHz.
We use TIM4 in this case to implement the timer interrupt. The
first thing is to select Internal Clock as Clock Source and we will
not have any outputs in this case, so, we will not select any chan-
nels. To do the parameter settings, we should note that the equa-
tion in this case is slightly different as below:

FCLK
ARR  1 (3.3)
 PSC  1   FINT 

The FINT in this case is 10 kHz, and the same procedure done
before is followed here. We select the PSC which is 1 in this case,
also the FCLK is 170 MHz, so the calculated ARR is to be 8499 and
we keep the auto-­reload preload to be Disable. So, everything is
perfect and we can click on the Generate Code button. After gen-
erating the code, the STM32CubeIDE is automatically opened. So,
the successful code generation message window is popped up
finally, and then we click on the Open Project button. So, we
launch the program in the workspace directory. Finally, you can
see successfully importing the program into the workspace
124   ◾    Digital Control of Power Converters

message. Then, we click on the project name to open it in


STM32CubeIDE. We go to the main.c file in Src folder and see
that the selected modules have been initialized. If you have forgot-
ten to add some initialization modules, you can click on the
BUCK_CONTROL.ioc file and in the popped up Open Associated
Perspective window, click on the Yes button. Then, a new window
called the Question window is popped up and we click on the No
button to load the IOC. You may have mistaken and it is possible
and that is basically what you need for initialization. In the next
section, we will dive into coding the firmware and several other
aspects that need to be taken into account.

3.3 MANUAL FIRMWARE INITIALIZATION


In this section, we are going to implement the second part of ini-
tialization of the firmware. This part is not done by CubeMX but
it is very necessary for the functionality of the closed-­loop control
system. The first thing is the initialization of PWM and the timer
actually we have done PWM with timer. In the previous section,
we did timer interrupts on TIM4 and did the parameter settings,
and then we go to the NVIC settings and enable the TIM4 global
interrupt. We just save the changes and generate the code gain.
Before doing anything, you should choose if the system giving
you the PWM with the frequency that is actually required and, in
this case, we have set it to be 100 kHz. The library we are using is
the HAL library and it means Hardware Abstraction Layer and it
is so convenient to use. Then, we go to start the PWM by writing
the following code before the while (1) code:

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

Then, we are going to initialize the PWM duty cycle. We calcu-


lated PWM duty cycle to be between 0 and 849. We start with a
duty cycle of 350 which is about 41.2% duty cycle by adding the
following code inside the while (1) loop and run the program as
depicted in Figure 3.3.
TIM1-­
>CCR1 = 350;
Digital Control Implementation of the Buck Converter   ◾    125

FIGURE 3.3 Adding code to start the PWM with a duty cycle of 41.2%.

If you connect pin PC0 to the oscilloscope, you can see the
PWM signal with a frequency of 100 kHz and a duty cycle of
41.2%. We will use a maximum of 70% of duty cycle in this pro-
gram. Next, we are going to initialize the ADC and DMA which is
actually done together in this case. As a first thing, we will utilize
the ADC with DMA and add the following code before while (1):

HAL_ADC_Start_DMA(&hadc1, (uint32_t *)
adcValues, 2);
Also, in the Private variables section, you need
to set up the code below.
float Vactual = 0.0;
float Iactual = 0.0;
uint32_t adcValues[2];

It is better to initialize the timer interrupt as well so we add the


following code before while (1).

HAL_TIM_Base_Start_IT(&htim4);

That code actually enables the timer interrupts to get started,


the TIM4 counter is counting up and when it is overflowed it can
126   ◾    Digital Control of Power Converters

trigger the interrupt duty. We need a section to do the interrupt


duty, so we just go to the bottom of the program in USER CODE
4 section and add the following code for interrupt duty.

void HAL_TIM_PeriodElapsedCallback(TIM_
HandleTypeDef* htim){
if(htim-­
>Instance == TIM4){
Vactual = adcValues[0]*0.008137207031;
Iactual = adcValues[1]*0.001611328125;
}
}

Once, initializing the timer interrupts, it starts to counting


up at the beginning of initialization and when it overflows it
executes the above code and then checks the Instance, if it is
TIM4, then it is triggered and then it executes the codes inside
of it. As you know, we have used resistor dividers to sense input
or output voltages, there are applications such as solar or bat-
tery charge controller, we are interested to sense the input volt-
age; however, in this case, we have used output voltage sensing
for our system. The following equations are used to calculate the
Vactual:

   RawAdcVal   R1  R2 
Vactual     AdcRes   Vref   R  (3.4)
 2   2 

   RawAdcVal   910k  100k 


Vactual       3. 3    (3.5)
 4096   100k 

Vref R  R2
Vactual  RawAdcVal   1 (3.6)
2AdcRes R2

3.3 910k  100k (3.7)


Vactual  RawAdcVal  
4096 100k
Digital Control Implementation of the Buck Converter   ◾    127

Vactual  RawAdcVal 0.008137207031 (3.8)

For the Iactual, we have something similar:

  RawAdcVal  
 AdcRes   Vref 
 2  
 AmpGain 
 
I actual  
Rshunt (3.9)

  RawAdcVal  
   3. 3 
 4096  
 50 
 
I actual   (3.10)
0.01

You should note that the voltage read in the STM32 microcon-
troller ADC pin is as below:

 RawAdcVal 
Vread     3. 3 (3.11)
 4096 

For calculating the actual voltage across the shunt resistor, we


should divide the voltage read in STM32 microcontroller ADC pin
by the amplifier gain, AmpGain, which is for INA180 differential
current sense amplifier is 50. Then for obtaining the Iactual, we should
divide the actual voltage across the shunt resistor by the shunt resis-
tor value, which is 10 mΩ as you can see in the following equations:

 3. 3 
  
 4096 

 50 
I actual  RawAdcVal    (3.12)
0.01
128   ◾    Digital Control of Power Converters

I actual  RawAdcVal 0.001611328125 (3.13)

Then we can run the program and debug the code. So, we run
the code in the debug mode to verify that the Vactual and Iactual are
really updated with the output voltage and output current. That is
very important before going ahead to control the converter and
first thing is to check that the duty cycle can be changed and the
second part is to check the timer interrupt is being triggered and
it is actually very important to execute the control code and the
third part is ensuring that you can read the actual output voltage
and current with the equations have been proposed because they
are very important to obtaining closed-­loop control. If one of
them is not set, nothing will be worked basically. We have checked
the PWM signal before but the others have not been checked yet
and they will be demonstrated in this section. Therefore, for run-
ning the program in debug mode, we do right click on the project
name, select Debug As and then choose Debug Configurations…
item. In the Debug Configurations window and in the Debugger
tab, we set the Enable live expressions and then click on the Close
button.
Then, we click on the Debug icon (green insect). In the opened
Confirm Perspective Switch window, we do click on the Switch
button. From Windows tab in menu, we select Show View and the
Expressions item. Then we click on the Add new expression, to see
the expressions we want, Vactual is one of them and Iactual is being
the other one and we want to show up them, so, we click on the
Resume (F8) icon in menu. The duty cycle of the PWM signal has
been set to as below equation:

400
PWM duty cycle   100  47% (3.14)
849

The system is turned on and the values of Vactual and Iactual are
displayed as Table 3.1.
Digital Control Implementation of the Buck Converter   ◾    129

TABLE 3.1 Displayed Vactual and Iactual Values


Expression Type Value
Vactual float 10.8957205
Iactual float 1.44052732

We see that values are not stable and changing because it is an


open-­loop control system and we have not added the controller
codes to make a closed-­loop controller yet, so, that is because it is
uncompensated or open-­loop control system. In this case, the
output resistor is about 7.5 Ω. Now, we connect the output voltage
to the oscilloscope to display the output voltage on it, we can see
that the value on the oscilloscope screen is different from the
value displayed on live expressions in debug mode running.
Because the oscilloscope used in this case has not been calibrated
that well, so, there is a slight difference with what it senses so it
reads 12.4 volts but in actuality when you use a multimeter, you
will see more accurate result of 11.48. We did manual initializa-
tion of our code and used the live expressions in debug mode run-
ning the program. In the next section, we will implement the
voltage and current closed-­loop controller and will add them to
our code.

3.4 FIRMWARE IMPLEMENTATION OF
VOLTAGE CONTROL
In this section, we will discuss about the next part of firmware
which is implementing the closed-­loop control system, especially
the function that will implement the closed-­loop control system,
that is, changing the duty cycle based on the center inputs. We
will think about the broader scheme which in terms of codes
in it and code the firmware in such a way that be easily used in
other families or use a function or separate file, that you actually
call to implement the controller, so that it can be used in other
microcontrollers as well and you basically copy and paste certain
file and change the duty cycle update and also do ADC update
130   ◾    Digital Control of Power Converters

from the DMA. The first step is that basically, you should create a
header file, so we do right click on the Inc folder, select New, and
then choose the Header File option. We do type a name, custom.h,
in Header file row and click on the Finish button. We define a
void function inside custom.h file as below, since it will not return
anything and save it.

#ifndef INC_CUSTOM_H_
#define INC_CUSTOM_H_
void CNTRL_ROUTINE(void);
#endif

After that, we do right click on the Src folder, select New, and
then choose the Source File option. We do type a name, custom.c,
in Source file row and click on the Finish button. First, we are
going to make the function we defined before, so we add the fol-
lowing code in custom.c file.

void CNTRL_ROUTINE(void){
}

A lot of extern variables need to be defined inside that function,


so, we are going to add them from main.c file, in the Private vari-
ables (PV) section, we add two variables, Vref and Iref, then you will
need to set up arrays to store the variables for the pole zero com-
pensator or digital controller so we define voltage and current
arrays for errors, e_v and e_i, also we define voltage and current
arrays for outputs, y_v and y_i, and initialize them to zero as
below.

/* USER CODE BEGIN PV */


float Vref = 16.0;
float Iref = 2.133;
float Vactual = 0.0;
float Iactual = 0.0;
float e_v[5] = {0};
Digital Control Implementation of the Buck Converter   ◾    131

float y_v[5] = {0};


float e_i[5] = {0};
float y_i[5] = {0};
uint32_t adcValues[2];
/* USER CODE END PV */

Remembering from Equation (2.30), we have substituted e_v


instead of e, and e_m instead of y, so en = e_v[0], en−1 = e_v[1], etc.,
and also yn = y_v[0], yn−1 = y_v[1], etc., and yn is actually the duty
cycle update. The closed-­loop block diagram of the system is illus-
trated in Figure 3.4.
Then, we go to the custom.c file and add them as extern vari-
ables as given in the following code.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include main.h
#include custom.h
extern float Vref;
extern float Iref;
extern float Vactual;
extern float Iactual;
extern float e_v[5];
extern float y_v[5];
extern float e_i[5];
extern float y_i[5];
extern uint32_t adcValues[2];
void CNTRL_ROUTINE(void){
}

FIGURE 3.4 The closed-­loop block diagram of the system.


132   ◾    Digital Control of Power Converters

Then, we should add necessary libraries to the custom.c file as


you can see in the above code; however, including math.h library
is not necessary in this case. So, we are going inside the CNTRL_
ROUTINE function. From Equation (2.30), we should note that
the yn(y[0]) is used to update the duty cycle and yn−1(y[1]) is the
history 1, yn−2(y[2]) is the history 2, and y n−3(y[3]) is the history 3.
After implementing them, you need to update each one, so y n−1
will be equated to what yn is, yn−2 will be equated to what yn−1 is
and yn−3 will be equated to what yn−2 is as below:

yn1  yn (3.15)

yn2  yn1 (3.16)

yn 3  yn 2 (3.17)

The same updates are applied for the errors, so, first, we do
copy and paste the Vactual equation code from interrupt duty func-
tion inside the CNTRL_ROUTINE function and apply the
updates for outputs and errors as depicted in the following code.

void CNTRL_ROUTINE(void){
Vactual = adcValues[0]*0.008137207031;
y_v[3] = y_v[2];
y_v[2] = y_v[1];
y_v[1] = y_v[0];
e_v[3] = e_v[2];
e_v[2] = e_v[1];
e_v[1] = e_v[0];
e_v[0] = Vref – Vactual;
y_v[0] = A1_v*y_v[1] + A2_v*y_v[2] +

A3_v*y_v[3] + B0_v*e_v[0] + B1_v*e_v[1] +
B2_v*e_v[2] + B3_v*e_v[3];
Digital Control Implementation of the Buck Converter   ◾    133

if(y_v[0] > y_v_max){


y_v[0] = y_v_max;
}
if(y_v[0] < y_v_min){
y_v[0] = y_v_min;
}
TIM1-­
>CCR1 = (int)(MAX_DUTY*y_v[0]);
}

Then we add the codes for e_v[0] and PI controller and define
limits for maximum and minimum duty cycles, y_v[0]. Since the
y_v[0] is of float type and is between 0 and 1, we should convert it
to integer and we know that the MAX_DUTY is 849 in this case as
you can see in the above code. It is the great advantage of STM32
microcontrollers that you can implement a controller mathemati-
cally and allow you to define float-­type numbers and it usually
does the mathematical operations in less than 10 μs. Now we are
going to define coefficients and variables that have been utilized in
the code inside the custom.c file as the following code.

#define A1_v 1
#define A2_v 0
#define A3_v 0
#define B0_v 0.001107
#define B1_v 0.002056
#define B2_v 0
#define B3_v 0
#define y_v_max 0.75
#define y_v_min 0.0
#define MAX_DUTY 849

In terms of protecting your microcontroller, one thing should be


considered and it is the constant duty cycle in Equation (2.1), so we
should note that when setting the maximum value of duty cycle.
Therefore, we can choose y_v_max to be a little bit more than D value,
that is, 0.75 as you can see in the above code. So, it will not go above
75% duty cycle. Next, we should call the function CNTRL_ROUTINE,
134   ◾    Digital Control of Power Converters

so we go back to the main.c file and call it inside the interrupt duty
function and do comment the Vactual and Iactual expressions, as depicted
in the following code, since they will be calculated inside the
CNTRL_ROUTINE function in custom.c file.

/* USER CODE BEGIN 4 */


void HAL_TIM_PeriodElapsedCallback(TIM_
HandleTypeDef* htim){
if(htim-­
>Instance == TIM4){
CNTRL_ROUTINE();
// Vactual = adcValues[0]

*0.008137207031;
// Iactual = adcValues[1]

*0.001611328125;
}
}
/* USER CODE END 4 */

Before starting to build the program, we should remove the fol-


lowing code inside the loop while (1).

TIM1-­>CCR1=400;

Then, we do build the program by clicking on the Build All


(Ctrl+B) icon in the menu. The program is successfully built and we
can now run it by clicking on the run icon in the menu. So, the code
is successfully uploaded to the STM32 microcontroller, now we can
see the output voltage using the oscilloscope and multimeter. As
you can see on the oscilloscope, the voltage displayed is 17.9 V;
however, on the multimeter screen, the voltage value is 16.36 V. You
should note that the Vref has been set to 16 V. In the next section, we
will evaluate the system operation for different set points.

3.5 FIRMWARE IMPLEMENTATION OF
CURRENT CONTROL
In this section, we will discuss about implementation of current
closed-­loop control specifically output current to duty cycle which
Digital Control Implementation of the Buck Converter   ◾    135

will be used to obtain the coefficients of the closed-­loop control-


ler and used for controlling the output current of buck converter.
Before we actually start, we are going to change the setpoint to
get the goal of robustness, so we change the set point Vref to 10 V
and see the results to ensure the operation of implemented voltage
closed-­loop control. Therefore, in the main.c file, we modify the
code as below, and then run the program.

/* USER CODE BEGIN PV */


float Vref = 10.0;
float Iref = 2.133;

As you can see, the voltage value on the oscilloscope is 11.5 V;


however, the output voltage on the multimeter screen is 10.41 V
which is much less than 11.5 V. As you can see, there is a slight off-
set from what we actually set up. In essence of how to deal with this
is basically to increase the average error, the average voltage error is
to use a more precise voltage sensor that will also affect the loop
and you will incorporate it with the loop design. Another thing you
can do is that you simply adjust the reference voltage, Vref, and make
it slightly lower and cause the offset value to change. In many appli-
cations that are actually utilized, you do want to be in a certain
range, for example, if you set the output voltage to be 3.3 V, and you
want to get about 3.3 V–3.5 V and you want it to be in certain range.
You should know there are many factors to cause the output voltage
to be exactly 10 V. Now, we are going to implement the output cur-
rent closed-­loop control, so, first of all in the custom.h file, we add
the new function, CNTRL_ROUTINE_CURRENT, and change
the name of the voltage control function, CNTRL_ROUTINE, to
CNTRL_ROUTINE_VOLTAGE as shown in the following code.

#ifndef INC_CUSTOM_H_
#define INC_CUSTOM_H_
void CNTRL_ROUTINE_VOLTAGE(void);
void CNTRL_ROUTINE_CURRENT(void);
#endif
136   ◾    Digital Control of Power Converters

Then we are going to the file custom.c and we create the func-
tion CNTRL_ROUTINE_CURRENT, exactly like the function
CNTRL_ROUTINE_VOLTAGE, and we use the Iactual code line
instead of Vactual in this case, and also change any v, in arrays or
variables to i, as you can see in the code below.

void CNTRL_ROUTINE_CURRENT(void){
Iactual = adcValues[1]*0.001611328125;
y_i[3] = y_i[2];
y_i[2] = y_i[1];
y_i[1] = y_i[0];
e_i[3] = e_i[2];
e_i[2] = e_i[1];
e_i[1] = e_i[0];
e_i[0] = Iref – Iactual;
y_i[0] = A1_i*y_i[1] + A2_i*y_i[2] +

A3_i*y_i[3] + B0_i*e_i[0] + B1_i*e_i[1] +
B2_i*e_i[2] + B3_i*e_i[3];
if(y_i[0] > y_i_max){
y_i[0] = y_i_max;
}
if(y_i[0] < y_i_min){
y_i[0] = y_i_min;
}
TIM1-­
>CCR1 = (int)(MAX_DUTY*y_i[0]);
}

We know that the output resistor value is 7.5 Ω and we set the
Iactual to 2.133 A, so, the output voltage will be 16 V. We have used
5% resistors for resistor divider sensors to get more accurate out-
put voltage it is better to use 1% resistors to achieve more accurate
values. Then we are going to define the PI current closed-­loop
controller coefficients as well as maximum and minimum values
for the duty cycles as depicted in the following code.

#define A1_v 1
#define A2_v 0
Digital Control Implementation of the Buck Converter   ◾    137

#define A3_v 0
#define B0_v 0.001107
#define B1_v 0.002056
#define B2_v 0
#define B3_v 0
#define A1_i 1
#define A2_i 0
#define A3_i 0
#define B0_i 0.008334
#define B1_i 0.01548
#define B2_i 0
#define B3_i 0
#define y_i_max 0.75
#define y_i_min 0.0
#define y_v_max 0.75
#define y_v_min 0.0
#define MAX_DUTY 849

Then we go to the interrupt duty function and call the current


controller function inside of it as given in the code below.

/* USER CODE BEGIN 4 */


void HAL_TIM_PeriodElapsedCallback(TIM_
HandleTypeDef* htim){
if(htim-­>Instance == TIM4){
// CNTRL_ROUTINE_VOLTAGE();
CNTRL_ROUTINE_CURRENT();
}
}
/* USER CODE END 4 */

You should note that we do not call the voltage controller func-
tion here, so we do comment it. Then we can build the program by
clicking on the Build All (Ctrl+B) icon in the menu and it is built
successfully. Since, the Iactual is 2.133 A, and the output resistor is
7.5 Ω, we should expect to have the output voltage in the range
from 16 V to 16.5 V. So, we can run the program to upload it to the
STM32 microcontroller and the download is verified successfully.
138   ◾    Digital Control of Power Converters

Now, we can see the output voltage value on the oscilloscope


which is 18.1 V; however, it is 16.51 V on the multimeter screen.
That is all about the current closed-­loop controller, and basically
all of the works have been done. We want to have precise current
closed-­loop controller, so we used a shunt in this case. However,
when you are going to sense high currents above 15 A, it is not
advisable to use a shunt because the shunt color is changing and
also its resistance is changing at some point and affects the effi-
ciency of the system. In certain cases, you want to utilize Hall
effect current sensors and they are much better and they are
highly efficient as well and also its resistance is almost negligible.
So, in that case, Equation (3.13) for Iactual will not suffice. How do
we modify the equation in case when we use the Hall effect sen-
sor? The Hall effect sensor essentially works with offset. It is usu-
ally an offset value and sensitivity. For example, the ACS712
current sensor is a Hall effect current sensor and it has an offset
value because it has been designed to work with DC and AC sys-
tems and we should scale the raw ADC value with the offset value
and we should subtract offset from it however we prefer to sub-
tract it from offset value since we will not pass 2.5 V in this case
since we assume the current is flowing in reverse direction, that is,
from IP-­to IP+ in ACS712 (−20 A to 20 A). So, we have the follow-
ing equations:

  RawAdcVal 
 OffsetVal   AdcRes
 Vref  
I actual   2  (3.18)
 Sensitivity 
 
 

OffsetVal RawAdcVal  Vref


I actual   (3.19)
Sensitivity Sensitivity 2AdcRes

OffsetVal = 2.5 V (3.20)


Digital Control Implementation of the Buck Converter   ◾    139

Sensitivity = 0.1 V / A (3.21)

Vref = 3.3 V (3.22)

2AdcRes 12
= 2= 4096 (3.23)

I actual  25  RawAdcVal  0.008056640625 (3.24)

So, we can use it in the function CNTRL_ROUTINE_


CURRENT in custom.c file as given in the following code.

void CNTRL_ROUTINE_CURRENT(void){
// Iactual = adcValues[1]*0.001611328125;
Iactual = 25-­
adcValues[1]*0.008056640625;

You should note that the Hall effect current sensors are very
prone to be affected by magnetic fields. In the next section, we will
discuss about average current mode control.

3.6 AVERAGE CURRENT MODE CONTROL OF


THE BUCK CONVERTER
In this section, we will deal with average current mode control
and essentially what it means you actually control the current
through the inductor, so instead of controlling the output volt-
age or output current, you basically control the current flowing
through the inductor and what that tells us, you have double
loop also it is called double loop control, and what you get in
double loop control is that the outer voltage loop makes a ref-
erence for the inner current loop and it really presents many
advantages in the converter control because you can essentially
ensure that your converter constantly operates in continuous
conduction mode, CCM, and additionally you can actually save
your MOSFET from a lot of stress because inherently you are
limited in the amount of the current goes through your inductor
140   ◾    Digital Control of Power Converters

by proxy MOSFET or diode as well, essentially the amount of


current goes through the converter so you basically limit it in
every cycle as opposed you have not checked it in other meth-
ods, that is, the output voltage to duty cycle or output current
to duty cycle where you control them like a single loop control.
If you want to limit current, you essentially have to use other
than the duty cycle method, we keep our fingers crossed, or, lit-
erally, you have to use another if statement, that is, if the cur-
rent above the limit reduces the duty cycle as opposed to double
control loop inherently and you just limit the current by default
as you are using the ADC of course. In this section, we will dive
into practical implementation of this method and we will not
go through the theoretical analysis because the average current
mode control in theoretical is rather complicated and we will
go to other approach so we will implement the average current
mode in the firmware and we are going to start coding it. You
should note that the outer control loop is quite slow, so, every
time the outer control loop is executed, the current control loop
is executed 10 times, so the voltage control loop only executes 1
iteration for 10 iterations of current loop control. Therefore, in
main.c file and Private variables section, we define a loop coun-
ter variable (loop_cnt) and initialize it to zero as given in the
code below.

/* USER CODE BEGIN PV */


float Vref = 10.0;
float Iref = 1.2;
float Vactual = 0.0;
float Iactual = 0.0;
float e_v[5] = {0};
float y_v[5] = {0};
float e_i[5] = {0};
float y_i[5] = {0};
int loop_cnt = 0;
uint32_t adcValues[2];
/* USER CODE END PV */
Digital Control Implementation of the Buck Converter   ◾    141

Then, we go to the custom.h file and define the functions we


require in this case as you can see in the following code.

#ifndef INC_CUSTOM_H_
#define INC_CUSTOM_H_
void CNTRL_ROUTINE_VOLTAGE(void);
void CNTRL_ROUTINE_CURRENT(void);
void DOUB_LOOP(void);
void DOUB_LOOP_VOLTAGE(void);
void DOUB_LOOP_CURRENT(void);
#endif

You should note that the first function is for the entire double
loop controller, the second one is for the voltage control loop, and
the third one is for the current control loop.
In custom.c file, we define the loop counter variable (loop_cnt)
as external integer and add the codes inside the entire double loop
control function and call the double loop current control in every
iteration and double loop voltage control in every 10 iterations as
given in the following code.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include main.h
#include custom.h
#define A1_v 1
#define A2_v 0
#define A3_v 0
#define B0_v 0.001107
#define B1_v 0.002056
#define B2_v 0
#define B3_v 0
#define A1_i 1
#define A2_i 0
#define A3_i 0
#define B0_i 0.008334
142   ◾    Digital Control of Power Converters

#define B1_i 0.01548


#define B2_i 0
#define B3_i 0
#define y_i_max 0.75
#define y_i_min 0.0
#define y_v_max 0.75
#define y_v_min 0.0
#define MAX_DUTY 849
extern float Vref;
extern float Iref;
extern float Vactual;
extern float Iactual;
extern float e_v[5];
extern float y_v[5];
extern float e_i[5];
extern float y_i[5];
extern uint32_t adcValues[2];
extern int loop_cnt;
void CNTRL_ROUTINE_VOLTAGE(void){
Vactual = adcValues[0]*0.008137207031;
y_v[3] = y_v[2];
y_v[2] = y_v[1];
y_v[1] = y_v[0];
e_v[3] = e_v[2];
e_v[2] = e_v[1];
e_v[1] = e_v[0];
e_v[0] = Vref – Vactual;
y_v[0] = A1_v*y_v[1] + A2_v*y_v[2] +

A3_v*y_v[3] + B0_v*e_v[0] + B1_v*e_v[1] +
B2_v*e_v[2] + B3_v*e_v[3];
if(y_v[0] > y_v_max){
y_v[0] = y_v_max;
}
else if(y_v[0] < y_v_min){
y_v[0] = y_v_min;
}
TIM1-­>CCR1 = (int)(MAX_DUTY*y_v[0]);
}
Digital Control Implementation of the Buck Converter   ◾    143

void CNTRL_ROUTINE_CURRENT(void){
Iactual = adcValues[1]*0.001611328125;
y_i[3] = y_i[2];
y_i[2] = y_i[1];
y_i[1] = y_i[0];
e_i[3] = e_i[2];
e_i[2] = e_i[1];
e_i[1] = e_i[0];
e_i[0] = Iref – Iactual;
y_i[0] = A1_i*y_i[1] + A2_i*y_i[2] +

A3_i*y_i[3] + B0_i*e_i[0] + B1_i*e_i[1] +
B2_i*e_i[2] + B3_i*e_i[3];
if(y_i[0] > y_i_max){
y_i[0] = y_i_max;
}
else if(y_i[0] < y_i_min){
y_i[0] = y_i_min;
}
TIM1-­
>CCR1 = (int)(MAX_DUTY*y_i[0]);
}
void DOUB_LOOP(void){
loop_cnt++;
if(loop_cnt == 10){
loop_cnt = 0;
DOUB_LOOP_VOLTAGE();
}
DOUB_LOOP_CURRENT();
}
void DOUB_LOOP_VOLTAGE(void);
void DOUB_LOOP_CURRENT(void);

You should note that the double loop current control function,
DOUB_LOOP_CURRENT, is identical to the current control
routine function, CNTRL_ROUTINE_CURRENT, however, the
double loop voltage control function, DOUB_LOOP_VOLTAGE,
is slightly different from the voltage control routine function,
CNTRL_ROUTINE_VOLTAGE. We do copy and paste the codes
inside the CNTRL_ROUTINE_VOLTAGE function to inside the
144   ◾    Digital Control of Power Converters

DOUB_LOOP_VOLTAGE function and remove the last code line


of it since the output of this function is the reference current, Iref,
and it will be used as a reference in the DOUB_LOOP_CURRENT
function, so we add the reference current code as given in the code
below.

void DOUB_LOOP_VOLTAGE(void){
Vactual = adcValues[0]*0.008137207031;
y_v[3] = y_v[2];
y_v[2] = y_v[1];
y_v[1] = y_v[0];
e_v[3] = e_v[2];
e_v[2] = e_v[1];
e_v[1] = e_v[0];
e_v[0] = Vref – Vactual;
y_v[0] = A1_v*y_v[1] + A2_v*y_v[2] +

A3_v*y_v[3] + B0_v*e_v[0] + B1_v*e_v[1] +
B2_v*e_v[2] + B3_v*e_v[3];
if(y_v[0] > y_v_max){
y_v[0] = y_v_max;
}
else if(y_v[0] < y_v_min){
y_v[0] = y_v_min;
}
Iref = Iref_max*y_v[0];
}
void DOUB_LOOP_CURRENT(void);

The Iref_max is the maximum current which is essentially


required and that is the maximum inductor current you want,
and we never get the inductor current above that value. Then we
go back to the custom.c file and define Iref_max as 2.133 and
change y_v_max from 0.75 to 1.0 as you can see in the following
code.

//#define y_v_max 0.75


#define y_v_max 1.0
Digital Control Implementation of the Buck Converter   ◾    145

#define y_v_min 0.0


#define Iref_max 2.133

Then we do copy and paste the codes inside the CNTRL_


ROUTINE_CURRENT function to inside the DOUB_LOOP_
CURRENT function and you have used Iref which has been
obtained directly from the double loop voltage control function,
DOUB_LOOP_VOLTAGE, as given in the following code.

void DOUB_LOOP_CURRENT(void){
Iactual = adcValues[1]*0.001611328125;
y_i[3] = y_i[2];
y_i[2] = y_i[1];
y_i[1] = y_i[0];
e_i[3] = e_i[2];
e_i[2] = e_i[1];
e_i[1] = e_i[0];
e_i[0] = Iref – Iactual;
y_i[0] = A1_i*y_i[1] + A2_i*y_i[2] +

A3_i*y_i[3] + B0_i*e_i[0] + B1_i*e_i[1] +
B2_i*e_i[2] + B3_i*e_i[3];
if(y_i[0] > y_i_max){
y_i[0] = y_i_max;
}
else if(y_i[0] < y_i_min){
y_i[0] = y_i_min;
}
TIM1-­
>CCR1 = (int)(MAX_DUTY*y_i[0]);
}

So, the reference current, Iref, basically keeps the inductor cur-
rent in CCM, which is literally constant, remember that Iref is run-
ning for 10 cycles and the function DOUB_LOOP_CURRENT
runs for 10 times at first before start up the function DOUB_
LOOP_VOLTAGE, so you should note that adequate Iref should be
there and not be too high that is why we initiate it to 0.2 A first,
until it gets updated inside the function DOUB_LOOP_VOLTAGE,
146   ◾    Digital Control of Power Converters

so we do the initialization of Iref inside the main.c file as given in


the code below.

/* USER CODE BEGIN PV */


float Vref = 10.0;
float Iref = 0.2;

Also, as we mentioned earlier, the function we want to call is


the DOUB_LOOP function in every 100 μs inside the interrupt
duty function. Therefore, we go to the main.c file and find the
interrupt duty function and call the DOUB_LOOP function
inside of it as you can see in the following code.

/* USER CODE BEGIN 4 */


void HAL_TIM_PeriodElapsedCallback(TIM_
HandleTypeDef* htim){
if(htim-­
>Instance == TIM4){
DOUB_LOOP();
// CNTRL_ROUTINE_VOLTAGE();
// CNTRL_ROUTINE_CURRENT();
}
}
/* USER CODE END 4 */

Then, we can build the program and run the program to upload
the code to the STM32 microcontroller. Just keep in mind that the
system is not modifying the duty cycle directly as a result of the
sensed output voltage, it takes and generates a reference current
value from the output voltage and the reference current value is
what used to actually modify the duty cycle directly, so it is almost
indirect control instead of direct control. As you can see on the
oscilloscope, the output voltage is not constant and it is going up
and down from 11.3 V to 11.5 V, so you need to modify the voltage
and current controller coefficients. So, we go back to the code and
inside the main.c file we change the set point, Vref value, from 10 V
to 15 V. You should note that we can only change the set point Vref
Digital Control Implementation of the Buck Converter   ◾    147

and we cannot change the Iref manually and it is changed auto-


matically and dynamically based on what Vref is, so we run the
program gain. There is some offset in the oscilloscope and it is
changing from 16.7 V to 16.9 V. So, that is basically what the aver-
age current mode control is and it is very useful in a vast majority
of applications such as battery chargers and, of course, you cannot
use average current mode control if you are not operating in con-
tinuous conduction mode, CCM. If the inductors are not large
enough, they will not be operating in CCM most time. We should
note that we are getting close to the rated, that is, maximum refer-
ence current, Iref_max, which is 2.133 A in this case. The last set-
point, Vref, that we want to use is 16 V, so we go to main.c file and
set it as given in the code below.

/* USER CODE BEGIN PV */


float Vref = 16.0;
float Iref = 0.2;

Also, we modify slightly Iref_max from 2.133 to 2.2 in custom.c


file as you can see in the following code.

//#define y_v_max 0.75


#define y_v_max 1.0
#define y_v_min 0.0
#define Iref_max 2.2

Then, we run the program again, and we see on the oscillo-


scope that the output voltage goes up and down from 17.9 V to
18.1 V. That is the implementation of average current mode con-
trol. The noise in the output voltage is mostly because of the AC/
DC converter, using the output of linear voltage regulators as an
input to the buck converter will give better results. It is very
advantageous to control the current through the inductor and
average current mode control can do that very well. If we modify
the coefficients, we can reduce the output voltage oscillations, for
148   ◾    Digital Control of Power Converters

example, we change the B0_v and B1_v and also B0_i and B1_i
values to one-­tenth of their previous values in custom.c file as
given in the code below.

#define A1_v 1
#define A2_v 0
#define A3_v 0
#define B0_v 0.0001107
#define B1_v 0.0002056
#define B2_v 0
#define B3_v 0
#define A1_i 1
#define A2_i 0
#define A3_i 0
#define B0_i 0.0008334
#define B1_i 0.001548
#define B2_i 0
#define B3_i 0

By doing that, you actually increase the settling time when


coefficients are more than what actually they are, and when you
reduce them, you actually reduce the settling time and you will
have more stable output. Then we run the program, we can see
that the output voltage is now more stable and it is not going up
and down so much. We again change more the B0_i and B1_i val-
ues to one-­tenth of their previous values as you can see in the fol-
lowing code.

#define A1_v 1
#define A2_v 0
#define A3_v 0
#define B0_v 0.0001107
#define B1_v 0.0002056
#define B2_v 0
#define B3_v 0
#define A1_i 1
#define A2_i 0
Digital Control Implementation of the Buck Converter   ◾    149

#define A3_i 0
#define B0_i 0.00008334
#define B1_i 0.0001548
#define B2_i 0
#define B3_i 0

Then, we run the program and can see that the output voltage
is now more stable and it is fixed at 18.1 V.
CHAPTER 4

Digital Control
Implementation with
PLECS

4.1 INTRODUCTION
PLECS is a simulation software tool used for the design and anal-
ysis of power electronic systems. It stands for piecewise linear
electrical circuit simulation and is developed by Plexim GmbH.
PLECS provides a user-­friendly interface for modeling complex
power electronic systems and simulating their behavior in real-­
time. Key features of PLECS include:

• Intuitive graphical modeling environment for designing


power electronic circuits.
• Support for modeling various power converters, inverters,
motor drives, and other power electronic systems.
• Real-­time simulation capabilities for rapid prototyping and
testing of control algorithms.

150 DOI: 10.1201/9781003541356-4


Digital Control Implementation with PLECS   ◾    151

• Integration with MATLAB/Simulink for system-­level simu-


lation and control design.
• Code generation capabilities for automatically generating
embedded code for microcontrollers.
• Extensive library of pre-­built power electronic components
and control blocks.
• Validation and verification tools for analyzing system behav-
ior and performance.

Overall, PLECS is a powerful tool for engineers and research-


ers working in the field of power electronics, enabling them
to model, simulate, and optimize the performance of power
electronic systems efficiently. You can generate code for power
converter control in PLECS for STM32 microcontrollers and
implement your control algorithm on the microcontroller to
regulate the power converter operation. In this chapter, we will
investigate and study a practical example of implementing a
power converter, designing a controller, and generating code
for the STM32 Nucleo-­G474RE microcontroller in detail using
PLECS and MATLAB software.

4.2 DESIGNING A CLOSED-­LOOP
CONTROLLER IN PLECS AND MATLAB
In this section, we intend to design a buck converter in the PLECS
software environment and simulate it. The designed buck con-
verter is shown in Figure 4.1.
The circuit parameter values are clearly visible in Figure 4.1.
The switching frequency is 20 kHz and the triangular wave gen-
erator amplitude changes between 0 and 1, and it is compared
with constant duty cycle value with a logical comparator or rela-
tional operator to generate the PWM signal and, finally, it is fed to
152   ◾    Digital Control of Power Converters
FIGURE 4.1 The designed buck converter in PLECS.
Digital Control Implementation with PLECS   ◾    153

FIGURE 4.2 The output voltage waveform.

the gate driver of the MOSFET. Also, there is a load change at 100
ms and the load resistance is changing from 8 Ω to 4 Ω at the time
of 100 ms. The output voltage waveform is also depicted in Figure
4.2 which has an undesirable overshoot at the startup and there is
an offset or a deviation from the reference voltage value, 5 V, as
shown in Figure 4.2. The simulation parameters window for this
system is illustrated in Figure 4.3.
For designing a PID controller for this power converter, we
need to know the control to output frequency response of the
system. Therefore, in library browser, control, and small signal
analysis section, we do drag and drop the small signal pertur-
bation and add it with the reference voltage value and also do
drag and drop the small signal response as shown in Figure 4.4
and connect it to the measured output voltage as shown in
Figure 4.1.
154   ◾    Digital Control of Power Converters

FIGURE 4.3 The simulation parameters window.

To see the control to output frequency response of the system


from Simulation tab in menu, we select the Analysis too as shown
in Figure 4.5.
In the opened Analysis Tools window, we do click on the plus
(+) button and select the AC Sweep Analyses and do the settings
as shown in Figure 4.6.
To see the control to output frequency response, that is, Bode
diagram of magnitude and phase of the system we do click on the
Start analysis button in Analysis Tools window which is depicted
in Figure 4.7.
We will use MATLAB software to design a PID controller for
closed-­loop system so we need to export the frequency response
data as a CSV file as illustrated in Figure 4.8.
Digital Control Implementation with PLECS   ◾    155

FIGURE 4.4 Choosing the small signal analysis elements.


156   ◾    Digital Control of Power Converters

FIGURE 4.5 Selecting the analysis tools… from simulation tab.

FIGURE 4.6 Settings of the analysis tools window.

In the opened Export as window, we choose a name (data.csv)


for it and click on the Save button to save it in the desired direc-
tory as shown in Figure 4.9.
Then we open the saved CSV file and delete the header or first
row of it and save it again as depicted in Figure 4.10, since if we do
not do that when we read the CSV file in MATLAB command
window, we will get an error message.
Digital Control Implementation with PLECS   ◾    157

FIGURE 4.7 The control to output frequency response.

Therefore, we use the following codes in the MATLAB com-


mand window to read the saved data.csv file and plot the Bode
diagram of the system in MATLAB.

>> data = csvread(‘C:\plecs\stm32\data.csv’);


>> w = 2*pi*data(:,1);
>> val=10.^(data(:,2)/20).*exp(j*data(:,3)
*pi/180);
>> sys = frd(val,w);
>> bode(sys),grid minor

By running those codes in the MATLAB command window,


the Bode diagram of the system is plotted in MATLAB as depicted
in Figure 4.11.
158   ◾    Digital Control of Power Converters

FIGURE 4.8 Exporting the frequency response data as a CSV file.

FIGURE 4.9 Choosing a name and saving the CSV file.


Digital Control Implementation with PLECS   ◾    159

FIGURE 4.10 Removing the first row of data.csv.

FIGURE 4.11 The Bode diagram of the system in MATLAB.


160   ◾    Digital Control of Power Converters

To get the transfer function of the system, we use the following


code in the MATLAB command window.

>> H = tfest(sys,2)
H =
2497 s + 5.186e08
-----------------------
s^2 + 4201 s + 5.639e08
Continuous-­time identified transfer function.
Parameterization:
Number of poles: 2 Number of zeros: 1
Number of free coefficients: 4
Use "tfdata", "getpvec", "getcov" for

parameters and their uncertainties.
Status:
Estimated using TFEST on frequency response data
"sys".
Fit to estimation data: 99.2% (simulation focus)
FPE: 7.625e-­05, MSE: 7.07e-­
05

As you can see above, estimated transfer function of the system


with an accuracy of 99.2% is as below:

2497 s  5.186  108


H (4.1)
s 2  4201s  5.639  108

Then we use the following code in MATLAB command win-


dow to design a closed-­loop PID controller for the system.

>> pidTuner(H)

By running the code above, the PID Tuner window is opened


and we select the Type as PID and Form as Parallel and also set the
Response Time (0.1173) and Transient behavior (0.66), so that an
appropriate step plot is achieved as shown in Figure 4.12.
Then we click on the Export button in the PID Tuner window
and in the opened Export Linear System we do enter a name (PID)
in Export PID controller and click on the OK button as illustrated
in Figure 4.13.
Digital Control Implementation with PLECS   ◾    161

FIGURE 4.12 Setting the PID tuner window.

FIGURE 4.13 Entering a name (PID) in export PID controller window.

Finally, in the MATLAB command window, we run the code


below to get the closed-­loop PID controller transfer function.

>> PID
PID =
1
Ki * ---
s
with Ki = 18.5
Continuous-­
time I-­
only controller.
162   ◾    Digital Control of Power Converters

FIGURE 4.14 Finding the continuous PID controller block.

So, the designed closed-­loop PID controller transfer function is


as follows:

18.5
PID  s   (4.2)
s

In the Library Browser, we can find the Continuous PID


Controller block in Control and Continuous section and drag and
drop it to the uncompensated system as shown in Figure 4.14.
Then, we do double click on the Continuous PID Controller
block and in the Basic tab we enter the PID(s) transfer function
values as depicted in Figure 4.15.
Also, in the Anti-­Windup tab of the Continuous PID Controller
window, we set the upper saturation limit to 0.9 and lower satura-
tion limit to 0.1, as shown in Figure 4.16, to limit the duty cycle
between 0.1 and 0.9 in order to safe operation of the MOSFET.
Then we can add the Continuous PID Controller to the closed-­
loop control system as illustrated in Figure 4.17.
Finally, we simulate the compensated closed-­loop control sys-
tem and we can see the output voltage waveform on the Scope as
shown in Figure 4.18.
As you can see in this case the output voltage offset is omitted
and the output voltage is equal to the reference voltage value
Digital Control Implementation with PLECS   ◾    163

FIGURE 4.15 Setting the PID(s) transfer function values.

FIGURE 4.16 Setting the upper and lower saturation limits in the anti-­
windup tab.
164   ◾    Digital Control of Power Converters
FIGURE 4.17 Adding the PID(s) block to the closed-­loop control system.
Digital Control Implementation with PLECS   ◾    165

FIGURE 4.18 The output voltage waveform on the scope.

which is 5 V. Also, the startup overshoot in output voltage is


removed and following a step load resistance change from 8 Ω to
4 Ω at 100 ms, the output voltage becomes stable in less than 5 ms.

4.3 CODE GENERATION FOR THE STM32


NUCLEO-­G474RE IN PLECS
Code generation for the STM32 Nucleo-­ G474RE in PLECS
involves converting the simulation model created in PLECS into
executable code that can be run on the specific microcontroller.
Here is a general overview of the steps involved in code generation
for the STM32 Nucleo-­G474RE in PLECS:

1. Design the control system in PLECS: Create and simulate


the control system model in PLECS to ensure that it meets
the desired performance specifications.
2. Configure the target settings: Select the STM32 Nucleo-­
G474RE microcontroller as the target for code generation in
PLECS by specifying the appropriate settings in the Target
Setup window.
166   ◾    Digital Control of Power Converters

3. Generate code: Click on the Generate Code button in PLECS


to initiate the code generation process. PLECS will convert
the simulation model into C code that can be compiled and
uploaded to the STM32 Nucleo-­G474RE.
4. Compile and upload code: Compile the generated C code
using an Integrated Development Environment (IDE) such
as the STM32CubeIDE. Upload the compiled code to the
STM32 Nucleo-­G474RE microcontroller using a program-
ming tool such as ST-­Link.
5. Test the control system: Run the control system on the STM32
Nucleo-­G474RE to verify its functionality and performance.
Make any necessary adjustments to the code or simulation
model in PLECS to optimize the system’s performance.

By following these steps, you can effectively generate code for the
STM32 Nucleo-­G474RE microcontroller in PLECS and imple-
ment the control system on the microcontroller for real-­world
applications. Now, we are going to create the same buck converter
using the STM32 PLECS library and then generate the code for
the STM32 Nucleo-­G474RE microcontroller in STM32CubeIDE.
To do that, we create two subsystems one for the buck converter
and the other one for the PID controller as shown in Figure 4.19.
The circuit inside the Buck_Converter subsystem is depicted in
Figure 4.20.
As you can see in Figure 4.20, we have added a resistor divider
with the values R5 = 100 kΩ and R6 = 10 kΩ, since we want to get

FIGURE 4.19 Creating two subsystems for buck converter and PID
controller.
Digital Control Implementation with PLECS   ◾    167
FIGURE 4.20 The circuit inside the Buck_Converter subsystem.
168   ◾    Digital Control of Power Converters

FIGURE 4.21 The circuit inside the PID_Controller subsystem.

a voltage below 3.3 V to the input of ADC1 pin of the STM32


microcontroller. Therefore, we have the following equation:

R6 1
Vosense   Vo  Vo (4.3)
R5  R6 11

Also, the circuit inside the PID_Controller subsystem is illus-


trated in Figure 4.21.
As you can see in Figure 4.21, we do multiply the output of
ADC1 by a Gain which is now equal to 11 to get the actual value
of output voltage, Vo, and then it is compared with the reference
voltage, 5 V. The ADC1 block parameters window is shown in
Figure 4.22.
As you can see in Figure 4.22, we could set the Cont. conversion
scale(s) to 11 instead of adding a Gain with the value of 11. The
PWM block parameters window is depicted in Figure 4.23.
Finally, from the Simulation tab in menu, we select the Start
option as depicted in Figure 4.24, to see the results of simulation
using the STM32 PLECS library elements and designed controller
in the previous section as illustrated in Figure 4.25.
Then we should enable the code generation option for the
PID_Controller subsystem. Therefore, we do right click on the
Digital Control Implementation with PLECS   ◾    169

FIGURE 4.22 The ADC1 block parameters window.

FIGURE 4.23 The PWM block parameters window.


170   ◾    Digital Control of Power Converters

FIGURE 4.24 Selecting the start option.

FIGURE 4.25 The results of simulation.

PID_Controller subsystem, select Subsystem, and then choose the


Execution settings… option as shown in Figure 4.26.
In the opened Execution Settings window, we tick on the
Enable code generation and enter the value of 1e-­4 in Discretization
step size field and then click on Apply and OK buttons, respec-
tively, as shown in Figure 4.27.
Digital Control Implementation with PLECS   ◾    171

FIGURE 4.26 Choosing the execution settings… option.

FIGURE 4.27 Ticking on the enable code generation.


172   ◾    Digital Control of Power Converters

FIGURE 4.28 Selecting open projects from file system… option.

Then we run the STM32CubeIDE to enter it and from File icon


we select Open projects from File System… option as depicted in
Figure 4.28.
In the Open projects from File System window, we click on the
Archive… button as illustrated in Figure 4.29, to open the g474.
zip file in the following directory as shown in Figure 4.30.

PLECS4.7(64 bit) > tsp_stm32 > projects > g474.zip

Then we do click on the Finish button in the Import Projects


from File System or Archive window as shown in Figure 4.31.

FIGURE 4.29 Clicking on the archive… button.


Digital Control Implementation with PLECS   ◾    173

FIGURE 4.30 Opening the g474.zip file.

FIGURE 4.31 Clicking on the finish button.


174   ◾    Digital Control of Power Converters

FIGURE 4.32 Selecting the properties option.

In the Project Explorer, we find the cg folder and then right


click on it and select the Properties option as depicted in Figure
4.32. Therefore, the Properties for cg window is opened and we do
copy the Location directory as illustrated in Figure 4.33.
Then, we close the properties for cg window and come back to
the PLECS environment and in the Coder icon of menu we select
the Coder options… as shown in Figure 4.34, to open the Coder
Options window and in the Target section we select the Target as
STM32G4x and chip as G474xx, the Build type as generate code
into STM32CubeIDE project and also we do paste the copied
Location directory in Figure 4.33 to the STM32CubeIDE project
directory and also tick use internal oscillator and finally click on
the Accept and Build buttons, respectively, as shown in Figure 4.35.
Digital Control Implementation with PLECS   ◾    175

FIGURE 4.33 Doing copy the location directory.

FIGURE 4.34 Selecting the coder options….

As shown in Figure 4.36, we get an error message since we have


not defined the I/O components for the output ports, m and e_v,
of the PID_Controller subsystem. We should note that we used
both of them for simulation purpose and in code generation we
can remove them from the PID_Controller subsystem as depicted
in Figures 4.37 and 4.38, respectively.
176   ◾    Digital Control of Power Converters

FIGURE 4.35 Settings of the coder options window.

FIGURE 4.36 Getting an error message.

Again, in the Coder Options window, we do click on the build


button as illustrated in Figure 4.35. The build is done successfully
and we come back to the STM32CubeIDE and in the Project
Explorer section we do right click and select the Refresh option as
illustrated in Figure 4.39 to see the codes added to the cg folder as
shown in Figure 4.40.
Digital Control Implementation with PLECS   ◾    177

FIGURE 4.37 Removing e_v and m ports from the PID_Controller


subsystem.

FIGURE 4.38 The PID_Controller subsystem without e_v and m ports.

FIGURE 4.39 Selecting the refresh option.


178   ◾    Digital Control of Power Converters

FIGURE 4.40 The codes added to the ‘cg’ folder.

FIGURE 4.41 Clicking on the build all (Ctrl+B) button.

FIGURE 4.42 The build finished message.

Then we click on the Build All (Ctrl+B) button to build the


project as shown in Figure 4.41.
The build is finished with zero errors as depicted in Figure 4.42.
Finally, we can run the program to upload the codes to the
STM32 microcontroller as illustrated in Figure 4.43.
Digital Control Implementation with PLECS   ◾    179

FIGURE 4.43 Running the program.

4.4 REVIEW OF SMALL SIGNAL ANALYSIS


TOOLS FOR CONTROLLER DESIGN IN
PLECS
We’re going to review how you can use the small signal analysis
tools found in PLECS for controller design. Since the focus is
going to be on using the analysis tools, we may not comment on
every single detail within our PLECS circuits that we’re going to
be using. The electronic engineering software, PLECS, is quite
widely used and adopted in various industries and in academic
institutions worldwide and it is a complete power conversion sys-
tem simulation package. It yields very robust and fast simula-
tion results and it’s a fully integrated power electronic system
simulation package. PLECS standalone offers an independent
solution. PLECS features a comprehensive component library,
which covers not only the electrical aspects but also the mag-
netic mechanical and thermal aspects of power conversion sys-
tems and their associated controls. So, let’s quickly go over the
development tools that we’ll actually be showing in this section.
So, we’ll be using PLECS standalone to demonstrate the capa-
bilities of the built-­in analysis tools models will contain com-
ponents from the electrical component library, which includes
both passive and active electrical components like resistors and
semiconductors. The magnetic, thermal, and mechanical mod-
eling domains are also available in PLECS. With the help of the
built-­in analysis tools and the controls library, we will design
180   ◾    Digital Control of Power Converters

and model our controller. PLECS does offer other tools that fur-
ther support the simulation development and testing of power
electronics controllers. In this section, the application that we’re
going to be using to demonstrate the built-­in analysis tools is
an auxiliary-­based power supply based on the flyback converter
topology as shown in Figure 4.44.
So, because we will be saving some time by using a few prebuilt
models, we’ll take a moment here to review what’s already been
developed. As we open new models, we’ll explain the changes
that we’ve made. So hopefully it’s easy for you to follow the flow.
As an input to the converter, here in Figure 4.44, we have a single-­
phase rectifier. We’re using a simplified high-­frequency trans-
former with three output windings, 5 V and plus and minus 12 V.
The total output power is around 30 W. This is a very low-­cost
simple implementation. It’s a popular choice for power supply
designs. The topology provides isolation between the primary
and the secondary sides, and it also then gives the designer the
ability to provide multiple outputs for different voltage levels and
a choice of positive or negative voltage for the output. So, during
this section, we will add an inner peak current controller, which
will regulate the peak MOSFET current and then also a voltage
controller to regulate the 5-­V winding. As we mentioned, we’re
going to present these control analysis tools within the context of
a design example. So, for the current and voltage control loop
design of the flyback converter, we can use the procedures
depicted in Figure 4.45.
This section will use a design flow that works well within the
PLECS modeling environment using these tools. There are of
course other approaches and methodologies that are possible.
So as a starting point, we will determine the small signal trans-
fer function of the current-­controlled converter in the form of
generating a Bode plot, and this will then allow us to design a
voltage controller and then subsequently calculate the loop gain
Digital Control Implementation with PLECS   ◾    181
FIGURE 4.44 The topology of auxiliary-­based power supply.
182   ◾    Digital Control of Power Converters

FIGURE 4.45 The current and voltage control loop design of the flyback
converter.

response to ascertain if that system is now stable. So as a quick


review here, let’s go over the peak current controller block,
which is actually found in the PLECS library as illustrated in
Figure 4.46.
So, this is a modifiable controller. It’s part of the controls cate-
gory. We’ll be opening it in PLECS, allowing you to see how it is
based on an SR latch or flip-­flop storage circuit. It has also a slope
Digital Control Implementation with PLECS   ◾    183

FIGURE 4.46 The peak current controller.

control to avoid oscillations when duty cycle, d, is greater than


50% (d > 50%). At the beginning of each switching cycle, a pulse
is applied at the input at the set input S of the flip-­flop, which also
turns the switch on. The switch signal remains on until the maxi-
mum duty cycle as specified by the user in the controller’s param-
eters is reached or the current sent signal exceeds the current
reference signal. The slope control is also included in the peak
current mode controller to avoid oscillations if the duty cycle is
greater than 50% and it does this by subtracting a ramp signal
from the reference current input. Let’s get to work now. We’ll
open up PLECS as we mentioned standalone and you should now
see a model in front of you in the PLECS schematic as shown in
Figure 4.47.
So, here in Figure 4.47, we do have a model of that flyback con-
verter with no closed-­loop control at all. The gate of our MOSFET
is connected to a pulse generator block and we’ll first run an open-­
loop simulation here so you can see the output voltage waveform.
We’ll do this by going to simulation and then select the start option,
184   ◾    Digital Control of Power Converters
FIGURE 4.47 The flyback converter model in PLECS schematic.
Digital Control Implementation with PLECS   ◾    185

FIGURE 4.48 The voltage waveform of +5 V scope.

and as shown in Figure 4.48 that the startup transients are really
not very smooth. Hence, we need to add a voltage controller.
This is what we’re going to be working on. In the PLECS library
browser, we’re going to add components in our library to our
schematic and to implement our control architecture. So first, we
should replace the pulse generator block with the peak current
controller that we’ve been talking about. So, we can use the search
function and search for the component and then we drag it into
our schematic. First, we’ll connect the switch signal to the
MOSFET, and now we can right click this component as with all
components in the library that are subsystems. You can select the
look under mask option as shown in Figure 4.49, and you can see
the implementation as in Figure 4.46, which we’ve modeled it and
you can then modify it as you would for your own application.
So, we can see here the behavior described in Figure 4.46. If we
double click the peak current controller, we can see the masked
subsystem parameters, so the only default parameters here that
we’re going to change are just the duty cycle, which we will set to
186   ◾    Digital Control of Power Converters
FIGURE 4.49 Selecting the look under mask option.
Digital Control Implementation with PLECS   ◾    187

FIGURE 4.50 Setting the peak current controller parameters.

50%. We’ll check the boxes, which will display the parameters on
the schematic for us to see as depicted in Figure 4.50.
There we go, so next, what we want to do is we want to create a
current sense signal to feed into our Isense of the peak current con-
troller. So, we’re going to do that by simply placing a resistor com-
ponent, which we’ll grab from our passive electrical library and
place that into our schematic, and we’ll wire it up. We will change
the resistor value to 0.5 ohms and we can display that. Now, we
also need a voltmeter component. Again, utilizing the search
function and we wire it up as illustrated in Figure 4.51.
So, here we go, and we’ve routed now our Isense signal, and now
for the reference current signal, Iref, we’re actually going to first use
a constant block, so we’re going to specify a set point value here,
0.1 amps as you can see in Figure 4.51. This is going to limit our
actual peak inductor current to 10 amps and it’s going to create an
188   ◾    Digital Control of Power Converters
FIGURE 4.51 Wiring up the peak current controller signals.
Digital Control Implementation with PLECS   ◾    189

FIGURE 4.52 Regulation on 5 V with peak current controller.

output voltage of 5 V in other primary winding of flyback trans-


former. So, we can run this simulation again, and now you can see
the regulation on the 5-­V output as shown in Figure 4.52.
So, what’s impractical about the controller that we just imple-
mented? So, what’s impractical about the converter system is that
an outer, not typically in a system, we’re going to have an outer
voltage loop that provides this reference current, 0.1 A, for the
current controller in order to regulate the output. To design the
voltage controller, now we’re going to use the small signal transfer
function of the current-­controlled converter to do that. We can
also now get into these impulse response and AC sweep tools to
get this function in the form of a Bode plot. So, to do that, we’re
going to open up another model as depicted in Figure 4.53.
So, we’ve pre-­configured this model to perform this impulse
response analysis. We will explain the changes that we’ve made.
So, first things first, we have changed the input rectifier and
capacitor, and we’ve changed it to a 300-­V DC source component,
the dynamics of the input rectifier are much slower than those of
the flyback converter and can therefore be ignored. Simple simpli-
fications like this don’t affect our controller design, and they make
190   ◾    Digital Control of Power Converters
FIGURE 4.53 The impulse response analysis schematic.
Digital Control Implementation with PLECS   ◾    191

this small signal analysis easier to execute. To obtain a Bode plot


of the open voltage loop, we’ve added two special components to
the model. So, you can see here, we’ve added what’s called a small
signal perturbation block (iref′). So, this component is added to
our current set point value. We also need to add a small signal
response to the perturbation to measure the perturbation at the
5-­V output. So here’s our small signal response block (vo′) that
we’re using to measure the output. These components are found in
the controls category, and then found down there in the small sig-
nal analysis sub-­category of the controls category. We’ve labeled
these as iref′ and vo′, respectively, and now we can open the con-
figuration settings of the analysis by going to the simulation menu
and going to analysis tools, and then click on the plus (+) button
to add an impulse response analysis as shown in Figure 4.54.
So, there are a few settings to highlight as shown in Figure 4.55.
We’ve got the impulse response analysis selected as our choice of
analysis. We’ve labeled it simply as impulse response analysis. This is
a configuration you add and remove analyses as you see fit for your
model. The system here, we’ve specified a period length, and it’s the
least common multiple of all the periodic sources in the model, so
which in our case is the switching signal or 1 over 50 kHz. The

FIGURE 4.54 Adding an impulse response analysis.


192   ◾    Digital Control of Power Converters

FIGURE 4.55 The settings for impulse response analysis.

frequency sweep range should be a vector that includes the lowest


and the highest perturbation frequencies, and then on the perturba-
tion and response section, we want to indicate the perturbation and
response blocks that we have that we want to use for this analysis in
our model. We only have one of each, so it’s very easy for us as illus-
trated in Figure 4.55. In the options tab as shown in Figure 4.56, we
can specify the number of automatically distributed frequencies.

FIGURE 4.56 The options tab of analysis tools window.


Digital Control Implementation with PLECS   ◾    193

FIGURE 4.57 The Bode plot of impulse response analysis.

So, we’re going to start this analysis, and then we’re going to
explain a few more things. So, that was very quick, we’re done,
that analysis was super-­ fast, and that’s because the impulse
response analysis is actually the fastest method that we have of
generating a Bode plot as shown in Figure 4.57.
When we run the impulse response analysis, it actually first
runs a steady-­state analysis in order to find the stable operating
point of the system. The steady-­state analysis is based on a Newton
Raphson iterative technique, and it may not converge when the
system is run from startup because the system is under damped,
and the state variables in PLECS are going to be too far from the
final operating point. So, the simplest method of addressing this
problem is to simulate the system for a specified number of initial-
ization cycles before the steady-­state analysis is run. If we go back
to our configuration settings and we go to the steady-­state options,
194   ◾    Digital Control of Power Converters

FIGURE 4.58 The steady-­state options tab of analysis tools window.

we can see here in Figure 4.58 that we have the ability to specify
this number of initialization cycles.
This then causes the Jacobian matrix to be calculated from
an operating point that is closer to the steady-­state operating
point, which increases the likelihood of convergence in the
under-­damp system and thus allowing the analysis to run to
completion. So, that’s our analysis, so we can go back to this
frequency response. We can see the frequency response here of
our current controlled flyback converter. We’re now going to
save this data. So, we’ll go file export as a CSV file as depicted
in Figure 4.59.
So, we’ll save it as flyback.csv, so now at this stage, we are ready
to start talking about that voltage controller. So, what we’re going
to use MATLAB for a PID controller design. So, in the MATLAB
command window, we write the following codes.

data = csvread(‘C:\CRC Press\flyback.csv’);


w = 2*pi*data(:,1);
val=10.^(data(:,2)/20).*exp(j*data(:,3)*pi/180);
Digital Control Implementation with PLECS   ◾    195

FIGURE 4.59 Exporting the Bode plot as a CSV file.

sys = frd(val,w);
bode(sys),grid minor
G = tfest(sys,3)

The estimated transfer function using MATAB with an accu-


racy of 99.71% is as below.

G =
-4.024e04 s^2 + 5.83e09 s + 1.338e12
------------------------------------------
s^3 + 2.596e05 s^2 - 4.657e08 s - 6.749e12
Continuous-­
time identified transfer function.
Parameterization:
Number of poles: 3 Number of zeros: 2
Number of free coefficients: 6
196   ◾    Digital Control of Power Converters

Use "tfdata", "getpvec", "getcov" for


parameters and their uncertainties.
Status:
Estimated using TFEST on frequency response data
"sys".
Fit to estimation data: 99.71%
FPE: 1.067e-­
05, MSE: 8e-­
06

Then, we can write the following code.

pidTuner(G)

We can adjust the response time and transient behavior slides


to get the step response as illustrated in Figure 4.60.
Then, we click on the Show Parameters button to see the PID
controller parameters alternatively, we can click on the Export
button and give it a name (Cg) and click on the OK button as
shown in Figure 4.61.

FIGURE 4.60 The PID tuner window.


Digital Control Implementation with PLECS   ◾    197

FIGURE 4.61 The show parameters and export windows.

Next, in the command window of MATLAB, we can type the


‘Cg’ and press the enter key to get the PID controller parameters as
below.

>> Cg
Cg =
1
Kp + Ki * --- + Kd * s
s
with Kp = 2.22, Ki = 4.78e+04, Kd = 1.23e-­
05
Continuous-­
time PID controller in parallel
form.

Now, we can add the Continuous PID Controller block in


Figure 4.53 to create a closed-­loop voltage and peak current con-
troller as depicted in Figure 4.62.
The waveform of 5 V scope is illustrated in Figure 4.63.
198   ◾    Digital Control of Power Converters
FIGURE 4.62 The closed-­loop voltage and peak current controller.
Digital Control Implementation with PLECS   ◾    199

FIGURE 4.63 The waveform of 5 V scope.

Then, we add a load step to the model, to evaluate the tran-


sient behavior of closed-­loop controller. So, at the time 25 ms,
we add a parallel resistor (2 Ω) in the 5 V circuit as shown in
Figure 4.64.
The output voltage waveforms during the load step at the time
25 ms are shown in Figure 4.65.
Therefore, our closed-­loop controller is stable. In order to code
generation for the closed-­loop voltage and peak current controller,
we use a subsystem as shown in Figure 4.66 and take our control-
ler inside of it. Then we use STM32 target elements such as ADC
and digital out as depicted in Figure 4.67.
If we run the schematic of Figure 4.66, the output voltage wave-
forms remain the same as Figure 4.65 as shown in Figure 4.68.
Then, we do right click on the subsystem and select Subsystem
and Execution settings… and in the popped-­up window we tick
the Enable code generation and choose the Discretization step
size as 2e-­7 as illustrated in Figures 4.69 and 4.70, respectively.
200   ◾    Digital Control of Power Converters
FIGURE 4.64 Adding a load step to the model.
Digital Control Implementation with PLECS   ◾    201

FIGURE 4.65 The output voltage waveforms during the load step.

In the Open projects from File System window, we click on the


Archive… button as illustrated in Figure 4.29, to open the g474.
zip file in the following directory as shown in Figure 4.30.

PLECS4.7(64 bit) > tsp_stm32 > projects > g474.


zip

Then we run the STM32CubeIDE to enter it and from File


icon we select Open projects from File System… option as
depicted in Figure 4.28. Then we do click on the Finish button in
the Import Projects from File System or Archive window as
shown in Figure 4.31. In the Project Explorer, we find the cg
folder and then right click on it and select the Properties option
as depicted in Figure 4.32. Therefore, the Properties for cg win-
dow is opened and we do copy the Location directory as illus-
trated in Figure 4.71.
202   ◾    Digital Control of Power Converters
FIGURE 4.66 Taking our controller inside the subsystem.
Digital Control Implementation with PLECS   ◾    203

FIGURE 4.67 The subsystem controller and STM32 target elements.

FIGURE 4.68 The output voltage waveforms with STM32 target elements.
204   ◾    Digital Control of Power Converters
FIGURE 4.69 Selecting the execution settings… option.
Digital Control Implementation with PLECS   ◾    205

FIGURE 4.70 Enabling code generation and setting discretization step


size.

FIGURE 4.71 Doing copy the location directory.


206   ◾    Digital Control of Power Converters

FIGURE 4.72 Settings of the coder options window.

Then, we close the Properties for cg window and come back to


the PLECS environment and in the Coder icon of menu we select
the Coder options…, to open the Coder Options window and
in the Target section we select the Target as STM32G4x and chip
as G474xx, the Build type as generate code into STM32CubeIDE
project and also we do paste the copied Location directory as in
Figure 4.71 to the STM32CubeIDE project directory and also tick
use internal oscillator and finally click on the Accept and Build
buttons respectively as shown in Figure 4.72.
The build is done successfully and we come back to the
STM32CubeIDE and in the Project Explorer section we do
right click and select the Refresh option to see the codes added
to the cg folder, then we click on the Build All (Ctrl+B) button
to build the project as shown in Figure 4.73. The build is fin-
ished with zero errors and finally, we can run the program to
upload the codes to the STM32 microcontroller as illustrated in
Figure 4.74.
Digital Control Implementation with PLECS   ◾    207

FIGURE 4.73 Clicking on the build all (Ctrl+B) button.

FIGURE 4.74 Successfully building and running the program.


References

[1] Kupolati H. STM32 Practical Buck Converter Implementation and


Control, Udemy, 2023.
[2] Nabil M. Digital Feedback Control Tutorial with Arduino, Udemy,
2019.
[3] Pakdel M. Advanced Programming with STM32 Microcontrollers,
Elektor, 2020, 216 p.
[4] DC Motor Speed: System Modeling. ​https://​ctms.​engin.​umich.​edu/​
C T M S / ​ i n d e x . ​ p h p ? ​ e x a m p l e = ​ M o t o r S p e e d & ​ s e c t i o n =​
SystemModeling
[5] Pakdel M. Advanced Modeling and Control of DC-­DC Converters,
Wiley, 2025, 352 p.

208
Index

Note: Pages in italics refer to figures and pages in bold refer to tables.

A B
ACS712 current sensor, 138 bilinear transformation, 16, 48
AmpGain, 127 Bode plots
Arduino demonstration closed-­loop transfer function
DC gearmotor’s, Serial Plotter, of Gid, 96, 96
76, 76 of Gpci_mat, 97, 97–98, 99
Measured_Speed, 77, 77 of Gpcv_mat, 102, 102
script, 70–75 of Gpcv_pm, 103, 104
set point speed tracking, of Gvd, 100, 101
70, 70 of Tpci_mat, 98, 98, 100, 100
simulated data, 78, 79 of Tpcv_mat, 102, 103
simulink block diagram, closed-­ of Tpcv_pm, 103, 104, 105
loop feedback system, 69, 70 CSV file, 194, 195
theoretical result and measured of impulse response analysis, 193, 193
result, 78, 80, 80 open voltage loop, 191
Arduino IDE’s Serial Plotter, 29, 29 buck converter
ARR, see Auto Reload Register (ARR) CCM, 90
Auto Reload Register (ARR), 123 compensator phase, 91, 93–94
average current mode control, buck controller design with OCTAVE
converter crossover frequency, 108
CCM, 147 current and voltage controller
double loop current control design, 110
function, 143–146 current and voltage controller
implementation of, 140, 147 transfer functions,
loop counter variable, 140–143 110–111
output voltage/output current, gain and phase margins,
139–140 111–117

209
210   ◾    Index

parameters, 107 analysis tools selection, 154, 156


small signal output current, analysis tools window settings,
108–109 154, 156
z-­domain transfer functions, Bode diagram, MATLAB, 157, 159
113 choose name and saving the CSV
crossover frequency, 91–93, 95 file, 156, 158
digital control implementation continuous PID controller block,
average current mode control 162, 162
of, 139–149 control to output frequency
firmware implementation of response, 154, 157
current control, 134–139 designed buck converter, 151, 152
firmware implementation of enter a name PID controller
voltage control, window, 160, 161
129–134, 131 first row of data.csv. remove, 156,
firmware peripherals 159
initialization with CubeMX frequency response data, CSV file,
software, 121–124 154, 157
hardware, 118–121, 119, 120 MATLAB command window, 160
manual firmware initialization, output voltage waveform, 153, 153
124–129, 125, 129 output voltage waveform, scope,
duty cycle and inductance values, 82 162, 165
inductor current ripple, 82–83 PID(s) block to the closed-­loop
MATLAB, current/voltage control control system, 162, 164
loop PID(s) transfer function values
Bode plot, 96–103, 96–105 setting, 162, 163
c2d function in, 86, 87, 89, 89 PID tuner window setting, 160,
Google Colab code, 95 161
PID tuner window, 84–86, 85, simulation parameters window,
87, 88 153, 154
step response of, 105, 106 small signal analysis elements,
transient response of, 105, 105 153, 155
parameters of, 81, 82, 84 upper and lower saturation limits,
schematic of, 81, 82 anti-­windup tab setting,
small signal transfer function, 83 162, 163
switching frequency, 90 code generation for the STM32
voltage and current sensors, 81 Nucleo-­G474RE
ADC1 block parameters window,
168, 169
C
buck converter and PID controller
CCM, see continuous conduction creation, 166, 166
mode (CCM) build finished message, 178, 178
closed-­loop controller in PLECS and circuit inside the Buck_Converter
MATLAB subsystem, 166, 167
Index   ◾    211

circuit inside the PID_Controller Measured_Speed, 77, 77


subsystem, 166, 168, 168 set point speed tracking, 70, 70
clicking on the archive, 172 simulated data, 78, 79
click the build all (Ctrl+B) button, Simulink block diagram,
178, 178 closed-­loop feedback
click the finish button, 172, 173 system, 69, 70
coder options selection, 174, 175 theoretical result and measured
coder options window setting, result, 78, 80, 80
174, 176 controller design
codes added to the cg folder, 176, approximate transfer function
178 for DC gearmotor, 60, 61
copy the location directory, 174, classical control techniques, 66
175 closed-­loop transfer function,
enable code generation, 170, 171 63
error message, 174, 176 continuous-­time block
open projects from file system diagram, 63, 63
selection, 172 continuous-­time controller,
open the g474.zip file, 172, 173 68, 68
PID_Controller subsystem difference equation, 69
e_v and m ports remove, 175, explicit transfer functions, 64,
177 64
without e_v and m ports, 175, rational transfer functions,
177 65, 65
program run, 178, 179 sampling time, T, 61, 62, 63
properties option selection, 174, Show Parameters tab, 67, 67
174 transfer functions P(s) and
PWM block parameters window, GZOHP(s), 66
168, 169 Tustin’s method, 68
refresh option selection, 176, 177 system modeling
results of simulation, 168, 170 Arduino script, 55–58
start option selection, 168, 170 block diagram, control loop,
steps, 165–166 49, 49
continuous conduction mode (CCM), data variables, 58, 58
90, 139, 145, 147 Kirchhoff ’s voltage law, 52
CubeMX software, 121–124 Newton’s second law, 52
open-­loop transfer function, 52
parameter values, 58–59, 59
D
plant’s transfer function, 60
DC motor speed control procedures, 50–51
Arduino demonstration setup, schematic of, 49, 49
Arduino script, 70–75 Simulink model, 54, 54–55
DC gearmotor’s, Serial Plotter, transfer function, 51, 51–52, 53
76, 76 digital control implementation
212   ◾    Index

of buck converter ZOH/sampling, 42, 43, 44–45,


average current mode control 45–46
of, 139–149 digital feedback control algorithm
firmware implementation of control structure, 38, 38
current control, 134–139 ‘if ’ statement, 37
firmware implementation of implementation, 35, 35–36
voltage control, 129–134, impulse function, 38, 38
131 ZOH block operation, 37,
firmware peripherals 37–38
initialization with CubeMX disadvantages of analog/
software, 121–124 continuous-­time
hardware, 118–121, 119, 120 controllers, 5
manual firmware initialization, discrete-­time system
124–129, 125, 129 Arduino IDE’s Serial Plotter,
with PLECS, see PLECS software 29, 29
digital controller design data variable creation, 32, 32
approximate sampling time, T, frequency response of, 20, 21
41, 48 frequency responses, 22, 23, 24
bilinear transform/Tustin’s From Workspace block
method, 48 properties, 32, 33
implementing, 49 if statement, 27–28
inverse Z-­transform, 48 input step signal, 26, 26
transfer function as P(s), 40–42 inverse Z-­transform, 25
ZOH/sampling, 42, 43, 44–45, MATLAB, 19–20
45–46 rename the data variable as
digital control with Arduino Output_Data, 32, 33
advantages of scope and running the
analog/continuous-­time simulation, 30, 31
control system, 3, 3 second-­order continuous-­time
buck converter, 3, 3–4 system, 19, 20
digital control scheme, 6, 6 second-­order system, 24
type II compensator, 4, 4 setting, 30, 30
DC motor speed control, see DC step input block, 30, 30
motor speed control step response in scope, 31, 31
digital controller design theoretical simulated output
approximate sampling time, T, against the implementation
41, 48 output, 33, 34
bilinear transform/Tustin’s transient response of, 21–22, 22
method, 48 discretization of continuous-­time
implementing, 49 systems
inverse Z-­transform, 48 Bode diagram of, 18, 19
transfer function as P(s), frequency response analysis
40–42 technique, 15
Index   ◾    213

MATLAB, 18 I
natural logarithm, 15–16
INA180, 121, 127
root locus, 14
Integrated Development Environment
Tustin’s method, 14, 16–17, 17
(IDE), 18
Z-­transform, 10
inverse Z-­transform, 16, 25, 48, 68–69
closed-­loop feedback diagram,
13
difference equation, 14 K
Kirchhoff ’s Current Law
(KCL), 10 Kirchhoff ’s Current Law (KCL), 10
Laplace transform, 8, 8–11, 11
s-­plane and z-­plane, 11, 12 M
type II compensator, 4, 9
digital feedback control algorithm MATLAB, 18–19, 22, 58, 61, 157
control structure, 38, 38 Bode diagram of, 159
‘if ’ statement, 37 ‘bode’ function, 20
implementation, 35, 35–36 c2d function, 68, 86, 89
impulse function, 38, 38 closed-­loop controller in, see
ZOH block operation, 37, 37–38 closed-­loop controller in
double loop control, 139, 141 PLECS and MATLAB
duty cycle method, 140 closed-­loop PID controller,
160–161
control design tools, 64, 66
E current control loop, 84
explicit transfer functions, 64, 64 frequency responses, 24
measured output speed, 77, 77
Octave, 108
F phase margin-­based frequency
firmware response, 95
implementation PI controllers, pidTuner tool, 95,
of current control, 134–139 97, 101, 105, 105, 106, 113
of voltage control, 129–134, 131 PID controller design, 194, 197
manual initialization, 124–129, 125 rational transfer function, 65
peripheral initialization with two-­dimensional variable, 31
CubeMX, 121–124 MATLAB Simulink, 30, 54–55, 77, 105
Metal-­Oxide-­Semiconductor Field-­
Effect Transistor (MOSFET),
G 108, 118–120, 139–140, 153,
Google Colab code, 95 162, 180, 183, 185

H N
Hall effect current sensor, 138 Newton’s second law, 52
214   ◾    Index

O MATLAB command window,


160
Octave software, PI controller design
output voltage waveform, 153,
crossover frequency, 108
153
current and voltage controller
output voltage waveform,
design, 110
scope, 162, 165
current and voltage controller
PID(s) block to the closed-­loop
transfer functions, 110–111
control system, 162, 164
gain and phase margins,
PID(s) transfer function values
111–117
setting, 162, 163
parameters, 107
PID tuner window setting, 160,
small signal output current,
161
108–109
simulation parameters window,
z-­domain transfer functions, 113
153, 154
small signal analysis elements,
P
153, 155
Pade approximation, 64 upper and lower saturation
PI controller design, see proportional limits, anti-­windup tab
integral (PI) controller setting, 162, 163
design code generation for the STM32
pidTuner(sys) function, 66 Nucleo-­G474RE, 165–179
PLECS software ADC1 block parameters
closed-­loop controller window, 168, 169
analysis tools selection, 154, buck converter and PID
156 controller creation, 166, 166
analysis tools window settings, build finished message, 178,
154, 156 178
Bode diagram, MATLAB, 157, circuit inside the Buck_
159 Converter subsystem, 166,
choose name and saving the 167
CSV file, 156, 158 circuit inside the PID_
continuous PID controller Controller subsystem, 166,
block, 162, 162 168, 168
control to output frequency clicking on the archive, 172
response, 154, 157 click the build all (Ctrl+B)
designed buck converter, 151, button, 178, 178
152 click the finish button, 172, 173
enter a name PID controller coder options selection, 174,
window, 160, 161 175
first row of data.csv. remove, coder options window setting,
156, 159 174, 176
frequency response data, CSV codes added to the cg folder,
file, 154, 157 176, 178
Index   ◾    215

copy the location directory, file export as a CSV file, 194,


174, 175 195
enable code generation, 170, 171 flyback converter model, 183,
error message, 174, 176 184
open projects from file system impulse response analysis
selection, 172 schematic, 189, 190
open the g474.zip file, 172, 173 impulse response analysis
PID_Controller subsystem, setting, 191, 192
175, 177 look under mask option
program run, 178, 179 selection, 185, 186
properties option selection, options tab of analysis tools
174, 174 window, 192, 192
PWM block parameters output voltage waveforms
window, 168, 169 during the load step, 199,
refresh option selection, 176, 201
177 output voltage waveforms with
results of simulation, 168, 170 STM32 target elements,
start option selection, 168, 170 199, 203
steps, 165–166 peak current controller, 182,
features of, 150–151 183
small signal analysis tools peak current controller
add an impulse response parameters setting, 187, 187
analysis, 191, 191 PID tuner window, 196, 196
Bode plot of impulse response regulation on 5 V with peak
analysis, 193, 193 current controller, 189, 189
click the build all (Ctrl+B) run the program, 206, 207
button, 206, 207 show parameters and export
closed-­loop voltage and peak windows, 196, 197
current controller, 197, 198 steady-­state options tab of
coder options window setting, analysis tools window, 194,
206, 206 194
controller inside the subsystem, topology of auxiliary-­based
199, 202 power supply, 180, 181
copy the location directory, voltage waveform of +5 V
205, 206 scope, 185, 185
current and voltage control waveform of 5 V scope, 197,
loop design, flyback 199
converter, 180, 182 wiring the peak current
enable code generation and controller signals, 187, 188
setting discretization step proportional integral (PI) controller
size, 199, 204 design
execution settings selection, MATLAB, current/voltage control
199, 204 loop
216   ◾    Index

Bode plot, 96–103, 96–105 current and voltage control loop


c2d function in, 86, 87, 89, 89 design, flyback converter,
vs. current and voltage control 180, 182
loops, 105, 105 enable code generation and setting
Google Colab code, 95 discretization step size, 199,
phase margin calculations, 105 204
PID tuner window, 84–86, 85, execution settings selection, 199,
87, 88 204
step response of, 105, 106 file export as a CSV file, 194, 195
Octave software flyback converter model, 183, 184
crossover frequency, 108 impulse response analysis
current and voltage controller schematic, 189, 190
design, 110 impulse response analysis setting,
current and voltage controller 191, 192
transfer functions, 110–111 look under mask option selection,
gain and phase margins, 185, 186
111–117 options tab of analysis tools
parameters, 107 window, 192, 192
small signal output current, output voltage waveforms during
108–109 the load step, 199, 201
z-­domain transfer functions, output voltage waveforms with
113 STM32 target elements,
199, 203
peak current controller, 182, 183
S
peak current controller parameters
Serial Plotter, 29, 29, 76, 76 setting, 187, 187
small signal analysis tools, PLECS for PID tuner window, 196, 196
controller design regulation on 5 V with peak
add an impulse response analysis, current controller, 189, 189
191, 191 run the program, 206, 207
Bode plot of impulse response show parameters and export
analysis, 193, 193 windows, 196, 197
click the build all (Ctrl+B) button, steady-­state options tab of analysis
206, 207 tools window, 194, 194
closed-­loop voltage and peak topology of auxiliary-­based power
current controller, 197, 198 supply, 180, 181
coder options window setting, voltage waveform of +5 V scope,
206, 206 185, 185
controller inside the subsystem, waveform of 5 V scope, 197, 199
199, 202 wiring the peak current controller
copy the location directory, 205, signals, 187, 188
206 small signal perturbation block, 191
Index   ◾    217

STM32CubeIDE, 121, 123–124, 166, Simulink model, 54, 54–55


172, 174, 176, 201, 206 transfer function, 51, 51–52, 53
STM32CubeMX, 121
STM32 microcontroller ADC pin, 127
T
STM32 Nucleo-­G474RE, 118–121; see
also code generation for the Tustin’s method, 14, 16–18, 41, 48, 68,
STM32 Nucleo-­G474RE 85, 88
system modeling, DC motor speed
control
Z
Arduino script, 55–58
block diagram, control loop, 49, 49 zero-­order hold (ZOH), 13, 37, 37–38,
data variables, 58, 58 42, 43, 44, 49
Kirchhoff ’s voltage law, 52 Z-­transform, 10
Newton’s second law, 52 closed-­loop feedback diagram, 13
open-­loop transfer function, 52 difference equation, 14
parameter values, 58–59, 59 Kirchhoff ’s Current Law (KCL), 10
plant’s transfer function, 60 Laplace transform, 8, 8–11, 11
procedures, 50–51 s-­plane and z-­plane, 11, 12
setup, schematic of, 49, 49 type II compensator, 4, 9

You might also like