PID library for Arduinos with greater accuracy than the legacy Arduino PID library.
PID stands for Proportional, Integral, and Derivative and is a simple type of controller. PID controllers can provide stable control of nearly any system such as the speed of a motor, position of a servo, speed of a car (cruise control), and much more.
See the explanation video here
See here
First import the library, instantiate an ArduPID class, and create 6 doubles:
- Setpoint
- Input
- Output
- P Gain
- I Gain
- D Gain
#include "ArduPID.h"
ArduPID myController;
double setpoint = 512;
double input;
double output;
double p = 1;
double i = 0;
double d = 0;
Next, within the setup()
function, initialize the controller with the references to the input, output, and setpoint variables. Also pass the values of the PID gains. After initializing the controller within setup()
, you can change the settings/configuration of the controller.
void setup()
{
Serial.begin(115200);
myController.begin(&input, &output, &setpoint, p, i, d);
// ADD MORE CONFIGURATION COMMANDS HERE <--------------------
}
Here are the different examples of configuration commands available via the library:
reverse()
- Reverse direction of output
setSampleTime(const unsigned int& _minSamplePeriodMs)
- Will ensure at least
_minSamplePeriodMs
have past between successful compute() calls - this function is not necessary, but is included for convenience
- Will ensure at least
setOutputLimits(const double& min, const double& max)
- Clip output to values to
min
andmax
- Clip output to values to
setBias(const double& _bias)
- Output will have a constant offset of
_bias
, usually used in conjunction withsetOutputLimits()
- Output will have a constant offset of
setWindUpLimits(const double& min, const double& max)
- Clip integral term values to
min
andmax
to prevent integral wind-up
- Clip integral term values to
start()
- Enable/turns on the controller
reset()
- Used for resetting the I and D terms - only use this if you know what you're doing
stop()
- Disable/turn off the PID controller (
compute()
will not do anything untilstart()
is called)
- Disable/turn off the PID controller (
Within the loop()
, update the input variable via your sensor and then call compute()
. The output variable will then be automatically updated and you can use that updated value to send an updated command to your actuator. You can also use the debug()
command to print various status information about your controller to the serial plottor/monitor:
void loop()
{
input = analogRead(A0); // Replace with sensor feedback
myController.compute();
myController.debug(&Serial, "myController", PRINT_INPUT | // Can include or comment out any of these terms to print
PRINT_OUTPUT | // in the Serial plotter
PRINT_SETPOINT |
PRINT_BIAS |
PRINT_P |
PRINT_I |
PRINT_D);
analogWrite(3, output); // Replace with plant control signal
}