thermferm/pid.c

changeset 492
750f2468dec5
parent 363
468ec0d96cce
child 495
712984fdd26b
equal deleted inserted replaced
491:31b14c9ac625 492:750f2468dec5
24 #include "pid.h" 24 #include "pid.h"
25 25
26 26
27 void InitPID(pid_var *pid, int type) 27 void InitPID(pid_var *pid, int type)
28 { 28 {
29 pid->Err = pid->ErrLast = pid->iState = 0.0; 29 pid->Err = pid->InputLast = pid->iState = 0.0;
30 pid->Input = pid->OutP = pid->SetP = 0.0; 30 pid->Input = pid->OutP = pid->SetP = 0.0;
31 pid->pGain = pid->iGain = pid->dGain = 0.0; 31 pid->pGain = pid->iGain = pid->dGain = 0.0;
32 pid->idleRange = 0.4; 32 pid->idleRange = 0.4;
33 pid->Mode = PID_MODE_NONE; 33 pid->Mode = PID_MODE_NONE;
34 pid->Type = type; 34 pid->Type = type;
39 39
40 void UpdatePID(pid_var *pid) 40 void UpdatePID(pid_var *pid)
41 { 41 {
42 if (pid->Mode == PID_MODE_AUTO) { 42 if (pid->Mode == PID_MODE_AUTO) {
43 43
44 double pTerm, dTerm, iTerm; 44 double dTerm;
45 45
46 if (pid->Type == PID_TYPE_HEAT) 46 if (pid->Type == PID_TYPE_HEAT)
47 pid->Err = pid->SetP - pid->Input; 47 pid->Err = pid->SetP - pid->Input;
48 else 48 else
49 pid->Err = pid->Input - pid->SetP; 49 pid->Err = pid->Input - pid->SetP;
50 50
51 /* 51 /*
52 * Calculate the integral state with appopriate limiting. 52 * Calculate the integral state with appopriate limiting.
53 * Use ErrLastLast as iState 53 * Use ErrLastLast as iState
54 */ 54 */
55 pid->iState += pid->Err; 55 pid->iState += (pid->iGain * pid->Err);
56 if (pid->iState > PID_WINDUP_GUARD) 56 if (pid->iState > pid->iMax)
57 pid->iState = PID_WINDUP_GUARD; 57 pid->iState = pid->iMax;
58 else if (pid->iState < -PID_WINDUP_GUARD) 58 else if (pid->iState < 0)
59 pid->iState = -PID_WINDUP_GUARD; 59 pid->iState = 0;
60 60
61 pTerm = pid->pGain * pid->Err; 61 dTerm = (pid->Input - pid->InputLast);
62 iTerm = pid->iGain * pid->iState;
63 dTerm = pid->dGain * (pid->Err - pid->ErrLast);
64 62
65 pid->OutP = pTerm + dTerm + iTerm; 63 pid->OutP = (pid->pGain * pid->Err) + pid->iState - (pid->dGain * dTerm);
66 pid->ErrLast = pid->Err; 64 pid->InputLast = pid->Input;
67 65
68 } else if (pid->Mode == PID_MODE_BOO) { 66 } else if (pid->Mode == PID_MODE_BOO) {
69 /* 67 /*
70 * Mode Bang On Off 68 * Mode Bang On Off
71 */ 69 */
72 pid->ErrLast = pid->Err; 70 pid->InputLast = pid->Input;
73 71
74 if (pid->Type == PID_TYPE_HEAT) 72 if (pid->Type == PID_TYPE_HEAT)
75 pid->Err = pid->SetP - pid->Input; 73 pid->Err = pid->SetP - pid->Input;
76 else 74 else
77 pid->Err = pid->Input - pid->SetP; 75 pid->Err = pid->Input - pid->SetP;
86 } else { 84 } else {
87 /* 85 /*
88 * While in manual mode, stay ready for bumpless switch to 86 * While in manual mode, stay ready for bumpless switch to
89 * auto. 87 * auto.
90 */ 88 */
91 pid->ErrLast = pid->Err = 0.0; 89 pid->InputLast = pid->Input;
92 pid->OutP = pid->iState = 0.0; 90 pid->OutP = pid->iState = 0.0;
93 } 91 }
94 92
95 if (pid->OutP > pid->iMax) 93 if (pid->OutP > pid->iMax)
96 pid->OutP = pid->iMax; 94 pid->OutP = pid->iMax;

mercurial