0% found this document useful (0 votes)
238 views16 pages

HERMS PID Controller Guide

This document describes deriving a PID controller to control the temperature of a Hot Liquid Tun (HLT) for a homebrewing system to within 0.5°C. It contains the derivation of a discrete-time PID algorithm using bilinear transformation to transform the continuous PID transfer function into the z-domain. It then simplifies the resulting equation and combines terms to arrive at the final discrete-time PID algorithm suitable for implementation on a computer to control the HLT temperature.

Uploaded by

Peter Uhule
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
238 views16 pages

HERMS PID Controller Guide

This document describes deriving a PID controller to control the temperature of a Hot Liquid Tun (HLT) for a homebrewing system to within 0.5°C. It contains the derivation of a discrete-time PID algorithm using bilinear transformation to transform the continuous PID transfer function into the z-domain. It then simplifies the resulting equation and combines terms to arrive at the final discrete-time PID algorithm suitable for implementation on a computer to control the HLT temperature.

Uploaded by

Peter Uhule
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

PID Controller Calculus for HERMS home-brewing system

1. Introduction

This document describes the derivation of a PID controller that can be implemented in the brew
application. The PID controller should be capable of controlling the temperature of the Hot
Liquid Tun (HLT, 90 L) to within 0.5 °C.
The HLT contains a heating element of 3 kW, which is driven by the PID controller output signal
Gamma [0..10 %]. The HLT temperature sensor is a LM92 12 bit + sign bit, ± 0.33°C accurate
temperature sensor.

This document contains the following information


• Chapter 2: Derivation of a time-discrete algorithm for a PID controller
• Chapter 3: Derivation of an improved algorithm (a so-called ‘type C’ PID controller)
• Chapter 4: Description of algorithms for finding the optimum set of Kc, Ti, Td and Ts
values of the PID controller
• Chapter 5: Experimental results
• An appendix containing the C source listing

2. Derivation of a time-discrete algorithm for a PID controller


w(t) e(t) PID u(t) Hot-Liquid y(t)
Controller Tun (HLT)

y(t)

The generic equation1 for a PID controller in the time-continuous domain is:


 1 de(t ) 
Ti ∫
u (t ) = K c . e(t ) + e (τ ) d τ + Td . eq. 01

 dt 

With: Kc = Kp Proportional Gain (for our temperature controller, unity is [% / °C])


Ti = Kc / Ki Time-constant Integral gain [sec.]
Td = Kd / Kc Time-constant Derivative gain [sec.]
Ts Sample period (default value is 5 seconds)
w(t) Set point (SP) value for temperature. Is also called Tset_hlt in this document
e(t) error signal = set-point w(t) – process variable y(t) = Tset_hlt – Thlt
u(t) PID output signal, also called Gamma, ranges from [0..100 %]
y(t) process variable PV = measured temperature (also called Thlt in this
document)

The corresponding equation in the s-domain is then:

 
U ( s)  1 
= K c .1 + + Td .s  eq. 02
E (s) 
 Ti .s 

This transfer function has no real practical use, since the gain is increased as the frequency
increases. Practical PID controllers limit this high frequency gain, using a first order low-pass
filter. This results in the following transfer function:

1
This is the ideal, textbook version of a continuous-time PID controller. See [1], page 54.

PID Controller Calculus, V3.20 Page 1/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system


U (s)  1 T .s  
 1 Td 
= K c .1 + + d  = K c .1 + + eq. 03
E (s) 
 Ti .s γ .s + 1  
 Ti .s γ + s −1 

where γ is a small time-constant and may be set as 10% of the value of the derivative term Td.

Equation eq. 03 needs to transferred to the Z domain to make it suitable for implementation on a
computer. This is done using the bilinear transformation (given in eq. 04):

2 1 − z −1
The bilinear transformation formula is given with: s = . eq. 04
Ts 1 + z −1
Now use the bilinear transformation, given in equation eq. 04, to transform equation eq.
03 onto an equivalent form in the Z –domain:

 
U ( z)  T 1 + z −1 (
Td . 1 − z −1 ) 
= K c .1 + s . −1
+  eq.05-1
E( z)  2.Ti 1 − z T 


( 2
)
γ . 1 − z −1 + s . 1 + z −1 ( ) 

