10000 Initial Commit To Git Hub · jim79/Arduino-PID-Library@98d2779 · GitHub
[go: up one dir, main page]

Skip to content

Commit 98d2779

Browse files
committed
Initial Commit To Git Hub
There are 3 changes: - All code changes will now be here instead of on Google Code - The license has been changed to GPLv3 - Support for Arduino 1.0 was added
0 parents  commit 98d2779

File tree

7 files changed

+464
-0
lines changed

7 files changed

+464
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/********************************************************
2+
* PID Adaptive Tuning Example
3+
* One of the benefits of the PID library is that you can
4+
* change the tuning parameters at any time. this can be
5+
* helpful if we want the controller to be agressive at some
6+
* times, and conservative at others. in the example below
7+
* we set the controller to use Conservative Tuning Parameters
8+
* when we're near setpoint and more agressive Tuning
9+
* Parameters when we're farther away.
10+
********************************************************/
11+
12+
#include <PID_v1.h>
13+
14+
//Define Variables we'll be connecting to
15+
double Setpoint, Input, Output;
16+
17+
//Define the aggressive and conservative Tuning Parameters
18+
double aggKp=4, aggKi=0.2, aggKd=1;
19+
double consKp=1, consKi=0.05, consKd=0.25;
20+
21+
//Specify the links and initial tuning parameters
22+
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
23+
24+
void setup()
25+
{
26+
//initialize the variables we're linked to
27+
Input = analogRead(0);
28+
Setpoint = 100;
29+
30+
//turn the PID on
31+
myPID.SetMode(AUTOMATIC);
32+
}
33+
34+
void loop()
35+
{
36+
Input = analogRead(0);
37+
38+
double gap = abs(Setpoint-Input); //distance away from setpoint
39+
if(gap<10)
40+
{ //we're close to setpoint, use conservative tuning parameters
41+
myPID.SetTunings(consKp, consKi, consKd);
42+
}
43+
else
44+
{
45+
//we're far from setpoint, use aggressive tuning parameters
46+
myPID.SetTunings(aggKp, aggKi, aggKd);
47+
}
48+
49+
myPID.Compute();
50+
analogWrite(3,Output);
51+
}
52+
53+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/********************************************************
2+
* PID Basic Example
3+
* Reading analog input 0 to control analog PWM output 3
4+
********************************************************/
5+
6+
#include <PID_v1.h>
7+
8+
//Define Variables we'll be connecting to
9+
double Setpoint, Input, Output;
10+
11+
//Specify the links and initial tuning parameters
12+
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
13+
14+
void setup()
15+
{
16+
//initialize the variables we're linked to
17+
Input = analogRead(0);
18+
Setpoint = 100;
19+
20+
//turn the PID on
21+
myPID.SetMode(AUTOMATIC);
22+
}
23+
24+
void loop()
25+
{
26+
Input = analogRead(0);
27+
myPID.Compute();
28+
analogWrite(3,Output);
29+
}
30+
31+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/********************************************************
2+
* PID RelayOutput Example
3+
* Same as basic example, except that this time, the output
4+
* is going to a digital pin which (we presume) is controlling
5+
* a relay. the pid is designed to Output an analog value,
6+
* but the relay can only be On/Off.
7+
*
8+
* to connect them together we use "time proportioning
9+
* control" it's essentially a really slow version of PWM.
10+
* first we decide on a window size (5000mS say.) we then
11+
* set the pid to adjust its output between 0 and that window
12+
* size. lastly, we add some logic that translates the PID
13+
* output into "Relay On Time" with the remainder of the
14+
* window being "Relay Off Time"
15+
********************************************************/
16+
17+
#include <PID_v1.h>
18+
#define RelayPin 6
19+
20+
//Define Variables we'll be connecting to
21+
double Setpoint, Input, Output;
22+
23+
//Specify the links and initial tuning parameters
24+
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
25+
26+
int WindowSize = 5000;
27+
unsigned long windowStartTime;
28+
void setup()
29+
{
30+
windowStartTime = millis();
31+
32+
//initialize the variables we're linked to
33+
Setpoint = 100;
34+
35+
//tell the PID to range between 0 and the full window size
36+
myPID.SetOutputLimits(0, WindowSize);
37+
38+
//turn the PID on
39+
myPID.SetMode(AUTOMATIC);
40+
}
41+
42+
void loop()
43+
{
44+
Input = analogRead(0);
45+
myPID.Compute();
46+
47+
/************************************************
48+
* turn the output pin on/off based on pid output
49+
************************************************/
50+
if(millis() - windowStartTime>WindowSize)
51+
{ //time to shift the Relay Window
52+
windowStartTime += WindowSize;
53+
}
54+
if(Output < millis() - windowStartTime) digitalWrite(RelayPin,HIGH);
55+
else digitalWrite(RelayPin,LOW);
56+
57+
}
58+
59+
60+

