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) |