This transforms into:


U ( z)  T 1 + z −1 1 − z −1 
= K c .1 + s . + 2.T .  eq.05-2
Ts + 2.γ + z .(Ts − 2.γ ) 
−1 d −1
E( z)  2.Ti 1 − z

 
 
U ( z)  Ts 1 + z −1 2.Td 1 − z −1 
= Kc . 1 + . + . eq.05-3
E( z)  2.Ti 1 − z −1 Ts + 2.γ T − 2.γ 
 1 + z −1. s 
 Ts + 2.γ 

Now, let all separate parts share the same denominator:


     2 
 1 − z −1 .1 + z −1. Ts − 2γ  + Ts . 1 + z −1 .1 + z −1. Ts − 2γ
( ) ( )  +
2Td
(
. 1 − z −1  )
  
Ts + 2γ  2.Ti  Ts + 2γ 
U ( z)
= K c .    Ts + 2γ eq.05-4
 
E( z)  T − 2γ  
 ( )
1 − z −1 .1 + z −1. s 
Ts + 2γ  
  

Rewrite equation eq.05-4 and combine all parts of z-1 and z-2 with each other:
  
 1 + z −1. Ts − 2γ − z −1 − z −2 . Ts − 2γ + Ts .1 + z −1 . Ts − 2γ + z −1 + z −2 . Ts − 2γ  + 2Td . 1 − 2 z −1 + z −2
 Ts + 2γ  Ts + 2γ
( ) 
U ( z)  Ts + 2γ Ts + 2γ 2Ti  Ts + 2γ 
= K c . 
E( z) T − 2.γ T − 2.γ
 1 + z −1 . s − z −1 − z −2 . s 
 Ts + 2.γ Ts + 2.γ 
 
... eq.05-5

Simplifying the various terms results in:

PID Controller Calculus, V3.20 Page 2/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

  Ts2   Ts .(Ts − 2γ ) 
  − 4γ − 4Td  2γ − Ts + + 2Td  
 Ts 2Td −1  Ti  + z −2 .  2.Ti 
 1 + 2T + T + 2γ + z . T + 2γ  Ts + 2γ 
 i s
 s
 
U ( z)    
= K c .  (eq.05-6)
E( z) 4γ T − 2γ
 1 − z −1. − z −2 . s 
 Ts + 2γ Ts + 2γ 
 
 
 
 

Now define the following parameters:


 Ts2 
 − 4γ − 4Td 
 Ts 2Td   Ti 
k0 = K c .1 + +  ; k1 = K c .
 
 2Ti Ts + 2γ  
Ts + 2γ

 
(eq.06)
 T 2 γ .T 
 2.γ − Ts + s − s + 2Td 
k2 = K c .  ;
2Ti Ti 4γ Ts − 2γ
p1 = ; p2 =
 Ts + 2γ  Ts + 2γ Ts + 2γ
 
 

Substituting these parameters back into equation 05-6 results in:

( ) (
U ( z ). 1 − p1.z −1 − p2 .z −2 = E ( z ). k0 + k1.z −1 + k2 .z −2 ) (eq. 07)

Transforming equation eq. 07 back to the time-discrete form results in:

u[ k ] = p1.u[ k − 1] + p2 .u[k − 2] + k0 .e[ k ] + k1.e[ k − 1] + k 2 .e[ k − 2] (eq. 08)

Equation eq.08 is implemented with pid_reg2() and eq.07 is implemented with init_pid2() (see
appendix for full C source listing).

PID Controller Calculus, V3.20 Page 3/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

3. Derivation of a Type C PID controller


