thermferm/pid.c

changeset 363
468ec0d96cce
parent 362
c92651a54969
child 492
750f2468dec5
equal deleted inserted replaced
362:c92651a54969 363:468ec0d96cce
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->ErrLastLast = 0.0; 29 pid->Err = pid->ErrLast = pid->iState = 0.0;
30 pid->Input = pid->InputD = pid->OutP = pid->InputLast = 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;
35 pid->iMax = 100.0; 35 pid->iMax = 100.0;
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 pid->InputD = pid->Input + (pid->Input - pid->InputLast) * pid->dGain * PID_TIMES; 44 double pTerm, dTerm, iTerm;
45 pid->InputLast = pid->Input; 45
46 if (pid->Type == PID_TYPE_HEAT) 46 if (pid->Type == PID_TYPE_HEAT)
47 pid->Err = pid->InputD - pid->SetP; 47 pid->Err = pid->SetP - pid->Input;
48 else 48 else
49 pid->Err = pid->SetP - pid->InputD; 49 pid->Err = pid->Input - pid->SetP;
50 50
51 pid->OutP = pid->OutP + pid->pGain * (pid->Err - pid->ErrLast + pid->iGain * pid->Err + pid->dGain * (pid->Err - pid->ErrLast * 2 + pid->ErrLastLast)); 51 /*
52 pid->ErrLastLast = pid->ErrLast; 52 * Calculate the integral state with appopriate limiting.
53 * Use ErrLastLast as iState
54 */
55 pid->iState += pid->Err;
56 if (pid->iState > PID_WINDUP_GUARD)
57 pid->iState = PID_WINDUP_GUARD;
58 else if (pid->iState < -PID_WINDUP_GUARD)
59 pid->iState = -PID_WINDUP_GUARD;
60
61 pTerm = pid->pGain * pid->Err;
62 iTerm = pid->iGain * pid->iState;
63 dTerm = pid->dGain * (pid->Err - pid->ErrLast);
64
65 pid->OutP = pTerm + dTerm + iTerm;
53 pid->ErrLast = pid->Err; 66 pid->ErrLast = pid->Err;
54 67
55 } if (pid->Mode == PID_MODE_BOO) { 68 } else if (pid->Mode == PID_MODE_BOO) {
56 /* 69 /*
57 * Mode Bang On Off 70 * Mode Bang On Off
58 */ 71 */
59 pid->InputLast = pid->Input; 72 pid->ErrLast = pid->Err;
73
60 if (pid->Type == PID_TYPE_HEAT) 74 if (pid->Type == PID_TYPE_HEAT)
61 pid->ErrLastLast = pid->ErrLast = pid->Err = pid->SetP - pid->Input; 75 pid->Err = pid->SetP - pid->Input;
62 else 76 else
63 pid->ErrLastLast = pid->ErrLast = pid->Err = pid->Input - pid->SetP; 77 pid->Err = pid->Input - pid->SetP;
64 78
65 if (pid->Err > 0.0) 79 if (pid->OutP && (pid->Err <= 0.0))
80 pid->OutP = 0.0;
81 else if ((pid->OutP == 0.0) && (pid->Err > pid->idleRange))
66 pid->OutP = pid->iMax; 82 pid->OutP = pid->iMax;
67 else 83
68 pid->OutP = 0.0; 84 pid->iState = 0.0;
69 85
70 } else { 86 } else {
71 /* 87 /*
72 * While in manual mode, stay ready for bumpless switch to 88 * While in manual mode, stay ready for bumpless switch to
73 * auto. 89 * auto.
74 */ 90 */
75 pid->InputLast = pid->Input; 91 pid->ErrLast = pid->Err = 0.0;
76 pid->ErrLastLast = pid->ErrLast = pid->Err; 92 pid->OutP = pid->iState = 0.0;
77 } 93 }
78 94
79 if (pid->OutP > pid->iMax) 95 if (pid->OutP > pid->iMax)
80 pid->OutP = pid->iMax; 96 pid->OutP = pid->iMax;
81 if (pid->OutP < 0.0) 97 if (pid->OutP < 0.0)

mercurial