PID Controller Basics: PID Implementation in Arduino

发布人是

For those who work in industrial controls, proportional, integral, derivative (PID) theory is likely a familiar concept. For most people, the term is entirely foreign, but you might be more familiar with it than you think. When you press the gas pedal in a car, you not only consider how far you are from your ideal speed—the proportional part of PID—you also take into account how your particular vehicle accelerates as well as conditions like hills.

These more subtle effects are what the I and D terms consider mathematically. In this example, they would prevent a car's speed from bouncing from an upper to a lower limit, and we can apply the same concept to a variety of control situations. While limit-based control can get you in the ballpark, your system will tend to act somewhat erratically.

PID Equation

We can express PID control mathematically with the following equation. P, I, and D are represented by the three terms that add together here. Kp, Ki, and Kd are constants that tune how the system reacts to each factor:

PID Equation 1

We can also replace Ki and Kd with 1/Ti and Td, respectively. This change gives the equation a better relationship to its physical meaning and allows the units to work out properly to a unitless number:

PID Equation 2

We can also transpose the equation to extract the Kp value and apply it to the entire equation, in what's known as the standard form. One advantage of this form is that we can adjust the overall Kp constant for the whole equation at one time:

PID Equation 3

All of this may look a bit intimidating, perhaps even to someone who graduated with an engineering degree. The good news is that you don't have to dig out your Modeling and Analysis of Dynamic Systems textbook to understand what's going on here. And while it never hurts, you don't even have to be able to do calculus.

Breaking the first equation down, we produce u(t)—the unitless controller output on the left-hand side of the equation—by adding three mathematical elements on the right-hand side of the equal sign: P, I, and D. Each element has a constant K value in front (Kp, Ki, and Kd), which signifies each element's weight as they form u(t), or the control output at a specific time. We can individually tune each K value for better system performance, which we'll explain further below:

Proportional (P—Kp)

The first and most crucial term in this equation is the e(t). As such, the Kp value that comes before it is generally larger than the other K values in the equation. Here, e(t) is simply the instantaneous error at a point in time—the actual value of a controlled device minus the desired value. Multiply this by Kp and you have its contribution to the overall controller output.

Integral (I—KI)

The second term in this equation has to do with the combined error over time. It's the sum of all errors experienced on the device:

  • Each time a controller calculates u(t), it adds the instantaneous error to a running tally.
  • This figure is then multiplied by Ki and added into u(t).

Consider a situation where a force holds a motor in place and doesn't allow it to return to the setpoint under normal conditions. As it's out of spec longer and longer, the I term will continue to increase, eventually overcoming this force or reaching the limits of the motor's capability.

Derivative (D—Kd)

The third term in this equation has to do with how fast the error changes:

  1. Controllers take an instantaneous error reading.
  2. Subtract the previous instantaneous reading from it.
  3. Multiply that resulting valueby Kd to calculate its contribution to u(t).

Theoretically, if you only had a D term in this equation and your process steadily maintained the wrong value, this term would remain zero and wouldn't contribute to the proper output. On the other hand, if one of the other two terms tries to make the device's output snap back into place too quickly, the derivative can help dampen the effect.

While the calculus-based expression of this concept can be useful, the reality of PID control is much less magical than it first appears. Practically speaking, we calculate output using only addition, subtraction, and multiplication, factoring in the error and time between readings. In fact, we used pneumatic systems to implement early forms of PID control, using mechanical means to input each "term."

Arduino PID Controller Tutorial

In many situations, it's expedient to plug in a dedicated PID controller to your process, but you can make your own with an Arduino or other similar dev board. You can even write your own PID routine. Express each term in your code in a manner similar to:

  • P:instanteneousError = setpoint – input;
  • I:cumulativeError = += error * elapsedTime;
  • D:rateOfError = (error – errorLastCalculation)/elapsedTime;

To get the necessary output, multiply each of these terms by its respective K value and add them together. On the other hand, if you'd like to avoid reinventing the wheel, you can jump in with Brett Beuregard's PID library. This library takes care of the details for you and lets you focus on tuning P, I, and D constant values as needed.

PID Controller Basics Image 2

To demonstrate PID theory in action, I pulled out an Arduino Nano Every from my toolbox, along with:

  • Motor driver board
  • Infrared sensor
  • Motor salvaged from a Hubsan H107C drone

I printed a breadboard mount for the motor along with a "fan" that blocks light 50% of the time to avoid missing pulses as it spins. The motor driver is the input to the (otherwise uncontrolled) motor, and feedback is based on the time between pulses.

When I finally worked out the code and obtained the 3D-printed parts, I was able to control the motor in a more sophisticated way than operating the power button with  constant PWM (pulse-width modulation) output.

PID Controller Basics Image 3

Code snippet from the PID routine linked above

Notable bits of code include using an interrupt routine to register each pulse as the blocking device spins and calculating the time between pulses using millis(). I set up the PID in the first part of the code outside of the functions with:

PID myPID(&difference, &driverOut, &setPoint,Kp,Ki,Kd, DIRECT);.

Kp, Ki, and Kd are defined before this line in the code, and &difference controls &driverOut, with &setPoint modified by the serial monitor. We can manipulate this math to transform this time difference into RPM, but the PID settings work out as DIRECT outputs because this particular driver turns on when the input is pulled low. As the analog output goes higher (motors off), the delay between pulses also increases.

PID Controller Basics Image 4

An earlier version of PID routine. Note CH1 reads input pulses, while CH2 is output calculated using PID routinelow pulses are inputs to motor.

This simple PID controller example was driven by parts on-hand (including the new Arduino Nano Every) and a motor with which I was loosely familiar. But I was able to demonstrate how to apply PID control in a wide variety of situations, even without all the facts. Whether it's motor control, temperature control of an oven, or balancing a robot, a little PID setup and tuning gives you endless experimentation options.

最新消息

Sorry, your filter selection returned no results.

请仔细阅读我们近期更改的隐私政策。当按下确认键时,您已了解并同意艾睿电子的隐私政策和用户协议。

本网站需使用cookies以改善用户您的体验并进一步改进我们的网站。此处阅读了解关于网站cookies的使用以及如何禁用cookies。网页cookies和追踪功能或許用于市场分析。当您按下同意按钮,您已经了解并同意在您的设备上接受cookies,并给予网站追踪权限。更多关于如何取消网站cookies及追踪的信息,请点击下方“阅读更多”。尽管同意启用cookies追踪与否取决用户意愿,取消网页cookies及追踪可能导致网站运作或显示异常,亦或导致相关推荐广告减少。

我们尊重您的隐私。请在此阅读我们的隐私政策。