PID_v1/PID_v1.cpp

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/**********************************************************************************************
2+
* Arduino PID Library - Version 1.0.1
3+
* by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com
4+
*
5+
* This Library is licensed under a GPLv3 License
6+
**********************************************************************************************/
7+
8+
#if ARDUINO >= 100
9+
#include "Arduino.h"
10+
#else
11+
#include "WProgram.h"
12+
#endif
13+
14+
#include <PID_v1.h>
15+
16+
/*Constructor (...)*********************************************************
17+
* The parameters specified here are those for for which we can't set up
18+
* reliable defaults, so we need to have the user set them.
19+
***************************************************************************/
20+
PID::PID(double* Input, double* Output, double* Setpoint,
21+
double Kp, double Ki, double Kd, int ControllerDirection)
22+
{
23+
PID::SetOutputLimits(0, 255); //default output limit corresponds to
24+
//the arduino pwm limits
25+
26+
SampleTime = 100; //default Controller Sample Time is 0.1 seconds
27+
28+
PID::SetControllerDirection(ControllerDirection);
29+
PID::SetTunings(Kp, Ki, Kd);
30+
31+
lastTime = millis()-SampleTime;
32+
inAuto = false;
33+
myOutput = Output;
34+
myInput = Input;
35+
mySetpoint = Setpoint;
36+
37+
}
38+
39+
40+
/* Compute() **********************************************************************
41+
* This, as they say, is where the magic happens. this function should be called
42+
* every time "void loop()" executes. the function will decide for itself whether a new
43+
* pid Output needs to be computed
44+
**********************************************************************************/
45+
void PID::Compute()
46+
{
47+
if(!inAuto) return;
48+
unsigned long now = millis();
49+
int timeChange = (now - lastTime);
50+
if(timeChange>=SampleTime)
51+
{
52+
/*Compute all the working error variables*/
53+
double input = *myInput;
54+
double error = *mySetpoint - input;
55+
ITerm+= (ki * error);
56+
if(ITerm > outMax) ITerm= outMax;
57+
else if(ITerm < outMin) ITerm= outMin;
58+
double dInput = (input - lastInput);
59+
60+
/*Compute PID Output*/
61+
double output = kp * error + ITerm- kd * dInput;
62+
63+
if(output > outMax) output = outMax;
64+
else if(output < outMin) output = outMin;
65+
*myOutput = output;
66+
67+
/*Remember some variables for next time*/
68+
lastInput = input;
69+
lastTime = now;
70+
}
71+
}
72+
73+
74+
/* SetTunings(...)*************************************************************
75+
* This function allows the controller's dynamic performance to be adjusted.
76+
* it's called automatically from the constructor, but tunings can also
77+
* be adjusted on the fly during normal operation
78+
******************************************************************************/
79+
void PID::SetTunings(double Kp, double Ki, double Kd)
80+
{
81+
if (Kp<0 || Ki<0 || Kd<0) return;
82+
83+
dispKp = Kp; dispKi = Ki; dispKd = Kd;
84+
85+
double SampleTimeInSec = ((double)SampleTime)/1000;
86+
kp = Kp;
87+
ki = Ki * SampleTimeInSec;
88+
kd = Kd / SampleTimeInSec;
89+
90+
if(controllerDirection ==REVERSE)
91+
{
92+
kp = (0 - kp);
93+
ki = (0 - ki);
94+
kd = (0 - kd);
95+
}
96+
}
97+
98+
/* SetSampleTime(...) *********************************************************
99+
* sets the period, in Milliseconds, at which the calculation is performed
100+
******************************************************************************/
101+
void PID::SetSampleTime(int NewSampleTime)
102+
{
103+
if (NewSampleTime > 0)
104+
{
105+
double ratio = (double)NewSampleTime
106+
/ (double)SampleTime;
107+
ki *= ratio;
108+
kd /= ratio;
109+
SampleTime = (unsigned long)NewSampleTime;
110+
}
111+
}
112+
113+
/* SetOutputLimits(...)****************************************************
114+
* This function will be used far more often than SetInputLimits. while
115+
* the input to the controller will generally be in the 0-1023 range (which is
116+
* the default already,) the output will be a little different. maybe they'll
117+
* be doing a time window and will need 0-8000 or something. or maybe they'll
118+
* want to clamp it from 0-125. who knows. at any rate, that can all be done
119+
* here.
120+
**************************************************************************/
121+
void PID::SetOutputLimits(double Min, double Max)
122+
{
123+
if(Min >= Max) return;
124+
outMin = Min;
125+
outMax = Max;
126+
127+
if(inAuto)
128+
{
129+
if(*myOutput > outMax) *myOutput = outMax;
130+
else if(*myOutput < outMin) *myOutput = outMin;
131+
132+
if(ITerm > outMax) ITerm= outMax;
133+
else if(ITerm < outMin) ITerm= outMin;
134+
}
135+
}
136+
137+
/* SetMode(...)****************************************************************
138+
* Allows the controller Mode to be set to manual (0) or Automatic (non-zero)
139+
* when the transition from manual to auto occurs, the controller is
140+
* automatically initialized
141+
******************************************************************************/
142+
void PID::SetMode(int Mode)
143+
{
144+
bool newAuto = (Mode == AUTOMATIC);
145+
if(newAuto == !inAuto)
146+
{ /*we just went from manual to auto*/
147+
PID::Initialize();
148+
}
149+
inAuto = newAuto;
150+
}
151+
152+
/* Initialize()****************************************************************
153+
* does all the things that need to happen to ensure a bumpless transfer
154+
* from manual to automatic mode.
155+
******************************************************************************/
156+
void PID::Initialize()
157+
{
158+
ITerm = *myOutput;
159+
lastInput = *myInput;
160+
if(ITerm > outMax) ITerm = outMax;
161+
else if(ITerm < outMin) ITerm = outMin;
162+
}
163+
164+
/* SetControllerDirection(...)*************************************************
165+
* The PID will either be connected to a DIRECT acting process (+Output leads
166+
* to +Input) or a REVERSE acting process(+Output leads to -Input.) we need to
167+
* know which one, because otherwise we may increase the output when we should
168+
* be decreasing. This is called from the constructor.
169+
******************************************************************************/
170+
void PID::SetControllerDirection(int Direction)
171+
{
172+
if(inAuto && Direction !=controllerDirection)
173+
{
174+
kp = (0 - kp);
175+
ki = (0 - ki);
176+
kd = (0 - kd);
177+
}
178+
controllerDirection = Direction;
179+
}
180+
181+
/* Status Funcions*************************************************************
182+
* Just because you set the Kp=-1 doesn't mean it actually happened. these
183+
* functions query the internal state of the PID. they're here for display
184+
* purposes. this are the functions the PID Front-end uses for example
185+
******************************************************************************/
186+
double PID::GetKp(){ return dispKp; }
187+
double PID::GetKi(){ return dispKi;}
188+
double PID::GetKd(){ return dispKd;}
189+
int PID::GetMode(){ return inAuto ? AUTOMATIC : MANUAL;}
190+
int PID::GetDirection(){ return controllerDirection;}
191+

0 commit comments

Comments
 (0)
0