258 CONTROLLER REALIZATION
/********************************************************************
DIGITAL CONTROLLER
==================
This program implements a second-order digital controller module on a PIC16F877 (or equivalent) microcontroller. The microcontroller operates with a 4MHz crystal. The analog input AN0 of the microcontroller is connected to the output sensor of the plant (y). The PORT B output of the microcontroller is connected to a AD7302 type D/A converter. The WR input of the controller is controlled from port pin RC0 of the microcontroller. The sampling interval is 0.01s (10ms) and the timer interrupt service routine is used to obtain the required sampling interval.
Program : Second Order Module.C
Date : July 2005
********************************************************************/
#include <pic.h> #define DA Write RC0
float DA LSB,AD LSB,a0,a1,a2, b1,b2,M1,M2,rk,rk 1,rk 2,ek,sk,yk,uk;
/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */
void Initialize AD(void)
{
}
/* This function initilizes the timer TMR0 so that interrupts can be generated at 10ms intervals */
void Initialize Timer(void)
{
}
/* This function reads data from the A/D converter and stores in variable yk */
void Read AD Input(void)
{
}
/* Interrupt Service Routine. The program jumps here every 10 ms */
void interrupt ISR(void) |
|
{ |
|
Read AD Input(); |
/* Read A/D input */ |
ek = sk - yk; |
/* Calculate error term */ |
rk = ek + M1; |
|
yk = a0*rk + M2; |
/* Calculate output */ |
uk = yk*DA LSB; |
|
PORTB = uk; |
/* Send to PORT B */ |
DA Write = 0; |
/* Write to D/A converter */ |
DA Write = 1; |
|
Figure 10.19 First program attempt (Continued )
|
|
|
MICROCONTROLLER IMPLEMENTATIONS |
259 |
rk 2 |
= rk 1; |
/* Update variables */ |
|
rk 1 |
= rk; |
|
|
M1 |
= -b1*rk 1 - b2*rk 2; |
|
|
M2 |
= a1*rk 1 + a2*rk 2; |
|
|
T0IF = 0; |
/* Re-enable timer interrupts */ |
|
}
/* Main Program. The main program initializes the variables, A/D converter, D/A converter etc. and then waits in an endless loop for timer interrupts to Occur every 10 ms */
main(void)
{
a0 |
= 1; a1 = 0.8; |
a2 = 1.2; |
|
b1 |
= 1.85; |
|
b2 = 0.92; |
|
M1 |
= 0; |
M2 = 0; |
rk = 0; |
rk 1 = 0; rk 2 = 0; |
sk = 1.0; |
|
|
|
DA LSB = 5000.0/1024.0; |
|
|
TRISA = 1; |
|
/* RA0 (AN0) is input */ |
TRISB = 0; |
|
/* PORT B is output */ |
TRISC = 0; |
|
/* RC0 is output */ |
DA Write = 1; |
|
/* Disable D/A converter */ |
Initialize AD(); |
/* Initialize A/D converter */ |
Initialize Timer(); |
/* Initialize timer interrupts */ |
ei(); |
|
/* Enable interrupts */ |
for(;;); |
|
/* Wait for an interrupt */ |
}
Figure 10.19 (Continued )
Initialize AD. This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller. As described in Chapter 3, the A/D converter is initialized by first selecting the reference voltage and the output data format using the ADCON1 register, and then selecting the A/D converter clock using the ADCON0 register. Thus, channel AN0 is configured by loading 0x8E into the ADCON1 register, and 0x41 into the ADCON0 register. Thus, the Initialize AD function is programmed as follows:
/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */
void Initialize AD(void)
{
ADCON1 |
= |
0 |
× |
8E; |
/* Configure |
AN0 for +5V reference */ |
ADCON0 |
= |
0 |
× |
41; |
/* Select A/D |
converter clock */ |
}
Read AD Input. This function starts the A/D converter and reads a sample at the end of the conversion. The conversion is started by setting the GO/DONE bit of ADCON0. The program
260 CONTROLLER REALIZATION
should then wait until the conversion is complete, which is indicated by the GO/DONE bit becoming zero. The high 2 bits of the converted data are in ADRESH, and the low 8 bits are in register ADRESL. The 10-bit converted data is extracted and stored in variable yk .
The Read AD Input function is programmed as follows:
/* This function reads data from the A/D converter and stores in variable yk */
void Read AD Input(void)
{
ADCON0 = 0 × 45; while(ADCON0 & 4) != 0); y high = ADRESH;
y low = ADRESL;
yk = 256.0*y high + y low; yk = yk*AD LSB;
}
/* Start A/D conversion */
/* Wait until conversion completes */ /* High 2 bytes of converted data */ /* Low byte of converted data */
/* Converted data in yk */ /* Sensor output in mV */
AD LSB converts the A/D value to into millivolts.
The complete program is shown in Figure 10.20.
10.5.2 Implementing First-Order Modules
In Section 10.2 we saw how a first-order module can be realized using adders, multipliers and delay elements. The first-order module is shown in Figure 10.21. The difference equations describing a first-order module were found to be
rk = ek − b1rk−1
and
uk = a0rk + a1rk−1.
If we let
M1 = −b1rk−1
and
M2 = a1rk−1,
then the difference equations for the first-order module becomes
rk = ek + M1
uk = a0rk + M2
The implementation of the first-order module is similar to the second-order module and an example is given below.
MICROCONTROLLER IMPLEMENTATIONS |
261 |
/****************************************************************************
DIGITAL CONTROLLER
==================
This program implements a second-order digital controller module on a PIC16F877 (or equivalent) microcontroller. The microcontroller operates with a 4MHz crystal. The analog input AN0 of the microcontroller is connected to the output sensor of the plant (y). The PORT B output of the microcontroller is connected to an AD7302 type D/A converter. The WR input of the controller is controlled from port pin RC0 of the microcontroller. The sampling interval is 0.01s (10ms) and the timer interrupt service routine is used to obtain the required sampling interval.
Program : Second Order Module.C
Date : July 2005
*****************************************************************************/
#include <pic.h> #define DA Write RC0
float DA LSB,AD LSB,a0,a1,a2, b1,b2,M1,M2,rk,rk 1,rk 2,ek,sk,yk,uk; float y high,y low;
/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */
void Initialize AD(void)
{
ADCON1 |
= |
0x8E; |
/* |
Configure AN0 for +5V reference |
*/ |
ADCON0 |
= |
0x41; |
/* |
Select A/D clock and channel */ |
|
}
/* This function initilizes the timer TMR0 so that interrupts can be generated at 10ms intervals */
void Initialize Timer(void)
{
T0CS = 0; |
/* Select f/4 clock for |
TMR0 */ |
PSA = 0; |
/* Select pre-scaler */ |
|
PS0 = 1; |
/* Set pre-scaler to 64 |
*/ |
PS1 = 0; |
/* PS2,PS1,PS0 = 101 */ |
|
PS2 = 1; |
|
|
TMR0 = 100; |
/* Load TMR0=100 */ |
|
T0IE = 1; |
/* Enable TMR0 interrupts */ |
T0IF = 0; |
/* Clear TMR0 interrupt flag */ |
*/
}
/* This function reads data from the A/D converter and stores in variable yk */
void Read AD Input(void)
{
ADCON0 = 0x45; |
/* |
Start A/D conversion */ |
While((ADCON0 & 4) != 0); |
/* |
Wait until conversion completes */ |
Figure 10.20 Complete program of the second-order controller (Continued )
262 |
CONTROLLER REALIZATION |
|
|
y high = ADRESH; |
/* High 2 bits of converted data */ |
|
y low = ADRESL; |
/* Low byte of converted data */ |
|
yk = 256.0*y high + y low; |
/* Converted data in yk */ |
|
yk = yk*AD LSB; |
/* Sensor output in mV */ |
} |
|
|
/* Interrupt Service Routine. The program jumps here every 10 ms */ |
void interrupt ISR(void) |
|
{ |
|
|
|
TMR0 = 100; |
/* Reload TMR0 */ |
|
Read AD Input(); |
/* Read A/D input */ |
|
ek = sk - yk; |
/* Calculate error term */ |
|
rk = ek + M1; |
|
|
yk = a0*rk + M2; |
/* Calculate output */ |
|
uk = yk*DA LSB; |
|
|
PORTB = uk; |
/* Send to PORT B */ |
|
DA Write = 0; |
/* Write to D/A converter */ |
|
DA Write = 1; |
|
|
rk 2 = rk 1; |
/* Update variables */ |
|
rk 1 = rk; |
|
|
M1 = -b1*rk 1 - b2*rk 2; |
|
|
M2 = a1*rk 1 + a2*rk 2; |
|
|
T0IF = 0; |
/* Re-enable timer interrupts */ |
} |
|
|
/* Main Program. The main program initializes the variables, A/D converter, D/A converter etc. and then waits in an endless loop for timer interrupts to Occur every 10 ms */
main(void)
{
a0 |
= 1; |
a1 = 0.8; |
a2 = 1.2; |
|
b1 |
= 1.85; |
b2 = 0.92; |
|
|
M1 |
= 0; |
M2 = 0; |
rk = 0; |
rk 1 = 0; rk 2 = 0; |
sk = 1.0; |
|
|
|
AD LSB = 5000.0/1024.0; |
|
|
DA LSB = 256.0/5000.0; |
|
|
TRISA = 1; |
|
/* RA0 (AN0) is input */ |
TRISB = 0; |
|
/* PORT B is output */ |
TRISC = 0; |
|
/* RC0 is output */ |
DA Write = 1; |
|
/* Disable D/A converter */ |
Initialize AD(); |
/* Initialize A/D converter */ |
Initialize Timer(); |
/* Initialize timer interrupts */ |
ei(); |
|
/* Enable interrupts */ |
for(;;); |
|
/* Wait for an interrupt */ |
}
Figure 10.20 (Continued )
|
|
CHOICE OF SAMPLING INTERVAL |
263 |
ek |
+ |
rk |
+ |
uk |
|
|
a0 |
|
|
|
z−1 |
|
|
|
|
|
−b1 |
|
a1 |
|
|
|
|
|
|
|
|
|
|
rk−1 |
|
|
|
Figure 10.21 First-order module
Example 10.7
The circuit diagram of a digital control system is shown in Figure 10.18. A PIC16F877 microcontroller is to be used as the digital controller in this system. Assume that the set-point input s is to be hard-coded to the program, and the output y is analog and connected to A/D channel AN0 (bit 0 of port A) of the microcontroller. The microcontroller is assumed to operate with a crystal frequency of 4 MHz as shown in the figure. The output (port B) of the microcontroller is interfaced to a D/A converter which acts as a zero-order-hold and generates an analog output to drive the plant.
Assume that the digital controller to be implemented is in the form of a first-order module, and write a program in C to implement this controller. The controller parameters are assumed to be:
a0 = 1, a1 = 0.8, b1 = 1.85,
i.e. the required controller transfer function is
1 + 0.8z−1 D(z) = 1 + 1.85z−1 .
Also assume that the required sampling interval is T = 0.01 s.
Solution
The implementation of a first-order module is very similar to a second-order module. The program to implement a first-order controller is shown in Figure 10.22. The operation of the program is very similar to the second-order program and is not described here.
10.5.3 Implementing Higher-Order Modules
Higher-order controllers can be implemented by cascading first-order and second-order modules. For example, a fourth-order controller can be implemented by cascading two second-order modules, as shown in Figure 10.23.
10.6 CHOICE OF SAMPLING INTERVAL
Whenever a digital control system is designed, a suitable sampling interval must be chosen. Choosing a large sampling time has destabilizing effects on the system. In addition, information loss occurs when large sampling times are selected. Also, the errors that occur when a continuous system is discretized increase as the sampling interval increases.
264 CONTROLLER REALIZATION
/****************************************************************************
DIGITAL CONTROLLER
==================
This program implements a first-order digital controller module on a PIC16F877 (or equivalent) microcontroller. The microcontroller operates with a 4MHz crystal. The analog input AN0 of the microcontroller is connected to the output sensor of the plant (y). The PORT B output of the microcontroller is connected to an AD7302 type D/A converter. The WR input of the controller is controlled from port pin RC0 of the microcontroller. The sampling interval is 0.01s (10ms) and the timer interrupt service routine is used to obtain the required sampling interval.
Program : First Order Module.C
Date : July 2005
*****************************************************************************/
#include <pic.h> #define DA Write RC0
float DA LSB,AD LSB,a0,a1,b1,M1,M2,rk,rk 1,rk 2,ek,sk,yk,uk; float y high,y low;
/* This function initializes the A/D converter so that analog data can be received from channel AN0 of the microcontroller */
void Initialize AD(void)
{
ADCON1 |
= |
0x8E; |
/* |
Configure AN0 */ |
ADCON0 |
= |
0x41; |
/* |
Select A/D clock and channel */ |
}
/* This function initilizes the timer TMR0 so that interrupts can be generated at 10ms intervals */
void Initialize Timer(void)
{
T0CS = 0; |
/* Select f/4 clock for TMR0 */ |
PSA = 0; |
/* Select pre-scaler */ |
PS0 = 1; |
/* Set pre-scaler to 64 */ |
PS1 = 0; |
|
PS2 = 1; |
|
TMR0 = 100; |
/* Load TMR0=100 */ |
T0IE = 1; |
/* Enable TMR0 interrupts */ |
T0IF = 0; |
/* Clear TMR0 interrupt flag */ |
} |
|
/* This function reads data from the A/D converter and stores in variable yk */
void Read AD Input(void)
{
ADCON0 = 0x45; While((ADCON0 & 4) != 0); y high = ADRESH;
y low = ADRESL;
/* Start A/D conversion */
/* Wait for conversion to complete */ /* High 2 bits of converted data */ /* Low byte of converted data */
Figure 10.22 Complete program of the first-order controller (Continued )
CHOICE OF SAMPLING INTERVAL |
265 |
yk = 256.0*y high + y low; yk = yk*AD LSB;
}
/* Converted data in yk */ /* Sensor output in mV */
/* Interrupt Service Routine. The program jumps here every 10 ms. */
void interrupt ISR(void) |
|
{ |
|
TMR0 = 100; |
/* Reload TMR0 */ |
Read AD Input(); |
/* Read A/D input */ |
ek = sk - yk; |
/* Calculate error term */ |
rk = ek + M1; |
|
yk = a0*rk + M2; |
/* Calculate output */ |
uk = yk*DA LSB; |
|
PORTB = uk; |
/* Send to PORT B */ |
DA Write = 0; |
/* Write to D/A converter */ |
DA Write = 1; |
|
rk 1 = rk; |
/* Update variables */ |
M1 = -b1*rk 1; |
|
M2 = a1*rk 1; |
|
T0IF = 0; |
/* Re-enable timer interrupts */ |
} |
|
/* Main Program. The main program initializes the variables, A/D converter, D/A converter etc. and then waits in an endless loop for timer interrupts to Occur every 10 ms */
main(void)
{
a0 |
= 1; |
a1 = 0.8; |
b1 = 1.85; |
|
M1 |
= 0; |
M2 = 0; |
rk = 0; |
rk 1 = 0; |
sk = 1.0; |
|
|
|
AD LSB = 5000.0/1024.0; |
|
|
DA LSB = 256.0/5000.0; |
|
|
TRISA = 1; |
|
/* RA0 (AN0) is input */ |
TRISB = 0; |
|
/* PORT B is output */ |
TRISC = 0; |
|
/* RC0 is output */ |
DA Write = 1; |
|
/* Disable D/A converter */ |
Initialize AD(); |
/* Initialize A/D converter */ |
Initialize Timer(); |
/* Initialize timer interrupts */ |
ei(); |
|
/* Enable interrupts */ |
for(;;); |
|
/* Wait for an interrupt */ |
}
266 CONTROLLER REALIZATION
ek |
+ |
a0 |
+ |
|
|
z−1 |
|
|
−b1 |
a1 |
|
|
|
z−1 |
|
|
−b2 |
a2 |
|
+ |
a3 |
+ |
uk |
|
z−1 |
|
|
−b3 |
a4 |
|
|
|
z−1 |
|
|
−b4 |
a5 |
|
|
Figure 10.23 Implementing a fourth-order module
It may be thought that decreasing the sampling interval towards zero will make a discrete system converge towards an equivalent continuous system. However, in practice this is not the case since 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 interval of 1 s is generally short enough for most applications such as pressure control, temperature control and flow control. Systems with fast responses such as electromechanical 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 closedloop system should be selected such that T < Tp /10.
Assuming that the process has a Ziegler–Nichols open-loop model
e−s T1
G(s) = , 1 + s T2
then the sampling interval should be selected such that T < T1/4.
D(z) =
D(z) =
EXERCISES 267
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 .
10.7 EXERCISES
1.The transfer function of a digital controller is given by
1+ 2z−1 + 3z−2
D(z) = 1 + 4z−1 + 5z−2 .
Draw the block diagram of the direct canonical realization of this controller. 2. Repeat Exercise 1 for a direct noncanocical controller realization.
3. Compare the realizations obtained in Exercises 1 and 2. 4. The transfer function of a digital controller is found to be
1 + 2z−1 + 5z−2 D(z) = 1 + 3z−1 + 7z−2 .
Draw the block diagram of the direct noncanonical realization of this controller. 5. The transfer function of a digital controller is given by
2(z + 2)(z + 3)
.
z2 + 0.4z + 0.03
Use two first-order cascaded transfer functions to implement this controller. 6. The transfer function of a digital controller is given by
(1 + 0.2z−1)(1 + 2z−1 + 4z−2) (1 + 0.3z−1)(1 + 0.2z−1 + 0.4z−2) .
Use a first-order and a second-order cascaded transfer function to implement this controller. 7. The transfer function of a digital controller is given by
D(z) = (1 + 2z−1)(1 + 3z−1) . (1 + z−1)(1 + 5z−1)
Realize this transfer function using first-order parallel transfer functions.
8.Draw the block diagram of the PID implementation using a parallel realization.
9.Draw the block diagram of the PID implementation using a direct canonical realization.
10.Describe how a given realization can be implemented on a microcontroller.
11.Draw a flow diagram to show how the PID algorithm can be implemented on a microcontroller. Write a program in C to implement this algorithm on a PIC microcontroller.