How to Control Output Voltage using a PID
2019-06-26 | By Maker.io Staff
Breadboards Capacitors Arduino
When it comes to closed-feedback loops, PIDs really are the best in the business. Being able to react to past errors, current errors, and even future errors, PID controllers are among the most critical components in modern engineering. But what are they, and how do you use them?
BOM
- Arduino Leonardo 1050-1040-ND
- Linear Potentiometer - 987-1301-ND
- 10K Resistor - CF14JT10K0CT-ND
- 100uF Capacitor - 1189-1300-ND
- Wire
- Breadboard - 1738-1326-ND
- AutoPID Library (See article for install instructions)
Scheme-It
PID Controllers
You will hear about PIDs (Proportional Integral Differential) when looking at many control systems, including industrial controllers, drones, and even cars. They are used to produce smooth, reliable mechanisms that can intelligently react to events. While the internal workings of PIDs involve a bit of math, the best way to understand them is to break them down into their three main parts and examine what those parts do.
A PID typically takes some feedback from an output (where our system currently is), a set point (where we want our system to be), and three constants (one for the P, I, and D terms) to produce an error output value. The diagram below shows the typical layout of a PID controller.
The first stage of the PID controller calculates the difference between the set point and the output. This value is the absolute error in our output. This absolute error is fed into the P, I, and D calculators, which then have their values summed together to produce the final error output. This error output is then used to adjust the output, and the whole process repeats.
The P section of the PID controller calculates an error value that is proportional to the absolute error. This can be thought of as the error at one exact moment.
The I section of the PID controller calculates an error value that is the integral of the absolute error. A simple way to describe this error value is that it’s the historic error that accumulates over time. If the output has been wrong for a long time, this value will get bigger as it “remembers” all the past errors.
The D section of the PID controller calculates an error value that is the differential of the absolute error. In other words, it differentiates the error and tries to predict what the error is going to be (for example, if the output falls, then the differential will say “the value is falling, and I predict it will continue to fall”).
The Intelligence of a PID Controller
The relationship between the I and D sections of a PID controller demonstrate the intelligence behind it. For example, the D section could produce an error value, as it has detected a change in the error value, but this could be canceled out by the I section, as it has detected that the past historical error will cancel out with the current change in the error value (essentially considering the past and future at the same time).
PID Library on the Arduino Uno
The Arduino Uno has a PID library, and it can be used for many different applications. In this How-To, we control an output voltage using a PID that reads the output voltage and tries to match this to a voltage formed on an external potentiometer.
To get the AutoPID library, go to the library manager in the Arduino IDE and search for AutoPID.
A detailed guide on how to install an Arduino Library can be found here https://www.arduino.cc/en/guide/libraries#toc3
Download the Arduino Code
#include <AutoPID.h> // PID settings and gains #define OUTPUT_MIN 0 #define OUTPUT_MAX 255 #define KP 0.12 #define KI 0.8 #define KD 0.003 // Variables double analogReadValue, setPoint, outputVal; // Input/output variables passed by reference, so they are updated automatically AutoPID myPID(&analogReadValue, &setPoint, &outputVal, OUTPUT_MIN, OUTPUT_MAX, KP, KI, KD); // Setup timeStep void setup() { myPID.setTimeStep(500); } void loop() { setPoint = analogRead(A3); // Set our desired point (read the POT) analogReadValue = analogRead(A1); // Read our output voltage myPID.run(); // Run the PID analogWrite(6, outputVal); // Write the PID result to the output }
Code Explanation
While most of the code is self-explanatory, let’s look at a few lines.
The first line is setTimeStep(), which tells the PID controller the timeStep that will be used. If this value is too large, then the PID controller can struggle to function properly, and there is a chance that your output will oscillate and swing too much. 500ms is generally a good value for use with voltages generated via PWM.
The next lines are the KP, KI, and KD values. These are the constants that are used by the PID controller to change the behavior of the individual P, I, and D sections. These values are obtained experimentally, so you will need to change these values to best work for your application.
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum