1414#include < PID_v1.h>
1515
1616/* Constructor (...)*********************************************************
17- * The parameters specified here are those for for which we can't set up
17+ * The parameters specified here are those for for which we can't set up
1818 * reliable defaults, so we need to have the user set them.
1919 ***************************************************************************/
2020PID::PID (double * Input, double * Output, double * Setpoint,
21- double Kp, double Ki, double Kd, int ControllerDirection)
21+ double Kp, double Ki, double Kd, int POn, int ControllerDirection)
2222{
23-
2423 myOutput = Output;
2524 myInput = Input;
2625 mySetpoint = Setpoint;
27- inAuto = false ;
28-
29- PID::SetOutputLimits (0 , 255 ); // default output limit corresponds to
26+ inAuto = false ;
27+
28+ PID::SetOutputLimits (0 , 255 ); // default output limit corresponds to
3029 // the arduino pwm limits
3130
3231 SampleTime = 100 ; // default Controller Sample Time is 0.1 seconds
3332
3433 PID::SetControllerDirection (ControllerDirection);
35- PID::SetTunings (Kp, Ki, Kd);
34+ PID::SetTunings (Kp, Ki, Kd, POn );
3635
37- lastTime = millis ()-SampleTime;
36+ lastTime = millis ()-SampleTime;
3837}
39-
40-
38+
39+ /* Constructor (...)*********************************************************
40+ * To allow backwards compatability for v1.1, or for people that just want
41+ * to use Proportional on Error without explicitly saying so
42+ ***************************************************************************/
43+
44+ PID::PID (double * Input, double * Output, double * Setpoint,
45+ double Kp, double Ki, double Kd, int ControllerDirection)
46+ :PID::PID(Input, Output, Setpoint, Kp, Ki, Kd, P_ON_E, ControllerDirection)
47+ {
48+
49+ }
50+
51+
4152/* Compute() **********************************************************************
4253 * This, as they say, is where the magic happens. this function should be called
4354 * every time "void loop()" executes. the function will decide for itself whether a new
4455 * pid Output needs to be computed. returns true when the output is computed,
4556 * false when nothing has been done.
46- **********************************************************************************/
57+ **********************************************************************************/
4758bool PID::Compute ()
4859{
4960 if (!inAuto) return false ;
@@ -52,55 +63,73 @@ bool PID::Compute()
5263 if (timeChange>=SampleTime)
5364 {
5465 /* Compute all the working error variables*/
55- double input = *myInput;
66+ double input = *myInput;
5667 double error = *mySetpoint - input;
57- ITerm+= (ki * error);
58- if (ITerm > outMax) ITerm= outMax;
59- else if (ITerm < outMin) ITerm= outMin;
6068 double dInput = (input - lastInput);
61-
62- /* Compute PID Output*/
63- double output = kp * error + ITerm- kd * dInput;
64-
65- if (output > outMax) output = outMax;
69+ outputSum+= (ki * error);
70+
71+ /* Add Proportional on Measurement, if P_ON_M is specified*/
72+ if (!pOnE) outputSum-= kp * dInput;
73+
74+ if (outputSum > outMax) outputSum= outMax;
75+ else if (outputSum < outMin) outputSum= outMin;
76+
77+ /* Add Proportional on Error, if P_ON_E is specified*/
78+ double output;
79+ if (pOnE) output = kp * error;
80+ else output = 0 ;
81+
82+ /* Compute Rest of PID Output*/
83+ output += outputSum - kd * dInput;
84+
85+ if (output > outMax) output = outMax;
6686 else if (output < outMin) output = outMin;
67- *myOutput = output;
68-
87+ *myOutput = output;
88+
6989 /* Remember some variables for next time*/
7090 lastInput = input;
7191 lastTime = now;
72- return true ;
92+ return true ;
7393 }
7494 else return false ;
7595}
7696
77-
7897/* SetTunings(...)*************************************************************
79- * This function allows the controller's dynamic performance to be adjusted.
98+ * This function allows the controller's dynamic performance to be adjusted.
8099 * it's called automatically from the constructor, but tunings can also
81100 * be adjusted on the fly during normal operation
82- ******************************************************************************/
83- void PID::SetTunings (double Kp, double Ki, double Kd)
101+ ******************************************************************************/
102+ void PID::SetTunings (double Kp, double Ki, double Kd, int POn )
84103{
85104 if (Kp<0 || Ki<0 || Kd<0 ) return ;
86-
105+
106+ pOn = POn;
107+ pOnE = POn == P_ON_E;
108+
87109 dispKp = Kp; dispKi = Ki; dispKd = Kd;
88-
89- double SampleTimeInSec = ((double )SampleTime)/1000 ;
110+
111+ double SampleTimeInSec = ((double )SampleTime)/1000 ;
90112 kp = Kp;
91113 ki = Ki * SampleTimeInSec;
92114 kd = Kd / SampleTimeInSec;
93-
115+
94116 if (controllerDirection ==REVERSE)
95117 {
96118 kp = (0 - kp);
97119 ki = (0 - ki);
98120 kd = (0 - kd);
99121 }
100122}
101-
123+
124+ /* SetTunings(...)*************************************************************
125+ * Set Tunings using the last-rembered POn setting
126+ ******************************************************************************/
127+ void PID::SetTunings (double Kp, double Ki, double Kd){
128+ SetTunings (Kp, Ki, Kd, pOn);
129+ }
130+
102131/* SetSampleTime(...) *********************************************************
103- * sets the period, in Milliseconds, at which the calculation is performed
132+ * sets the period, in Milliseconds, at which the calculation is performed
104133 ******************************************************************************/
105134void PID::SetSampleTime (int NewSampleTime)
106135{
@@ -113,7 +142,7 @@ void PID::SetSampleTime(int NewSampleTime)
113142 SampleTime = (unsigned long )NewSampleTime;
114143 }
115144}
116-
145+
117146/* SetOutputLimits(...)****************************************************
118147 * This function will be used far more often than SetInputLimits. while
119148 * the input to the controller will generally be in the 0-1023 range (which is
@@ -127,22 +156,22 @@ void PID::SetOutputLimits(double Min, double Max)
127156 if (Min >= Max) return ;
128157 outMin = Min;
129158 outMax = Max;
130-
159+
131160 if (inAuto)
132161 {
133162 if (*myOutput > outMax) *myOutput = outMax;
134163 else if (*myOutput < outMin) *myOutput = outMin;
135-
136- if (ITerm > outMax) ITerm = outMax;
137- else if (ITerm < outMin) ITerm = outMin;
164+
165+ if (outputSum > outMax) outputSum = outMax;
166+ else if (outputSum < outMin) outputSum = outMin;
138167 }
139168}
140169
141170/* SetMode(...)****************************************************************
142171 * Allows the controller Mode to be set to manual (0) or Automatic (non-zero)
143172 * when the transition from manual to auto occurs, the controller is
144173 * automatically initialized
145- ******************************************************************************/
174+ ******************************************************************************/
146175void PID::SetMode (int Mode)
147176{
148177 bool newAuto = (Mode == AUTOMATIC);
@@ -152,21 +181,21 @@ void PID::SetMode(int Mode)
152181 }
153182 inAuto = newAuto;
154183}
155-
184+
156185/* Initialize()****************************************************************
157186 * does all the things that need to happen to ensure a bumpless transfer
158187 * from manual to automatic mode.
159- ******************************************************************************/
188+ ******************************************************************************/
160189void PID::Initialize ()
161190{
162- ITerm = *myOutput;
191+ outputSum = *myOutput;
163192 lastInput = *myInput;
164- if (ITerm > outMax) ITerm = outMax;
165- else if (ITerm < outMin) ITerm = outMin;
193+ if (outputSum > outMax) outputSum = outMax;
194+ else if (outputSum < outMin) outputSum = outMin;
166195}
167196
168197/* SetControllerDirection(...)*************************************************
169- * The PID will either be connected to a DIRECT acting process (+Output leads
198+ * The PID will either be connected to a DIRECT acting process (+Output leads
170199 * to +Input) or a REVERSE acting process(+Output leads to -Input.) we need to
171200 * know which one, because otherwise we may increase the output when we should
172201 * be decreasing. This is called from the constructor.
@@ -175,16 +204,16 @@ void PID::SetControllerDirection(int Direction)
175204{
176205 if (inAuto && Direction !=controllerDirection)
177206 {
178- kp = (0 - kp);
207+ kp = (0 - kp);
179208 ki = (0 - ki);
180209 kd = (0 - kd);
181- }
210+ }
182211 controllerDirection = Direction;
183212}
184213
185214/* Status Funcions*************************************************************
186215 * Just because you set the Kp=-1 doesn't mean it actually happened. these
187- * functions query the internal state of the PID. they're here for display
216+ * functions query the internal state of the PID. they're here for display
188217 * purposes. this are the functions the PID Front-end uses for example
189218 ******************************************************************************/
190219double PID::GetKp (){ return dispKp; }
0 commit comments