There are three types of PID equations (see http://bestune.50megs.com/typeabc.htm) , with type
C being the preferred one. Equation eq. 01 (and ultimately eq. 08) are type A equations, since the
P- and the D-term both contain the set-point. Any changes in the set-point may cause an
unwanted change in the PID output u(t).
Removing the set-point from the D-term results in a type B controller. The type C controller has
also removed the set-point from the P-term, resulting in an even better PID controller
implementation.

Starting with equation 01 and differentiating both sides gives equation eq. 09

 e(t ) d 2e(t ) 
du (t ) = K c . de(t ) + + Td . (eq. 09)

 Ti dt 

Transforming equation eq. 09 to the time-discrete domain, using backwards differentiation,


results in equation eq. 10:
 T .e T 
uk = uk −1 + K c .(ek − ek −1 ) + s k + d .(ek − 2.ek −1 + ek −2 ) (eq. 10)
 Ti Ts 

The D-term needs to be filtered with a Low-Pass Filter (LPF) to make it more practical. The
transfer function of a simple LPF is given with:

1
H (s) = , with γ typically set to about 10% of the Td value. (eq.11a)
γ .s + 1

The equivalent Z transfer function is:

H ( z) =
( )
Ts . 1 + z −1
=
Ts
.
1 + z −1
(eq.11b)
( ) ( )
2.γ . 1 − z −1 + Ts . 1 + z −1 Ts + 2.γ 1 + Ts − 2.γ .z −1
Ts + 2.γ

The equivalent function is the time-discrete domain is then:

2.γ − Ts Ts
lpf k= .lpf k −1 + .(ek + ek −1 ) (eq.11c)
2.γ + Ts Ts + 2.γ

Equation eq.10 can now also be written as:


 T .e T 
uk = uk −1 + K c .(ek − ek −1 ) + s k + d .(lpf k − 2.lpf k −1 + lpf k −2 ) (eq. 12)
 Ti Ts 

Equation 12 is still a type A equation (“textbook PID”), because the Kc term depends on ek and
the input of the LPF also has ek as input. Equation eq.11c and eq.12 are implemented with
pid_reg3() and with init_pid3() (see appendix for full C source listing).

PID Controller Calculus, V3.20 Page 4/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

Because it is not easy to transform this equation into a full type C controller (because of the
addition in eq.11c), we will revert to equation eq.10 and transform this equation into a type C
equation (eq. 13):
 T .e T 
uk = uk −1 + K c .(ek − ek −1 ) + s k + d .(ek − 2.ek −1 + ek −2 ) (eq .10)
 Ti Ts 

 T .e T  (eq .13)
u k = u k −1 + K c .SPk − PVk − (SPk −1 − PVk −1 ) + s k + d .(SPk − PVk − 2.(SPk −1 − PVk −1 ) + SPk −2 − PVk −2 )
 T i T s 
Here, PV is the process variable, which is Thlt (the actual temperature of the HLT). Furthermore
SP is the set-point or the reference temperature.

If we assume that the set-point is not changed, we can state the PVk = PVk-1 = PVk-2. With this,
the equation transforms into:
 T .e T 
u k = uk −1 + K c .(PVk −1 − PVk ) + s k + d .(2.PVk −1 − PVk − PVk −2 ) (eq .14)
 Ti Ts 

Equation 14 is a type C PID controller and normally referred to as a Takahaski PID controller.
This equation is implemented with pid_reg4() and with init_pid4() (see appendix for full C
source listing).

PID Controller Calculus, V3.20 Page 5/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

4. Finding the optimum set of PID parameters


Finding the optimum parameters for a PID controller can be difficult. Optimum means that the
set-point temperature is reached as quickly as possible with overshoot minimised.

Three well-known algorithms for determining the PID parameters are described here:
• Ziegler-Nichols open-loop: set PID controller to a certain output and determine slope
and dead-time of HLT system
• Ziegler-Nichols closed-loop: measure step-response
• Cohen-Coon: also a closed-loop method. Measure step-response
• Integral of the time weighted absolute error (ITAE): results in the best performance. The error
signal is minimised (over time).

Some terms are frequently used in this document:


• Dead-time Θ: this is the time-delay between the initial step and a 10% increase in the
process variable (the HLT temperature in our case).
• Khlt: the gain of the HLT-system. The HLT-system receives the Gamma value (PID
output) as input and has the HLT temperature as output. Unity of Khlt is [°C / %].
• τhlt: the time-constant of the HLT-system. The HLT-system can be described with a
first-order process model with time-delay (FOPTD). The transfer function for this
model is:
K hlt .e −θ .s
HLT ( s ) =
τ hlt .s + 1
• a*: the normalised slope of the step response. Equal to ∆T / (∆t. ∆p) with:
o ∆T : change in temperature [°C]
o ∆t : change in time [seconds]
o ∆p: change in PID controller output [%]

With these three parameters, the optimum PID parameters are determined using table 1 on the
next page (values are given both for PID operation and for PI-only operation):

PID Controller Calculus, V3.20 Page 6/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

Method: / Kc [% / °C] Ti [seconds] Td [seconds]


Parameter:
Ziegler-Nichols 1,2 Ti = 2,0.θ Td = 0,5.θ
Open-loop Kc =
θ .a *
Ziegler-Nichols 0,9 Ti = 3,33.θ --
Open-loop Kc =
θ .a *
Ziegler-Nichols 1,2.τ hlt Ti = 2,0.θ Td = 0,5.θ
Closed-loop Kc =
K hlt .θ
Ziegler-Nichols 0,9.τ hlt Ti = 3,33.θ --
Closed-loop Kc =
K hlt .θ
Cohen-Coon τ hlt  θ 4 32.τ hlt + 6.θ 4.τ hlt
Kc = . +  Ti = θ . Td = θ .
K hlt .θ  4.τ hlt 3  13.τ hlt + 8.θ 2.θ + 11.τ hlt
Cohen-Coon τ hlt  θ 9 30.τ hlt + 3.θ --
Kc = . +  Ti = θ .
K hlt .θ  12.τ hlt 10  9.τ hlt + 20.θ
ITAE-Load 1,357  θ 
−0 , 947
τ  θ 
0 , 738
 θ 
0 , 995

Kc = .  Ti = hlt .  Td = 0,381.τ hlt . 


K hlt  τ hlt  0,842  τ hlt   τ hlt 
ITAE-Load 0,859  θ
−0 , 977
τ  θ 
0 , 680 --
Kc = . Ti = hlt . 
K hlt  τ hlt
 0,674  τ hlt 
Table 1: optimum PID parameters for the various methods

To be able to find these three parameters accurately, two experiments need to be conducted.
These two experiments are described in the next two paragraphs.
The last paragraph (§ 4.3) shows the calculated PID parameters for all these methods.

PID Controller Calculus, V3.20 Page 7/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

4.1 Experiment 1: Determine dead-time Θ of HLT-system


Manually set the PID-controller output (“gamma”) to a certain value (e.g. 20 %). In case of a
heavy load, 100 % is recommended (more accurate), but if you don’t know the performance of
the system, a lower value to start with is better. The temperature starts to increase and follows the
curve in figure 1.

Figure 1: Open-loop response of the system

Calculate the average slope of the rise (a = ∆T / ∆t) by using regression analysis if possible.
Calculate the normalised slope a*, which is defined as: a* = a / ∆p.
The dead-time Θ is defined as the time between t0 and t1 (by using regression analysis, this can
be done quite accurately).

Experimental data:2 HLT filled with 85 L water, lid off


19:08:20 t0, the PID controller output gamma was set to 100 %, T1 = 47,41 °C
Step-response up to 55.00 °C, ∆T = 7,59 °C
19 :12 :25 Thlt = 48,18 °C (≥ T1 + 10%.∆T = 48,17 °C)
19 :27 :21 Thlt = 54,25 °C (≥ T1 + 90%.∆T = 54,24 °C)

Regression analysis of the data between 19 :12 :25 and 19:27 :21 resulted in the following:
y = a.x + b = 0,0334x + 48,278 R2 = 0,9995
Here, every data-point for x represents 5 seconds. Therefore, the average slope a is equal to:
a = 0,0334 °C / 5 sec. = 6,68E-03 °C/second (which is 0,4 °C/minute)
Now solve where this curve hits the Tenv line:

2
Measurements are recorded in HLT_open_loop_response_260404.xls

PID Controller Calculus, V3.20 Page 8/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

x = (47.41 – 48.278) / 6.68E-03 = -130 seconds (or 2 minutes and 10 seconds)


The dead-time moment is then 19:12:25 – 2:10 = 19:10:15
Therefore, the dead-time Θ = 19:10:15 – 19:08:20 = 1:55 = 115 seconds
The normalised slope a* is equal to :
a* = a / ∆p = 6,68E-05 °C/(%.second)

4.2 Experiment 2: Determine gain Khlt and time-constant τhlt of HLT-system


Manually set the PID-controller output (“gamma”) to a certain value (e.g. 20 %). The
temperature starts to increase and follows the curve in figure 2.

Figure 2: Step response of the system

Because of the large time-constant presumably present in the HLT system, the step response is
not very accurate in determining the dead-time Θ. This is the mean reason to conduct two
experiments (theoretically, the step-response would give you all the required information to
determine the three parameters).

Experimental data:3 HLT filled with 85 L water, lid off


09:49:04 t0, the PID controller output gamma was set to 20 %, T1 = 19,20 °C
20:24:03 Experiment stopped, T = 52,98 °C.
Regression analysis (2nd order polynomial) used to find maximum.
Maximum found at 21:20:44 (8300 ticks of 5 seconds). T2 = 52,989 °C
∆T = 52,989 – 19,20 = 33,789 °C
T(t = 1/3.τhlt) = T1 + 0,283 * ∆T = 28,762 °C => 1/3.τhlt = 6599 seconds
T(t = τhlt) = T1 + 0,632 * ∆T = 40,555 °C => τhlt = 16573 seconds
Solve for τhlt: τhlt – 1/3. τhlt = 16573 – 6599 => τhlt = 14961 seconds
Solve for Gain Khlt: Khlt = ∆T / ∆p = 33,789 °C / 20 % = 1,689 °C / %

3
Measurements are recorded in HLT_step_response_290404.xls

PID Controller Calculus, V3.20 Page 9/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

4.3 Calculation of PID parameters for the various methods


In the previous paragraphs, the following parameters were found:
• dead-time Θ = 115 seconds
• Gain Khlt = 1,689 °C / %
• Time-constant τhlt = 14961 seconds
• Normalised slope a* = a / ∆p = 6,68E-05 °C/(%.second)

Kc [%/°C] Ti [sec] Td [sec]


Ziegler-Nichols Open Loop 156,2 230,0 57,5 PID
117,2 383,0 - - PI
Ziegler-Nichols Closed Loop 92,4 230,0 57,5 PID
69,3 383,0 - - PI
Cohen-Coon 102,8 282,2 41,8 PID
69,4 377,2 - - PI
ITAE-Load 80,8 489,0 44,9 PID
59,2 810,2 - - PI
Table 2: Calculation of parameters for the various methods

PID Controller Calculus, V3.20 Page 10/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

Referenced Documents

Referenced documents
Version Date Title: Author Tag
2005 “Digital Self-Tuning Controllers”, V. Bobál, J. [01]
ISBN 1-85233-980-2, Springer Böhm, J.
Fessl, J.
Machácek

Version History
Date Version Description
01-02-2003 V1.0 First version for display on web-site
08-03-2004 V2.0 - Removed implementation 1 and 3
- Added description of types A, B and C
- Added type C PID algorithm
- Added auto-tuning algorithm + example
10-03-2004 V2.1 Incorrect dead-time calculation
09-05-2004 V2.2 - Added Cohen-Coon + ITAE methods
- Added two experiments + description
- Calculations are updated
10-05-2004 V3.0 - Derivation with Taylor series replaced by exact derivation. Current
implementation worked well, but simulation showed problems
13-05-2004 V3.01 - Update of document, corrected a few mistakes
- Add low-pass filter to the D-term of the PID-controllers
13-05-2004 V3.02 Some textual changes
09-05-2006 V3.03 Error corrected in equation eq.09
26-02-2007 V3.10 - Referenced documents added
- Typo corrected in eq.08
- Block diagram added
- Source code shortened, non-relevant code removed
- More consistent naming of variables
- More elaborate derivation in chapter 2.
06-05-2011 V3.20 - Better derivation for pid_reg3() and pid_reg4(). Pid_reg3() is now a
type A PID controller with filtering of the D-action. Pid_reg4() is now
a pure Takahashi type C PID controller.

PID Controller Calculus, V3.20 Page 11/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

Appendix I: C-programs (pid_reg.h, pid_reg.c)


/*==================================================================
File name : $Id: pid_reg.h,v 1.7 2004/05/13 20:51:00 emile Exp $
Author : E. vd Logt
------------------------------------------------------------------
Purpose : This file contains the defines for the PID controller.
------------------------------------------------------------------
$Log: pid_reg.h,v $
Revision 1.7 2004/05/13 20:51:00 emile
V0.1 060302 First version
==================================================================
*/
#ifndef PID_REG_H
#define PID_REG_H

#ifdef __cplusplus
extern "C" {
#endif

// These defines are needed for loop timing and PID controller timing
#define TWENTY_SECONDS (400)
#define TEN_SECONDS (200)
#define FIVE_SECONDS (100)
#define ONE_SECOND (20)
#define T_50MSEC (50) // Period time of TTimer in msec.

#define GMA_HLIM (100.0) // PID controller upper limit [%]


#define GMA_LLIM (0.0) // PID controller lower limit [%]

typedef struct _pid_params


{
double kc; // Controller gain from Dialog Box
double ti; // Time-constant for I action from Dialog Box
double td; // Time-constant for D action from Dialog Box
double ts; // Sample time [sec.] from Dialog Box
double k_lpf; // Time constant [sec.] for LPF filter
double k0; // k0 value for PID controller
double k1; // k1 value for PID controller
double k2; // k2 value for PID controller
double k3; // k3 value for PID controller
double lpf1; // value for LPF filter
double lpf2; // value for LPF filter
int ts_ticks; // ticks for timer
int pid_model; // PID Controller type [0..3]
double pp; // debug
double pi; // debug
double pd; // debug
} pid_params; // struct pid_params

//--------------------
// Function Prototypes
//--------------------
void init_pid2(pid_params *p);
void pid_reg2(double xk, double *yk, double tset, pid_params *p, int vrg);
void init_pid3(pid_params *p);
void pid_reg3(double xk, double *yk, double tset, pid_params *p, int vrg);
void init_pid4(pid_params *p);
void pid_reg4(double xk, double *yk, double tset, pid_params *p, int vrg);

#ifdef __cplusplus
};
#endif
#endif

PID Controller Calculus, V3.20 Page 12/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

/*==================================================================
Function name: init_pid2(), pid_reg2()
init_pid3(), pid_reg3(), init_pid4(), pid_reg4()
Author : E. vd Logt
File name : $Id: pid_reg.c,v 1.6 2004/05/13 20:51:00 emile Exp $
------------------------------------------------------------------
Purpose : This file contains the main body of the PID controller.
For design details, please read the Word document
"PID Controller Calculus".

In the GUI, the following parameters can be changed:


Kc: The controller gain
Ti: Time-constant for the Integral Gain
Td: Time-constant for the Derivative Gain
Ts: The sample period [seconds]
------------------------------------------------------------------
$Log: pid_reg.c,v $
Revision 1.6 2004/05/13 20:51:00 emile
==================================================================
*/
#include "pid_reg.h"

static double ek_1; // e[k-1] = SP[k-1] - PV[k-1] = Tset_hlt[k-1] - Thlt[k-1]


static double ek_2; // e[k-2] = SP[k-2] - PV[k-2] = Tset_hlt[k-2] - Thlt[k-2]
static double xk_1; // PV[k-1] = Thlt[k-1]
static double xk_2; // PV[k-2] = Thlt[k-1]
static double yk_1; // y[k-1] = Gamma[k-1]
static double yk_2; // y[k-2] = Gamma[k-1]
static double lpf_1; // lpf[k-1] = LPF output[k-1]
static double lpf_2; // lpf[k-2] = LPF output[k-2]

void init_pid2(pid_params *p)


/*------------------------------------------------------------------
Purpose : This function initialises the PID controller, based on
the new Type A PID controller.
Variables: p: pointer to struct containing all PID parameters

Ts 2.Td
k0 = Kc.(1 + ---- + ------------)
2.Ti Ts + 2.k_lpf

Ts.Ts/Ti – 4.k_lpf - 4.Td


k1 = Kc.( ------------------------- )
Ts + 2.k_lpf

2.k_lpf – Ts + Ts.Ts/(2.Ti) – k_lpf.Ts/Ti + 2.Td


K2 = Kc.( ------------------------------------------------ )
Ts + 2.k_lpf

Returns : No values are returned


------------------------------------------------------------------*/
{
double alfa = p->ts + 2.0 * p->k_lpf; // help variable

p->ts_ticks = (int)((p->ts * 1000.0) / T_50MSEC);


if (p->ts_ticks > TWENTY_SECONDS)
{
p->ts_ticks = TWENTY_SECONDS;
}
if (p->ti > 0.001)
{
p->k0 = p->kc * (+1.0 + (p->ts / (2.0 * p->ti))
+ (2.0 * p->td / alfa));
p->k1 = p->kc * (p->ts * p->ts / p->ti - 4.0 * p->k_lpf – 4.0 * p->td);
p->k1 /= alfa;
p->k2 = 2.0 * p->k_lpf – p->ts + p->ts * p->ts / (2.0 * p->ti);
p->k2 += 2.0 * p->ti – p->k_lpf * p->ts / p->ti;
p->k2 *= p->kc / alfa;
} // if
//--------------------------------------------------
// u[k] = lpf1*u[k-1] + lpf2*u[k-2] + ....
//--------------------------------------------------
p->lpf1 = 4.0 * p->k_lpf / alfa;
p->lpf2 = (p->ts – 2.0 * p->k_lpf) / alfa;
} // init_pid2()

void pid_reg2(double xk, double *yk, double tset, pid_params *p, int vrg)
/*------------------------------------------------------------------
Purpose : This function implements the updated PID controller.
It is an update of pid_reg1(), derived with Bilinear
Transformation. It is a Type A controller.
This function should be called once every TS seconds.
Variables:
xk : The input variable x[k] (= measured temperature)
*yk : The output variable y[k] (= gamma value for power electronics)

PID Controller Calculus, V3.20 Page 13/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

tset : The setpoint value for the temperature


*p : Pointer to struct containing PID parameters
vrg: Release signal: 1 = Start control, 0 = disable PID controller
Returns : No values are returned
------------------------------------------------------------------*/
{
double ek; // e[k]

ek = tset - xk; // calculate e[k]


if (vrg)
{
*yk = p->lpf1 * yk_1 + p->lpf2 * yk_2; // y[k] = p1*y[k-1] + p2*y[k-2]
*yk += p->k0 * ek; // ... + k0 * e[k]
*yk += p->k1 * ek_1; // ... + k1 * e[k-1]
*yk += p->k2 * ek_2; // ... + k2 * e[k-2]
}
else *yk = 0.0;

ek_2 = ek_1; // e[k-2] = e[k-1]


ek_1 = ek; // e[k-1] = e[k]

// limit y[k] to GMA_HLIM and GMA_LLIM


if (*yk > GMA_HLIM)
{
*yk = GMA_HLIM;
}
else if (*yk < GMA_LLIM)
{
*yk = GMA_LLIM;
} // else

yk_2 = yk_1; // y[k-2] = y[k-1]


yk_1 = *yk; // y[k-1] = y[k]
} // pid_reg2()

void init_pid3(pid_params *p)


/*------------------------------------------------------------------
Purpose : This function initialises the Allen Bradley Type A PID
controller.
Variables: p: pointer to struct containing all PID parameters

Kc.Ts
k0 = ----- (for I-term)
Ti

Td
k1 = Kc . -- (for D-term)
Ts

The LPF parameters are also initialised here:


lpf[k] = lpf1 * lpf[k-1] + lpf2 * lpf[k-2]
Returns : No values are returned
------------------------------------------------------------------*/
{
p->ts_ticks = (int)((p->ts * 1000.0) / T_50MSEC);
if (p->ts_ticks > TWENTY_SECONDS)
{
p->ts_ticks = TWENTY_SECONDS;
}
if (p->ti == 0.0)
{
p->k0 = 0.0;
}
else
{
p->k0 = p->kc * p->ts / p->ti;
} // else
p->k1 = p->kc * p->td / p->ts;
p->lpf1 = (2.0 * p->k_lpf - p->ts) / (2.0 * p->k_lpf + p->ts);
p->lpf2 = p->ts / (2.0 * p->k_lpf + p->ts);
} // init_pid3()

void pid_reg3(double xk, double *yk, double tset, pid_params *p, int vrg)
/*------------------------------------------------------------------
Purpose : This function implements the type Allen Bradley Type A PID
controller. All terms are dependent on the error signal e[k].
The D term is also low-pass filtered.
This function should be called once every TS seconds.
Variables:
xk : The input variable x[k] (= measured temperature)
*yk : The output variable y[k] (= gamma value for power electronics)
tset : The setpoint value for the temperature
*p : Pointer to struct containing PID parameters
vrg: Release signal: 1 = Start control, 0 = disable PID controller
Returns : No values are returned
------------------------------------------------------------------*/
{

PID Controller Calculus, V3.20 Page 14/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

double ek; // e[k]


double lpf; //LPF output

ek = tset - xk; // calculate e[k] = SP[k] - PV[k]


//--------------------------------------
// Calculate Lowpass Filter for D-term
//--------------------------------------
lpf = p->lpf1 * lpf_1 + p->lpf2 * (ek + ek_1);

if (vrg)
{
//-----------------------------------------------------------
// Calculate PID controller:
// y[k] = y[k-1] + Kc*(e[k] - e[k-1] +
// Ts*e[k]/Ti +
// Td/Ts*(lpf[k] - 2*lpf[k-1]+lpf[k-2]))
//-----------------------------------------------------------
p->pp = p->kc * (ek - ek_1); // y[k] = y[k-1] + Kc*(e[k] - e[k-1])
p->pi = p->k0 * ek; // + Kc*Ts/Ti * e[k]
p->pd = p->k1 * (lpf - 2.0 * lpf_1 + lpf_2);
*yk += p->pp + p->pi + p->pd;
}
else *yk = 0.0;

ek_1 = ek; // e[k-1] = e[k]


lpf_2 = lpf_1; // update stores for LPF
lpf_1 = lpf;

// limit y[k] to GMA_HLIM and GMA_LLIM


if (*yk > GMA_HLIM)
{
*yk = GMA_HLIM;
}
else if (*yk < GMA_LLIM)
{
*yk = GMA_LLIM;
} // else
} // pid_reg3()

void init_pid4(pid_params *p)


/*------------------------------------------------------------------
Purpose : This function initialises the Allen Bradley Type C PID
controller.
Variables: p: pointer to struct containing all PID parameters
Returns : No values are returned
------------------------------------------------------------------*/
{
init_pid3(p); // identical to init_pid3()
} // init_pid4()

void pid_reg4(double xk, double *yk, double tset, pid_params *p, int vrg)
/*------------------------------------------------------------------
Purpose : This function implements the Takahashi PID controller,
which is a type C controller: the P and D term are no
longer dependent on the set-point, only on PV (which is Thlt).
The D term is NOT low-pass filtered.
This function should be called once every TS seconds.
Variables:
xk : The input variable x[k] (= measured temperature)
*yk : The output variable y[k] (= gamma value for power electronics)
tset : The setpoint value for the temperature
*p : Pointer to struct containing PID parameters
vrg: Release signal: 1 = Start control, 0 = disable PID controller
Returns : No values are returned
------------------------------------------------------------------*/
{
double ek; // e[k]
double lpf; //LPF output

ek = tset - xk; // calculate e[k] = SP[k] - PV[k]

if (vrg)
{
//-----------------------------------------------------------
// Calculate PID controller:
// y[k] = y[k-1] + Kc*(PV[k-1] - PV[k] +
// Ts*e[k]/Ti +
// Td/Ts*(2*PV[k-1] - PV[k] - PV[k-2]))
//-----------------------------------------------------------
p->pp = p->kc * (xk_1 - xk); // y[k] = y[k-1] + Kc*(PV[k-1] - PV[k])
p->pi = p->k0 * ek; // + Kc*Ts/Ti * e[k]
p->pd = p->k1 * (2.0 * xk_1 - xk - xk_2);
*yk += p->pp + p->pi + p->pd;
}
else { *yk = p->pp = p->pi = p->pd = 0.0; }

xk_2 = xk_1; // PV[k-2] = PV[k-1]

PID Controller Calculus, V3.20 Page 15/16


© ir. drs. E.H.W. van de Logt
PID Controller Calculus for HERMS home-brewing system

xk_1 = xk; // PV[k-1] = PV[k]

// limit y[k] to GMA_HLIM and GMA_LLIM


if (*yk > GMA_HLIM)
{
*yk = GMA_HLIM;
}
else if (*yk < GMA_LLIM)
{
*yk = GMA_LLIM;
} // else
} // pid_reg4()

PID Controller Calculus, V3.20 Page 16/16


© ir. drs. E.H.W. van de Logt

You might also like