PID Control - Program (sort of)
Archiver
Posts: 46,084
I didn't write the following program; I posted it back in 1998 and John
Piccirillo commented on it complete with a reference to its
origin. Unfortunately that reference is now a dead link.
Some other very useful references on PID control can be found at:
http://www.expertune.com/articles.html
http://www.controleng.com/archives/1998/ctl0301.98/03a305.htm
http://lorien.ncl.ac.uk/ming/pid/PID.pdf
http://www.tpub.com/doeinstrument/instrumentationandcontrol84.htm
http://www.stampsinclass.com/html_files/downloads_curriculum.htm
Industrial Control (Version 1.1) Experiment #6: PID Control.
Jim Higgins
>Date: Wed, 23 Sep 1998 17:55:52 -0500
>From: John Piccirillo <jpiccirillo@s...>
>Subject: PIDdling Around
>
> Regarding the recent thread on PID algorithms and the one
> published in Embedded Systems Programming, here are
> some references and notes that may help.
>
>1) The Embedded Systems Programming code is at:
>ftp://ftp.mfi.com/pub/espmag/1997/gaddy.txt
>and an accompanying article on PID is at:
>http://www.embedded.com/db_area/FULL/30804.HTM
[noparse][[/noparse]The two URLS above have since become DEAD LINKS, but
the code from the first link is the code that is copied below. - JH]
>2) An excellent tutorial on PID is at:
> http://www.expertune.com/tutor.html
>
>3) My notes from the article on the algorithm, referencing
> line numbers below, are:
> a) The algorithm uses three main variables, the setpoint (SP),
>the process variable (PV), and the control variable (CV). The
>setpoint is the value you want the variable to achieve, the process
>variable is the measured value of the variable, the difference gives
>an error signal, which the algorithm turns into a control variable
>(output on line 48) which is used to change the functioning of the
>device. Changes in the desired setpoint and updates to the
>process variable are made outside the algorithm.
>
> b) Variable definitions
> SP - setpoint, ie desired output
> PV - process variable, ie actual output
> CV - control variable, ie independent variable
> KP - proportional gain
> KI - integral gain
> KD - derivative gain
> PTerm - proportional term
> ITerm - integral term
> DTerm - derivative term
> PV_Span = PV High Limit - PV Low Limit
> CV_Span = CV High Limit - CV Low Limit
> d_PV - change in process variable since last PID execution
>
> c) The basic idea is start with manual control (Auto_Mode = 0),
>lines 49 to 51, then change to Auto_Mode to 1 when ready to
>change over to automatic, ie PID, control, when the process is near
>where you want it. The algorithm should keep up with changes in
>setpoint and system changes, for instance changes in load.
> The first time through the PID loop (lines 3 to 48) lines 6 to 10
>are executed once, this sets the Initial_Error and Sum_Error terms.
> The PID loop is divided into three parts. Lines 14 to 22 uses
>integral control only until the value of the process value passes
>that of the setpoint, ie until the error changes sign. After this the
>PID loop uses lines 25 to 31 if the setpoint doesn't change or 33
>to 44 if the setpoint does change. The latter loop is integral only
>control.
>
> d) At least that's my understanding.
>
>
>Code associated with "How to Write a PID Algorithm" by Garth Gaddy, p. 62,
>May 1997
>
>listing 1
>Screw servo motion program.
>
>01 While (True)
>02 If (Auto_Mode = 1 )
>03 If (First_PID_Execution = 0 OR First_PID_Execution = 1)
>04 Error = (SP - PV) * (CV_Span / PV_Span)
>05 Sum_Error = Sum_Error + Error
>06 If (First_PID_Execution = 0)
>07 Sum_Error = Manual_Command / KI
>08 First_PID_Execution = 1
>09 Initial_Error = Error
>10 Endif
>11 Pterm = 0
>12 Iterm = KI * Sum_Error
>13 Dterm = 0
>14 If (Initial_Error > 0 and Error < 0)
>15 First_PID_Execution = 2
>16 Last_PV = PV
>17 Endif
>18 If (Initial_Error < 0 and Error > 0)
>19 First_PID_Execution = 2
>20 Last_PV = PV
>21 Endif
>22 Last_SP = SP
>23 Else
>24 If (SP = Last_SP)
>25 Error = (SP - PV) * (CV_Span / PV_Span)
>26 Pterm = KP * Error
>27 Sum_Error = Sum_Error + Error
>28 Iterm = KI * Sum_Error
>29 d_PV = (Last_PV - PV) * (CV_Span / PV_Span)
>30 Last_PV = PV
>31 Dterm = KD * d_PV
>32 Else
>33 Error = (SP - PV) * (CV_Span / PV_Span)
>34 Sum_Error = Sum_Error + Error
>35 Pterm = 0
>36 Iterm = KI * Sum_Error
>37 Dterm = 0
>38 If (SP > Last_SP and PV > SP)
>39 Last_SP = SP
>40 Last_PV = PV
>41 Endif
>42 If (SP < Last_SP and PV < SP)
>43 Last_SP = SP
>44 Last_PV = PV
>45 Endif
>46 Endif
>47 Endif
>48 CV = Pterm + Iterm + Dterm
>49 Else
>50 CV = Manual_Command
>51 First_PID_Execution = 0
>52 Endif
>53 EndWhile
Piccirillo commented on it complete with a reference to its
origin. Unfortunately that reference is now a dead link.
Some other very useful references on PID control can be found at:
http://www.expertune.com/articles.html
http://www.controleng.com/archives/1998/ctl0301.98/03a305.htm
http://lorien.ncl.ac.uk/ming/pid/PID.pdf
http://www.tpub.com/doeinstrument/instrumentationandcontrol84.htm
http://www.stampsinclass.com/html_files/downloads_curriculum.htm
Industrial Control (Version 1.1) Experiment #6: PID Control.
Jim Higgins
>Date: Wed, 23 Sep 1998 17:55:52 -0500
>From: John Piccirillo <jpiccirillo@s...>
>Subject: PIDdling Around
>
> Regarding the recent thread on PID algorithms and the one
> published in Embedded Systems Programming, here are
> some references and notes that may help.
>
>1) The Embedded Systems Programming code is at:
>ftp://ftp.mfi.com/pub/espmag/1997/gaddy.txt
>and an accompanying article on PID is at:
>http://www.embedded.com/db_area/FULL/30804.HTM
[noparse][[/noparse]The two URLS above have since become DEAD LINKS, but
the code from the first link is the code that is copied below. - JH]
>2) An excellent tutorial on PID is at:
> http://www.expertune.com/tutor.html
>
>3) My notes from the article on the algorithm, referencing
> line numbers below, are:
> a) The algorithm uses three main variables, the setpoint (SP),
>the process variable (PV), and the control variable (CV). The
>setpoint is the value you want the variable to achieve, the process
>variable is the measured value of the variable, the difference gives
>an error signal, which the algorithm turns into a control variable
>(output on line 48) which is used to change the functioning of the
>device. Changes in the desired setpoint and updates to the
>process variable are made outside the algorithm.
>
> b) Variable definitions
> SP - setpoint, ie desired output
> PV - process variable, ie actual output
> CV - control variable, ie independent variable
> KP - proportional gain
> KI - integral gain
> KD - derivative gain
> PTerm - proportional term
> ITerm - integral term
> DTerm - derivative term
> PV_Span = PV High Limit - PV Low Limit
> CV_Span = CV High Limit - CV Low Limit
> d_PV - change in process variable since last PID execution
>
> c) The basic idea is start with manual control (Auto_Mode = 0),
>lines 49 to 51, then change to Auto_Mode to 1 when ready to
>change over to automatic, ie PID, control, when the process is near
>where you want it. The algorithm should keep up with changes in
>setpoint and system changes, for instance changes in load.
> The first time through the PID loop (lines 3 to 48) lines 6 to 10
>are executed once, this sets the Initial_Error and Sum_Error terms.
> The PID loop is divided into three parts. Lines 14 to 22 uses
>integral control only until the value of the process value passes
>that of the setpoint, ie until the error changes sign. After this the
>PID loop uses lines 25 to 31 if the setpoint doesn't change or 33
>to 44 if the setpoint does change. The latter loop is integral only
>control.
>
> d) At least that's my understanding.
>
>
>Code associated with "How to Write a PID Algorithm" by Garth Gaddy, p. 62,
>May 1997
>
>listing 1
>Screw servo motion program.
>
>01 While (True)
>02 If (Auto_Mode = 1 )
>03 If (First_PID_Execution = 0 OR First_PID_Execution = 1)
>04 Error = (SP - PV) * (CV_Span / PV_Span)
>05 Sum_Error = Sum_Error + Error
>06 If (First_PID_Execution = 0)
>07 Sum_Error = Manual_Command / KI
>08 First_PID_Execution = 1
>09 Initial_Error = Error
>10 Endif
>11 Pterm = 0
>12 Iterm = KI * Sum_Error
>13 Dterm = 0
>14 If (Initial_Error > 0 and Error < 0)
>15 First_PID_Execution = 2
>16 Last_PV = PV
>17 Endif
>18 If (Initial_Error < 0 and Error > 0)
>19 First_PID_Execution = 2
>20 Last_PV = PV
>21 Endif
>22 Last_SP = SP
>23 Else
>24 If (SP = Last_SP)
>25 Error = (SP - PV) * (CV_Span / PV_Span)
>26 Pterm = KP * Error
>27 Sum_Error = Sum_Error + Error
>28 Iterm = KI * Sum_Error
>29 d_PV = (Last_PV - PV) * (CV_Span / PV_Span)
>30 Last_PV = PV
>31 Dterm = KD * d_PV
>32 Else
>33 Error = (SP - PV) * (CV_Span / PV_Span)
>34 Sum_Error = Sum_Error + Error
>35 Pterm = 0
>36 Iterm = KI * Sum_Error
>37 Dterm = 0
>38 If (SP > Last_SP and PV > SP)
>39 Last_SP = SP
>40 Last_PV = PV
>41 Endif
>42 If (SP < Last_SP and PV < SP)
>43 Last_SP = SP
>44 Last_PV = PV
>45 Endif
>46 Endif
>47 Endif
>48 CV = Pterm + Iterm + Dterm
>49 Else
>50 CV = Manual_Command
>51 First_PID_Execution = 0
>52 Endif
>53 EndWhile