PID-based Practical Digital Control With Raspberry Pi and Arduino Uno
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno
PID-based Practical
PID-based Practical
● All rights reserved. No part of this book may be reproduced in any material form, including photocopying, or
storing in any medium by electronic means and whether or not transiently or incidentally to some other use of this
publication, without the written permission of the copyright holder except in accordance with the provisions of the
Copyright Designs and Patents Act 1988 or under the terms of a licence issued by the Copyright Licencing Agency
Ltd., 90 Tottenham Court Road, London, England W1P 9HE. Applications for the copyright holder's permission to
reproduce any part of the publication should be addressed to the publishers.
● Declaration
The Author and Publisher have used their best efforts in ensuring the correctness of the information contained in
this book. They do not assume, and hereby disclaim, any liability to any party for any loss or damage caused by
errors or omissions in this book, whether such errors or omissions result from negligence, accident, or any other
cause.
All the programs given in the book are Copyright of the Author and Elektor International Media. These programs
may only be used for educational purposes. Written permission from the Author or Elektor must be obtained before
any of these programs can be used for commercial purposes.
Elektor is part of EIM, the world's leading source of essential technical information and electronics products for pro
engineers, electronics designers, and the companies seeking to engage them. Each day, our international team develops
and delivers high-quality content - via a variety of media channels (including magazines, video, digital media, and social
media) in several languages - relating to electronics design and DIY electronics. www.elektormagazine.com
●4
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 4 11/10/2022 13:54
Contents
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Chapter 2 • Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
●5
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 5 11/10/2022 13:54
PID-based Practical Digital Control
5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
●6
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 6 11/10/2022 13:54
Contents
7.4 Project 2: ON-OFF Temperature Control with Hysteresis and Arduino Uno . . . . . . . 99
7.5 Project 3: ON-OFF Temperature Control with Button Control – Arduino Uno . . . . . 101
7.6 Project 4: ON-OFF Temperature Control with Rotary Encoder and Arduino Uno . . . 104
9.4 Project 3: PID Temperature Control with Arduino Uno and Timer Interrupts . . . . . 152
9.5 Project 4: PID Temperature Control using the Arduino Uno PID Library . . . . . . . . 155
●7
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 7 11/10/2022 13:54
PID-based Practical Digital Control
10.8 Project 1: Motor Speed and Direction Control Using an H-Bridge Integrated Circuit 170
10.9 Project 2: Displaying the Motor Speed with Arduino Uno. . . . . . . . . . . . . . . . . . 177
10.10 Project 3: Displaying Motor Speed on LCD with Arduino Uno . . . . . . . . . . . . . . 181
10.14 Project 7: PID Motor Speed control with Raspberry Pi. . . . . . . . . . . . . . . . . . . 191
10.15 Project 8: PID Motor Speed Control with Arduino Uno . . . . . . . . . . . . . . . . . . 195
11.3 Project 1: Measuring Distance using the HC-SR04 Ultrasonic Module with
Arduino Uno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
11.4 Project 2: Measuring Distance using the HC-SR04 Ultrasonic Module with
Raspberry Pi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
11.5 Project 3: Step Input Response of the System with Raspberry Pi . . . . . . . . . . . . 206
11.7 Project 5: PID-based Water Level Control with Arduino Uno . . . . . . . . . . . . . . . 215
12.2 Project 1: Step Time Response of LED Brightness Control using the Raspberry Pi 220
12.3 Project 2: PID-Based LED Brightness Control using the Raspberry Pi . . . . . . . . . 224
12.4 Project 3: PID-based LED Brightness Control using the Arduino Uno . . . . . . . . . 229
12.5 Project 4: PID-based LED Brightness Control using the Arduino Uno Library . . . . 232
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
●8
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 8 11/10/2022 13:54
Preface
Microcontrollers are highly popular integrated circuits commonly used in many domestic,
commercial, and industrial electronic monitoring and control applications. It is estimated
that there are more than 50 microcontrollers in every home in developed countries. Do-
mestic equipment having embedded microcontrollers include microwave ovens, printers,
keyboards, computers, tablets, washing machines, dishwashers, smart televisions, smart-
phones, and many more.
The Raspberry Pi 4 is one of the latest credit-card sized popular computers that can be used
in many applications such as in audio and video media centers, as a desktop computer, in
industrial controllers, robotics, games, and many domestic and commercial applications. In
addition to rich set of features found in other Raspberry Pi computers, the Raspberry Pi 4
also offers Wi-Fi and Bluetooth capability which makes it highly desirable for incorporation
in remote and Internet-based control and monitoring applications.
This book is about using both the Raspberry Pi 4 and the Arduino Uno in PID-based auto-
matic control applications. The book starts with basic theory of the control systems and
feedback control. Working and tested projects are given for controlling real systems using
PID controllers. The open-loop step time response, tuning the PID parameters, and the
closed-loop time response of the developed systems are discussed in depth together with
the block diagrams, circuit diagrams, PID controller algorithms, and the full program list-
ings for the Raspberry Pi as well as the Arduino Uno. The projects given in the book should
teach the theory and applications of PID controllers. They can be modified easily as desired
for other applications. The projects given for Raspberry Pi 4 should work with all other
models of Raspberry Pi family.
It is expected that the readers have some programming experience with the Arduino Uno
using the Arduino IDE. The same for the Raspberry Pi with the Python 3 programming lan-
guage. Some basic electronic hardware experience and knowledge of basic mathematics
will also be useful.
●9
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 9 11/10/2022 13:54
PID-based Practical Digital Control
All programs discussed in the book are contained in an archive file you can download free
of charge from the Elektor website. Head to: www.elektor.com/books and enter the book
title in the Search box.
I hope that you enjoy reading the book and at the same time learn the theory and practical
applications of the PID controllers.
Dogan Ibrahim
London, 2022
● 10
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 10 11/10/2022 13:54
Chapter 1 • Control Systems
A plant can have one or more inputs and one or more outputs. The dynamic behavior of a
plant is described by differential equations. Given the model (or the differential equations),
inputs, and initial conditions of a plant we can easily calculate its outputs. Generally, a
plant is a continuous-time system with its inputs and outputs also continuous in time. For
example, an electromagnetic motor is a continuous-time plant whose input (e.g., voltage
or current) and its output (e.g., speed or position) are also continuous in time.
Control engineering is based on the theories of system modelling, feedback, system re-
sponse, and stability. As a result, control engineering is not limited to only one engineering
discipline, but is equally applicable to mechanical, chemical, aeronautical, civil, and electri-
cal engineering disciplines.
A plant is normally an open-loop system (Figure 1.1) where an actuating device is used
to control the plant directly without using feedback. For example, a motor is expected to
rotate when a voltage is applied across its input terminals, but we do not know by how
much the motor rotates since there is no knowledge about its output. If the motor shaft is
loaded and the motor slows down, there is no knowledge about this. As shown in Figure
1.1, a plant may also have external disturbances affecting its behavior, and in an open-loop
system there is no way of knowing or minimizing such disturbances.
In contrast to open-loop control system, in a closed-loop control system (Figure 1.2) the
actual plant output is measured and compared with what we would like to see at the plant
output. The measure of the output is called feedback signal. The difference between
the desired output value and the actual output value is called the error signal. The error
signal is used to force the system output to a point such that the desired output value and
the actual output value are equal, i.e., the error signal is zero. One of the advantages of
closed-loop control, or feedback control is the ability to compensate for disturbances and
yield the correct output even in the presence of disturbances. Also, the plant output settles
● 11
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 11 11/10/2022 13:54
PID-based Practical Digital Control
and remains at the desired value. For example, in a motor speed control system the speed
of the motor remains the same when load is applied to the motor shaft. A controller (or
compensator) is usually used to read the error signal and drive the plant in such a way
that the error tends to zero.
Sensors are devices which measure the plant output. For example, a thermistor is a sensor
used to measure the temperature and it can be used in a closed-loop thermal plant control.
Similarly, a tachometer or an encoder can be used to measure the rotational speed of a
motor and they can be used in closed-loop motor speed control applications. Notice that
in electrical systems a power amplifier may be required after the DAC to drive the plant.
As you'll discover in a later Chapter, most sensors are analog devices giving analog voltage
or current outputs. These sensors can be used directly in analog systems where the inputs,
controller, plant, and the outputs are all analog variables.
Figure 1.3 shows a digital control system where the input and the output of the sensor are
assumed to be analog. An ADC is used to periodically convert the error signal into digital
form and this is fed to a digital controller which is usually a microcontroller. The microcon-
troller implements a control algorithm (e.g., PID algorithm) and its output is converted into
analog form using a digital-to-analog converter (DAC) so that it can drive the plant to set
the plant output to the desired value.
● 12
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 12 11/10/2022 13:54
Chapter 1 • Control Systems
Figure 1.4 shows the block diagram of a digital control system where the ADC is shown as
a sampler. Most microcontrollers incorporate ADC and DAC modules and these are shown
as part of the microcontroller in Figure 1.4.
In Figure 1.4 the input and the sensor output are analog signals. A variation of this system
is shown in Figure 1.5 where the input is digital and is either hardcoded to the microcon-
troller software or is input using a suitable input device such as a keypad. Here, a sensor
with digital output is used and is connected directly to the microcontroller.
Figure 1.6 shows a typical analog speed control system. Here, the desired speed is set
using a potentiometer. The speed of the motor is measured using a tachometer and is fed
back to a difference amplifier. The output of this amplifier is the error signal which is input
to an analog controller consisting of operational amplifiers. The output of the controller
drives the motor through a power amplifier to achieve the desired speed.
● 13
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 13 11/10/2022 13:54
PID-based Practical Digital Control
Figure 1.7 shows the digital equivalent of Figure 1.6. Here, a digital encoder is used to
measure the motor speed and this is fed to the microcontroller together with the desired
speed where the speed is set using a keypad. The microcontroller implements the control
algorithm and sends its output to the power amplifier in the form of a Pulse Width-Modulat-
ed (PWM) signal which in turn provides power to the motor to set the speed at the desired
value.
Since a plant can be controlled using an analog approach, you might be tempted to ask
why use digital control? In the 1960s, computers and microcontrollers were bulky and very
expensive devices and their use as digital controllers was not justified. They were only used
in large and expensive plants, such as large chemical processing sites or oil refineries. Since
the introduction of microcontrollers in 1970s, the cost and size of digital controllers have
dropped dramatically. As a result of this, also from the drop in the price of other digital
components such as memories, interest in using digital control has soared in the past few
decades.
• Improved user interface. Digital controllers can display the system parameters
and response graphically on a monitor.
• Digital controllers can be configured to be adaptive. Complex controller
algorithms can easily be implemented using digital controllers.
• The cost of digital controllers are lower than the analog ones, especially if
additional control loops have to be added to the system.
• It is easy to tune digital controllers. All that is required is to change pertinent
parameters in software.
• Digital controllers are more dependable than the analog ones and they are
not affected by environmental factors such as component aging, component
tolerances, etc.
• Digital controllers can be modified easily through software. Modification of
an analog controller on the other hand usually require re-wiring or the use of
different or additional components.
• Almost all analog controllers have been replaced over time by digital ones.
● 14
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 14 11/10/2022 13:54
Chapter 1 • Control Systems
● 15
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 15 11/10/2022 13:54
PID-based Practical Digital Control Chapter 2 • Sensors
Chapter 2 • Sensors
Sensors can be divided into two groups: analog or digital. Analog sensors are widely used
and their outputs are analog signals (e.g., voltage or current) proportional to the physical
quantity to be measured. Most environmental variables in the world are analog by nature,
for example the temperature, humidity, pressure etc. An analog temperature sensor gives
an analog voltage directly proportional to the measured temperature. Analog sensors can
only be connected to microcontrollers using ADC converter modules.
Digital sensors are not very common and they give digital logic level outputs which can be
directly connected to a computer. The advantage of using digital sensors is that they are
more accurate and stable than the analog ones and they can directly be connected to a
computer. Digital sensors also tend to me more expensive than their analog equivalents.
The choice of a sensor for a particular application depends on several factors such as the
availability, cost, accuracy, precision, resolution, range, and linearity of the sensor. Some
important sensor related parameters are described below.
Range: The range of a sensor specifies the upper and lower limits that can be measured
by the sensor. For example, if the range of a temperature sensor is specified as 10 – 60 ºC
then the sensor should only be used to measure temperatures within this range.
Resolution: The resolution of a sensor is specified as the largest change in measured value
that will not result in a change in sensor's output. i.e., the measured value can change by
the amount quoted by the resolution before this change can be detected by the sensor. In
general, the smaller this amount the better the sensor is, and sensors with a wide range
have less resolution. For example, a temperature sensor with a resolution of 0.01 ºC is
better than a sensor with a resolution of 0.1 ºC.
Sensitivity: The sensitivity of a sensor is defined as the slope of the output characteris-
tic curve. More generally, it is the minimum input of physical parameter that will create a
detectable output change. For example, a typical temperature sensor may have a sensi-
tivity rating of 1 ºC. This means that the output voltage will not change if the temperature
change is less than 1 ºC .
● 16
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 16 11/10/2022 13:54
Chapter 2 • Sensors
Accuracy: The accuracy of a sensor is the maximum difference that will exist between
the actual value and the indicated value at the output of the sensor. The accuracy can be
expressed either as a percentage of full scale or in absolute terms.
Repeatability: The repeatability of a sensor is the variation of output values that can be
expected when the sensor measures the same physical quantity with the same conditions.
For example, if the voltage across a resistor is measured at the same time several times
you may get slightly different results.
Linearity: An ideal sensor is expected to have a linear transfer function. i.e., the sensor
output is expected to be exactly proportional to the measured value. For example, the
LM35 temperature sensor chip output is linear and is specified as 10mV/ºC. At 10 ºC the
output voltage is 100 mV, at 20 ºC it is 200 mV and so on. In practice all sensors exhibit
some amount of nonlinearity depending upon the manufacturing tolerances and the meas-
urement conditions.
Offset error: The offset error of a sensor is defined as the output that will exist when it
should be zero. For example, the output of a force sensor should be zero if there is no force
applied to the sensor.
Dynamic response: The dynamic response of a sensor specifies the limits of the sensor
characteristics when the sensor is subject to a sinusoidal frequency change. For example,
the dynamic response of a microphone may be expressed in terms of the 3-dB bandwidth
of its frequency response.
Response time: Sensors do not change their output states immediately when an input
parameter change occurs. For example, a temperature sensor does not give new reading
as soon as the temperature changes, but rather, it will take some time before the output
changes. The response time can be in microseconds, milliseconds, or seconds depending
upon the sensor used. Sensors with short response times, although more expensive, are
preferred in most applications.
Self-heating: The internal temperatures of some sensors may increase when used con-
tinuously for long times and this is called self-heating. Self-heating is not desirable as it
may cause the output of the sensor to change. For example, a temperature sensor with
self-heating feature may give wrong and fluctuating outputs as the sensor is used over
time.
Physical size: The physical size of a sensor can be important in some applications. Users
should check the dimensions of a sensor before it is considered for use.
Operating voltage: This is also an important factor to consider before a sensor is used.
The operating voltage, as well as the minimum and maximum voltages that can be applied
to the sensor should be known before a sensor is used. For example, if the operating volt-
age is specified as +3.3 V then this value must not be exceeded.
● 17
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 17 11/10/2022 13:54
PID-based Practical Digital Control
In the remainder of this Chapter, the operation and characteristics of some popular sensors
are discussed.
Thermocouples
Thermocouples (Figure 2.1) are best suited to very low and very high temperature meas-
urements. They have the advantages that they are low-cost, very robust, and they can be
used in chemical environments. The typical accuracy of a thermocouple is ±1 ºC. Thermo-
couple temperature sensors can be made with various conductor materials for different
temperature ranges and output characteristics. Thermocouple types are identified with sin-
gle letters of the alphabet. Figure 2.1 shows the temperature ranges of various thermocou-
ples. Notice that lead color codes are used to identify thermocouples. The materials used
to form thermocouples is shown in Figure 2.2. For example, one of the commonly used
low-cost thermocouples is Type K which is made from chromel/alumel junction, identified
with green lead color, and has temperature range of –180 ºC to +1300 ºC .
● 18
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 18 11/10/2022 13:54
Chapter 2 • Sensors
● 19
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 19 11/10/2022 13:54
PID-based Practical Digital Control
Thermocouples are available in various shapes and forms. Some sensors are equipped with
2-way plugs for ease of connecting to a measuring device. Figure 2.4 shows some of the
commonly available thermocouples.
RTDs
RTDs (Resistance Temperature Detector) are sensors whose resistance changes with tem-
perature. The resistance increases as the temperature of the sensor increases. The resist-
ance vs temperature relationship is well known and repeatable over time. RTDs are passive
devices and they do not produce any output. Usually, the resistance of an RTD is measured
by passing a small electrical current through it and then measuring the voltage across the
sensor. Care should be taken not to pass large currents as self-heating of the sensor may
occur. Typically, 1 mA or less current is passed through the sensor. Figure 2.5 shows some
RTD sensors. RTDs have excellent accuracies over a wide temperature range and some
RTDs have accuracies better than 0.001 ºC . another advantage of the RTDs is that they
drift less than 0.1 ºC /year.
● 20
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 20 11/10/2022 13:54
Chapter 2 • Sensors
In order to achieve high stability and accuracy, RTD sensors must be contamination free.
Below about 250 ºC the contamination is not much of a problem, but above this tem-
perature, special manufacturing techniques are used to minimize the contamination. RTD
sensors are usually manufactured in two forms: wire wound, or thin film. Wire-wound
RTDs are made by winding a very fine strand of platinum wire into a coil shape around a
non-conducting material until the required resistance is obtained. Thin-film RTDs are made
by depositing a layer of platinum in a resistance pattern on a ceramic substrate. The most
commonly used RTD standard is the IEC 751 which is based on platinum with a resistance
of 100 Ω at 0 ºC.
For high accuracy it is recommended to use an RTD-to-digital converter module like the
MAX31865 module (Figure 2.6). This chip is optimized for platinum RTDs. An accurate ref-
erence resistor is used to set the sensitivity for the RTD. An on-chip ADC returns the ratio
of the RTD resistance to the reference resistance in digital form. Knowing the reference re-
sistance, you can easily calculate the RTD resistance and hence the measured temperature
either from temperature-resistance tables or using a library function.
Thermistors
The name thermistor derives from the words thermal and resistor. Thermistors are
temperature sensitive passive semiconductors which exhibit a large change in electrical
resistance when subjected to a small change in body temperature. Thermistors are man-
ufactured in a variety of sizes and shapes (Figure 2.7). beads, discs, washers, wafers, and
chips are the most widely used thermistor sensor types.
● 21
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 21 11/10/2022 13:54
PID-based Practical Digital Control
Thermistors are generally available in two types: Negative Temperature Coefficient (NTC)
and Positive Temperature Coefficient (PTC). PTC thermistors are generally used in power
circuits for inrush current protection. NTC thermistors exhibit many desirable features for
temperature measurement. Their electrical resistance decreases with increasing tempera-
ture (Figure 2.8) and the resistance-temperature relationship is very nonlinear. The resist-
ance of a thermistor is referenced to 25 ºC and for most applications the resistance at this
temperature is between 100 Ω and 100 kΩ.
Small size: Thermistors have very small sizes and this makes for a very rapid response
to temperature changes. This feature is very important in temperature feedback control
systems where a fast response may be required.
Ruggedness: Most thermistors are rugged and can handle mechanical and thermal shock
and vibration better than other types of temperature sensors.
● 22
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 22 11/10/2022 13:54
Chapter 2 • Sensors
Low-cost: Thermistors cost less than most other types of temperature sensors.
Thermistors can suffer from self-heating problems as a result of current passing through
them. When a thermistor self-heats, the resistance reading drops relative to its true value
and this causes errors in the measured temperature. It is therefore important to minimize
the electrical current through a thermistor.
Thermistors can be used in circuits in series with a known accurate fixed resistor. By meas-
uring the voltage across the thermistor, you can calculate its resistance. Alternatively,
constant current, bridge, or operational amplifier circuits can be designed to measure the
resistance of a thermistor. After finding the resistance of a thermistor, you can calculate
the temperature using tables (if available), or a library function (if available), or use the
standard Steinhart-Hart equation given below:
or
Example
The temperature constant of a thermistor is B = 2910. Also, its resistance at room tem-
perature (25 ºC ) is 1 kΩ. This thermistor is used in an electrical circuit to measure the
temperature and it is found that the resistance of the thermistor is 800 Ω. Calculate the
measured temperature.
Solution
Here, you know that B = 2910, T0 = 298.15, R = 800 Ω, and R0 = 1000 Ω
● 23
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 23 11/10/2022 13:54
PID-based Practical Digital Control
Kelvin
Integrated circuits
Integrated circuit analog sensors are semiconductor devices. they differ from other sensors
in some fundamental ways:
Analog integrated circuit temperature sensor can be voltage output or current output. In
this section you will look at the characteristics of some commonly used sensors.
LM35DZ
This is a popular 3-pin temperature sensor (Figure 2.9) chip whose output voltage is linear,
given by 10 mV/ ºC . For example, at 10 ºC the output voltage is 100 mV, at 20 ºC it is
200 mV and so on. this sensor has the range 0 ºC to +100 ºC (the CZ version of this sen-
sor has a wider temperature range like –20 ºC to +120 ºC ). The accuracy of this sensor
is ±1.5 ºC and the operating voltage is 4 to 30 V.
The LM34 is similar to the LM35DZ but it measures in degrees Fahrenheit. The LM134,
AD590, and AD592 are current-output temperature sensors where the output current is di-
rectly proportional to the measured temperature. For example, the output of AD590 (Figure
2.10) is given as 1 µA/K.
● 24
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 24 11/10/2022 13:54
Chapter 2 • Sensors
TMP36
This is another popular analog integrated circuit temperature sensor chip. The size and
configuration of the sensor is same as in Figure 2.9. The output of TMP36 is linear with the
measured temperature given by: Vo – 500 /10, where Vo is the sensor output voltage in
millivolts.
DHT11 and DHT22 (Figure 2.11) are highly popular 3-terminal digital output sensors. Both
devices can measure temperature as well as relative humidity. Arduino and Raspberry Pi li-
braries are available for both sensors for reading the temperature and humidity data easily.
● 25
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 25 11/10/2022 13:54
PID-based Practical Digital Control
The simplest position sensor is a potentiometer. Potentiometers are available in linear and
rotary forms. In a typical application, a fixed voltage is applied across the potentiometer
and the voltage across the potentiometer arm is measured. This voltage is proportional to
the position of the arm, and hence by measuring the voltage you know the position of the
arm. Figure 2.12 shows a linear potentiometer. If the applied voltage is Vi , the voltage
across the arm is given by:
Va = k Vi y
where y is the position of the arm from the beginning of the potentiometer, and k is a
constant.
● 26
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 26 11/10/2022 13:54
Chapter 2 • Sensors
Figure 2.13 shows a rotary potentiometer which can be used to measure angular position.
If Vi is again the applied voltage, the voltage across the arm is given by:
Va = k Vi θ
Other types of position sensors are capacitive sensors, inductive sensors, linear variable
differential transformers (LVDTs), magnetic linear encoders, optical encoders, ultrasonic
sensors etc. Capacitive position sensors rely on the fact that the capacitance of a paral-
lel-plate capacitor changes as the distance between the plates is changed. These sensors
are used in micrometer and millimeter applications where their resolution can be in nano-
meters (e.g., the MicroSense Model 4810).
LVDT sensors (Figure 2.14) consist of one primary and two secondary windings on a hollow
cylinder. A magnetic core which measures the position moves inside the cylinder, and the
movement of this core varies the magnetic field linking the primary winding to the second-
ary windings. The movement of the core to one position increases the induced voltage in
one secondary coil and decreases the induced voltage in the other secondary coil. The net
voltage difference is proportional to the position of the core inside the cylinder. Thus, by
measuring the induced voltage you know the position of the core.
• low cost
• robust design
• no hysteresis effect
• fast response time;
• no friction resistance
• long life
● 27
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 27 11/10/2022 13:54
PID-based Practical Digital Control
To be fair, the main disadvantage of the LVDT is that the core must have direct contact with
the measured surface, which may not always be possible.
A magnetic linear encoder system uses a magnetic sensor head and a magnetic scale to
produce analog or digital output. As the magnetic sensor head passes along the magnetic
scale, the sensor detects the change in magnetic field and outputs a signal to indicate the
position of the head.
Optical encoders are sensors commonly used for measuring the position or speed of a
rotating body. There are several different types of optical encoders. In its simplest applica-
tion, the device consists of a shaft connected to a circular disc with holes on it (Figure 2.15).
A light beam shines from one side and a light detector is used at the other side. By counting
the holes passing in-front of the sensor you can tell the position or the speed of the rotating
shaft. Other types of optical encoders use the Hall-effect principle where one or more small
magnets are attached to the rotor and the magnetic field is detected as the rotor rotates.
Using two such magnets you can determine the direction of rotation of the rotor.
● 28
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 28 11/10/2022 13:54
Chapter 2 • Sensors
Vo = k ω
where k is the gain constant of the tachometer. Another popular velocity sensor is the op-
tical encoder as shown in Figure 2.15 and described earlier.
● 29
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 29 11/10/2022 13:54
PID-based Practical Digital Control
Strain gauges can be used to measure force accurately. There are many different types of
strain gauges. A strain gauge can be made from capacitors and inductors, but the most
widely used types are made from resistors. A wire strain gauge is made from a resistor, in
the form of a metal foil. The principle of operation is that the resistance of a wire increases
with increasing strain and decreases with decreasing strain. In order to measure strain
with a strain gauge, it must be connected to an electrical circuit, and a Wheatstone bridge
is commonly used to detect the small changes in the resistance of the strain gauge. Strain
gauges can be used to measure force, load, weight pressure, torque or displacement.
Force can also be measured using the principle of piezoelectricity. A piezoelectric sensor
produces voltage when a force is applied to its surface. The disadvantage of this method is
that the voltage decays after the application of the force and thus piezoelectric sensors are
only useful for measuring dynamic force.
Some of the popular force sensors used in microcontroller applications are the FlexiForce
sensors. For example, the A201 is a variable resistance flexible force sensor (Figure 2.18)
that can be used to measure force from 4.4N to up to 440N. This is a 191mm long, 14mm
wide flexible sensor. The sensor is usually used with an operational amplifier where the
output voltage is proportional to the measured force.
● 30
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 30 11/10/2022 13:54
Chapter 2 • Sensors
Relative pressure sensors measure the pressure relative to the ambient atmospheric pres-
sure. It is positive for pressures higher than atmospheric, or negative for lower pressures.
These sensors have two ports to allow the reference pressure and the pressure to be meas-
ured.
Absolute pressure sensors give the result relative to perfect vacuum (i.e., zero pressure).
These sensors have one port for the pressure to be measured. These sensors can be used
to measure the atmospheric pressure (e.g., for determining the altitude).
Differential pressure sensors measure the difference in pressure between two points, simi-
lar to relative sensors, but here the reference pressure may not have to be the atmospheric
pressure.
There are many pressure sensors available that can be used with microcontrollers. For
example, the Adafruit MPRLS 3965 module (Figure 2.19) uses the I2C bus and includes a
24-bit ADC, operating at 3-5V. This sensor can measure the absolute pressure from 0 to
25 PSI. this is a small module measuring only 3.7 mm long and 2.5 mm diameter. Arduino
and Raspberry Pi libraries are available for this module.
SparkFun MPL3115A2 is another popular pressure sensor module (Figure 2.20) for micro-
controllers. This sensor module also provides altitude data to within 30 cm. Interface to
the module is through the I2C bus. The device also contains a 12-bit temperature sensor.
Operating with 1.95 to +3.6 V, pressure output is in Pascals and altitude in meters. The
sensor can measure pressures from 20 to 110 kPa. The temperature sensor range is –40 ºC
to +85 ºC with an accuracy of ±3 ºC across the whole temperature range.
● 31
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 31 11/10/2022 13:54
PID-based Practical Digital Control
The BMP280 is another popular pressure sensor frequently used in microcontroller applica-
tions. This is an absolute barometric pressure sensor. This sensor, based on piezo-resistive
technology has been developed by Bosch and features high accuracy and linearity as well
as long term stability. The sensor is available as a module as shown in Figure 2.21. pressure
range of this sensor is 300 to 1100 hPa with an accuracy of ±1 hPa. The module operates
with the I2C interface and provides temperature measurement as well in the range –40 ºC
to +85 ºC with an accuracy of ±1 ºC .
The presence of a liquid can be detected by using optical, ultrasonic, change of resistance,
change of capacitance or similar techniques. For example, optical technique is based on us-
ing an LED and a photo-transistor, both housed within a plastic dome and at the head of the
● 32
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 32 11/10/2022 13:54
Chapter 2 • Sensors
device. When no liquid is present, light from the LED is internally reflected from the dome to
the photo-transistor and the output is designed to be off. When liquid is present the dome is
covered with liquid and the refractive index at the dome–liquid boundary changes, allowing
some light to escape from the LED. As a result of this, the amount of light received by the
photo-transistor is reduced and the output is designed to switch on, indicating the presence
of liquid.
The level of liquid in a tank can be measured using immersed sensor techniques, or
non-touching ultrasonic techniques. The simplest technique is to immerse a rod in the liquid
with a potentiometer placed inside the rod. The potentiometer arm is designed to move as
the level of the liquid is changed. The change in the resistance can be measured and hence
the level of the liquid is obtained.
Ultrasonic transmitter-receiver pair modules are often used to measure the level of liquid
in a container. An ultrasonic signal is transmitter by the transmitter module. This signal
reflects back from the surface of the liquid and is detected by the receiver module. The time
difference between sending and receiving the signal is used to determine the distance to
the surface of the liquid. Knowing the height of the container you can easily calculate the
height of the liquid in the container.
Pressure sensors are also used to measure the level of liquid in a tank. Typically, the pres-
sure sensor is mounted at the bottom of the tank where change of pressure is proportional
to the height of the liquid. These sensors usually give an analog output voltage proportional
to the height of the liquid inside the tank.
Non-touching ultrasonic level measurement is very accurate, but more expensive than the
other techniques. Basically, an ultrasonic beam is sent to the surface of the water and the
echo of the beam is detected. The time difference between sending the beam and the echo
is proportional to the level of the liquid in the tank.
• paddlewheel sensors;
• displacement flow meters;
• magnetic flow meters.
Paddlewheel sensors are cost-effective and very popular for the measurement of liquid flow
rate. A wheel is mounted inside the sensor whose speed of rotation is proportional to the
flow rate. As the wheel rotates a voltage is produced which indicates the flow rate.
Displacement flow meters measure the flow rate of a liquid by separating the flow into
known volumes and counting them over time. These meters provide good accuracy. Dis-
placement flow meters have several types such as sliding vane meters, rotary piston me-
ters, helix flow meters and so on.
● 33
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 33 11/10/2022 13:54
PID-based Practical Digital Control
Magnetic flow meters are based on Faraday's law of magnetic induction. Here, the liquid
acts as a conductor as it flows through a pipe. This induces a voltage which is proportional
to the flow rate. The faster the flow rate, the higher is the voltage. This voltage is picked
up by the sensors mounted in the meter tube and electronic means are used to calculate
the flow rate based on the cross-sectional area of the tube. The advantages of magnetic
flow rates are as follows:
The e-Tape Liquid Level Sensor (Figure2.22) is a low-cost solid-state sensor with a resistive
output that varies with the level of the fluid and it is used in liquid level control applications
as liquid level sensor. The sensor's resistive output is inversely proportional to the height of
the liquid: the lower the liquid level, the higher the output resistance; the higher the liquid
level, the lower the output resistance. The length and width of the sensor are 257 mm and
25.4 mm respectively. Sensor output is 1500 Ω when empty, and 300 Ω when full. The
resolution of the sensor is 0.25 mm.
The LV170 device from Omega is a liquid sensor switch (Figure 2.23) based on optical
technology. This electro-optical sensor contains an infrared LED and a light receiver. Con-
tinuous light from the LED is directed into a prism which forms the tip of the sensor. With
no liquid present, light from the LED is reflected within the prism to the receiver. When a
rising liquid immerses the prism, the light is refracted out into the liquid, leaving little or no
light to reach the receiver. Sensing this change, the receiver actuates electronic switching
within the unit to operate an external alarm or control circuit.
The low-cost float switch (Figure 2.24) can be mounted at the edge of a tank and used
to detect the level of liquid in a tank. The switch provides normally-open/normally-closed
● 34
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 34 11/10/2022 13:54
Chapter 2 • Sensors
contacts so that external equipment can be switched on or off depending on the level of
the liquid.
The mini liquid level sensor (Figure 2.25) from Parallax can be used to detect water level
in a small tank by inserting it vertically into the tank. Liquid levels from 0 to 48mm can be
detected by the sensor. The sensor has 2 to 5 V analog output and therefore ADC is needed
to connect it to a microcontroller. With an operating voltage of 2 to 5 V, the sensor can be
used in non-toxic, non-corrosive liquids such as water.
The low-cost YF-S201 can be used to measure the liquid flow rate (Figure 2.26). This sen-
sor operates with 5 to 18 V and provides TTL output with 450 pulses per liter. The range
of the sensor is 1 to 30 liters/minute, with an accuracy of ±10%. This sensor can directly
be connected to the Arduino. Connection to Raspberry Pi required the output voltage to be
dropped to 3.3 V, e.g., using a resistive potential divider circuit.
● 35
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 35 11/10/2022 13:54
PID-based Practical Digital Control
The FT-210 series is also a popular liquid flow rate sensor, although more expensive than
the YF-S201. This sensor operates with 5 to 24V and provides open-collector output with
22,000 pulses/liter, at an accuracy of ±3% of reading.
The Renesas type FS2012 sensor can be used to measure the flow rate of both liquid and
gas (Figure 2.28). Operating at 5 V, the sensor output is 0 to 5 V analog or I2C digital. It is
resistant to vibration and pressure shock. Gas flow range of the sensor is 0.015 to 2 SLPM
(Standard Liters Per Minute), with a flow accuracy of ±2% of the reading. Liquid flow range
is 0.025 to 0.5 SLPM, with an accuracy of ±2% of the reading.
● 36
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 36 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
3.1 Overview
In the previous Chapter, you had a look at some of the sensors that can be used in micro-
controller based digital control applications. In this Chapter, you will learn the theory and
time response of the first-order and second-order systems. They are important as most
control structures can be reduced to simple first or second-order systems. The aim of this
book is to minimize the theory and mathematical derivation as much as possible,
and yet learn the fundamental properties and the design of microcontroller based control.
In this Chapter, only continuous-time systems are considered since it is necessary to learn
the fundamental aspects of continuous-time systems before moving to digital systems.
Digital systems will be covered in a later Chapter.
(3.1)
Taking the Laplace transform with the initial conditions, you have
(3.2)
With zero initial conditions, the transfer function relating the current to the applied voltage
is given by:
(3.3)
● 37
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 37 11/10/2022 13:54
PID-based Practical Digital Control
or
(3.4)
Figure 3.2 shows the open-loop block diagram of the system with V(s) as input and I(s) as
output.
Example 2
Let's now consider a liquid level system (Figure 3.3) where liquid enters a tank at the rate
of qi and leaves at the rate of qo through an orifice. Derive the mathematical model for the
system, showing the relationship between the height h of the liquid and the input flow rate
qi.
(3.5)
or
(3.6)
● 38
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 38 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
(3.7)
(3.8)
(3.9)
So that
(3.10)
(3.11)
(3.12)
(3.13)
or conclusively:
(3.14)
● 39
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 39 11/10/2022 13:54
PID-based Practical Digital Control
(3.15)
If you now apply a unit step input R(t) to the system, where R(s) = 1/s, the Laplace trans-
form of the overall open-loop system C(s) becomes:
(3.16)
The time response of the open-loop system is given by taking the inverse Laplace transform
of (3.16), which gives:
(3.17)
The response is clearly an exponential rise. Initially at t = 0, system output c(t) = 0. The
output then rises to 1 in an exponential manner.
Parameter 1/a is known as the time constant of the system. At t = 1/a, the response
becomes:
(3.18)
You can therefore say that when a step input is applied to a first-order system, the system
output rises to 63% of its final value at the time equal to the time constant of the system.
Notice that the time constant 1/a has the unit of time.
● 40
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 40 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
Question
The transfer function of a first-order system is given by:
Calculate the time response if a unit step input is applied to the system.
Solution
With a unit step input the open-loop transfer function is:
or
From inverse Laplace transform tables, you find that the time response is given by:
At t = 0 the output is 0, and the final value of the output is (for very large t) equal to K/a.
Question
The unit step time response of a first-order system is found to be as shown in Figure 3.5.
Calculate the transfer function of this system.
● 41
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 41 11/10/2022 13:54
PID-based Practical Digital Control
Solution
The final value of the system is clearly 2.5. Time constant is when the curve reaches 63% of
its final value. Therefore, the time constant occurs at the y axis point 2.5 × 0.63 = 1.575.
Drawing a horizontal line from this point, you find on the horizontal axis that the time
constant is 1/a = 0.25. Therefore, a = 1/0.25 = 4. You now have to find K. The final value
is K/a = 2.5, therefore K = 4 × 2.5 = 10. The required transfer function of the system is:
Question
The unit step time response of a first-order system is found to be as shown in Figure 3.6,
where the initial value of the output is 4. Calculate the transfer function of this system.
● 42
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 42 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
Solution
The final value of the system is 9, where its initial value is 4. The time constant occurs when
the curve reaches 63% of its final value, i.e., at the y axis point 4 + (9 – 4) × 0.63 = 7.15.
Drawing a horizontal line from this point, you find that the time constant on the horizontal
axis is 1/a = 0.5. Therefore, a = 1/0.5 = 2. You now have to find K. The final value is K/a =
(9 – 4), therefore K = 5 × 2 = 10. The required transfer function of the system is:
The net force on the mass is the applied force minus the forces exerted by the spring and
the dashpot. Applying Newton's second law, you can write:
(3.19)
or,
(3.20)
(3.21)
● 43
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 43 11/10/2022 13:54
PID-based Practical Digital Control
Which is usually written in the standard form as a second-order open-loop system transfer
function:
(3.22)
Example 2
Consider the electrical system given in Figure 3.8, consisting of a resistor (R), inductor (L),
and a capacitor (C). Let's derive the model of this system.
(3.23)
or,
(3.24)
(3.25)
(3.26)
● 44
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 44 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
(3.27)
Equation (3.27) is similar to (3.22) as both systems are second-order. In fact, the general
form of a second-order open-loop transfer function is of the following format:
(3.28)
Case 1: Undamped
Case 3: Overdamped
Case 4: Underdamped
● 45
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 45 11/10/2022 13:54
PID-based Practical Digital Control
and
Figure 3.9 shows the time response for all four cases.
In controlling a plant, you are mainly interested in the underdamped case where the damp-
ing ratio is less than one. As shown in Figure 3.10, as the damping ratio gets smaller you
get higher overshoots in the response. You should aim for a damping ratio of about 0.7
whish gives a very slight overshoot and a fast rise time.
Some important parameters that define a second-order underdamped response are given
below (see Figure 3.11)
● 46
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 46 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
Peak time (Tp) : This is the time required for the system response to reach its first over-
shoot and is given by:
Rise time (Tr): This is the time required for the system to reach the final value first time.
It is given by:
where
Maximum overshoot (Mp): This is the difference between the maximum overshoot and
the final value, given by:
Settling time (ts): This is the time required for a response to become steady. It is usually
defined as the time required by the response to reach within specified range of 2% to 5%
of its final value, given by:
to 2%
to 5%
● 47
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 47 11/10/2022 13:54
PID-based Practical Digital Control
Example
Given the following open-loop transfer function of a system with unit step input applied,
calculate the Tp, Tr, Mp, and ts to 2%.
Solution
Therefore:
or
seconds
seconds
or 16.3%
seconds
Example
Sometimes you have a DC gain and the transfer function (3.28) becomes:
● 48
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 48 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
An example is given below. Draw the unit step time response for the following two transfer
functions:
and
Solution
Figure 3.12 shows the two step functions next to each other. Notice that in the second re-
sponse the gain is 4 and therefore the final state of the time response settled at 4.
Example
The unit step time response of a second-order system is shown in Figure 3.13. Derive the
transfer function of this system.
Solution
In reference to Figure 3.14, you can read the following:
● 49
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 49 11/10/2022 13:54
PID-based Practical Digital Control
seconds
Also,
And , or
or
● 50
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 50 11/10/2022 13:54
Chapter 3 • Transfer Functions and Time Response
Where T is the delay in seconds. As an example, the transfer function of a first-order sys-
tem with time delay is given below.
Figure 3.16 shows the block diagram of a feedback control system with the forward trans-
fer function G(s) and the feedback transfer function H(s), and input and outputs I(s) and
O(s), respectively. It can be shows that the transfer function of this closed-loop system is
given by:
● 51
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 51 11/10/2022 13:54
PID-based Practical Digital Control
When the blocks are in series to each other you can multiply them to find the overall
transfer function (interested readers can find lots of information on the Internet on block
diagram manipulation).
Example
Find the overall transfer function of the system shown in Figure 3.17.
Solution
The overall transfer function is given by:
● 52
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 52 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
4.1 Overview
A digital system operates on discrete-time rather than continuous-time signals. A digital
computer (e.g. a microcontroller) is used as the controller in such a system. A DAC con-
verter is usually connected to the output of the computer to drive the plant. Let's assume
that all the signals enter and leave the computer at the same fixed times, known as the
sampling times.
A typical sampled data control system is shown in Figure 4.1. The digital computer per-
forms the controller or the compensation function within the system. The ADC converts the
error signal, which is a continuous signal, into digital form so that it can be processed by the
computer. At the computer output the DAC converts the digital output of the computer into
a form which can be used to drive the plant. It is also common to use some form of power
amplifier circuit before the plant in electrical systems such as electromechanical motors.
In practice the closure time q is much smaller than the sampling time T, and the pulses can
be approximated by flat-topped rectangles as shown in Figure 4.4.
In control applications the switch closure time q is much smaller than the sampling time T
and can be neglected. This leads to the ideal sampler with output as shown in Figure 4.5.
● 53
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 53 11/10/2022 13:54
PID-based Practical Digital Control
● 54
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 54 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
A DAC converts the sampled signal r ∗(t) into a continuous signal y(t). The DAC can be ap-
proximated by a zero-order hold (ZOH) circuit as shown in Figure 4.6. This circuit remem-
bers the last information until a new sample is obtained, i.e. the zero-order hold takes the
value r(nT) and holds it constant for nT ≤ t < (n + 1)T, and the value r(nT) is used during
the sampling period.
A sampler and zero-order hold can accurately follow the input signal if the sampling time T
is small compared to the transient changes in the signal. The response of a sampler and a
zero-order hold to a ramp input is shown in Figure 4.7 for two different values of sampling
period.
● 55
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 55 11/10/2022 13:54
PID-based Practical Digital Control
Figure 4.7: Response of a sampler and a zero-order hold for a ramp input.
Example
Figure 4.8 shows an ideal sampler followed by a zero-order hold. Assuming the input signal
r(t) is as shown in the figure, show the waveforms after the sampler and also after the
zero-order hold.
Solution
The signals after the ideal sampler and the zero-order hold are shown in Figure 4.9.
● 56
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 56 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
The z-transform of the function r (t) is Z [r (t)] = R(z) and is given by:
(4.1)
Notice that the z-transform consists of an infinite series in the complex variable z, and
(4.2)
i.e. are the coefficients of this power series at different sampling instants. The re-
sponse of a sampled data system can be determined easily by finding the z-transform of
the output and then calculating the inverse z-transform.
From (4.1),
or, for
● 57
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 57 11/10/2022 13:54
PID-based Practical Digital Control
From (4.1),
Or, for
Given G (s), calculate the time response g(t) by finding the inverse Laplace transform of
G(s). Then find the z-transform either from the first principles, or by looking at the z-trans-
form tables.
Given G(s), find the z-transform (z) by looking at the tables which give the Laplace trans-
forms and their equivalent z-transforms.
● 58
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 58 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
Example
Let
or,
Solution 2 - By using the z-transform transform tables for the partial product
or,
● 59
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 59 11/10/2022 13:54
PID-based Practical Digital Control
There are several methods to find the inverse z-transform of a given function as described
below:
In this section you will look at an example using the power series method. This method
involves dividing the denominator of Y (z) into the numerator.
Example
Find the inverse z-transform (time function) for the following transfer function:
Solution
Dividing the denominator into the numerator is shown in Figure 4.12.
● 60
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 60 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
Figure 4.13 shows the first few samples of the time sequence y(t).
Suppose you wish to sample a system with output response given by:
or,
● 61
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 61 11/10/2022 13:54
PID-based Practical Digital Control
Example
Figure 4.15 shows an open-loop digital system. Derive an expression for the z-transform of
the output of the system, where
and
Solution
The following expressions can be written for the system:
or,
and,
where,
● 62
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 62 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
Example
A unit step signal is applied to the electrical RC system shown in Figure 4.16. Calculate and
draw the output response of the system, assuming a sampling period of T = 1 s.
Solution
For this system you can write:
and
giving
● 63
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 63 11/10/2022 13:54
PID-based Practical Digital Control
The output time response is obtained by finding the inverse z-transform of y(z). You can
either use an inverse z-transform table, divide the numerator by the denominator, or find
the partial fractions as follows:
And finally,
From the inverse z-transform tables you find the time function as:
And the output time response is (see Figure 4.17) given by:
● 64
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 64 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
It is important to notice that the response is only known at the sampling instants. For
example, in Figure 4.17 the capacitor discharges through the resistor between the sam-
pling instants, and this causes an exponential decay in the response between the sampling
intervals. But this behaviour between the sampling instants cannot be determined by the
z-transform method of analysis.
Example
Assume that the system in Example 4.16 is used with a zero-order hold (see Figure 4.18).
What will the system output response be if a unit step input is applied.
Solution
The transfer function of the zero-order hold is
And
● 65
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 65 11/10/2022 13:54
PID-based Practical Digital Control
Now, T = 1 s and
● 66
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 66 11/10/2022 13:54
Chapter 4 • Discrete Time (Digital) Systems
Example
A unit step signal is applied to the sampled data digital system shown in Figure 4.20. Cal-
culate and plot the output response of the system. Assume that T = 1 s.
Solution
The transfer function of the system is found as
Or e*(s)=r*(s)-G*(s)e*(s)
Solving for e*(s) , you obtain
● 67
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 67 11/10/2022 13:54
PID-based Practical Digital Control
And therefore
The first 10 samples of the output response are shown in Figure 4.21
● 68
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 68 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
5.1 Overview
A PID controller (sometimes called three-term controller) is an algorithm that is widely
used in industrial process control systems, and in many other control systems where zero
error is required in the final system output. It is important to realize that PID is not the
only controller type used in control systems. There are many other types such as lead, lag,
lead-lag, pole assignment, dead-beat, Dahlin, etc.
In a PID control algorithm, the controller receives the error value which is the difference be-
tween the desired and the actual measured value, and then applies correction to the plant
in order to force the error value to zero and obtain a successful, stable response.
In PID control, P is the proportional control action, I is the integral control action, and D is
the derivative control action. As you will learn in this Chapter, P is proportional to the error
and if the error is large then the value applied to the plant will also be large. Using pro-
portional control on its own results in error between the desired and the actual measured
values.
Integral action provides an integral of the error value over time to the plant. As a result,
any error value will be eliminated and the integral term will cease to grow. The objective of
using the integral control action is to force the error value to zero.
Derivative action provides the derivative of the error value to the plant. This action tends
to reduce the error value as well as the inevitable overshoot. The derivative action is not
used in all systems.
Where, u(t) is the controller output, and e(t) is the error value which is input to the control-
ler. Also, Kp, Ki, and Kd are known as the proportional, integral, and derivative constants of
the PID controller. The Laplace transform of the PID controller is:
(5.1)
or (5.2)
● 69
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 69 11/10/2022 13:54
PID-based Practical Digital Control
(5.3)
One of the problems in PID controller design is tuning the values of the P, I, and D coeffi-
cients or parameters (Kp, Ki, and Kd) so that the required output response is obtained from
the system. There are many methods for doing this and you will explore some popular ones
in this Chapter.
In the remaining sections of this Chapter, you will discover details of the PID controller by
using it with a first-order continuous-time system.
giving
Which has the time constant 1/11 = 0.09. The closed-loop system without the proportional
only controller had the time constant 1/2 = 0.5. You can see that with the proportional
only controller the time constant has decreased. i.e., the system response became faster.
Figure 5.2 shows the unit time response of the closed-loop system with and without the
proportional only controller. It is also interesting to notice that there is steady state error
in system response with proportional only controller. i.e., the final state of the system is at
● 70
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 70 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
0.9 and not 1.0. You can reduce the error with larger proportional constant Kp but this will
require very large value (theoretically infinite value).
giving
Figure 5.4 shows the unit step, closed-loop system response with and without the inte-
gral-only controller. It is interesting to note that the closed-loop system response with the
integral-only controller is fast but exhibits overshoots. Also, there is no steady state error,
i.e., the final state of the system is at 1.0. The overshoot can be reduced by reducing the
integral amount. Figure 5.5 shows the response when the integral controller is 0.5/s. Notice
that the overshoot is reduced considerably and also the steady state error is zero. You can
● 71
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 71 11/10/2022 13:54
PID-based Practical Digital Control
conclude here that integral action is very important in systems where you want the steady
state error to be zero.
Figure 5.5 System response with the integral-only controller set to 0.5/s.
● 72
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 72 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
giving
Figure 5.7 shows the closed-loop system response. Notice that the derivative action does
not track the error. Instead, it tracks the rate of change of the error and is not useful on
its own.
● 73
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 73 11/10/2022 13:54
PID-based Practical Digital Control
giving
Figure 5.9 shows the closed-loop unit step response with and without the controller. Notice
that this is an acceptable response since there is little overshoot and the steady state error
is zero.
Figure 5.9: First-order, closed-loop system response with and without P+I controller.
● 74
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 74 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
giving
Figure 5.11 shows the system response with the PID in action. Compare this response with
Figure 5.9. Notice that by adding a derivative action, the system now has slightly higher
overshoot and higher rise time meaning you have not gained a better response. The impor-
tance of setting the PID parameters is very important as you have seen in these example
plots. This is called tuning the controller and you will look at different methods of tuning a
system.
Figure 5.11: First-order closed-loop unit step response with PID controller.
● 75
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 75 11/10/2022 13:54
PID-based Practical Digital Control
The closed-loop unit step time response with the above parameters is pictured in Figure
5.12a. It shows the response after doubling Kp. PID parameters were put back to what they
were and Figure 5.12c shows the response after Ki is doubled. Finally, the parameters were
put back to what they were again and Figure 5.12d is the response after Kd is doubled. No-
tice that the steady state error is zero in all cases. Increasing the integral parameter makes
the system faster but at the same time oscillatory before it settles down.
● 76
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 76 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
You will use the following form of the PID controller in tuning the controller:
Ziegler and Nichols then suggest using the PID controller settings given in Table 5.1 when
the loop is closed. These parameters are based on the concept of minimizing the integral of
the absolute error after applying a step change to the set-point. An example is given here
to illustrate the method used.
• simple to implement
• very little knowledge required about the system dynamics
● 77
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 77 11/10/2022 13:54
PID-based Practical Digital Control
Where L is the delay time, T is the system time constant, and Kprocess is the gain of the
process. This method can only be used offline.
Example
Figure 5.14 shows the open-loop unit step time response of a system with time delay. Your
task is to derive the Ziegler and Nichols tuning parameters for this system and draw the
time response of the closed system with the PI controller.
Soluti on
With reference to Figure 5.14, the open-loop system parameters are given as follows:
K = 10, TD = 2, T1 = 4
● 78
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 78 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
● 79
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 79 11/10/2022 13:54
PID-based Practical Digital Control
The unit step time response of the closed-loop system is shown in Figure 5.16. Notice that
the system has high overshoot which is the characteristic of the design using Ziegler &
Nichol method. If you reduce Kp to 0.15 the transfer function of the controller becomes:
There are several other PID tuning algorithms used in practice, such as modified Ziegler
and Nichols, Lambda, Chien-Hrones-Reswick, the Tyreus-Luyben method, Ciancone-Mar-
line method, Internal Model Control (IMC), and others. You will now proceed to designing a
Lambda type controller for your example system.
● 80
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 80 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
Example
Let's design a Lambda PI controller for the plant whose transfer function is found to be:
Solution
Like the Ziegler and Nichols tuning, lambda tuning involves a set of formulas or tuning
rules that dictate the values of the PI parameters required to achieve the desired controller
performance. The tuning rules for the Lambda PI controller are as follows:
Where is the process time constant. In order to obtain a closed-loop system with a
non-oscillatory setpoint response that will settle out in approximately 4λ seconds. These
tuning rules require the user to specify only one performance parameter: λ. This simplifies
the calculations considerably.
The closed-loop system response with this controller is shown in Figure 5.18.
● 81
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 81 11/10/2022 13:54
PID-based Practical Digital Control
• Disable any derivative and integral action in the controller and leave only the
proportional action.
• Carry out a set-point step test and observe the system response.
• Repeat the set-point test with increased (or decreased) controller gain until a
stable oscillation is achieved (see Figure 5.19). This gain is called the ultimate
gain, Ku.
• Read the period of the steady oscillation and define it as Pu.
• Calculate the controller parameters according to the following formulae: Kp =
0.45Ku, Ti = Pu/1.2 in the case of the PI controller; and Kp = 0.6Ku, Ti = Pu/2, Td
= Tu/8 in the case of the PID controller.
● 82
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 82 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
Example
Let's go ahead and design a PI controller for a system whose open-loop transfer function
is given by:
Solution
Increasing the gain of the system, you find that the system output starts to oscillate when
the gain is 3.803. The period of the oscillations was found to be 7.5 seconds (Figure 5.20).
Therefore, , and
and
● 83
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 83 11/10/2022 13:54
PID-based Practical Digital Control
Figure 5.21 shows the closed-loop time response of the system. There is about 18% over-
shoot in the response which is expected from the Ziegler and Nichol type tuning.
Note that most systems can easily be controlled using just the PI controller without the
derivative action. The derivative action is exceedingly sensitive to noise and it must not
be used unless the system time constant is very slow. Filters are commonly used with the
derivative action to cancel out the noise.
• Use only Proportional Control (set the integral and derivative to zero) and
apply step input to the system. Vary the proportional parameter until a good
response is obtained. Then decrease the proportional parameter slightly.
• Keep the proportional parameter found and now vary the integral parameter
until a good response is obtained and the steady state error is zero.
• Keep the proportional and integral parameters found and vary the derivative
parameter until a good response is obtained. It is interesting to note that most
systems do not require the derivative action.
● 84
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 84 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
● 85
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 85 11/10/2022 13:54
PID-based Practical Digital Control
As a result of this physical limitation, the error signal does not return to zero and the inte-
gral term keeps adding up continuously. This effect is called integral wind-up (or integral
saturation). As a result of it, long periods of overshoot can occur in the plant response.
A simple example of what happens is the following. Suppose you wish to control the po-
sition of a motor and a large setpoint change occurs, resulting in a large error signal. The
controller will then try to reduce the error between the set-point and the output. The inte-
gral term will grow by summing the error signals at each sample and a large control action
will be applied to the motor. But because of the physical limitation of the motor electronics,
the motor will not be able to respond linearly to the applied control signal. If the set-point
now changes in the other direction, then the integral term is still large and will not respond
immediately to the set-point request. Consequently, the system will have a poor response
when it comes out of this condition.
The integral wind-up problem affects positional PID controllers. With velocity PID control-
lers, the error signals are not summed up and as a result integral wind-up will not occur,
even though the control signal is physically constrained.
Many techniques have been developed to eliminate integral wind-up from the PID control-
lers, and some of the popular ones are as follows:
• Stop the integral summation when saturation occurs. This is also called
conditional integration. The idea is to set the integrator input to zero if the
controller output is saturated and the input and output are of the same sign.
• Fix the limits of the integral term between a minimum and a maximum.
● 86
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 86 11/10/2022 13:54
Chapter 5 • The PID Controller in Continuous-Time Systems
The PID Loop Simulator software application for PC is available free of charge from the
following website:
https://view.officeapps.live.com/op/view.aspx?src=http%3A%2F%2Fwww.engineers-
excel.com%2FApps%2FPID_Simulator%2FPID_scrollbar.xls&wdOrigin=BROWSELINK
Figure 5.23 shows the PID Loop Simulator software application. In the middle part of
the screen, the general simulation block diagram is shown with the PID controller and a
first-order plant with time delay. The transfer function of the plant (gain, time constant, and
delay time) are entered at the top left under heading Process. The controller parameters
(proportional, integral and derivative) are entered under the heading Controller. The unit
step output time response of the plant as well as the output time response of the controller
are shown at the bottom of the screen. System output is shown in blue while the controller
output is shown in green.
● 87
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 87 11/10/2022 13:54
PID-based Practical Digital Control
Entering the plant and controller values into the simulator produces the theoretical system
time response shown in Figure 5.23. The system has a small overshoot and the steady
state error is zero for all practical purposes. You can easily change the controller parame-
ters and view the output time response immediately.
● 88
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 88 11/10/2022 13:54
Chapter 6 • The Digital PID Controller
6.1 Overview
This Chapter discusses the digital form of the continuous-time PID controller as well as
ways of using it in a computer system like a microcontroller.
(6.1)
The digital form of the PID controller can be found by taking the z-transform of the above
transfer function:
(6.2)
This transfer function can be implemented as a parallel structure by summing the pro-
portional, integral, and derivative terms.
(6.4)
It can be shown that equation (6.4) can be implemented as shown in Figure 6.1 with the
following sets of equations.
PID:
● 89
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 89 11/10/2022 13:54
PID-based Practical Digital Control
PI:
For the case of PI-only controller, you have the following equations:
● 90
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 90 11/10/2022 13:54
Chapter 6 • The Digital PID Controller
You may think that decreasing the sampling interval towards zero will make a discrete sys-
tem converge towards an equivalent continuous system. However, in practice this is not the
case. As the sampling interval is reduced, the change between the successive data values
becomes less than the resolution of the system, leading to loss of information. In general,
if a shorter sampling interval is to be used then the word length of the system should be
increased so that the difference between adjacent samples can be resolved.
It has been found from practical applications in the process industry that a sampling inter-
val of 1 second is generally short enough for most applications such as pressure control,
temperature control and flow control. Systems with fast responses such as electromechan-
ical systems (e.g., motors) require much shorter sampling intervals, usually of the order
of milliseconds.
Various empirical rules have been suggested by many researchers for the selection of the
sampling interval. These rules are based on practical experience and simulation results.
Among them are the following:
If the plant has the dominant time constant Tp, then the sampling interval T for the closed-
loop system should be selected such that T < Tp/10.
then the sampling interval should be selected such that T < T1/4.
If the closed-loop system is required to have a settling time Tss or a natural frequency of ωn
then choose the sampling interval T such that T < Tss/10 and ωs > 10ωn, where ωs is the
sampling frequency, i.e., ωs = 2π/T.
Microcontrollers have traditionally been programmed using the assembly language of the
target hardware. Assembly language has several important disadvantages and is currently
less popular than it used to be. One important disadvantage is that the code generated
using the assembly language can only run on the specific target hardware. For example,
the assembly program developed for a PIC microcontroller cannot be used, say, on an Intel
8051 microcontroller. Assembly language programs also tend to be more difficult to devel-
op, test and maintain. In the projects in this book, you will be using C programs for the
Arduino, and Python programs for the Raspberry Pi.
● 91
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 91 11/10/2022 13:54
PID-based Practical Digital Control
There are several methods that can be used to implement the controller algorithm on a
microcontroller. One of the most common methods with the advantage of accurate imple-
mentation involves a timer interrupt to generate the required loop delay (or the sampling
interval). In this method, the software consists of two parts: the main program and the
timer interrupt service routine (ISR).
As shown in Figure 6.3 in the form of a Program Description Language (PDL), in the main
program various variables such as the setpoint value, PID controller parameters, as well
as the A/D converter and the timer interrupt mechanism are initialized. The setpoint value
can either be hardcoded into the software or a keypad & pushbutton combination can be
used to set it. The timer is set to interrupt at an interval equivalent to the chosen sampling
interval of the system.
The main program then enters a loop waiting for the timer interrupts to occur. Whenever a
timer interrupt occurs, the program jumps the interrupt service routine where the PID con-
troller algorithm is implemented in software. The error signal is obtained by calculating the
difference between the setpoint value and measured output value. The algorithm is then
implemented and the output sample for the current sampling time is obtained.
A pre-processing step is then performed by updating the variables for the next sample. On
return from the ISR, the program waits in the main program until the next sampling inter-
val, while the above process repeats forever.
MAIN:BEGIN
Initialize PID parameters
Initialize other variables used
Set/Read setpoint value, sk
Initialize ADC
Initialize Timer interrupts, interrupt at T intervals
DO FOREVER
Wait for timer interrupts
ENDDO
MAIN:END
ISR:BEGIN
Get setpoint, sk
Read output, yk
Calculate error, ek
Calculate controller output, uk (section 6.2)
Limit uk to avoid interrupt windup
Update controller memory variables, pk-1 and ek-1
Return from interrupt
ISR:END
● 92
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 92 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
7.1 Overview
Temperature control is used to control the temperature of a gas (e.g., air) in a closed space,
or the temperature of liquid in a container, or for example to control the temperature of
an oven. Here, the aim is to design a controller which will force the measured temperature
to be the same as the desired SetTemp temperature. Thus, if for example the measured
temperature changes then the controller will take the necessary steps to force the output
temperature to be same as the SetTemp value. Also, if the SetTemp value is changed then
again the controller will make sure that the SetTemp and the measured values are the
same. The controller takes inputs from temperature sensors and provides output that is
usually connected to a heater or a fan.
One disadvantage of this method is that the temperature is not controlled closely, and also
the rapid cycling of the relay can shorten its life and can cause damage to it. One technique
used in On-Off control is to add hysteresis to the controller operation. With the hysteresis,
the measured temperature is allowed to exceed the SetTemp value by some amount before
the relay is turned off. Similarly, the measured temperature is allowed to drop below the
SetTemp value by some amount before the relay is turned back on. For example, if the
SetTemp value is 20 ºC, a 2 ºC hysteresis can be used such that the relay turns off when
the temperature reaches 22 ºC, and it turns on when the temperature falls below 18 ºC.
Although this technique will eliminate the rapid cycling of the relay, it has the disadvantage
that the output temperature will fluctuate between the two limits of the hysteresis points.
The response will show overshoot and undershoot from the setpoint value.
The On-Off type control is used in applications where precise control of the temperature is
not required, or in temperature alarm systems such that an alarm is generated if the tem-
perature goes above or below pre-specified values.
● 93
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 93 11/10/2022 13:54
PID-based Practical Digital Control
In the remaining sections of this Chapter, you'll examine ON-OFF temperature controllers
using the Arduino Uno and the Raspberry Pi computers.
Block diagram: Figure 7.1 shows the block diagram of the project. A relay is controlled
from the Arduino Uno which turns the heater power on/off. A red LED indicates when the
relay (i.e., the heater) is ON. The room temperature is sensed using an analog TMP36 type
semiconductor temperature sensor chip.
Circuit diagram: The circuit diagram of the project is shown in Figure 7.2. An I2C type LCD
is used in this project with the on-board PCF8574T type I2C controller chip. The interface
between the Arduino Uno and the external components are as follows (Ground and power
supply pins are not shown):
● 94
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 94 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
I2C LCD: The Arduino Uno has one I2C bus at the following pins:
As shown in Figure 7.3, the I2C address of the PCF8574T chip is selected by 3 jumpers
labeled A0, A1, and A2 on the controller board. By default, the address is set to 0x27 (i.e.,
no jumper connections), but your LCD address may be different.
Before using the I2C LCD, you have to add the I2C library to our IDE. Libraries are often
distributed as a ZIP file or folder where the name of the folder is the name of the library.
Inside the folder, there is a .cpp file, a .h file, a keywords.txt file, examples folder, and
other files that may be required by the library. You should not unzip the library.
• Browse to the following website to locate the library file (the file is also
available in the support software package for the book):
https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c
● 95
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 95 11/10/2022 13:54
PID-based Practical Digital Control
• Return to Sketch Include Library menu and you should see the new library
at the bottom of the drop-down menu.
• To test that the library has been added successfully, enter the following lines in
a newly created program:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
void setup()
{
void loop()
{
}
The I2C LCD library supports many functions. Some most commonly used functions are:
The address of the I2C LCD must be defined at the beginning of the program. For example,
if the address is 0x3F and the LCD is 16 columns by 2 rows (i.e., 16×2), then:
● 96
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 96 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
Following the above statement, you can call the LCD functions by indexing them with the
keyword lcd. For example, to initialize the LCD:
Program listing: Figure 7.4 shows the program listing (Program: AONOFF1). At the
beginning of the program, SetTemp is set to 20.0 degrees C, and the LED and RELAY
are assigned to port numbers 3 and 2, respectively. Inside the setup() function, both the
RELAY and LED are configured as outputs and are deactivated to start with.
The output voltage of the TMP36 temperature sensor chip is proportional to the tempera-
ture and is given by:
T = (Vo – 500) / 10
Where T is the measured temperature in Degrees C, and Vo is the sensor output voltage is
millivolts.
Inside the main program loop the room temperature is read by the ADC channel A0 and
subsequently compared to the desired temperature. If the room temperature is lower than
the desired temperature then both the LED and RELAY are activated so that the heater is
turned ON, otherwise they are deactivated to turn OFF the heater. The program checks the
temperature every 10 seconds. The SetTemp and RoomTemp are displayed on the LCD
as shown in Figure 7.5.
//----------------------------------------------------------------------
// ON-OFF TEMPERATURE CONTROL
// ==========================
//
// This is an ON-OFF temperature controller project. The ambient temperature
// is read and compared to the desired set value. If it is less than the set
// value then the relay and LED are activated, otherwise they are deactivated
//
// Author: Dogan Ibrahim
// File : AONOFF1
// Date : June, 2022
//----------------------------------------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
● 97
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 97 11/10/2022 13:54
PID-based Practical Digital Control
void setup()
{
pinMode(LED, OUTPUT); // LED is output
pinMode(RELAY, OUTPUT); // RELAY is output
digitalWrite(LED, LOW); // LED OFF at beginning
digitalWrite(RELAY, LOW); // RELAY OFF at beginning
lcd.init(); // Initialize LCD
lcd.backlight(); // Backlight ON
}
void loop()
{
raw = analogRead(TMP36); // Read temperature
float mV = 5000.0 * raw / 1023.0; // in mV
float RoomTemp = (mV-500.0) / 10.0; // Room temperature in C
}
else
{
digitalWrite(LED, LOW); // LED OFF
digitalWrite(RELAY, LOW); // RELAY OFF
}
delay(10000); // Wait 10 seconds
}
● 98
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 98 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
The block diagram and circuit diagram of the project are as in Figure 7.1 and 7.2, respec-
tively.
Program listing: Figure 7.6 shows the program listing (Program: AONOFF2). This pro-
gram is very similar to the one given in Figure 7.4 but here the temperature is kept be-
tween TLOW and THIGH. If the room temperature is equal to or lower than TLOW then the
relay is activated. If on the other hand the room temperate higher or equal to THIGH then
the relay is deactivated. Figure 7.7 shows the LCD output.
//--------------------------------------------------------------------------
// ON-OFF TEMPERATURE CONTROL WITH HYSTERESIS
// ==========================================
//
// This is an ON-OFF temperature controller project. The ambient temperature
// is read and compared to TLOW. If it is lower than or equal to TLOW then the
// relay is activated. If on the other hand it is higher than or equal to THIGH
// then the relay is deactivated.
//
// Author: Dogan Ibrahim
// File : AONOFF2
// Date : June, 2022
//---------------------------------------------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
● 99
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 99 11/10/2022 13:54
PID-based Practical Digital Control
void setup()
{
pinMode(LED, OUTPUT); // LED is output
pinMode(RELAY, OUTPUT); // RELAY is output
digitalWrite(LED, LOW); // LED OFF at beginning
digitalWrite(RELAY, LOW); // RELAY OFF at beginning
lcd.init(); // Initialize LCD
lcd.backlight(); // Backlight ON
}
void loop()
{
raw = analogRead(TMP36); // Read temperature
float mV = 5000.0 * raw / 1023.0; // in mV
float RoomTemp = (mV-500.0) / 10.0; // Room temperature in C
}
else
{
if(RoomTemp >= THIGH) // If greater or equal
{
digitalWrite(LED, LOW); // LED OFF
digitalWrite(RELAY, LOW); // RELAY OFF
}
}
delay(10000); // Wait 10 seconds
}
● 100
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 100 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
Block diagram: Figure 7.8 shows the block diagram of the project.
Circuit diagram: The circuit diagram of the project is shown in Figure 7.9. The control
buttons UP, DOWN, and START are connected to Arduino Uno port pins 4, 5, and 6, respec-
tively. The output state of the buttons is at logic 1 and go to logic 0 when pressed. The LCD,
relay, and the LED are connected as in Project 1.
● 101
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 101 11/10/2022 13:54
PID-based Practical Digital Control
Program listing: Figure 7.10 shows the program listing (Program: AONOFF3). Function
Desired() controls the button actions. When the program runs, the default value of the
SetTemp (20 ºC) is displayed. Pressing button UP will increment the SetTemp by one, while
pressing button DOWN will decrement it by one. Pressing the START button will launch the
controller. The control action is as in Project 1 where the SetTemp value is compared to the
measured value (RoomTemp) and the relay is turned ON or OFF to control the heater. At
this point, the program will have to be restarted in order to set another SetTemp value. The
control action is implemented at every 10 seconds.
//--------------------------------------------------------------------------
// ON-OFF TEMPERATURE CONTROL - SetTemp with buttons
// =================================================
//
// This is an ON-OFF temperature controller project. In this version of the
// project the SetTemp is set using buttons
//
// Author: Dogan Ibrahim
// File : AONOFF3
// Date : June, 2022
//---------------------------------------------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
pinMode(LED, OUTPUT); // LED is output
pinMode(RELAY, OUTPUT); // RELAY is output
pinMode(UP, INPUT); // Button is input
pinMode(DOWN, INPUT); // Button is input
pinMode(START, INPUT); // Button is input
digitalWrite(LED, LOW); // LED OFF at beginning
digitalWrite(RELAY, LOW); // RELAY OFF at beginning
lcd.init(); // Initialize LCD
lcd.backlight(); // Backlight ON
Desired();
● 102
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 102 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
//
// This function sets the desired temperature using buttons
//
void Desired()
{
lcd.clear();
while(ExitFlag == 0)
{
lcd.setCursor(0, 0);
lcd.print("SetTemp = ");
lcd.print(SetTemp);
while(digitalRead(UP) == 1 && digitalRead(DOWN) == 1 && digitalRead(START)==
1);
if(digitalRead(UP) == 0)
{
SetTemp++;
while(digitalRead(UP) == 0);
}
else if(digitalRead(DOWN) == 0)
{
SetTemp--;
while(digitalRead(DOWN) == 0);
}
delay(10);
if(digitalRead(START) == 0)ExitFlag = 1;
}
}
void loop()
{
raw = analogRead(TMP36); // Read temperature
float mV = 5000.0 * raw / 1023.0; // in mV
float RoomTemp = (mV-500.0) / 10.0; // Room temperature in C
● 103
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 103 11/10/2022 13:54
PID-based Practical Digital Control
{
digitalWrite(LED, HIGH); // LED ON
digitalWrite(RELAY, HIGH); // RELAY ON
}
else
{
digitalWrite(LED, LOW); // LED OFF
digitalWrite(RELAY, LOW); // RELAY OFF
}
delay(10000); // Wait 10 seconds
}
Block diagram: Figure 7.11 shows the block diagram of the project.
A rotary encoder (Figure 7.12) is a device that looks like a potentiometer and it senses the
rotation and direction of its knob. The device has two internal contacts that make and break
a circuit as the knob is turned. As the knob is turned, a click is felt that indicates that the
know has been rotated by one position. With a simple logic you can determine the direction
of rotation.
● 104
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 104 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
CLK: This is an output pin used to determine the amount of rotation. Each time the
knob is rotated by one click in either direction, the CLK output goes to HIGH and
then LOW
DT: This is an output similar to CLK pin, but it lags the CLK by 90 degrees. This
output is used to determine the direction of rotation
SW: This is an active LOW push button. When the knob is pushed, the voltage
goes LOW
In our project each rotation (i.e., click) of the knob will increment (or decrement) the Set-
Temp by 1ºC. Turning the knob in one direction will increment by one, while turning it in
the other direction will decrement it by one. When the required value is reached, the user
has to push the knob so that the controller action.
Circuit diagram: the connections between the Arduino Uno and the external components
are as follows (power supply and GND connections are not shown):
● 105
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 105 11/10/2022 13:54
PID-based Practical Digital Control
Program listing: Figure 7.14 shows the program listing (Program: AONOFF4). At the
beginning of the program the interface between Arduino Uno and external components are
defined and the variables used in the program are initialized.
Inside the setup() function, LED and RELAY ae configured as outputs, and the rotary en-
coder pins are configured as inputs. The LED and RELAY are turned OFF at the beginning
of the program and the LCD is initialized. The program then calls function Rotary(). This
function senses when the user turns the encoder arm and increments or decrements var-
iable SetTemp depending on which direction the arm is rotated. When the user is happy
with the SetTemp value, the rotary encoder shaft should be pushed in. After reading the
SetTemp value, the remainder of the program is same as in Project 1.
//--------------------------------------------------------------------------
// ON-OFF TEMPERATURE CONTROL - SetTemp with Rotary Encoder
// ========================================================
//
// This is an ON-OFF temperature controller project. In this version of the
// project the SetTemp is set using a rotary encoder
//
// Author: Dogan Ibrahim
// File : AONOFF4
// Date : June, 2022
//---------------------------------------------------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
● 106
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 106 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
void setup()
{
pinMode(LED, OUTPUT); // LED is output
pinMode(RELAY, OUTPUT); // RELAY is output
pinMode(CLK, INPUT); // CLK is input
pinMode(DT, INPUT); // DT is input
pinMode(SW, INPUT_PULLUP); // SW is input
digitalWrite(LED, LOW); // LED OFF at beginning
digitalWrite(RELAY, LOW); // RELAY OFF at beginning
lcd.init(); // Initialize LCD
lcd.backlight(); // Backlight ON
Rotary();
}
//
// This functon reads the rotary encoder value as the encoder arm
// is rotated. The SetTemp value in changes by 1 (incremented or
// decremented at each click of the rotary encoder).
//
void Rotary()
{
ClkOldState = digitalRead(CLK);
lcd.clear(); // Clear LCD
lcd.setCursor(0, 0); // Cursor at 0,0
lcd.print("SetTemp:"); // Display SetTemp
lcd.setCursor(0, 1); // Cursor at 0,1
lcd.print(SetTemp); // Display initial value
while(flag == 1)
{
ClkState = digitalRead(CLK);
DTState = digitalRead(DT);
if(ClkState != ClkOldState && ClkState == 1)
{
if(DTState != ClkState)
SetTemp++; // Increment SetTemp
else
{
SetTemp--; // Decrement SetTemp
if(SetTemp == 0)SetTemp = 20; // Back to 20 if 0
● 107
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 107 11/10/2022 13:54
PID-based Practical Digital Control
}
lcd.setCursor(0, 1); // Cursor at 0,1
lcd.print(" "); // Delete
lcd.setCursor(0, 1); // Cursor back at 0,1
lcd.print(SetTemp); // Display SetTEmp
}
ClkOldState = ClkState;
SWState = digitalRead(SW); // Read stste of SW button
if(SWState == 0)flag = 0; // Exit Rotary() function
}
}
void loop()
{
raw = analogRead(TMP36); // Read temperature
float mV = 5000.0 * raw / 1023.0; // in mV
float RoomTemp = (mV-500.0) / 10.0; // Room temperature in C
}
else
{
digitalWrite(LED, LOW); // LED OFF
digitalWrite(RELAY, LOW); // RELAY OFF
}
delay(10000); // Wait 10 seconds
}
Figure 7.15 shows the LCD display when the program is first run, where the default tem-
perature value 20 ºC is displayed before the rotary encoder arm is rotated.
● 108
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 108 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
Block diagram: Figure 7.16 shows the block diagram of the project. This figure is very
similar to Figure 7.1, but here you have used an external ADC chip to convert the analog
temperature output of the TMP36 sensor into digital form. This is because the Raspberry Pi
does not have any ADC channels and external ADC chips must be used to interface analog
devices to Raspberry Pi.
Circuit diagram: In this project, the MC3002 ADC chip is used (Figure 7.17). This chip has
the following features:
The MCP3002 is a successive approximation 10-bit ADC with on-board sample and hold
circuitry. The chip is programmable to operate as either a differential-input pair or as dual
single-ended inputs. The pin definitions are as follows:
● 109
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 109 11/10/2022 13:54
PID-based Practical Digital Control
In this project, the supply voltage and the reference voltage are both set to +3.3 V. Thus,
the digital output code is given by:
or
Thus, for example, digital input data "00 00000001" corresponds to 3.22 mV, "00 00000010"
corresponds to 6.44 mV, and so on.
The MCP3002 has two configuration bits: SGL/DIFF and ODD/SIGN. These bits follow the
sign bit and are used to select the input channel configuration. The SGL/DIFF is used to
select single-ended or differential mode. The ODD/SIGN bit selects which channel is used
in single-ended mode and is used to determine polarity in differential mode. In this project,
you are using channel CH0 in single-ended mode. According to the MCP3002 datasheet,
SGL/DIFF and ODD/SIGN must be set to 1 and 0 respectively.
Notice that Raspberry Pi pins are not +5 V tolerant, but the I2C LCD operates with +5 V
where its SDA and SCL pins are pulled to +5 V. It is generally not a good idea to connect
the LCD directly to the Raspberry Pi as it can damage its I/O circuitry. There are several
solutions here. On solution is to remove the I2C pull-up resistors on the LCD module. The
other option is to use an I2C which operates with +3.3 V. The other solution is to use a bidi-
rectional +3.3 V to +5 V logic level converter chip. In this project, you will use the TXS0102
bidirectional logic level converter chip like the one shown in Figure 7.18.
● 110
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 110 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
The circuit diagram of the project is shown in Figure 7.19. The interface between the Rasp-
berry Pi 4 and the external devices are as follows (power and ground connections are not
shown):
● 111
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 111 11/10/2022 13:54
PID-based Practical Digital Control
• Select SPI.
• Select <Yes> to enable the bus and select <OK>.
• Select Interface Options again.
• Select I2C.
• Select <Yes> to enable the bus and select <OK>.
• Move the cursor to <Finish> and press Enter to exit.
• Enter the following command:
sudo reboot
sudo i2cdetect –y 1
you should see display as shown in Figure 7.21. The address of the LCD author is using
was: 0x27.
● 112
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 112 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
The I2C LCD library supports the following functions (see the RPLCD I2C LCD library docu-
mentation for more details):
If you have used a text editor (e.g., nano) to create the program, you can run it by enter-
ing the following command:
python3 lcdtest.py
If on the other hand you have used the Thonny IDE, then just run the program.
#---------------------------------------
#
# LCD TEST PROGRAM
# ================
#
● 113
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 113 11/10/2022 13:54
PID-based Practical Digital Control
lcd.clear()
lcd.home
lcd.write_string("MY LCD")
sudo ls –l /dev/spidev*
Function Description
Program listing: Figure 7.24 shows the Raspberry Pi Python program listing (Program:
AONOFF5.py). At the beginning of the program the library modules used in the program
are imported to the program. SetTemp is set to 33 ºC and the LED and RELAY ports are
defined. The function Setup() configures LED and RELAY as outputs and deactivates them
at the beginning of the program.
● 114
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 114 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
The function Get_ADC_Data() is used to read the analog data from the temperature sen-
sor chip, where the channel number (channel_no) is specified in the function argument as
0 or 1. Notice that you have to send the start bit, followed by the SGL/DIFF and ODD/SIGN
bits and the MSBF bit to the MCP3002 ADC chip. It is recommended to send leading zeroes
on the input line before the start bit. This is often done when using microcontroller based
systems required to send 8 bits at a time.
The following data can be sent to the ADC (SGL/DIFF = 1 and ODD/SIGN = channel_no) as
bytes with leading zeroes for more stable clock cycle. The general data format is:
Where, S = start bit, D = SGL/DIFF bit, C = ODD/SIGN bit, and M = MSBF bit.
For channel 0: 0000 0001 1000 0000 0000 0000 (0x01, 0x80, 0x00)
For channel 1: 0000 0001 1100 0000 0000 0000 (0x01, 0xC0, 0x00)
Notice that the second byte can be sent by adding 2 to the channel number (to make it 2 or
3) and then shifting 6 bits to the left as shown above to give 0x80 or 0xC0. The chip returns
24-bit data (i.e., 3 bytes) and you must extract the correct 10-bit ADC data from this 24-bit
data. The 24-bit data is in the following format ("X" is don't care bit):
Assuming that the returned data is stored in 24 bit variable ADC, you have:
ADC[0] = "XXXX"
ADC[1] = "XXXX DDDD"
ADC[2] = "DDDD DDXX"
Thus, you can extract the 10-bit ADC data with the following operations:
and
(ADC[1] & 15) << 6) so, high byte = "DD DD00 0000"
Adding the low byte and the high byte you get the 10-bit converted ADC data as:
DD DDDD
The raw data read from the ADC is stored in variable adc, which is then converted into
physical voltage in millivolts and stored in variable mv. This value is then converted into
temperature in degrees Celsius by subtracting 500 and dividing by 10, and then stored
● 115
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 115 11/10/2022 13:54
PID-based Practical Digital Control
#----------------------------------------------------------
#
# ON-OFF TEMPERATURE CONTROLLER
# =============================
#
# This is an ON-OFF temperature controller program.
# The meaured temperatrue is compared to the SetTemp
# and if it greater than SetTemp then the relay and LED
# are turned OFF, otherwise they are both turned ON
#
# Author: Dogan Ibrahim
# File : AONOFF5.py
# Date : June, 2022
#----------------------------------------------------------
import RPi.GPIO as GPIO
import time
from RPLCD.i2c import CharLCD
import spidev
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
#
# This function configures the LED and RELAY and set them
# both OFF at the beginning of the program
#
def Setup():
GPIO.setup(LED, GPIO.OUT) # LED is output
GPIO.setup(RELAY, GPIO.OUT) # RELAY is output
GPIO.output(LED, 0) # LED OFF
GPIO.output(RELAY, 0) # RELAY OFF
● 116
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 116 11/10/2022 13:54
Chapter 7 • On-Off Temperature Control
#
# This function returns the ADC result in variable rcv
#
def Get_ADC_Data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv
Setup()
while True: # Do Forever
adc = Get_ADC_Data(0) # Read temperature
mv = adc * 3300.0 / 1024.0 # Convert to mV
Temperature = (mv - 500) / 10.0 # In Degrees C
lcd.clear() # Clear LCD
lcd.home() # Home LCD
head1 = "SetTemp = " + str(SetTemp) # Heading
lcd.write_string(head1) # Write top row
head2 = "Measured= " + str(Temperature)[:4] # Heading
lcd.cursor_pos = (1, 0) # Bottom row
lcd.write_string(head2) # Write bottom row
Figure 7.25 shows an example display of the LCD. Figure 7.26 shows the project built on
a breadboard.
● 117
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 117 11/10/2022 13:54
PID-based Practical Digital Control
Figure 7.26: Project built on a breadboard (relay and heater are not shown).
● 118
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 118 11/10/2022 13:54
Chapter 8 • PID Temperature Control with the Raspberry Pi
8.1 Overview
In the previous Chapter you engaged in designing ON-OFF type temperature control sys-
tems using Arduino and Raspberry Pi computers. In this Chapter you will learn how to de-
sign PID based temperature control systems using the Raspberry Pi 4 computer.
The hotbed is fixed on an aluminum plate enabling it to dissipate its heat. Before developing
the PID controller software for the hotbed, you will learn how to measure the temperature
of the hotbed via the built-in thermistor.
● 119
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 119 11/10/2022 13:54
PID-based Practical Digital Control
The hotbed has 4 wires: 2 for the heater and 2 for the thermistor. The thermistor wires are
identified easily because they are much thinner than the heater wires.
Figure 8.3 shows the circuit to be used to measure the thermistor resistance.
Assuming a power supply of +3.3 V, The voltage across the series resistor is given by:
● 120
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 120 11/10/2022 13:54
Chapter 8 • PID Temperature Control with the Raspberry Pi
where is in millivolts
,
You can then use the Steinhart-Hart equation to find the temperature as described in
Chapter 2:
The output voltage of the resistive potential divider circuit is connected to CH0 of the
MCP3002 ADC as shown in Figure 8.4.
Program listing: Figure 8.5 shows the program listing (Program: thermistor). At the be-
ginning of the program the libraries used are imported to the program, resistors
are initialized. Function Get_ADC_Data() returns the analogue value read from the
thermistor. Function Calc_Temperature() calculates the temperature using the Stein-
hart-Hart equation, which is displayed every 2 seconds on the screen. Figure 8.6 shows
the temperature readings displayed on te screen.
● 121
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 121 11/10/2022 13:55
PID-based Practical Digital Control
#----------------------------------------------------------
#
# THERMISTOR TEMPEARTURE SENSOR
# =============================
#
# This program measures the temperature of a thermistor
#
# Author: Dogan Ibrahim
# File : thermistor.py
# Date : June, 2022
#----------------------------------------------------------
import RPi.GPIO as GPIO
import time
import spidev
import math
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
#
# This function returns the ADC result in variable rcv
#
def Get_ADC_Data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv
#
# This function calculates the temperature
#
def Calc_Temperature(Vo):
Rt = Rs * (3300 - Vo) / Vo # Find Rt
R = math.log(Rt / R0) # Find temperature
R = R / B # ...
T = R + 1 / T0 # ...
T = 1 / T # ...
T = T - 273.15 # ...
return T
● 122
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 122 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
Block diagram: Figure 8.7 shows the open-loop block diagram of the project. The temper-
ature of the hotbed is measured with the built-in thermistor as described in Project 1. The
MOSFET switch is driven by the Raspberry Pi PWM (Pulse Width Modulated) output signal
and it switches an external high capacity power supply voltage to provide the required cur-
rent to the hotbed. Since the hotbed operates with 12 V 120 W, the external power supply
must be able to supply at least 10 A of current at 12 V.
Before going into more details of the design, it is worthwhile to review the basic principles
of the PWM signals and the MOSFET switch used in this project.
● 123
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 123 11/10/2022 13:55
PID-based Practical Digital Control
PWM
Pulse Width Modulation (PWM) is a commonly used technique for controlling the power
delivered to analog loads using digital waveforms. Although analog voltages (and cur-
rents) can be used to control the delivered power, they have several drawbacks. Controlling
large analog loads require large voltages and currents that cannot easily be obtained us-
ing standard analogue circuits and DACs. Large analog voltage generators can be heavy,
large, and expensive and they are also sensitive to noise. By using the PWM technique the
average value of voltage (and current) fed to a load is controlled by switching the supply
voltage ON and OFF at a fast rate. The longer the power on time, the higher is the voltage
supplied to the load.
Figure 8.8 shows a typical PWM waveform where the signal is basically a repetitive positive
pulse, having the period T, ON time TON and OFF time of T – TON seconds. The minimum and
maximum values of the voltage supplied to the load are 0 and VP respectively. The PWM
switching frequency is usually set to be very high (usually in the order of several kHz) so
that it does not affect the load that uses the power. The main advantage of PWM is that the
load is operated efficiently since the power loss in the switching device is very low. When
the switch is ON there is practically no voltage drop across the switch, and when the switch
is OFF there is no current supplied to the load.
The duty cycle (or D) of a PWM waveform is defined as the ratio of the ON time to its period.
Expressed mathematically,
By varying the duty cycle between 0% and 100% you can effectively control the average
voltage supplied to the load between 0 and Vp.
The average value of the voltage applied to the load can be calculated by considering a
general PWM waveform shown in Figure 8.8. The average value A of waveform f(t) with
period T and peak value ymax and minimum value ymin is calculated as:
● 124
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 124 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
or
or
As evident from the above equation, the average value of the voltage supplied to the load is
directly proportional to the duty cycle of the PWM waveform, and by varying the duty cycle
you control the average load voltage. Figure 8.9 shows the average voltage for different
values of the duty cycle.
By varying the duty cycle you can effectively vary the average analog voltage supplied to
the load, e.g., to a heater and therefore control the heat output.
GPIO12 PWM0
GPIO18 PWM0
GPIO13 PWM1
GPIO19 PWM1
● 125
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 125 11/10/2022 13:55
PID-based Practical Digital Control
The PWM pin must be configured as an output before it can be used to generate PWM sig-
nals. The following built-in functions are available with Python to control the PWM:
PWM duty cycle has the range 0 to 100, corresponding to 0% (no output) to 100% (full
output).
MOSFET switch
The hotbed operates with 12 V and consumes about 120 watts. This means that about 10
A current is required for its operation. In this project an external 12 V power supply is used
capable of supplying the required power. A MOSFET switch assembly with a large heatsink
is used to power the hotbed. This module is sold as a 3D printer heating controller. The
input to the switch is the PWM waveform from the Raspberry Pi, and its output drives the
hotbed. Figure 8.10 shows the MOSFET switch module used. This module has the following
features:
● 126
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 126 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
The MOSFET switch operates with +5 V to +12 V but the output voltage of the Raspberry Pi
is only +3.3 V. Therefore, a +3.3 V to +5 V logic level converter chip (Figure 8.11) is used
to provide the required +5 V for the MOSFET switch.
Circuit diagram: Figure 8.12 shows the circuit diagram of the project. The thermistor volt-
age is read using the MCP3002 ADC chip and the temperature is calculated as described in
the previous project. GPIO12 is used as the PWM output and is connected to the SIG input
of the MOSFET switch. An external 12 V 10 A DC power supply is connected to this switch.
The other two pins of the MOSFET switch are connected to the hotbed. You should make
sure that the external power supply polarity is correct when connected to the MOSFET
switch. The hotbed has no polarity.
Program listing: Figure 8.13 shows the program listing (Program: StepResponse.py).
In this program, you effectively display the temperature readings in real-time on a graph
using the matplotlib library of the Raspberry Pi. At the beginning of the program, the li-
braries used in the program are imported and the parameters of the thermistor and series
resistor are defined. Function Get_ADC_Data() reads the voltage at the series resistor
and then calculates the resistance of the thermistor. Then, the Steinhart-Hart equation is
used as before to calculate the temperature of the hotbed. Then, a step input is applied to
the hotbed by setting the PWM duty cycle to 25%. The temperature of the hotbed is then
plotted in real-time and is shown in Figure 8.14.
● 127
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 127 11/10/2022 13:55
PID-based Practical Digital Control
#----------------------------------------------------------
#
# PID TEMPERATURE CONTROLLER
# ==========================
#
# This is the step response program display
#
# Author: Dogan Ibrahim
# File : StepResponse.py
# Date : June, 2022
#----------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
import spidev
import math
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
B = 3950 # Thermistor B
R0 = 100000 # Thermistor R0
Rs = 100000 # Rs
T0 = 298.15 # T0
MOSFET = 12 # MOSFET
GPIO.setup(MOSFET, GPIO.OUT) # PWM port
GPIO.output(MOSFET, 0)
pwm = GPIO.PWM(MOSFET, 100) # PWM at 100 Hz
#
# Setup real time plot
#
def SetupPlot():
plt.axis([0,400, 0,100]) # Axes limits
plt.title('Temperature') # Graph title
plt.xlabel('Time (seconds)') # X label
plt.ylabel('Temperature') # Y label
plt.ion()
return
● 128
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 128 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
#
# This function returns the ADC result in variable rcv
#
def Get_ADC_Data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv
#
# This function calculates and returns the thermistor temperature
#
def Calc_Temperature():
adc = Get_ADC_Data(0) # Read voltage
Vo = adc * 3300.0 / 1024.0 # in millivolts
Rt = Rs * (3300 - Vo) / Vo # Find Rt
R = math.log(Rt / R0)
R = R / B
T = R + 1 / T0
T = 1 / T # Temperature
T = T - 273.15 # In Centigrade
return T
● 129
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 129 11/10/2022 13:55
PID-based Practical Digital Control
Notice that the delay time of the system was small because the thermistor is embedded
to the hotbed and responds quickly to temperature changes. In reference to Figure 8.14,
you can calculate the open-loop system transfer function either graphically or as described
in Chapter 3. Time constant is the value when the response is 63% of the final value.
Therefore, 24 + (84 – 24) × 0.63 = 52.92. Drawing a horizontal line from this point to
the response curve you find that the system time constant is 78 seconds. This is shown in
Figure 8.15, which gives:
Note: the program must be run from the Thonny IDE in Desktop mode, and not from the
command mode. This is because graphics can only be drawn in Desktop mode.
● 130
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 130 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
Block diagram: Figure 8.16 shows the block diagram of the project. The hotbed temper-
ature is measured with the built-in thermistor as described in Project 1. This temperature
is then fed back to the Raspberry Pi where the PI algorithm is implemented to control the
temperature so that it is at the SetTemp. In this project SetTemp is set to 50 ºC and is
hardcoded in the program, which is shown by the LCD. The MOSFET switch is driven by the
Raspberry Pi PWM (Pulse Width Modulated) output signal and it provides the high current
required by the hotbed by switching he external power supply.
Circuit diagram: Figure 8.17 shows the circuit diagram of the project. Notice that the
MOSFET switch requires +5 V for its operation and a logic level converter is used to increase
the Raspberry Pi output voltage to +5 V.
● 131
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 131 11/10/2022 13:55
PID-based Practical Digital Control
The parallel-PI realization shown in Figure 6.1 was used in this project.
Program listing: Figure 8.18 shows the program listing (Program: PItemp.py). At the
beginning of the program the libraries used are imported to the program, I2C LCD and the
SPI bus are initialized. Then the thermistor parameters are defined and PWM output is as-
signed to GPIO12 where the MOSFET switch is connected to.
Function SetupPlot() initializes the real-time graphic drawing parameters. Function Get_
ADC_Data() reads analogue data from the thermistor. Function Calc_Temperature()
reads the thermistor data and returns the temperature in degrees Centigrade. The function
Init() is where the PI parameters are defined and the LCD is configured to display the
SetTemp which is named as sk in the program.
Function PI() implements the PI algorithm as described in Figure 6.2. The error ek is cal-
culated as ek = sk – yk where sk is the SetTemp and yk is the output (i.e., the hotbed
temperature). Then the controller output uk is calculated and sent to the PWM to activate
the MOSFET switch. Note that PWM can only take values between 0 and 100 and therefore
the uk output is bound within these values.
A 'while' loop is formed inside the main program. Inside this loop the temperature of the
hot bed is read and PI() is called to calculate and output the controller values. The time
response of the system (i.e., the change of the hotbed temperature) is plotted in real-time
by the program. It is important that the program must be run in Desktop mode and
the Thonny IDE must be used to run the program so that the system response can
be plotted in real-time. The program WILL NOT work if run from the command
mode. Also, the real-time plot may introduce additional delays to the loop time
which is also the PID sample time. If the real-time plot time is a problem, then the
response time can be stored in a list (e.g., every second) and then plotted offline
at the end of the program. Additionally, it is worth to mention that the time scale
of the graph is not very accurate.
The program is repeated after a 1-second delay. i.e., the sample time is chosen as 1 sec-
ond. To be more precise, you could have setup a 1-second timer interrupt routine and
execute the PI algorithm inside the timer interrupt service routine.
● 132
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 132 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
#----------------------------------------------------------
#
# PI TEMPERATURE CONTROLLER
# =========================
#
# This is the PI temperature controller program
#
# Author: Dogan Ibrahim
# File : PItemp.py
# Date : June, 2022
#----------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
from RPLCD.i2c import CharLCD
import spidev
import math
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
B = 3950 # Thermistor B
R0 = 100000 # Thermistor R0
Rs = 100000 # Rs
T0 = 298.15 # T0
MOSFET = 12 # MOSFET
GPIO.setup(MOSFET, GPIO.OUT)
pwm = GPIO.PWM(MOSFET, 100) # PWM port
global sk, Kp, T, Ti, pk, pk_1, b, yk
#
# Setup real time plot
#
def SetupPlot():
plt.axis([0,400, 0,100]) # Axes limits
plt.title('Temperature') # Title
plt.xlabel('Time (seconds') # X label
plt.ylabel('Temperature') # Y label
● 133
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 133 11/10/2022 13:55
PID-based Practical Digital Control
plt.ion()
return
#
# This function returns the ADC result in variable rcv
#
def Get_ADC_Data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv
#
# This function calculates and returns the temperature in C
#
def Calc_Temperature():
adc = Get_ADC_Data(0) # Get ADC value
Vo = adc * 3300.0 / 1024.0 # in millivolts
Rt = Rs * (3300 - Vo) / Vo # Calculate Rt
R = math.log(Rt / R0)
R = R / B
T = R + 1 / T0
T = 1 / T # T in Kelvin
T = T - 273.15 # In Degrees C
return T
#
# This function initializes the LCD and displays SetTemp
#
def Init():
global sk, b, Kp, T, Ti, pk, pk_1
sk = 50 # SetTemp
Kp = 2.0
T = 1.0
Ti = 50.0
b = Kp*T/Ti
pk = 0.0
pk_1 = 0.0
lcd.clear() # Clear LCD
lcd.home() # Home cursor
lcd.cursor_pos = (0, 0) # At 0,0
lcd.write_string("SetTemp:") # Heading
lcd.cursor_pos = (1, 0) # At 1,0
lcd.write_string(str(sk)) # SetTEmp
return
● 134
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 134 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
Figure 8.19 shows the closed-loop output time response of the system where the SetTemp
(desired temperature) was set to 50 ºC. Notice that even though the steady-state error is
zero and the response settles down at 50 ºC, the response shows a large overshoot which
is not acceptable in many process control systems. Large overshoot is one of the results of
tuning a system using the Ziegler and Nichol algorithm.
● 135
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 135 11/10/2022 13:55
PID-based Practical Digital Control
The integral time Ti was increased and the proportional constant reduced in order to de-
crease the overshoot and get a more acceptable result. Figure 8.20 shows the result when
Kp = 2.0 and Ti = 35.0.
Finally, an acceptable and nice response was obtained by increasing Ti further. Figure 8.21
shows the response with Kp = 2.0 and Ti = 50. In this response, the overshoot is small and
the system settles down at the desired temperature quickly.
● 136
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 136 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
Notice that the acceptable PI parameters were found after a few trial and error rounds. The
Ziegler and Nichol tuning parameters gave us a starting point for tuning the system.
Block diagram and circuit diagram: The block diagram and circuit diagram of the pro-
ject are as shown in Figure 8.16 and Figure 8.17, respectively.
In reference to Figure 8.15 and the Ziegler and Nichols PID table of settings, you find the
following P, I, and D controller parameters:
The parallel-PID realization shown in Figure 6.1 was used in this project.
Program listing: Figure 8.22 shows the program listing (Program: PIDtemp.py). As in
the previous program, at the beginning of the program the libraries used are imported
● 137
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 137 11/10/2022 13:55
PID-based Practical Digital Control
.
to the program, and the I2C LCD and the SPI bus get initialized. Then the thermistor pa-
rameters are defined and PWM output is assigned to GPIO12 where the MOSFET switch is
connected to.
The only change from Figure 8.18 is the controller algorithm. Here, function PI() is re-
placed with function PID() and the derivative term is added to the controller.
#----------------------------------------------------------
#
# PID TEMPERATURE CONTROLLER
# ==========================
#
# This is the PID temperature controller program
#
# Author: Dogan Ibrahim
# File : PIDtemp.py
# Date : June, 2022
#----------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
from RPLCD.i2c import CharLCD
import spidev
import math
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
B = 3950 # Thermistor B
R0 = 100000 # Thermistor R0
Rs = 100000 # Rs
T0 = 298.15 # T0
MOSFET = 12 # MOSFET
GPIO.setup(MOSFET, GPIO.OUT)
pwm = GPIO.PWM(MOSFET, 100) # PWM port
global sk, Kp, T, Ti, pk, pk_1, ek_1, a, b, yk
● 138
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 138 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
#
# This function returns the ADC result in variable rcv
#
def Get_ADC_Data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv
#
# This function calculates and returns the temperature in C
#
def Calc_Temperature():
adc = Get_ADC_Data(0) # Get ADC value
Vo = adc * 3300.0 / 1024.0 # in millivolts
Rt = Rs * (3300 - Vo) / Vo # Calculate Rt
R = math.log(Rt / R0)
R = R / B
T = R + 1 / T0
T = 1 / T # T in Kelvin
T = T - 273.15 # In Degrees C
return T
#
# This function initializes the LCD and displays SetTemp
#
def Init():
global sk, a, b, Kp, T, Ti, pk, pk_1, ek_1
sk = 50 # SetTemp
Kp = 2.0
T = 1.0
Ti = 45.0
Td = 5.0
a = Kp*T/Ti
b = Kp*Td/T
pk = 0.0
pk_1 = 0.0
● 139
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 139 11/10/2022 13:55
PID-based Practical Digital Control
ek_1 = 0.0
lcd.clear() # Clear LCD
lcd.home() # Home cursor
lcd.cursor_pos = (0, 0) # At 0,0
lcd.write_string("SetTemp:") # Heading
lcd.cursor_pos = (1, 0) # At 1,0
lcd.write_string(str(sk)) # SetTEmp
return
#
# This is the Proportional+Integral+Derivative algorithm function
#
def PID():
global yk, pk_1, ek_1
ek = sk - yk
pk = a*ek + pk_1
wk = Kp*ek
qk = b*(ek-ek_1)
uk = wk + pk + qk # PID output
if uk > 100.0: # Limit uk for PWM
uk = 100.0
if uk < 0.0: # Limit uk for PWM
uk = 0.0
pwm.ChangeDutyCycle(uk) # To PWM
pk_1 = pk # Update pk_1
ek_1 = ek # Update ek_1
return
x = i
plt.scatter(x, yk,color='red')
plt.show()
plt.pause(0.0001)
time.sleep(1)
pwm.stop()
● 140
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 140 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
Figure 8.23 shows the closed-loop output time response of the system where the SetTemp
(desired temperature) was set to 50 ºC. Notice that even though the steady state error is
zero and the response settles down at 50 ºC, the response shows a large overshoot which
is not acceptable in many process control systems. Large overshoot is one of the results of
tuning a system using the Ziegler and Nichol algorithm.
The integral time Ti was increased and the proportional constant reduced in order to de-
crease the overshoot and get a more acceptable result. At the same time, the derivative
term was increased to overcome any overshoot. Figure 8.24 shows the result when Kp =
2.0 and Ti = 45.0, Td = 3.
Finally, a disturbance response was plotted by removing the controller for a short while and
then reconnecting it. Figure 8.25 shows the disturbance recovery response of the system.
The steady-state response settled back at 50 ºC after the disturbance is removed.
● 141
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 141 11/10/2022 13:55
PID-based Practical Digital Control
Notice that the acceptable PID parameters were found after a few trial and error rounds.
The Ziegler and Nichol tuning parameters gave us a starting point for tuning the system.
The sample time of the PID is based on using the Python built-in delay function time.
sleep(). The delay introduced by this function is not very accurate. As a result, the re-
al-time plots drawn in this Chapter are not very accurate. More accurate sample times and
more accurate real-time plots can be obtained if the PID algorithm is implemented inside a
timer iterrupt service routine.
● 142
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 142 11/10/2022 13:55
Chapter 8 • PID Temperature Control with the Raspberry Pi
until a good response is obtained. Next, these parameters can be used on the actual con-
troller.
you have: C = 2, I = 22.5, and D = 6. Entering the plant and the controller parameters into
the simulator gives the response as in Figure 8.27, which is very similar to the response
you obtained in Figure 8.24.
● 143
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 143 11/10/2022 13:55
PID-based Practical Digital Control
9.1 Overview
In the previous Chapter you absorbed how to read the temperature of a thermistor, and
how to design a PID controller for a temperature control system using a Raspberry Pi. In
this Chapter, you will learn how to design PID based temperature control systems using an
Arduino Uno.
Circuit diagram: Although a resistive potential divider circuit is formed using the thermis-
tor as shown in Figure 8.3, a +5 V power supply is used. The circuit diagram of the project
is shown in Figure 9.1. Arduino Uno has built-in ADC meaning you do not need an external
ADC. The thermistor is connected to analogue input A0 of the Arduino Uno. As shown in the
previous Chapter, using a 100 kΩ series resistor, the resistance of the thermistor is given
by:
where is in millivolts
,
You can then use the Steinhart-Hart equation to find the temperature as described in the
previous Chapter:
● 144
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 144 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
Program listing: Figure 9.2 shows the program listing (Program: thermistor2). At the
beginning of the program, the Thermistor is assigned to analog port A0. Next, the ther-
mistor parameters and series resistor value are defined. Inside the setup() function, the
Serial Monitor is configured at 9600 baud. The function Calc_Temperature() calculates
the thermistor temperature and returns it to the main program where the temperature is
displayed every second on the Serial Monitor, as shown in Figure 9.3.
//--------------------------------------------------------------------------
// READING THE TEMPERATURE OF A THERMISTOR
// =======================================
//
// This program reads and displays the temperature of a thermistor
//
// Author: Dogan Ibrahim
// File : thermistor2
// Date : June, 2022
//---------------------------------------------------------------------------
int Thermistor = A0;
int B = 3950; // Thermistor B
float R0 = 100000.0; // Thermistor R0
float Rs = 100000.0; // Series resistor
float Vo, Rt, R, T, Temperature, T0 = 298.15;
unsigned int adc;
//
// Configure the Serial Monitor at 9600 BAud
//
void setup()
{
Serial.begin(9600);
}
//
// This function calculates and returns the temperature in C
//
float Calc_Temperature()
{
adc = analogRead(Thermistor); // Read voltage
Vo = adc * 5000.0 / 1024.0;
Rt = Rs * (5000.0 - Vo) / Vo; // Thermistor resistance
R = log(Rt / R0);
R = R / B;
T = R +1 / T0;
T = 1 / T;
T = T - 273.15; // Temperature in C
return T;
● 145
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 145 11/10/2022 13:55
PID-based Practical Digital Control
void loop()
{
Temperature = Calc_Temperature(); // Read temperature
Serial.println(T); // Display temperature
delay(1000); // Wait 1 seconds
}
Block diagram: Figure 9.4 shows the block diagram of the project. The temperature of the
hotbed is measured with the built-in thermistor as described in Project 1. This temperature
value is fed back to the Arduino Uno where the PID algorithm is implemented to control the
temperature so that it is at the SetTemp. In this project, SetTemp is set to 50 ºC. The MOS-
FET switch is driven by the Raspberry Pi PWM (Pulse Width Modulated) output signal and
it provides the high current required by the hotbed by switching he external power supply.
● 146
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 146 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
Circuit diagram: Figure 9.5 shows the circuit diagram of the project. Notice that because
the output port voltages of the Arduino Uno are +5 V, there is no need to use logic level
convertor chip.
On Arduino Uno, the PWM pins are numbers 3, 5, 6, 9, 10, and 11. The frequency of the
PWM signal at pins 5 and 6 will be about 980 Hz and 490 Hz on the other pins. The PWM
pins are labeled with the tilde (~) sign.
A PID-type controller was designed, but initially the derivative term was set to 0 so that you
had a PI controller. The following PI controller parameters were chosen since the system is
similar to the one given in the previous Chapter, but the PWM range is different:
The parallel PI realization shown in Figure 6.1 was used in this project.
● 147
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 147 11/10/2022 13:55
PID-based Practical Digital Control
Program listing: In Arduino Uno the PWM duty cycle range is 0 to 255, where 0 corre-
sponds to 0% and 255 corresponds to 100% duty cycle. The statement analogWrite(pin,
duty cycle) sets the duty cycle on the specified pin.
Figure 9.6 shows the program listing (Program: PIDtemp2). Inside the setup() function,
the Serial Monitor was initialized to 19200 baud, the MOSFET switch is configured as an
output, and finally the PID parameters are defined. The function Calc_Temperature()
calculates and returns the thermistor temperature to the main program loop.
The function PID() is where the PID algorithm is implemented. Inside the main program
loop, the temperature is read and function PID() is called. The time response of the system
is plotted using the Tools Serial Plotter of the Arduino IDE. It is important to make sure
that the loop time of the program does not exceed 1 second since the sample time is set to
one second. The time response is plotted in real time as it happens. If the required sample
time is very small as the plotting may affect the sample time. It is also possible to store the
response time values in an array and then plot them offline.
//--------------------------------------------------------------------------
// TEMPERATURE PID CONTROLLER
// ==========================
//
// This is teh Arduino Uno PID temperature controller. The desired temperature
// is set to 50 Degrees C
//
// Author: Dogan Ibrahim
// File : PIDtemp2
// Date : June, 2022
//---------------------------------------------------------------------------
int Thermistor = A0;
int B = 3950; // Thermistor B
float R0 = 100000.0; // Thermistor R0
float Rs = 100000.0; // Series resistor
float Vo, Rt, R, T, Temperature, adcconv, T0 = 298.15;
float sk, Kp, Ti, Td, pk, pk_1, ek, ek_1, a, b, yk, qk, wk, uk;
unsigned int adc;
int MOSFET = 3;
//
// Configure PWM pin and Initialize variables
//
void setup()
{
Serial.begin(19200);
pinMode(MOSFET, OUTPUT);
sk = 50.0;
Kp = 6.5; // Proportional
● 148
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 148 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
//
// This function calculates and returns the temperature in C
//
float Calc_Temperature()
{
adc = analogRead(Thermistor); // Read voltage
Vo = adc * adcconv;
Rt = Rs * (5000.0 - Vo) / Vo; // Thermistor resistance
R = log(Rt / R0);
R = R / B;
T = R +1.0 / T0;
T = 1.0 / T;
T = T - 273.15; // Temperature in C
return T;
}
//
// This is the PID function
//
void PID()
{
ek = sk - yk;
pk = a*ek + pk_1;
wk = Kp*ek;
qk = b*(ek - ek_1);
uk = wk + pk + qk;
if(uk > 255.0)
uk = 255;
if(uk < 0)
uk = 0;
analogWrite(MOSFET, uk);
pk_1 = pk;
ek_1 = ek;
}
● 149
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 149 11/10/2022 13:55
PID-based Practical Digital Control
void loop()
{
yk = Calc_Temperature();
PID();
Serial.println(yk);
delay(1000); // Wait 1 seconds
}
Figure 9.7 shows the time response of the system with the PI controller, where the desired
SetTemp was set to 50 ºC. The response shows a small overshoot and settles down to
50 ºC.
By adding the following derivative action, the response is shown in Figure 9.9:
● 150
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 150 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
Here again, you have some overshoot and the response settled at 50 ºC.
Notice that the sample time is set to 1 second, but this is not very accurate since the de-
lay() function is not accurate and the code executed before the delay() function is not
considered.
● 151
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 151 11/10/2022 13:55
PID-based Practical Digital Control
9.4 Project 3: PID Temperature Control with Arduino Uno and Timer
Interrupts
Description: The delay time of the Arduino is not very accurate and this affects the sample
time of the PID. For accurate sample timing you can use timer interrupts and execute the
PID algorithm inside the timer interrupt service routine.
In this project, you have modified the program and introduced 1 second timer interrupts
and moved the PID algorithm to within the interrupt service routine.
The block diagram and circuit diagram of the project are as before.
Program listing: Figure 9.10 shows the program listing (Program: PIDtemp3). Parts of
the program are similar to Figure 9.6, but here timer interrupts are enabled. In this pro-
ject, you want to generate timer interrupts every second. i.e., the frequency of
the interrupts is 1 Hz. Using a Prescaler value of 1024, the value of the compare
match register is calculated to be:
Timer 1 interrupts are enabled inside the setup() function with the following code:
TCCR1A = 0; // Set to 0
TCCR1B = 0; // Set to 0
TCNT1 = 0; // Set counter to 0
OCR1A = 15624; // Compare reg value
TCCR1B |= (1 << WGM12); // Turn on CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler=1024
TIMSK1 |= (1 << OCIE1A); // Enable Timer compare interrupt
sei(); // Enable all interrupts
//--------------------------------------------------------------------------
// TEMPERATURE PID CONTROLLER - USING TIMER INTERRUPTS
// ===================================================
//
// This is the Arduino Uno PID temperature controller. The desired temperature
// is set to 50 Degrees C. PID algorithm is implemented in timer interrupt
//
// Author: Dogan Ibrahim
// File : PIDtemp3
// Date : June, 2022
//---------------------------------------------------------------------------
int Thermistor = A0;
● 152
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 152 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
//
// Configure PWM pin and Initialize variables
//
void setup()
{
Serial.begin(19200);
pinMode(MOSFET, OUTPUT);
sk = 50.0;
Kp = 5.0; // Proportional
T = 1.0; // Sample time
Ti = 80.0; // Integral
Td = 0.0; // Derivative
a = Kp*T/Ti;
b = Kp*Td/T;
pk = 0.0;
pk_1 = 0.0;
ek_1 = 0.0;
adcconv = 5000.0 / 1024.0;
//
// Timer1 configuration for 1s (1Hz) interrupts
//
TCCR1A = 0; // Set to 0
TCCR1B = 0; // Set to 0
TCNT1 = 0; // Set counter to 0
OCR1A = 15624; // Compare reg value
TCCR1B |= (1 << WGM12); // Turn on CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler=1024
TIMSK1 |= (1 << OCIE1A); // Enable Timer compare
interrupt
sei(); // Enable all interrupts
}
//
// This function calculates and returns the temperature in C
//
float Calc_Temperature()
{
● 153
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 153 11/10/2022 13:55
PID-based Practical Digital Control
//
// This is the PID timer interrupt service routine
//
ISR(TIMER1_COMPA_vect)
{
yk = Calc_Temperature();
ek = sk - yk;
pk = a*ek + pk_1;
wk = Kp*ek;
qk = b*(ek - ek_1);
uk = wk + pk + qk;
if(uk > 255.0)
uk = 255;
if(uk < 0)
uk = 0;
analogWrite(MOSFET, uk);
pk_1 = pk;
ek_1 = ek;
Serial.println(yk);
}
void loop()
{
}
● 154
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 154 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
9.5 Project 4: PID Temperature Control using the Arduino Uno PID
Library
Description: There are several Arduino IDE based libraries that can be used to simplify
the design of PID controllers. In this section, you will be using the popular PID library by
Brett Beauregard (br3ttb@gmail.com), whose details are available at the following website:
https://playground.arduino.cc/Code/PIDLibrary/
The block diagram and the circuit diagram of the project are as in the previous project in
this Chapter.
PID(&Input, &Output, &Setpoint, Kp, Ki, Kd, Direction): This function creates a PID
controller in parallel form, linked to the specified Input, Output, and Setpoint. The param-
eters are:
Direction: This is either DIRECT or REVERSE and it determines which direction the output
will move when faced with a given error (DIRECT is most commonly used).
● 155
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 155 11/10/2022 13:55
PID-based Practical Digital Control
Compute(): This function contains the PID algorithm. it should be called once every loop
(or sample). The function calculates a new Output. The function returns true when output
is computed, and false if a new value is not evaluated.
SetOutputLimits(min,max): This function is used to set the output limits of the PWM. By
default, in Arduino Uno, these limits are 0 to 255.
SetSampleTime(): This function sets the PID sample time in milliseconds. i.e., how often
the PID algorithm will evaluate. The default is 200 ms. The compute function returns to the
calling program if it is not time to evaluate a new output.
SetMode(): This function specifies whether the PID should be on (AUTOMATIC) or off
(MANUAL) The default is MANUAL (off) when created.
SetTunings(Kp,Ki,Kd): Initial PID parameters are usually specified when the PID is cre-
ated. This function can be called to change these parameters.
Additionally, the following display functions are provided. These functions return the PID
parameters for display purposes:
GetKp()
GetKi()
GetKd()
GetMode()
GetDirection()
Before using the PID library, you have to include the library in our IDE. The steps are as
follows:
You are now ready to develop a PID controller for our hotbed. The program details are given
below.
Program listing: Figure 9.12 shows the program listing (Program: PIDlibtemp). At the
beginning of the program, the header file PID_v1.h is included in the program, the ther-
mistor parameters and series resistance are defined, and the MOSFET is assigned to port
3. Then the PID parameters are defined as double variables. Inside the setup() function,
● 156
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 156 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
the desired temperature is set to 50 ºC, the sample time is set to 1000 ms (1 second), and
the Serial Monitor is set to 19200 Baud. The program loop calls function Calc_Tempera-
ture() to calculate the temperature, then the function Compute of the PID library is called
to evaluate the PID. The output is sent to the MOSFET switch as a PWM waveform.
It is important to notice that the PID equation used in the library is of the following format:
But you have been using the PID equation in the following form:
Therefore,
and
You can use the following parameters for the library version of the PID:
and
//--------------------------------------------------------------------------
// TEMPERATURE PID CONTROLLER - USING PID LIBRARY
// ==============================================
//
// This is the Arduino Uno PID temperature controller. The desired temperature
// is set to 50 Degrees C. PID library is used in this program
//
// Author: Dogan Ibrahim
// File : PIDlibtemp
// Date : June, 2022
//---------------------------------------------------------------------------
#include <PID_v1.h>
int Thermistor = A0;
int B = 3950; // Thermistor B
float R0 = 100000.0; // Thermistor R0
float Rs = 100000.0; // Series resistor
float Vo, Rt, R, T, Temperature, adcconv, T0 = 298.15;
unsigned int adc;
int MOSFET = 3;
● 157
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 157 11/10/2022 13:55
PID-based Practical Digital Control
//
//Define Variables we will be connecting to
//
double Setpoint, Input, Output;
//
//Specify the PID tuning parameters
//
double Kp=2.0, Ki=0.022, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
//
// Configure PWM pin and Initialize variables
//
void setup()
{
Setpoint = 50.0;
myPID.SetSampleTime(1000);
Serial.begin(19200);
pinMode(MOSFET, OUTPUT);
myPID.SetMode(AUTOMATIC);
adcconv = 5000.0 / 1024.0;
}
//
// This function calculates and returns the temperature in C
//
float Calc_Temperature()
{
adc = analogRead(Thermistor); // Read voltage
Vo = adc * adcconv;
Rt = Rs * (5000.0 - Vo) / Vo; // Thermistor resistance
R = log(Rt / R0);
R = R / B;
T = R +1.0 / T0;
T = 1.0 / T;
T = T - 273.15; // Temperature in C
return T;
}
void loop()
{
Input = Calc_Temperature(); // Calculate temperature
boolean flag = myPID.Compute(); // Compute PID
● 158
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 158 11/10/2022 13:55
Chapter 9 • PID Temperature Control with the Arduino Uno
Figure 9.13 shows the closed-loop time response of the system. The temperature settles
down to 50 ºC after a small overshoot. This plot can be obtained by selecting the Serial
Plotter from the Tools menu. In Figure 9.14, the term was reduced to 0.028 to reduce
the overshoot.
● 159
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 159 11/10/2022 13:55
PID-based Practical Digital Control
10.1 Overview
In the previous Chapter you learned about controlling temperature using a PID controller
implemented on the Arduino Uno. This Chapter discusses the basic principles of DC motors
in relation to PID and worked out for both the Arduino and Raspberry Pi microcomputing
platforms.
• AC motors
• DC motors
Alternating Current (AC) motors are not commonly used in robotics because most robots
are powered with batteries which are DC voltage. AC motors are generally used in industrial
automation applications where very large torques may be required, such as in conveyor
belts, cranes and so on.
• Low-cost
• Can operate with low DC voltages
● 160
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 160 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
• Small size
• Easy to control their speeds
• Widely available in all sizes
• Good torque-speed characteristics
• a stator;
• a rotor;
• brushes and a commutator.
The stator generates a stationary magnetic field that surrounds the rotor. This field is
generated by either permanent magnets placed around the rotor, or by electromagnetic
windings surrounding the rotor.
The rotor is also called the armature and it is made up of windings which produce magnetic
field when energized by applying a DC voltage. The magnetic poles of the rotor are attract-
ed to opposite magnetic poles of the stator, thus causing the rotor to turn.
The commutator is placed on the axle of a BDC motor and as the motor turns, carbon
brushes provide a supply voltage to the rotor windings through the commutator. The brush-
es come in contact with different segments of the commutator, thus providing the required
supply voltage to different windings of the rotor. Notice that commutator is part of the rotor
and as the rotor turns, so does the commutator.
● 161
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 161 11/10/2022 13:55
PID-based Practical Digital Control
flux densities compared to externally supported magnetic fields. There is also a risk of
demagnetization which can stop the motor from functioning. Figure 10.3 shows the circuit
diagram of a permanent-magnet BDC motor.
● 162
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 162 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
● 163
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 163 11/10/2022 13:55
PID-based Practical Digital Control
Servo motors are normally operated with PWM type pulses (positive-going squarewave
shaped pulses) with a period of 50 Hz (20 ms period). In most types, a 1.5-ms pulse puts
the motor in a stationary position, a 1-ms pulse turns the motor 90 degrees to one direc-
tion, and a 2-ms pulse turns the motor 90 degrees in the opposite direction. Some types
of servo motors are modified such that they rotate continuously. Figure 10.8 shows a small
servo motor.
● 164
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 164 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
as in printers, plotters, PCB drilling machines, and any other applications requiring precise
control of the rotor position. Stepper motors suffer from relatively low torque.
Basically, there are two types of stepper motors: unipolar and bipolar. The main difference
between these two types is the applied voltage levels. Unipolar stepper motors operate
with positive voltages only (e.g., 0 and +12 V). Bipolar motors, on the other hand, operate
with positive and negative voltages (e.g. –5 V and +5 V). As shown in the images, unipo-
lar motors require an additional wire in the middle of each coil. Bipolar motors have the
advantages that they produce larger torques (since the current flows in the entire coil and
generates stronger electromagnetic field) and require one less wire for operation.
• Torque
• Speed
• Accuracy
• Operating voltage
• Cost
• Physical size and weight
● 165
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 165 11/10/2022 13:55
PID-based Practical Digital Control
Figure 10.10 shows the circuit diagram of the motor where R (in ohms) and L (in henries)
are the resistance and inductance of the motor windings, V (in volts) is the applied DC volt-
age, J (in kg.m2/s2) is the inertial of the load attached to the motor, and Ve (in volts) is the
back emf generated by the motor.
The torque generated by the motor is proportional to the current through the motor wind-
ings and it can be written as:
T = KT I (10.1)
Where KT is the motor torque constant and i (in ampères) is the current
The back emf is proportional to the motor angular speed W (in rad/s) and is given by:
Ve = KE W (10.2)
Notice that W = dΘ/dt where Θ is the angle rotated by the motor (in radians). KE is the
motor back emf constant.
Using Kirchoff's law, you can write the following equation about the motor circuit:
V – Ve = Ri + L di/dt (10.3)
or,
also,
T = J dW / dt (10.5)
● 166
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 166 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
i = J / KT dW / dt (10.6)
(10.7)
In small motors the inductance L is very small and can be neglected. Equation (10.7) then
becomes:
(10.8)
Equation (10.8) is a first order equation. Using the Laplace transforms where s is the Lap-
lace operator, you can rewrite it as:
(10.9)
or
(10.10)
When a step voltage VO is applied across the motor terminals the motor speed increases
exponentially until it settles down at a final value. The step response of the motor (i.e.,
the motor speed when a sudden step voltage is applied) can be derived by multiplying the
transfer function by 1/s and then taking the inverse Laplace transform. The result is given
below:
(10.11)
Initially the speed is 0, and it increases exponentially, having a final value of W(t) = VO /
KE. Figure 10.11 shows the typical step response of a brushed DC motor.
● 167
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 167 11/10/2022 13:55
PID-based Practical Digital Control
Notice that the term T = R J / KT KE is the motor time constant of the motor and this is the
time it takes for the motor to reach 63% of its final value.
• Operating voltage: 12 V
• Gearbox ratio: 30:1
• Rated torque: 1.5 kg/cm
• Rated speed 170 rpm
• Rated current: 530 mA
• No load speed: 216 rpm
• No load current: 150 mA
• Stall current: 2.5 A
• Encoder counts: 360 per revolution of the motor shaft
A small mounting bracket is available from the manufacturers. For the purpose of the
projects in this book, the motor is mounted on a small wooden plate using the mounting
bracket. A plastic wheel is connected to its shaft so that the motor shaft can be observed
as is rotates (see Figure 10.13).
● 168
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 168 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
The motor comes with a small 6-way JST connector having six colored wires with the fol-
lowing functions:
The Hall sensor encoder used in this project operates between +3.5 V to +20 V, with its
outputs being open-collector hence requiring pull-ups to whatever signal level is required.
Encoder works by observing changes to the magnetic field created by a magnet attached
the motor shaft. As the motor rotates, the encoder outputs will trigger periodically.
An incremental encoder provides a specified amount of pulses in one rotation of the encod-
er. In a two-phase encoder, like the one used here, the output consists of two lines of puls-
es (an "A" and "B" channel) that are offset in order to determine rotation (Figure 10.14).
This phasing between the two signals is called quadrature. The speed of a motor can be
determined by counting the number of pulses generated by one phase of an encoder. The
direction of the motor is determined from the phase difference of the two encoder outputs
(Figure 10.15).
● 169
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 169 11/10/2022 13:55
PID-based Practical Digital Control
Block Diagram: The block diagram of the project is shown in Figure 10.16. In this project,
the type LMD18200 H bridge motor controller module is used. The module (Figure 10.17)
is a H bridge where the speed and the direction of rotation of a motor can be controlled.
The speed is controlled by sending PWM waves to the chip, and the direction of rotation is
controlled by setting or clearing a direction control bit.
● 170
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 170 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
• Up to 3 A continuous current
• Supply voltage up to 55 V
• TTL- and CMOS-compatible inputs
• Motor speed and direction control
• Thermal shutdown
• Motor stop (break) input
The LMD18200 controller module has the following screw terminal configuration:
● 171
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 171 11/10/2022 13:55
PID-based Practical Digital Control
Table 10.1 shows the operational logic table of the LMD18200 controller.
1 1 1 Break
1 0 1 Break
0 X 1 Break
● 172
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 172 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
The frequency of the PWM depends upon the speed of the Timer/Counter which in turn
depends upon counter's clock divided by a pre-scaler value. The pre-scaler is 3 bits wide
and is stored in the three least significant bits (LSb) of the Timer/Counter registers CS02,
CS01, and CS00. The Timer/Counter registers are TCCR0B, TCCR1B, and TCCR2B. Notice
that the pairs of PWM pins have the same frequency. For example, PWM on pins 11 and 3
are controlled by Timer/Counter TCCR2B, pins 9 and 10 are controlled by TCCR1B, and pins
5 and 6 are controlled by TCCR0B.
● 173
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 173 11/10/2022 13:55
PID-based Practical Digital Control
The default values of the PWM frequencies at boot time are as follows:
In order to change the PWM frequency, you must re-load the three least significant bits of
the required Timer/Counter registers. The values and corresponding PWM frequencies for
PWM pins 11 and 3 are given below (these statements must be included in the setup()
function of the program):
For example, to set the PWM frequency to 980.39 Hz use the following statement inside
the setup() function:
The program listing is shown in Figure 10.22 (program: Motor1). At the beginning of the
program, DIR and PWM are assigned to port pins 2 and 3 respectively. Inside the setup()
function the ports are configured as output. Function Rotate has two character arguments:
direction and speed. If the direction is c (clockwise) then the DIR pin of the LMD18200
module is set to LOW. If on the other hand the direction is a (anticlockwise) then the DIR
pin of the LMD18200 module is set HIGH. If the speed is f (fast) then PWM voltage with
50% (i.e., a value of 128) duty cycle is sent to the PWM pin. If on the other hand the speed
is s (slow) then the PWM duty cycle is set to 25% (i.e., a value of 64).
/*****************************************************************
* MOTOR SPEED AND DIRECTION CONTROL USING AN IC
* =============================================
*
* This is a simple motor speed and direction control project
* using the LMD18200 motor control module. Pins 3 and 2 of the
* Arduino Uno are connected to pins PWM and DIR of the LMD18200
* respectively. A +12V external power supply is used to power the
* motor.
*
* File : Motor1
* Date : July 2022
* Author: Dogan Ibrahim
● 174
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 174 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
*****************************************************************/
#define PWM 3 // PWM pin
#define DIR 2 // DIR pin
//
// Configure DIR as output
//
void setup()
{
pinMode(DIR, OUTPUT); // Direction is output
pinMode(PWM, OUTPUT); // PWM is output
}
//
// This function rotates the motor. Argument direction can be 'c'
// for clockwise or 'a' for anticlockwise. Argument speed can be
// 'f' for fast or 's' for slow
//
void Rotate(char direction, char speed)
{
if(direction == 'c')
digitalWrite(DIR, LOW); // Direction control
else
if(direction == 'a')digitalWrite(DIR, HIGH);
//
// The motor is rotated as follows:
// 5 seconds clockwise and fast
// 5 seconds clockwise and slow
// 5 seconds anticlockwise and fast
// 5 seconds anticlockwise and slow
//
void loop()
{
Rotate('c', 'f'); // clockwise, fast
delay(5000);
Rotate('c', 's'); // clockwise, slow
delay(5000);
Rotate('a', 'f'); // anticlockwise, fast
delay(5000);
● 175
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 175 11/10/2022 13:55
PID-based Practical Digital Control
#-------------------------------------------------------------------
# MOTOR SPEED AND DIRECTION CONTROL
# =================================
#
# This is a simple motor speed and direction control project
# using the LMD18200 motor control module. Pins 2 and 3 of the
# Raspberry Pi are connected to pins DIR and PWM of the
# LMD18200 respectively. A +12V external power supply is used
# to power the motor.
#
# File : Pimotor1.py
# Date : July 2022
# Author: Dogan Ibrahim
#----------------------------------------------------------------------
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
DIR = 2 # DIR port
PWM = 3 # PWM port
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(PWM, 1000)
● 176
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 176 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
#
# This function rotates the motor with the given direction and speed
#
def Rotate(direction, speed):
if direction == 'c':
GPIO.output(DIR, 0)
else:
if direction == 'a':
GPIO.output(DIR, 1)
if speed == 'f':
p.ChangeDutyCycle(50) # HALF FULL speed
else:
if speed == 's':
p.ChangeDutyCycle(25) # QUARTER FULL SPEED
return
while True:
Rotate('c', 'f')
time.sleep(5)
Rotate('c', 's')
time.sleep(5)
Rotate('a', 'f')
time.sleep(5)
Rotate('a', 's')
time.sleep(5)
Block Diagram: The block diagram of the project is same as in Figure 10.16. The speed
of the motor is easily found by counting the number of pulses either from one or from both
encoders within a given time. For example, if only the rising edges of phase A are counted
every second, then the speed of the motor shaft after the gears can be calculated and ex-
pressed in RPM.
Circuit Diagram: Figure 10.24 shows the circuit diagram of the project. In this project, the
Hall sensor output B (purple wire) is connected to the MCU with a pull-up resistor enabling
the sensor pulses to be counted and the motor speed to be calculated. Additionally, the
LMD18200 module is connected to the MCU with the PWM and DIR pins connected to port
pins 3 and 4, respectively.
● 177
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 177 11/10/2022 13:55
PID-based Practical Digital Control
Encoder pulses are received using one of the external interrupt inputs of the Arduino Uno.
Program Listing: The Arduino Uno has two external interrupt pins at GPIO ports: 2 and
3. Pin 2 corresponds to interrupt number 0 and pin 3 corresponds to interrupt number
1. When the attachInterrupt(interrupt number,….,….) function is used to 'connect'
an interrupt to a function you have to specify the interrupt number as the first argument
of the function. Alternatively, you can use function attachInterrupt(digitalPinToInter-
rupt(pin number),……,…) and specify the GPIO pin number as the external interrupt pin.
Figure 10.25 shows the program listing of the project (program: Motor2). Phase B is as-
signed to pin number 2 and this pin is attached to interrupt service routine called Encod-
erISR. Variable interval is set to 1 second. Inside the EncoderISR the value of variable
Count is incremented by one.
Function millis() returns the number of milliseconds that elapsed since the program start-
ed running on the Arduino Uno. Inside the program loop, the elapsed milliseconds since the
last time is calculated and if this value is greater than or equal to the interval (1 second)
then it is assumed that a second has elapsed. At the end of one second, the speed of the
motor shaft after the gears is determined in RPM and then displayed on the Serial Monitor
of the Arduino IDE. Notice that the Arduino delay function is not used here to create one
second timing interval for the Count since it gives inaccurate results when this function
is interrupted by an external or a timer interrupt. Instead, the mills() function is used to
create a one second timing interval. Figure 10.26 shows the speed displayed in RPM on the
Serial Monitor.
/*****************************************************************
* MOTOR SPEED SENSE USING ENCODER
* ===============================
*
* In this project the speed of the motor is measured using the Hall
* Effect sensor with a magnetic disc attached to the shaft of the
* motor.
*
* The speed (RPM) of the motor is found by counting the number
● 178
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 178 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
//
// Configure Encoder Phase A as input. Also, attach the Encoder A
// output to external interrupt 0 (GPIO pin 2). The interrupt
// service routine is named EncoderISR and is when an interrupt
// occurs (an encoder pulse is generated). External interrupts
// are generated on the rising edge (LOW to HIGH) of the encoder
//
void setup()
{
pinMode(DIR, OUTPUT); // Direction is output
pinMode(PWM, OUTPUT); // PWM is output
Serial.begin(9600);
pinMode(PhaseB, INPUT); // Phase A is input
attachInterrupt(digitalPinToInterrupt(2), EncoderISR, RISING);
Rotate();
}
● 179
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 179 11/10/2022 13:55
PID-based Practical Digital Control
//
// Wait until a second has elapsed and then calculate the speed
// of the motor in RPM and display the speed on the Serial Monitor.
// The interval is set to 1000ms (1 second). When
// CurrentMillis-previousMillis = interval
// then it is assumed that a second has elapsed
//
//
// This function rotates the motor so that we can measure its speed
//
void Rotate()
{
digitalWrite(DIR, LOW);
analogWrite(PWM, 20); // Roate the motor
}
void loop()
{
unsigned long CurrentMillis = millis();
if(CurrentMillis - previousMillis >= interval)
{
Pulses = Count; // Copy of Count
previousMillis = CurrentMillis;
Count = 0; // Clear Count
RPM = Pulses * 60.0 / 90.0; // Calculate RPM
Serial.println(RPM); // Display motor speed
}
}
● 180
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 180 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
Block Diagram: Figure 10.27 shows the block diagram of the project.
Circuit diagram: The circuit diagram is shown in Figure 10.28. The I2C LCD is connected
to pins SDA (A4) and SCL (A5) of the Arduino Uno.
● 181
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 181 11/10/2022 13:55
PID-based Practical Digital Control
Program listing: Figure 10.29 shows the program listing (Program: Motor3). The pro-
gram is very similar to Figure 10.25 but here the motor speed is displayed on LCD every
second.
/*****************************************************************
* DISPLAY MOTOR SPEED ON LCD
* ==========================
*
* In this project the speed of the motor EMG30 is measured using
* the built-in encoder attached to the shaft of the motor and the
* speed is displayed on LCD in RPM
*
* File : Motor3
* Date : July 2022
* Author: Dogan Ibrahim
*****************************************************************/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
//
// Configure Encoder Phase A as input. Also, attach the Encoder A
// output to external interrupt 0 (GPIO pin 2). The interrupt
// service routine is named EncoderISR and is when an interrupt
// occurs (an encoder pulse is generated). External interrupts
// are generated on the rising edge (LOW to HIGH) of the encoder
//
● 182
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 182 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
void setup()
{
lcd.init(); // Initialize LCD
lcd.backlight(); // Backlight ON
pinMode(DIR, OUTPUT); // Direction is output
pinMode(PWM, OUTPUT); // PWM is output
pinMode(PhaseB, INPUT); // Phase A is input
attachInterrupt(digitalPinToInterrupt(2), EncoderISR, RISING);
Rotate();
}
//
// Wait until a second has elapsed and then calculate the speed
// of the motor in RPM and display the speed on the Serial Monitor.
// The interval is set to 1000ms (1 second). When
// CurrentMillis-previousMillis = interval
// then it is assumed that a second has elapsed
//
//
// This function rotates the motor so that we can measure its speed
//
void Rotate()
{
digitalWrite(DIR, LOW);
analogWrite(PWM, 20); // Rotate the motor
}
void loop()
{
unsigned long CurrentMillis = millis();
if(CurrentMillis - previousMillis >= interval)
{
Pulses = Count; // Copy of Count
previousMillis = CurrentMillis;
Count = 0; // Clear Count
RPM = Pulses * 60.0 / 90.0; // Calculate RPM
lcd.clear(); // Clear LCD
lcd.setCursor(0,0); // Cursor at 0,0
lcd.print(RPM); // Display RPM
}
}
● 183
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 183 11/10/2022 13:55
PID-based Practical Digital Control
Block Diagram: The block diagram of the project is same as in Figure 10.16. The speed
of the motor is easily found by counting the number of pulses either from one or from both
encoders in a given time. For example, if only the rising edges of phase A are counted every
second, then the speed of the motor shaft after the gears can be calculated and expressed
in RPM.
Circuit Diagram: Figure 10.30 shows the circuit diagram of the project. In this project, the
Hall sensor output B (purple wire) is connected to the MCU with a pull-up resistor, enabling
the sensor pulses can be counted and the motor speed to be calculated. Additionally, the
LMD18200 module is connected to the MCU with the PWM and DIR pins connected to port
pins 3 and 2, respectively. The encoder output is connected to GPIO21 (pin 40) through a
pull-up resistor.
Encoder pulses are received using external interrupts on the Raspberry Pi.
Program Listing: Figure 10.31 shows the program listing (Program: Pimotor2). The
function Rotate() rotates the motor at fixed speed. External interrupts are enabled on pin
GPIO21 on the rising edge of PhaseB. When an interrupt is detected, the program jumps
to the interrupt service routine (ISR) named EncoderISR. Variable Count is incremented
by 1 inside the ISR. The value of Count is then converted into RPM and stored in variable
RPM, which is then displayed on the screen every second.
#-------------------------------------------------------------------
# DISPLAY MOTOR SPEED
# ===================
#
# This program displays the motor speed on the screen
#
# File : Pimotor2.py
● 184
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 184 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
DIR = 2 # DIR at port 2
PWM = 3 # PWM at port 3
PhaseB = 21 # Phase B at port 40
global Count
Count = 0
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(PWM, 1000)
p.start(0) # Start PWM
#
# This function rotates the motor
#
def Rotate():
GPIO.output(DIR, 0)
p.ChangeDutyCycle(25) # QUARTER FULL SPEED
return
def EncoderISR(PhaeB):
global Count
Count = Count + 1
return
Rotate()
GPIO.add_event_detect(PhaseB, GPIO.RISING, callback = EncoderISR)
try:
while True:
EndTime = time.time() + 1
while time.time() - EndTime < 0:
pass
● 185
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 185 11/10/2022 13:55
PID-based Practical Digital Control
except KeyboardInterrupt:
p.ChangeDutyCycle(0)
p.stop()
Block Diagram: The block diagram of the project is shown in Figure 10.32.
Circuit Diagram: Figure 10.33 shows the circuit diagram of the project. Notice that the
TXS0102 logic level converter chip is used to convert the +3.3 V output of the Raspberry
Pi to +5 V to drive the LCD.
● 186
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 186 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
Program listing: Figure 10.34 shows the program listing (Program: Pimotor3). This pro-
gram is similar to Figure 10.31 but here the motor speed is displayed on the LCD.
#-------------------------------------------------------------------
# DISPLAY MOTOR SPEED ON LCD
# ==========================
#
# This program displays the EMG30 motor speed on I2C LCD
#
# File : Pimotor3.py
# Date : July 2022
# Author: Dogan Ibrahim
#----------------------------------------------------------------------
import RPi.GPIO as GPIO
import time
from RPLCD.i2c import CharLCD
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
lcd = CharLCD('PCF8574', 0x27)
DIR = 20 # DIR at port 2
PWM = 16 # PWM at port 3
PhaseB = 21 # Phase B at port 40
global Count
Count = 0
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(PWM, 1000)
p.start(0) # Start PWM
#
# This function rotates the motor
#
def Rotate():
GPIO.output(DIR, 0)
p.ChangeDutyCycle(25) # QUARTER FULL SPEED
return
● 187
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 187 11/10/2022 13:55
PID-based Practical Digital Control
Rotate()
GPIO.add_event_detect(PhaseB, GPIO.RISING, callback = EncoderISR)
try:
while True:
EndTime = time.time() + 1
while time.time() - EndTime < 0:
pass
except KeyboardInterrupt:
p.ChangeDutyCycle(0)
p.stop()
The block diagram and circuit diagram of the project are as in Figures 10.16 and 10.30,
respectively.
A PWM waveform with a duty cycle of 50% is applied to the motor through the LMD18200
module and the open-loop time response gets plotted by your Raspberry Pi.
Program listing: Figure 10.35 shows the program listing (Program: PiStep.py). Because
the motor time response is fast, the time axis was set to be in units of 100 ms. The motor
response is plotted in real-time by the program.
● 188
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 188 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
#-------------------------------------------------------------------
# MOTOR OPEN-LOOP STEP RESPONSE
# =============================
#
# This program applies a step of 50% PWM waveform to the motor.
# the open-loop time response is plotted by the program
#
# File : PiStep.py
# Date : July 2022
# Author: Dogan Ibrahim
#----------------------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
DIR = 2 # DIR at port 2
PWM = 3 # PWM at port 3
PhaseB = 21 # Phase B at port 40
global Count
Count = 0
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(PWM, 1000)
p.start(0) # Start PWM
def SetupPlot():
plt.axis([0, 20, 0, 150])
plt.title('Speed')
plt.xlabel('Time')
plt.ylabel('Speed')
plt.ion()
return
● 189
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 189 11/10/2022 13:55
PID-based Practical Digital Control
def EncoderISR(PhaeB):
global Count
Count = Count + 1
return
SetupPlot()
conv = 600.0 / 90.0
except KeyboardInterrupt:
p.ChangeDutyCycle(0)
p.stop()
The open-loop time response of the motor is shown in Figure 10.36. The motor speed
settles at 100 rpm at a 50% PWM input. The time constant of the motor can be calculated
when the output reaches 63% of its final value, and this is found to be 30 ms (0.03 s). The
transfer function can be derived to be:
or
● 190
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 190 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
Program listing: Figure 10.37 shows the motor PID control system (Program: PIDmotor.
py). At the beginning of the program the modules used are imported to the program, DIR,
PWM, and PhaseB pins are configured and variable Count is declared as a global variable.
Function SetupPlot() defines the axes and their titles. Function Init() initializes the PID
algorithm. The algorithm is implemented in the function PID(). The step response of the
closed-loop system with the PID is implemented in the main program loop. The sample
time is set to 0.2 seconds.
#----------------------------------------------------------
#
# PID MOTOR CONTROLLER
# ====================
#
# This is the PID motor controller program
#
# Author: Dogan Ibrahim
# File : PIDmotor.py
# Date : June, 2022
#----------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
import spidev
import math
GPIO.setwarnings(False)
● 191
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 191 11/10/2022 13:55
PID-based Practical Digital Control
GPIO.setmode(GPIO.BCM)
DIR = 2
PWM = 3
PhaseB = 21
GPIO.setup(PWM, GPIO.OUT)
GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(PhaseB, GPIO.IN)
GPIO.output(DIR, 0)
p = GPIO.PWM(PWM, 1000)
p.start(0)
global Count
Count = 0
global sk, Kp, T, Ti, pk, pk_1, ek_1, a, b, yk
#
# Setup real time plot
#
def SetupPlot():
plt.axis([0,100, 0,150]) # Axes limits
plt.title('Speed Response') # Title
plt.xlabel('Time (x 0.2s)') # X label
plt.ylabel('Speed') # Y label
plt.ion()
return
def EncoderISR(PhaseB):
global Count
Count = Count + 1
return
#
# This function initializes the LCD and displays SetTemp
#
def Init():
global sk, a, b, Kp, Ti, pk, pk_1, ek_1
sk = 100 # SetTemp
Kp = 0.03
T = 0.2
Ti = 0.05
Td = 0
a = Kp*T/Ti
b = Kp*Td/T
pk = 0.0
pk_1 = 0.0
● 192
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 192 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
ek_1 = 0.0
return
#
# This is the Proportional+Integral+Derivative algorithm function
#
def PID():
global yk, pk_1, ek_1
ek = sk - yk
pk = a*ek + pk_1
wk = Kp*ek
qk = b*(ek-ek_1)
uk = wk + pk + qk # PID output
if uk > 100.0: # Limit uk for PWM
uk = 100.0
if uk < 0.0: # Limit uk for PWM
uk = 0.0
p.ChangeDutyCycle(uk) # To PWM
pk_1 = pk # Update pk_1
ek_1 = ek # Update ek_1
return
try:
while i < 1000: # Do Forever
yk = Count * conv
PID()
i = i + 1
plt.scatter(i, yk,color='red')
plt.pause(0.00001)
Count = 0
EndTime = time.time() + 0.2
while time.time() - EndTime < 0:
pass
except KeyboardInterrupt:
p.ChangeDutyCycle(0)
p.stop()
● 193
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 193 11/10/2022 13:55
PID-based Practical Digital Control
C = 0.03, I = 3, D = 0
From these values, you calculate that, Kp = 0.03, Ti = 0.09. It was found that Kp = 0.03
and Ti = 0.05 gave good results in practice. Including derivative term did not improve the
response. Figure 10.39 shows the system response plotted in real-time with the program.
in this program the desired speed was set to 100 rpm. It is clear that the response settles
down to the desired value with no steady-state errors.
● 194
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 194 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
Notice that the encoder has two outputs, PhaseA and PhaseB. In this program, you have
used only one output. It is possible to use both outputs to improve the accuracy of the
speed of the motor. With both outputs the pulses received from the encoder will double
(see next project).
Circuit diagram: The circuit diagram of the project is shown in Figure 10.40. Notice that
both outputs of the encoder are used in this project.
Program listing: Figure 10.41 shows the motor PID controller program (Program: PID-
motor3). A timer interrupt scheme is used to set the PID sample time to 0.2 seconds. The
compare-register value for 0.2 seconds (i.e., 5 Hz) is given by:
which gives OCR1A = 3124. The PID algorithm is implemented by timer interrupts (func-
tion: ISR(TIMER1_COMPA_vect)), which equals every 0.2 seconds.
The motor speed is found by counting the encoder pulses. When using only one phase of
the encoder and counting pulses for one second, the speed in RPM is given by: Count ×
60.0 / 90.0. In this project you are counting the pulses for 0.2 seconds and therefore the
motor speed when only one phase is used is given by: Count × 300.0 / 90.0. When both
phases are used, you get double the count and therefore the motor speed is given by:
Count × 150.0 / 90.0.
Encoder outputs PhaseA and PhaseB are connected to pins 2 and 3 of Arduino Uno through
pull-up resistors. External interrupts are configured for both pins using the attachInter-
rupt() function, and the encoder pulses are counted (pins 2 and 3 are external interrupt
pins of the Arduino Uno) and stored in variable Count every sample time.
● 195
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 195 11/10/2022 13:55
PID-based Practical Digital Control
//--------------------------------------------------------------------------
// MOTOR PID CONTROLLER - USING TIMER INTERRUPTS
// =============================================
//
// This is the Arduino Uno PID motor controller. The desired motor speed
// is set to 100 RPM. PID algorithm is implemented in timer interrupt
//
// Author: Dogan Ibrahim
// File : PIDmotor3
// Date : July, 2022
//---------------------------------------------------------------------------
#define PhaseA 2 // Phase A
#define PhaseB 3 // Phase B
#define PWM 5 // PWM pin
#define DIR 4 // DIR pin
float sk, Kp, Ti, Td, pk, T, pk_1, ek, ek_1, a, b, yk, qk, wk, uk;
volatile unsigned long Count = 0; // Encoder count
float conv = 150.0 / 90.0;
//
// Configure PWM pin and Initialize variables
//
void setup()
{
TCCR2B = TCCR2B & B11111000 | B00000011;
pinMode(DIR, OUTPUT); // Direction is output
digitalWrite(DIR, LOW);
pinMode(PWM, OUTPUT); // PWM is output
pinMode(PhaseB, INPUT); // Phase B is input
pinMode(PhaseA, INPUT); // Phase A is input
attachInterrupt(digitalPinToInterrupt(PhaseB), EncoderISR, RISING);
attachInterrupt(digitalPinToInterrupt(PhaseA), EncoderISR2, RISING);
Serial.begin(19200);
sk = 100.0; // Desired speed
Kp = 0.5; // Proportional
T = 0.2; // Sample time
Ti = 3.5; // Integral
Td = 0.02; // Derivative
a = Kp*T/Ti;
b = Kp*Td/T;
pk = 0.0;
pk_1 = 0.0;
ek_1 = 0.0;
//
// Timer1 configuration for 0.2s (5Hz) interrupts
● 196
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 196 11/10/2022 13:55
Chapter 10 • DC Motor Control with Arduino and Raspberry Pi
//
TCCR1A = 0; // Set to 0
TCCR1B = 0; // Set to 0
TCNT1 = 0; // Set counter to 0
OCR1A = 3124; // Compare reg value
TCCR1B |= (1 << WGM12); // Turn on CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler=1024
TIMSK1 |= (1 << OCIE1A); // Enable Timer compare interrupt
sei(); // Enable all interrupts
}
//
// This is the interrupt service routine which is called everytime
// a pulse is generated from the encoder PhaseB output rising (going from
// LOW to HIGH)
//
void EncoderISR()
{
Count++;
}
//
// This is the interrupt service routine which is called everytime
// a pulse is generated from the encoder PhaseA output rising (going from
// LOW to HIGH)
//
void EncoderISR2()
{
Count++;
}
//
// This is the PID timer interrupt service routine
//
ISR(TIMER1_COMPA_vect)
{
yk = Count * conv;
Count = 0;
ek = sk - yk;
pk = a*ek + pk_1;
wk = Kp*ek;
qk = b*(ek - ek_1);
uk = wk + pk + qk;
if(uk > 255.0)
uk = 255;
if(uk < 0)
● 197
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 197 11/10/2022 13:55
PID-based Practical Digital Control
uk = 0;
analogWrite(PWM, uk);
pk_1 = pk;
ek_1 = ek;
Serial.println(yk);
}
void loop()
{
}
The following PID parameters were found by trial and error to be satisfactory:
The time response shown in Figure 10.42 was plotted using the Serial Plotter of Arduino
IDE. The desired speed was set to 100 RPM. The system settles to the desired speed with
no errors.
● 198
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 198 11/10/2022 13:55
Chapter 11 • Water Level Control
11.1 Overview
In Chapter 2 you saw various types of liquid level sensors. In this Chapter you will be using
an ultrasonic ((U/S) transmitter-receiver pair to control the level of water in a vessel or
another type of liquid container.
Figure 11.1 shows the commonly used ultrasonic transmitter-receiver module known as
the HC-SR04.
Block diagram: Figure 11.2 shows the block diagram of the project. The distance to the
obstacle will be displayed on the screen via the Serial Monitor of the Arduino IDE.
● 199
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 199 11/10/2022 13:55
PID-based Practical Digital Control
• Operating voltage: 5V
• Operating current: 2 mA
• Detection distance: 2 – 450 cm
• Input trigger signal: 10 µs TTL level
• Sensor angle: under 15 degrees
Therefore,
or
For example, if the duration of the echo signal is 294 microseconds then the distance to the
object is calculated as follows:
● 200
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 200 11/10/2022 13:55
Chapter 11 • Water Level Control
lthough it is very easy to write a program to measure the distance using the HC-SR04, a
library is available for the Arduino Uno for you to use.
Circuit diagram: Figure 11.4 shows the circuit diagram of the project. The interface be-
tween the Arduino Uno and the ultrasonic TX/RX module are as follows:
Before writing the program, you have to install the HC-SR04 library to our Arduino IDE.
The steps are:
• Download the library from the following web site. At the time of writing, this
book the library file was called Ultrasonic-3.0.0.zip
https://www.arduino.cc/reference/en/libraries/ultrasonic/
● 201
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 201 11/10/2022 13:55
PID-based Practical Digital Control
• Start your Arduino IDE and click Sketch Include Library Add .zip
Library.
Program listing: Figure 11.5 shows the program listing (Program: Unodistance). The
ultrasonic library is included at the beginning of the program. The Serial Monitor is initial-
ized to 9600 Baud in the setup() function. The main program loop reads and displays the
distance to an object in-front of the sensor module.
//--------------------------------------------------------------------------
// HC-SR04 ULTRASONIC DISTANCE MEASUREMENT
// =======================================
//
// This program uses the HC-SR04 ultrasonic module to measure distance
//
// Author: Dogan Ibrahim
// File : Unodistance
// Date : July, 2022
//---------------------------------------------------------------------------
#include <Ultrasonic.h>
Ultrasonic ultrasonic(13, 12); // trig=13, echo=12
int Distance;
void setup()
{
Serial.begin(9600); // Serial Monitor
}
void loop()
{
Distance = ultrasonic.read(); // Get distance
Serial.print("Distance (cm): "); // Heading
Serial.println(Distance); // Display distance
delay(500); // 500ms delay
}
● 202
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 202 11/10/2022 13:55
Chapter 11 • Water Level Control
Block diagram: Figure 11.7 shows the block diagram of the project.
Circuit diagram: The circuit diagram of the project is shown in Figure 11.8. Note that
the Echo pin output of the sensor is at +5 V which is not compatible with the Raspberry Pi
inputs. A resistive potential divider circuit can be used to lower this voltage to +3.3 V. Also,
the Trig input of the HC-SR04 module is pulled up to +5 V internally and this may damage
the Raspberry Pi output circuitry. A logic level converter module (Figure 11.9) is used to
connect the Trig and Echo pins to the Raspberry Pi without damaging its ports.
● 203
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 203 11/10/2022 13:55
PID-based Practical Digital Control
Although the program is simple, a HC-R04 library (called Bluetin_Echo library) is used
in this project to read the distance from the sensor to an obstacle. The steps to install
this library on your Raspberry Pi are as follows (for more information, see the website:
https://www.bluetin.io/sensors/python-library-ultrasonic-hc-sr04/ ):
• If you have the Bluetin_Echo library on the Raspberry Pi already, try upgrading
with the following command.
The trigger and echo pins and optionally the speed of sound must be specified and then
configured as follows. If the speed of sound is not specified, the default is 340 m/s:
● 204
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 204 11/10/2022 13:55
Chapter 11 • Water Level Control
The distance is returned in mm, cm, or in inches. It is possible to do more than one meas-
urement and return the average by specifying a samples value. For example, to do 3 meas-
urements and return the average distance in cm enter:
samples = 3
result = echo.read('cm', samples)
It is important to set enough delay between sensor echo reads for returning consistent val-
ues. The default for this property is 0.06 second (60 milliseconds) and can be changed with
the rest command. For example, to change the delay to 0.08 seconds (80 milliseconds),
use the following command:
echo.rest = 0.08
Program listing: Figure 11.10 shows the program listing (Program: RPdistance). At the
beginning of the program, Bluetin_Echo library is imported and the Trig and Echo pins are
defined. Then the speed of sound is defined as 340 m/s and number of samples to take is
set to 2. The program receives the distance in cm and displays the value on the screen. A
sample output is shown in Figure 11.11.
#-----------------------------------------------------------
# ULTRASONIC DISTANCE MESUREMENT
# ==============================
#
# This program measures the distance to an obstacle in-front
# of the ultrasonic sensor and displays the distance in cm
# 2 samples are taken and averaged in this program
#
# Author: Dogan Ibrahim
# File : RPdistance.py
# Date : July 2022
#------------------------------------------------------------
import RPi.GPIO as GPIO
import time
from Bluetin_Echo import Echo
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
● 205
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 205 11/10/2022 13:55
PID-based Practical Digital Control
Block diagram: Figure 11.12 shows the block diagram of the project. A water pump (Fig-
ure 11.13) is used in the project. This is model DIFCUL submersible pump operating at 12 V
and requiring about 1.3 A on full power. The ultrasonic TX/RX sensor module measures the
distance to the surface of the water and from this data you can calculate the level of water
inside the tank. The MOSFET switch used in this project is same as the one used in temper-
ature control projects in Chapters 8 and 9. An external 12-V, 3-A power supply is used to
power the water pump. The length of the tank (D) was 24 cm.
● 206
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 206 11/10/2022 13:55
Chapter 11 • Water Level Control
Circuit diagram: The circuit diagram of the project is shown in Figure 11.14. The Trig and
Echo pins of the ultrasonic sensor are connected to the Raspberry Pi through a logic level
converter module as in the previous project.
Program listing: Figure 11.15 shows the program listing (Program: PiStepWater,py).
The Bluetin_Echo library and other libraries used for plotting real-time graphs are import-
ed to the program. A PWM step input with duty cycle of 60% is applied to the pump and
● 207
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 207 11/10/2022 13:55
PID-based Practical Digital Control
the level of the water in the tank is plotted in real-time. D is the length of the tank, d is the
distance from the ultrasonic sensor to the surface of the water, and L is the level of water
in the tank which is given by: L = D - d
#-------------------------------------------------------------------
# WATER LEVEL CONTROL OPEN-LOOP STEP RESPONSE
# ===========================================
#
# This program applies a step input to the pump. Then open-loop
# time response is plotted by the program
#
# File : PiStepWater.py
# Date : July 2022
# Author: Dogan Ibrahim
#----------------------------------------------------------------------
from Bluetin_Echo import Echo
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
speed_of_sound = 340
echo = Echo(trigpin, echopin, speed_of_sound)
GPIO.setup(PWM, GPIO.OUT)
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(PWM, 1000)
p.start(0) # Start PWM
#
# Plot the graph axes and labels
#
def SetupPlot():
plt.axis([0, 100, 0, 10])
● 208
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 208 11/10/2022 13:55
Chapter 11 • Water Level Control
plt.title('Water Level')
plt.xlabel('Time')
plt.ylabel('Level (cm)')
plt.ion()
return
SetupPlot()
i = 0
#
# Send step input to the motor with 10% PWM. Sample every second
#
try:
while True:
EndTime = time.time() + 1
while time.time() - EndTime < 0:
pass
except KeyboardInterrupt:
p.ChangeDutyCycle(0)
p.stop()
The step response of the open-loop system is shown in Figure 11.16. After 3 seconds of de-
lay, the water level increases and settles down at 7.9 cm. The time constant of the system
is the point where the response rises to 63.2% of its final value. In Figure 11.16 this corre-
sponds to 19 seconds. Therefore, the open-loop transfer function of the system is given by:
or
● 209
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 209 11/10/2022 13:55
PID-based Practical Digital Control
The block diagram and circuit diagram of the project are as in Figure 11.12 and Figure
11.14, respectively.
Figures 11.17 through 11.20 show a proposed construction of the project. The ultrasonic
sensor module is placed at the top of the tank. A hole is made at the bottom part of the tank
so that the water can be released. A pipe is connected to the pump and water is pumped
from the reservoir into the tank. Both the reservoir and the tank are plastic containers. A
container was placed under the tank so that the released water can be collected.
● 210
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 210 11/10/2022 13:55
Chapter 11 • Water Level Control
● 211
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 211 11/10/2022 13:55
PID-based Practical Digital Control
Program listing: Figure 11.21 shows the PID program listing (Program: PiWaterPID.
py). This program is similar to the temperature control or the motor control PID programs,
but here the water level is measured and controlled.
#-------------------------------------------------------------------
# PID WATER LEVEL CONTROL
# =======================
#
# This is the PID water level controller program. The desired water
# level is set to 12cm
#
# File : PiWaterPID.py
# Date : July 2022
# Author: Dogan Ibrahim
#----------------------------------------------------------------------
from Bluetin_Echo import Echo
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
● 212
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 212 11/10/2022 13:55
Chapter 11 • Water Level Control
speed_of_sound = 340
echo = Echo(trigpin, echopin, speed_of_sound)
GPIO.setup(pwm, GPIO.OUT)
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(pwm, 1000)
p.start(0) # Start PWM
#
# Plot the graph axes and labels
#
def SetupPlot():
plt.axis([0, 100, 0, 20])
plt.title('Water Level')
plt.xlabel('Time')
plt.ylabel('Level (cm)')
plt.ion()
return
#
# Initialize
#
def Init():
global sk, a, b, Kp, Ti, pk, pk_1, ek_1
sk = 10 # SetTemp
Kp = 25.0
T = 1.0
Ti = 20.0
Td = 0.0
a = Kp*T/Ti
b = Kp*Td/T
pk = 0.0
pk_1 = 0.0
ek_1 = 0.0
return
#
# This is the Proportional+Integral+Derivative algorithm function
#
def PID():
● 213
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 213 11/10/2022 13:55
PID-based Practical Digital Control
Init()
SetupPlot()
i = 0
#
# Send step input to the motor with 10% PWM. Sample every second
#
try:
while True:
d = echo.read('cm', 1) # Dist to surface
yk = D - d # Water level
PID()
plt.scatter(i, yk, color='Red') # Plot water level
i = i + 1
plt.pause(0.00001)
EndTime = time.time() + 1
while time.time() - EndTime < 0:
pass
except KeyboardInterrupt:
p.ChangeDutyCycle(0)
p.stop()
The PID parameters were initially found using the PID Loop Simulator software and they
were adjusted to get a good response from the system. Figure 11.22 shows the PID loop
simulator response produced by the system. The PID loop simulator suggested the follow-
ing values for PI type controller. Note that it was found that adding the derivative term had
not improved the response much and was therefore not used.
● 214
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 214 11/10/2022 13:55
Chapter 11 • Water Level Control
Kp = 20, I = 1
Converting this to our PID parameters you get: Kp = 20 and Kp / Ti = 1 or Ti = 20. These
were the initial values suggested by the simulator program. A good response was obtained
by setting Kp = 25 and Ti = 20.
Figure 11.23 shows the closed-loop time response of the system as plotted by the Rasp-
berry Pi program. The water level settles down at 10 cm with no overshoot, exactly as
required.
● 215
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 215 11/10/2022 13:55
PID-based Practical Digital Control
Block diagram: The block diagram of the project is shown in Figure 11.24.
Circuit diagram: Figure 11.25 shows the circuit diagram of the project.
● 216
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 216 11/10/2022 13:55
Chapter 11 • Water Level Control
Program listing: Figure 11.27 shows the program listing (Program: PIDWaterL). This
program is similar to the PID temperature controller program but here the manipulated
variable is the distance instead of the temperature. The PI controller was found to be sat-
isfactory for this system. Adding the derivative term did not appear to improve the system
response and consequently was not used. The following PID parameters were found to be
satisfactory after a few trial and errors:
Kp = 20, Ti = 11, Td = 0
In this program, the delay function is used to create the one second sample time delay. You
could have also used a timer interrupt for more accurate delays.
//--------------------------------------------------------------------------
// WATER LEVEL PID CONTROLLER
// ==========================
//
// This is the PID water level controller for the Arduino Uno. The desired
// water level is set to 10 cm
//
// Author: Dogan Ibrahim
// File : PIDWaterL
// Date : July, 2022
//---------------------------------------------------------------------------
#include <Ultrasonic.h>
Ultrasonic ultrasonic(13, 12); // trig=13, echo=12
● 217
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 217 11/10/2022 13:55
PID-based Practical Digital Control
float d, D = 24.0;
float sk, Kp, Ti, Td, pk, pk_1, ek, ek_1, a, b, yk, qk, wk, uk, T;
int MOSFET = 3;
//
// Configure PWM pin and Initialize variables
//
void setup()
{
Serial.begin(19200);
pinMode(MOSFET, OUTPUT);
sk = 7.0;
Kp = 20.0; // Proportional
T = 1.0; // Sample time
Ti = 11.0; // Integral
Td = 0.0; // Derivative
a = Kp*T/Ti;
b = Kp*Td/T;
pk = 0.0;
pk_1 = 0.0;
ek_1 = 0.0;
}
//
// This is the PID function
//
void PID()
{
ek = sk - yk;
pk = a*ek + pk_1;
wk = Kp*ek;
qk = b*(ek - ek_1);
uk = wk + pk + qk;
if(uk > 255.0)
uk = 255;
if(uk < 0)
uk = 0;
analogWrite(MOSFET, uk);
pk_1 = pk;
ek_1 = ek;
}
void loop()
{
d = ultrasonic.read();
● 218
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 218 11/10/2022 13:55
Chapter 11 • Water Level Control
yk = D - d;
PID();
Serial.println(yk);
delay(1000); // Wait 1 seconds
}
Figure 11.28 shows the closed-loop system time response. The water level settled at 7 cm
without any noticeable overshoot.
● 219
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 219 11/10/2022 13:55
PID-based Practical Digital Control
12.1 Overview
In this Chapter you will use an LED and an LDR sensor positioned next to it. The aim here
is to control the brightness of the LED using a PID controller so that it remains constant no
matter what the environment light level is.
• Turn ON the LED and place a dark paper between the LED and LDR.
• Set the potentiometer to somewhere near 10 kΩ value.
• Run the program to plot the time response.
• Remove the paper quickly after about 10 seconds. The change in the LDR
output will be displayed as the step response of the system.
Block diagram: Figure 12.1 shows the block diagram of the project.
Circuit diagram: The circuit diagram of the project is shown in Figure 12.2. A 100-Ω re-
sistor is used in series with the LED and the LED is connected to port pin GPIO21 (pin 40).
Using a low value resistance makes the LED shine brighter. Using the 100-Ω resistor the
current through the LED is approximately: 3.3 V – 2 V / 100 = 13 mA. A 10-kΩ potentiom-
eter is used in series with the LDR and the voltage across the LDR is read by the Raspberry
Pi through an external ADC. The LDR was placed close to the LED so that the brightness
of the LED could be measured by the LDR. MCP3002 ADC chip is used to read the analog
output voltage across the resistor in series with the LDR. This reading is proportional to the
brightness of the LED.
● 220
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 220 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
Construction of the project: Figure 12.3 shows the project constructed on a breadboard.
Program listing: Figure 12.4 shows the program listing (Program: LEDLDR.py). A piece
of dark paper blocks the light from the LED to the LDR. The program turns ON the LED so
that the LDR reads a constant value. Remove the paper quickly to display the step time re-
sponse of the system. Normally, the input to the system is the brightness of the LED which
is measured in lux. In this project you will assume that the input is the raw value read from
the ADC, which ranges from 0 to 1023.
● 221
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 221 11/10/2022 13:55
PID-based Practical Digital Control
#----------------------------------------------------------
#
# LED BRIGHTNES STEP RESPONSE
# ===========================
#
# This program is used to determine the step time response
#
# Author: Dogan Ibrahim
# File : LEDLDR.py
# Date : July, 2022
#----------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
import time
import spidev
import math
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
LED = 21
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, 1)
#
# Setup real time plot
#
def SetupPlot():
plt.axis([0,60, 0,600]) # Axes limits
plt.title('LED BRIGHTNESS') # Title
plt.xlabel('Time (x0.1 seconds)') # X label
plt.ylabel('BRIGHTNESS') # Y label
plt.ion()
return
#
# This function returns the ADC result in variable
#
def Get_ADC_Data(channel_no):
● 222
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 222 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
Figure 12.5 shows the step time response of the system. In this graph, the horizontal axis
is in units of 0.1 seconds. Notice that the time delay (approximately 10–20 ms) is ignored.
Also, the timing and graph plotting of Raspberry Pi is not accurate. When the dark paper is
removed this is like setting the input to full brightness and in Figure 12.5 this corresponds
to 575.
Assuming that the ADC reading is the system input, the open-loop system transfer function
is found to be approximately (see Figure 12.6):
Gain = 1
Time constant = 80 ms
Therefore:
● 223
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 223 11/10/2022 13:55
PID-based Practical Digital Control
The block diagram and circuit diagram are as in Figure 12.1 and Figure 12.2, respectively.
PID parameters: The previously discussed PID Loop Simulator program was used to get
the initial settings for the PID parameters. As shown in Figure 12.7, the following parame-
ters were initially found to be satisfactory:
C = 0.01, I = 1, Td = 0
● 224
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 224 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
Program listing: Figure 12.8 shows the program listing (Program: RPLED.py). The LED
brightness is controlled by sending a PWM waveform from the Raspberry Pi. The duty cycle
of this waveform sets the average voltage sent to the LED, and hence the perceived bright-
ness. The desired LED brightness value was set to 600. As shown in Figure 12.9, the LED
brightness settled to the desired value with no overshoot.
It is recommended to possibly cover the LED-LDR pair with a carton box so that ambient
light does not affect the LDR output. This is necessary, since if you want to set the bright-
ness at, say, 800 then this will require the LDR to be darker, which cannot be implemented
by the system. The system can only increase the LDR readings by applying a PWM wave-
form to the LED.
#----------------------------------------------------------
#
# LED BRIGHTNES PID CONTROL
# =========================
#
# This program is the LED brightness PID controller
#
# Author: Dogan Ibrahim
# File : RPLED.py
# Date : July, 2022
#----------------------------------------------------------
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import RPi.GPIO as GPIO
● 225
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 225 11/10/2022 13:55
PID-based Practical Digital Control
import time
import spidev
import math
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
#
# Generate PWM waveform at PWM pin with frequency of 1000 Hz
#
p = GPIO.PWM(pwm, 1000)
p.start(0) # Start PWM
#
# Setup real time plot
#
def SetupPlot():
plt.axis([0,60, 0,1000]) # Axes limits
plt.title('LED BRIGHTNESS') # Title
plt.xlabel('Time (x0.1 seconds)') # X label
plt.ylabel('BRIGHTNESS') # Y label
plt.ion()
return
#
# Initialize
#
def Init():
global sk, a, b, Kp, Ti, pk, pk_1, ek_1
sk = 600 # SetTemp
Kp = 0.01
T = 0.1
Ti = 0.01
Td = 0.0
a = Kp*T/Ti
b = Kp*Td/T
pk = 0.0
pk_1 = 0.0
● 226
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 226 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
ek_1 = 0.0
return
#
# This is the Proportional+Integral+Derivative algorithm function
#
def PID():
global yk, pk_1, ek_1
ek = sk - yk
pk = a*ek + pk_1
wk = Kp*ek
qk = b*(ek-ek_1)
uk = wk + pk + qk # PID output
if uk > 100.0: # Limit uk for PWM
uk = 100.0
if uk < 0.0: # Limit uk for PWM
uk = 0.0
p.ChangeDutyCycle(uk) # To PWM
pk_1 = pk # Update pk_1
ek_1 = ek # Update ek_1
return
#
# This function returns the ADC result in variable
#
def Get_ADC_Data(channel_no):
ADC = spi.xfer2([1, (2 + channel_no) << 6, 0])
rcv = ((ADC[1] & 15) << 6) + (ADC[2] >> 2)
return rcv
Init()
SetupPlot() # Setup plot
i = 0
try:
while i < 400: # Do Forever
yk = Get_ADC_Data(0)
PID()
i = i + 1
plt.scatter(i, yk,color='red')
plt.pause(0.00001)
EndTime = time.time() + 0.1
while time.time() - EndTime < 0:
pass
except KeyboardInterrupt:
● 227
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 227 11/10/2022 13:55
PID-based Practical Digital Control
p.ChangeDutyCycle(0)
p.stop()
Figure 12.10 shows the closed-loop system time response when disturbance was applied
to the system by shining light very briefly on the LDR (or by removing the cover on top of
the LED-LDR pair).
Figure 12.11 shows the LED-LDR mounted next to each other on the breadboard.
● 228
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 228 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
Block diagram: Figure 12.12 shows the block diagram of the project.
Circuit diagram: The circuit diagram of the project is shown in Figure 12.13. Your LED is
connected to port 3 which is a PWM output.
● 229
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 229 11/10/2022 13:55
PID-based Practical Digital Control
Program listing: Figure 12.15 shows the program listing (Program: ARDLED). The LED
brightness is controlled by sending a PWM waveform from the Arduino Uno. The following
PID parameters were found to give satisfactory response:
//--------------------------------------------------------------------------
// LED BRIGHTNESS PID CONTROL
// ==========================
//
// This is the PID controller to control the brightness of the LED
//
// Author: Dogan Ibrahim
// File : ARDLED
// Date : July, 2022
//---------------------------------------------------------------------------
float sk, Kp, Ti, Td, pk, pk_1, ek, ek_1, a, b, yk, qk, wk, uk, T;
int LED = 3;
int LDR = A0;
//
// Configure PWM pin and Initialize variables
//
void setup()
{
Serial.begin(19200);
pinMode(LED, OUTPUT);
sk = 600.0;
Kp = 0.15; // Proportional
● 230
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 230 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
//
// This is the PID function
//
void PID()
{
ek = sk - yk;
pk = a*ek + pk_1;
wk = Kp*ek;
qk = b*(ek - ek_1);
uk = wk + pk + qk;
if(uk > 255.0)
uk = 255;
if(uk < 0)
uk = 0;
analogWrite(LED, uk);
pk_1 = pk;
ek_1 = ek;
}
void loop()
{
yk = analogRead(LDR);
PID(); // Call PID
Serial.println(yk);
delay(100); // Wait 100 ms
}
Figure 12.16 shows the closed-loop time response of the system. The system settles to 600
as desired, with no overshoot.
● 231
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 231 11/10/2022 13:55
PID-based Practical Digital Control
Figure 12.17 shows the system response when a disturbance was applied by removing the
cover over the LED-LDR for a short time. The system recovers from the disturbance in a
short time.
● 232
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 232 11/10/2022 13:55
Chapter 12 • PID-based LED Brightness Control
The block diagram and circuit diagram of the project are as in Figures 12.12 and Figure
12.13 respectively.
Program listing: Figure 12.18 shows the program listing (Program: ARDLEDLIB).
//--------------------------------------------------------------------------
// LED BRIGHTNESS PID CONTROLLER - USING PID LIBRARY
// =================================================
//
// This is the Arduino Uno PID LED brightness controller using the IDE library. #
// The desired brightness is set to 600
//
// Author: Dogan Ibrahim
// File : ARDLEDLIB
// Date : June, 2022
//---------------------------------------------------------------------------
#include <PID_v1.h>
int LDR = A0;
int LED = 3;
//
//Define Variables we will be connecting to
//
double Setpoint, Input, Output;
//
//Specify the PID tuning parameters
//
double Kp=0.02, Ki=0.2, Kd=0.0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
//
// Configure PWM pin and Initialize variables
//
void setup()
{
Setpoint = 500.0;
myPID.SetSampleTime(50);
Serial.begin(19200);
pinMode(LED, OUTPUT);
myPID.SetMode(AUTOMATIC);
}
void loop()
{
Input = analogRead(LDR); // Calculate temperature
● 233
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 233 11/10/2022 13:55
PID-based Practical Digital Control
● 234
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 234 11/10/2022 13:55
Index
Index
A Derivative-only Controller 72
A201 30 Desktop mode 132
Absolute pressure sensors 31 DHT11 25
Acceleration 29 DHT22 25
Accuracy 17 DIFCUL 206
AD590 24 Differential pressure sensors 31
AD592 24 digital control system 13
ADC 12 digital encoder 14
ADXL203 29 Digital PID Controller 89
Analog sensors 16 Digital sensors 16
Analog Temperature Sensors 18 digital system 53
attachInterrupt 178 Digital Temperature Sensors 25
Auto-tuning 85 DIR 191
displacement flow meters 33
B Distance to object 200
BDC Motors 161 disturbance 232
Bluetin_Echo 204 disturbance response 141
BMP280 32 Disturbance response 232
Brett Beauregard 155 disturbances 11
Brushed DC Motors 161 duty cycle 124
Brushless DC Motors 165 Dynamic response 17
dynamic system 11
C
Chien-Hrones-Reswick 80 E
chromel/alumel junction 18 Echo pin 203
Ciancone-Marline 80 Electric Motors 160
Cohen-Coon 78 EMG30 168
commutator 161 EncoderISR 178
Compare match register 152 error signal 11
compensator 12 e-Tape Liquid Level Sensor 34
Compound-wound 163
Compute 156 F
continuous-time system 11 feedback 11
control algorithm 12 feedback control 11
controller 12 First-order Systems 37
FlexiForce 30
D Flow Sensors 35
DAC 12 Force Sensors 30
Dahlin 69 FS2012 36
damping ratio 45 FT-210 36
DC Motor Control 160
dead-beat 69 G
derivative control 69 gauge 30
Derivative Kick 86 GetDirection 156
● 235
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 235 11/10/2022 13:55
PID-based Practical Digital Control
● 236
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 236 11/10/2022 13:55
Contents
● 237
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 237 11/10/2022 13:55
PID-based Practical Digital Control
THIGH 99
Thin-film RTDs 21
Thonny IDE 132
time constant 40
Time Delay 50
Time Response 39
timer interrupts 152
TLOW 99
TMP36 25
Tools 159
torque 160
Trig input 203
tuning the controller 75
two-phase encoder 169
TXS0102 110
Type K 18
Tyreus-Luyben 80
U
ultimate gain 82
ultrasonic techniques 33
Ultrasonic transmitter-receiver 33
Unit ramp function 58
Unit step function 57
V
Velocity and Acceleration Sensors 28
W
water level 206
Water Level Control 199
water pump 206
Wire-wound RTDs 21
Y
YF-S201 35
Z
zero-order hold 55
Ziegler and Nichols 76
Z-Transform 57
● 238
PID-based Practical Digital Control With Raspberry Pi and Arduino Uno 220802 v3 UK.indd 238 11/10/2022 13:55
books books
PID-based Practical
PID-based Practical