Version 1.2
-Added capability for Proportional On Measurement -Changed license from GPLv3 to MIT
This commit is contained in:
parent
5adeed52b0
commit
5cefbae8e5
73
PID_v1.cpp
73
PID_v1.cpp
@ -18,25 +18,36 @@
|
|||||||
* reliable defaults, so we need to have the user set them.
|
* reliable defaults, so we need to have the user set them.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
PID::PID(double* Input, double* Output, double* Setpoint,
|
PID::PID(double* Input, double* Output, double* Setpoint,
|
||||||
double Kp, double Ki, double Kd, int ControllerDirection)
|
double Kp, double Ki, double Kd, int POn, int ControllerDirection)
|
||||||
{
|
{
|
||||||
|
|
||||||
myOutput = Output;
|
myOutput = Output;
|
||||||
myInput = Input;
|
myInput = Input;
|
||||||
mySetpoint = Setpoint;
|
mySetpoint = Setpoint;
|
||||||
inAuto = false;
|
inAuto = false;
|
||||||
|
|
||||||
PID::SetOutputLimits(0, 255); //default output limit corresponds to
|
PID::SetOutputLimits(0, 255); //default output limit corresponds to
|
||||||
//the arduino pwm limits
|
//the arduino pwm limits
|
||||||
|
|
||||||
SampleTime = 100; //default Controller Sample Time is 0.1 seconds
|
SampleTime = 100; //default Controller Sample Time is 0.1 seconds
|
||||||
|
|
||||||
PID::SetControllerDirection(ControllerDirection);
|
PID::SetControllerDirection(ControllerDirection);
|
||||||
PID::SetTunings(Kp, Ki, Kd);
|
PID::SetTunings(Kp, Ki, Kd, POn);
|
||||||
|
|
||||||
lastTime = millis()-SampleTime;
|
lastTime = millis()-SampleTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Constructor (...)*********************************************************
|
||||||
|
* To allow backwards compatability for v1.1, or for people that just want
|
||||||
|
* to use Proportional on Error without explicitly saying so
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
PID::PID(double* Input, double* Output, double* Setpoint,
|
||||||
|
double Kp, double Ki, double Kd, int ControllerDirection)
|
||||||
|
:PID::PID(Input, Output, Setpoint, Kp, Ki, Kd, P_ON_E, ControllerDirection)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Compute() **********************************************************************
|
/* Compute() **********************************************************************
|
||||||
* This, as they say, is where the magic happens. this function should be called
|
* This, as they say, is where the magic happens. this function should be called
|
||||||
@ -52,38 +63,49 @@ bool PID::Compute()
|
|||||||
if(timeChange>=SampleTime)
|
if(timeChange>=SampleTime)
|
||||||
{
|
{
|
||||||
/*Compute all the working error variables*/
|
/*Compute all the working error variables*/
|
||||||
double input = *myInput;
|
double input = *myInput;
|
||||||
double error = *mySetpoint - input;
|
double error = *mySetpoint - input;
|
||||||
ITerm+= (ki * error);
|
|
||||||
if(ITerm > outMax) ITerm= outMax;
|
|
||||||
else if(ITerm < outMin) ITerm= outMin;
|
|
||||||
double dInput = (input - lastInput);
|
double dInput = (input - lastInput);
|
||||||
|
outputSum+= (ki * error);
|
||||||
|
|
||||||
/*Compute PID Output*/
|
/*Add Proportional on Measurement, if P_ON_M is specified*/
|
||||||
double output = kp * error + ITerm- kd * dInput;
|
if(!pOnE) outputSum-= kp * dInput;
|
||||||
|
|
||||||
if(output > outMax) output = outMax;
|
if(outputSum > outMax) outputSum= outMax;
|
||||||
|
else if(outputSum < outMin) outputSum= outMin;
|
||||||
|
|
||||||
|
/*Add Proportional on Error, if P_ON_E is specified*/
|
||||||
|
double output;
|
||||||
|
if(pOnE) output = kp * error;
|
||||||
|
else output = 0;
|
||||||
|
|
||||||
|
/*Compute Rest of PID Output*/
|
||||||
|
output += outputSum - kd * dInput;
|
||||||
|
|
||||||
|
if(output > outMax) output = outMax;
|
||||||
else if(output < outMin) output = outMin;
|
else if(output < outMin) output = outMin;
|
||||||
*myOutput = output;
|
*myOutput = output;
|
||||||
|
|
||||||
/*Remember some variables for next time*/
|
/*Remember some variables for next time*/
|
||||||
lastInput = input;
|
lastInput = input;
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SetTunings(...)*************************************************************
|
/* SetTunings(...)*************************************************************
|
||||||
* This function allows the controller's dynamic performance to be adjusted.
|
* This function allows the controller's dynamic performance to be adjusted.
|
||||||
* it's called automatically from the constructor, but tunings can also
|
* it's called automatically from the constructor, but tunings can also
|
||||||
* be adjusted on the fly during normal operation
|
* be adjusted on the fly during normal operation
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void PID::SetTunings(double Kp, double Ki, double Kd)
|
void PID::SetTunings(double Kp, double Ki, double Kd, int POn)
|
||||||
{
|
{
|
||||||
if (Kp<0 || Ki<0 || Kd<0) return;
|
if (Kp<0 || Ki<0 || Kd<0) return;
|
||||||
|
|
||||||
|
pOn = POn;
|
||||||
|
pOnE = POn == P_ON_E;
|
||||||
|
|
||||||
dispKp = Kp; dispKi = Ki; dispKd = Kd;
|
dispKp = Kp; dispKi = Ki; dispKd = Kd;
|
||||||
|
|
||||||
double SampleTimeInSec = ((double)SampleTime)/1000;
|
double SampleTimeInSec = ((double)SampleTime)/1000;
|
||||||
@ -99,6 +121,13 @@ void PID::SetTunings(double Kp, double Ki, double Kd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SetTunings(...)*************************************************************
|
||||||
|
* Set Tunings using the last-rembered POn setting
|
||||||
|
******************************************************************************/
|
||||||
|
void PID::SetTunings(double Kp, double Ki, double Kd){
|
||||||
|
SetTunings(Kp, Ki, Kd, pOn);
|
||||||
|
}
|
||||||
|
|
||||||
/* SetSampleTime(...) *********************************************************
|
/* SetSampleTime(...) *********************************************************
|
||||||
* sets the period, in Milliseconds, at which the calculation is performed
|
* sets the period, in Milliseconds, at which the calculation is performed
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -133,8 +162,8 @@ void PID::SetOutputLimits(double Min, double Max)
|
|||||||
if(*myOutput > outMax) *myOutput = outMax;
|
if(*myOutput > outMax) *myOutput = outMax;
|
||||||
else if(*myOutput < outMin) *myOutput = outMin;
|
else if(*myOutput < outMin) *myOutput = outMin;
|
||||||
|
|
||||||
if(ITerm > outMax) ITerm= outMax;
|
if(outputSum > outMax) outputSum= outMax;
|
||||||
else if(ITerm < outMin) ITerm= outMin;
|
else if(outputSum < outMin) outputSum= outMin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,10 +188,10 @@ void PID::SetMode(int Mode)
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void PID::Initialize()
|
void PID::Initialize()
|
||||||
{
|
{
|
||||||
ITerm = *myOutput;
|
outputSum = *myOutput;
|
||||||
lastInput = *myInput;
|
lastInput = *myInput;
|
||||||
if(ITerm > outMax) ITerm = outMax;
|
if(outputSum > outMax) outputSum = outMax;
|
||||||
else if(ITerm < outMin) ITerm = outMin;
|
else if(outputSum < outMin) outputSum = outMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SetControllerDirection(...)*************************************************
|
/* SetControllerDirection(...)*************************************************
|
||||||
@ -175,7 +204,7 @@ void PID::SetControllerDirection(int Direction)
|
|||||||
{
|
{
|
||||||
if(inAuto && Direction !=controllerDirection)
|
if(inAuto && Direction !=controllerDirection)
|
||||||
{
|
{
|
||||||
kp = (0 - kp);
|
kp = (0 - kp);
|
||||||
ki = (0 - ki);
|
ki = (0 - ki);
|
||||||
kd = (0 - kd);
|
kd = (0 - kd);
|
||||||
}
|
}
|
||||||
|
22
PID_v1.h
22
PID_v1.h
@ -13,8 +13,14 @@ class PID
|
|||||||
#define MANUAL 0
|
#define MANUAL 0
|
||||||
#define DIRECT 0
|
#define DIRECT 0
|
||||||
#define REVERSE 1
|
#define REVERSE 1
|
||||||
|
#define P_ON_M 0
|
||||||
|
#define P_ON_E 1
|
||||||
|
|
||||||
//commonly used functions **************************************************************************
|
//commonly used functions **************************************************************************
|
||||||
|
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
|
||||||
|
double, double, double, int, int);// Setpoint. Initial tuning parameters are also set here.
|
||||||
|
// (overload for specifying proportional mode)
|
||||||
|
|
||||||
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
|
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
|
||||||
double, double, double, int); // Setpoint. Initial tuning parameters are also set here
|
double, double, double, int); // Setpoint. Initial tuning parameters are also set here
|
||||||
|
|
||||||
@ -25,16 +31,19 @@ class PID
|
|||||||
// calculation frequency can be set using SetMode
|
// calculation frequency can be set using SetMode
|
||||||
// SetSampleTime respectively
|
// SetSampleTime respectively
|
||||||
|
|
||||||
void SetOutputLimits(double, double); //clamps the output to a specific range. 0-255 by default, but
|
void SetOutputLimits(double, double); // * clamps the output to a specific range. 0-255 by default, but
|
||||||
//it's likely the user will want to change this depending on
|
// it's likely the user will want to change this depending on
|
||||||
//the application
|
// the application
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//available but not commonly used functions ********************************************************
|
//available but not commonly used functions ********************************************************
|
||||||
void SetTunings(double, double, // * While most users will set the tunings once in the
|
void SetTunings(double, double, // * While most users will set the tunings once in the
|
||||||
double); // constructor, this function gives the user the option
|
double); // constructor, this function gives the user the option
|
||||||
// of changing tunings during runtime for Adaptive control
|
// of changing tunings during runtime for Adaptive control
|
||||||
|
void SetTunings(double, double, // * overload for specifying proportional mode
|
||||||
|
double, int);
|
||||||
|
|
||||||
void SetControllerDirection(int); // * Sets the Direction, or "Action" of the controller. DIRECT
|
void SetControllerDirection(int); // * Sets the Direction, or "Action" of the controller. DIRECT
|
||||||
// means the output will increase when error is positive. REVERSE
|
// means the output will increase when error is positive. REVERSE
|
||||||
// means the opposite. it's very unlikely that this will be needed
|
// means the opposite. it's very unlikely that this will be needed
|
||||||
@ -63,6 +72,7 @@ class PID
|
|||||||
double kd; // * (D)erivative Tuning Parameter
|
double kd; // * (D)erivative Tuning Parameter
|
||||||
|
|
||||||
int controllerDirection;
|
int controllerDirection;
|
||||||
|
int pOn;
|
||||||
|
|
||||||
double *myInput; // * Pointers to the Input, Output, and Setpoint variables
|
double *myInput; // * Pointers to the Input, Output, and Setpoint variables
|
||||||
double *myOutput; // This creates a hard link between the variables and the
|
double *myOutput; // This creates a hard link between the variables and the
|
||||||
@ -70,11 +80,11 @@ class PID
|
|||||||
// what these values are. with pointers we'll just know.
|
// what these values are. with pointers we'll just know.
|
||||||
|
|
||||||
unsigned long lastTime;
|
unsigned long lastTime;
|
||||||
double ITerm, lastInput;
|
double outputSum, lastInput;
|
||||||
|
|
||||||
unsigned long SampleTime;
|
unsigned long SampleTime;
|
||||||
double outMin, outMax;
|
double outMin, outMax;
|
||||||
bool inAuto;
|
bool inAuto, pOnE;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
***************************************************************
|
***************************************************************
|
||||||
* Arduino PID Library - Version 1.1.1
|
* Arduino PID Library - Version 1.2.0
|
||||||
* by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com
|
* by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com
|
||||||
*
|
*
|
||||||
* This Library is licensed under a GPLv3 License
|
* This Library is licensed under the MIT License
|
||||||
***************************************************************
|
***************************************************************
|
||||||
|
|
||||||
- For an ultra-detailed explanation of why the code is the way it is, please visit:
|
- For an ultra-detailed explanation of why the code is the way it is, please visit:
|
||||||
|
36
examples/PID_PonM/PID_PonM.ino
Normal file
36
examples/PID_PonM/PID_PonM.ino
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/********************************************************
|
||||||
|
* PID Proportional on measurement Example
|
||||||
|
* Setting the PID to use Proportional on measurement will
|
||||||
|
* make the output move more smoothly when the setpoint
|
||||||
|
* is changed. In addition, it can eliminate overshoot
|
||||||
|
* in certain processes like sous-vides.
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
#include <PID_v1.h>
|
||||||
|
|
||||||
|
//Define Variables we'll be connecting to
|
||||||
|
double Setpoint, Input, Output;
|
||||||
|
|
||||||
|
//Specify the links and initial tuning parameters
|
||||||
|
PID myPID(&Input, &Output, &Setpoint,2,5,1,P_ON_M, DIRECT); //P_ON_M specifies that Proportional on Measurement be used
|
||||||
|
//P_ON_E (Proportional on Error) is the default behavior
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
//initialize the variables we're linked to
|
||||||
|
Input = analogRead(0);
|
||||||
|
Setpoint = 100;
|
||||||
|
|
||||||
|
//turn the PID on
|
||||||
|
myPID.SetMode(AUTOMATIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
Input = analogRead(0);
|
||||||
|
myPID.Compute();
|
||||||
|
analogWrite(3,Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -32,3 +32,5 @@ AUTOMATIC LITERAL1
|
|||||||
MANUAL LITERAL1
|
MANUAL LITERAL1
|
||||||
DIRECT LITERAL1
|
DIRECT LITERAL1
|
||||||
REVERSE LITERAL1
|
REVERSE LITERAL1
|
||||||
|
P_ON_E LITERAL1
|
||||||
|
P_ON_M LITERAL1
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=PID
|
name=PID
|
||||||
version=1.1.1
|
version=1.2.0
|
||||||
author=Brett Beauregard
|
author=Brett Beauregard
|
||||||
maintainer=Brett Beauregard
|
maintainer=Brett Beauregard
|
||||||
sentence=PID controller
|
sentence=PID controller
|
||||||
|
Loading…
Reference in New Issue
Block a user