view history edit print login register

Arduino PID Library
by Brett Beauregard
contact: br3ttb@gmail.com

DOWNLOAD

PID Library

PID Front-End using Processing.org

  • Latest version: v0.2

Older Versions can be viewed / downloaded here

DESCRIPTION

If you are unfamiliar with PID control, a good place you start might be: http://en.wikipedia.org/wiki/PID_controller

There has been a PID algorithm for the Arduino available for some time now. The goal of this library was to create a more modular pid controller on-par with those found in industry. All of the standard industrial error checks are in there. The main improvements that this Library brings are:

  • Speed of implementation. you still have to tune it, but the coding/debugging piece is easier.
  • The ability to change tunings on the fly (i.e. while in Auto)
  • The addition of input and output limits
  • Being a library, multiple PIDs can be easily created within the same program
  • The option of putting the controller in Manual (turning it off / reinitializing it)
  • Reset-Windup mitigation (the previously published Arduino PID addressed this somewhat. This library does it in a more industry-standard way)

BASIC DEFINITION OF TERMS

I throw around a lot to terms in this wiki. hopefully this example will help decipher some of them. Let's say our PID controller is working as the cruise control in a car. in that situation:

  • Input = Current (Actual) Speed of the Car
  • SetPoint = Your Desired Speed
  • Output = signal to the throttle
  • Error = Setpoint-Input, how far we are from where we want to be. (Ideally we want this to be 0)
  • AUTO(matic) Mode = the cruise control is on and is deciding what the throttle should be.
  • MANUAL Mode = the cruise control is off and you are free to manually adjust the throttle.

  • Tuning parameters (P_Param, I_Param, D_Param) determine how the cruise control will behave. When we change our set point, do we want the controller to stomp on the gas pedal to get there? or do we want it to rise gradually? the tuning parameters allow that to be specified. (adjusting these parameters is known as "tuning" the controller)

NOTES

  • This is my first contribution to the arduino effort, or to any GPL-type effort, so please keep that in mind.
  • This is a pretty robust beta. I've tested it in my projects, but there might be some odd things (interrupts, or low power mode or some other randomness) that I have not encountered. if you have problems let me know.
  • This Library uses around 5k of memory (It's big. I know, I know. see "Still to Come" below)

STILL TO COME

  • A smaller "light" version of the library. I'm holding off on that until I find out what people use / don't use in the full version.
  • Currently, this library doesn't handle the millis() wrap issue. Be aware of this if you plan on running this controller for more than 55 days straight. (this is probably the first issue I'll address)

BASIC TUNING SUGGESTIONS

(these are by no means comprehensive)

  • Unless you know what it's for, don't use D (D_Param=0)
  • Make I_Param about the same as your manual response time (in Seconds)/4
  • Adjust P_Param to get more aggressive or conservative control
  • If you find that your controller output seems to be moving in the wrong direction , change the sign of the P_Param (+/-)

CREATION

PID(double *Input, double *Output, double *SetPoint, double P_Param, double I_Param, double D_Param)

Description: Creates a PID object and links it to the Input, Output, and Setpoint. Initial tuning parameters are also set here.

Arguments:

  • *Input : Link (pointer) with the double that will be the PID's Input
  • *Ouput : Link to the Output
  • *SetPoint : Link to the Set Point
  • P_Param : Proportional Parameter. MUST BE NON-ZERO.
  • I_Param : Integral Parameter. Must be non-negative.
  • D_Param : Derivative Parameter. Must be non-negative.

METHODS

void Compute()

Description: Decides if the PID calculation needs to be performed, and if so, performs it. Ideally this method should be called every time loop() cycles. The PID's Auto / Manual state and calculation frequency can be set using the SetMode(...) and SetCalcFrequency(...) functions respectively.

void SetMode(int Mode)

Description: sets PID to either Manual (0) or Auto (non-0) Mode

Available Constants: MANUAL, AUTO

void SetOutputLimits(double OUTMin, double OUTMax)

Description: This function tells the controller What 0% and 100% are for the Output. By default these limits are 0-255: the Arduino PWM output limits. Take a look at Example 2 below to see how this function was used to quickly set up an on/off time window.

Arguments:

  • OUTMin : 0% of the Output Span. must be < OUTMax
  • OUTMax : 100% of the Output Span. must be >OUTMin

void SetTunings(double P_Param, double I_Param, double D_Param)

Description: While most users will set the tunings once during creation, this function gives the user the option of changing tunings during runtime for Adaptive control

Arguments:

  • P_Param : Proportional Parameter. MUST BE NON-ZERO.
  • I_Param : Integral Parameter. Must be non-negative. 0 = no Integral action.
  • D_Param : Derivative Parameter. Must be non-negative. 0 = no Derivative action.

There are also more advanced methods available

EXAMPLE 1

/********************************************************
 * PID Simple Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_Beta6.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);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(0);
  Setpoint = 100;

  //turn the PID on
  myPID.SetMode(AUTO);
}

void loop()
{
  Input = analogRead(0);
  myPID.Compute();
  analogWrite(3,Output);
}

EXAMPLE 2

/***************************************************
 * Advanced PID Example
 * PID input: Analog input 0
 * output = time proportion on/off of output 0 (50% = 2 sec on, 2 sec off)
 * and just to make it more complicated:
 * - start with a setpoint ramp (0 to 500 over 5 minutes (300 seconds))
 * - use gap control (moderate tunings when within 100 of setpoint, aggressive when outside 100)
 ***************************************************/

 #include <PID_Beta6.h>

 unsigned long windowStartTime;
 unsigned long RampStartTime;
 double Input, Output, Setpoint;
 PID pid(&Input, &Output, &Setpoint, 3,4,1);

unsigned long printTime= millis();

 void setup()
 {

   pid.SetOutputLimits(0,4000); //tell the PID to range the output from 0 to 4000 
   Output = 4000; //start the output at its max and let the PID adjust it from there

   pid.SetMode(AUTO); //turn on the PID
   windowStartTime = millis();
   RampStartTime = millis();
 }


 void loop()
 {

  //Set Point Ramp
   if(millis()-RampStartTime<300000)
   {
     Setpoint = ((double)(millis()-RampStartTime))/(300000.0)*500.0;
   }
   else Setpoint = 500;

   //Set Tuning Parameters based on how close we are to setpoint
   if(abs(Setpoint-Input)>100)pid.SetTunings(6,4,1);  //aggressive
   else pid.SetTunings(3,4,1); //comparatively moderate

   //give the PID the opportunity to compute if needed
   Input = analogRead(0);
   pid.Compute();

   //turn the output pin on/off based on pid output
   if(millis()-windowStartTime>4000) windowStartTime+=4000;
   if(Output > millis()-windowStartTime) digitalWrite(0,HIGH);
   else digitalWrite(0,LOW);

 }

HISTORY

  • 2009/7/4: v0.2 of Front-End Released
  • 2009/5/30: Tuning / Graphing Front-End using Processing.org
    • Graphically Displays performance in real time
    • Can change Mode, SetPoint, and Tuning Parameters; also in real time
  • 2009/2/2: Beta 0.6
    • Renamed the library to reflect the current version. This way if code is posted it will be obvious which version of the library was used.
    • "CalcFrequency" renamed to the more appropriate "SampleTime"
    • Separated SetIOLimits into two functions: the commonly used SetOutputLimits, and the less used SetInputLimits
    • Added a second constructor that allows for Feed Forward control
  • 2008/11/11: Initial Beta Release (Beta 0.5)