## Overview

This code is a working example of a
**PID**
(Proportional, Integral, Derivative)
**
control**.
This type of a **
control**
is used when **
processes**
change due to inertia. (A car's cruise
control is a
**PID**
controller.)
The **PID**
algorithm is surprisingly simple, and can be
implemented in five lines of code. There are three
constants that must be determined in order to shape
the control's
output. The three constants as well as the set point
and sampling interval can be changed in real time.
The resulting shape of the output will be displayed
in a strip **chart**.

## How are PID loops
used?

Many **real**
world processes
build up over **time**.
When you step on the accelerator, your car moves
slowly, then faster, and faster still, until you let
off the gas pedal. As you speed up, you press the
gas pedal less, then a little less, then even less,
until you reach the speed limit. Unlike the digital
world where things are either “on” (1) or “off” (0),
real processes
have varying degrees of “on”. In the driving
example, how much the accelerator is turned “on”
depends on the car's current inertia and how
different the car's speed is from the speed limit.
Controlling
such a process
with inertia can be done with only five lines of
code. But, just like learning to drive, it takes
practice to know if you are starting too quickly, or
if you'll overshoot the speed limit.

Cruise **
control**
is one example of a** PID
control l**oop.
To calculate the output, it needs three factors. The
first, (P), is the difference between the current
speed and the desired speed. The second, (I), is the
sum of the differences over time. And, the third,
(D), is the rate of change between sampled
differences. Each factor is scaled by a gain
constant; they are refered to as Kp, Ki, and Kd. The
value of these gain constants determines how
responsive the output will be. If the Kp, Ki, and Kd
values are too high, the output (car's speed) will
far exceed the set point (speed limit). Set too low,
the output may never reach the set point (like
driving 40mph on the highway).

## Code implementation

In the **real**
world, a **
process**
updates constantly. In order to
**simulate** this
action, a timer is used to run an equation that
models the **
process**.
From a second timer, the **
PID** **
control**
algorithm samples the **
process**
value at a rate slower than the
**
process**
model updates. The “Process
Value” or PV timer should run at least twice as
faster than the “**PID
control**”
timer. In the application, the PV timer runs every
17ms, and the **PID**
timer runs every 100ms.

The PV timer (`tmrPV`

)
tick event handler runs the following code:

Collapse |

Copy Code
private void tmrPV_Tick(object sender, EventArgs e)
{
PV = PV + (output * 0.20) - (PV * 0.10) + noise;
}

The **PID
control**
timer (`tmrPID_Ctrl`

)
tick event handler runs:

Collapse |

Copy Code
private void tmrPID_Ctrl_Tick(object sender, EventArgs e)
{
error = setpoint - PV;
integral = integral + (error * Dt);
derivative = (error - preError) / Dt;
output = (Kp * error) + (Ki * integral) + (Kd * derivative);
preError = error;
}

## Take a look at some typical output shapes

In the images below, the green line is the set
point, the blue line is the input (or
**
process**
value), and the red line is the output (or
manipulated value).

Correct **
control**
signal. All three gain constants are set
correctly.

Overshoot. Integral constant too high.

Undershoot. Integral constant too low.

Ringing. Integral and Proportional gain
constants too low.

Noise (under
control). All three constants are set
correctly.

Noise (not
controlled). Derivative gain constant too
high.

## Code modifications
you might consider

This example works for modeling any
**
process**
that has inertia. The **
process**
being modeled here is a car's cruise
**
control**.
In order to adapt the code to model a
**
process**
other than cruise
control, the equation in the PV timer tick
event handler should be changed.

I use **PID**
loops for electric furnace **
control**.
In furnace **
control**,
thermal mass is measured by sampling temperature.
Better **PID** loop
tuning results in efficient energy use. The code
currently in the PV timer tick event handler is
pretty close to a furnace equation. You can modify
the equation to fit the system you want to model. As
a rule of thumb, use the following equation:

Collapse |

Copy Code
ProcessValue = ProcessValue + (output * efficiency) – loss

In a real cruise **
control**,
there are limits on how much the output can change
from sample to sample. This example does not include
any way to limit the output's magnitude of the
change. Such code might look like:

Collapse |

Copy Code
if ( (output – outputLast) > maxChange)
output = outputLast + maxChange;
else if ( (outputLast – output) > maxChange)
output = outputLast – maxChange;
outputLast = output;

The noise that can be added to the signal is not
representative of anything your car might encounter.
(It is really just a model of electrical noise.)
Noise to a car's cruise **
control**
might be something like a hill, or a gust of wind.
Both of those examples have a lower frequency than
our noise. Since the noise is created in its own
timer event handler, you can change the interval of
the noise to change its frequency. You could also
change the noise equation to model the effects of a
hill, or even a chilling arctic blast.