PID Controller

A PID Controller (or proportional–integral–derivative controller) is a way of controlling some external system so that it reaches a desired point.

For example a fridge or freezer. Mostly these turn the compressor on when the temperature is too high and off when the temperature is too low, and keep the temperature constant that way. However if you can control the speed of the compressor you can use a PID controller to work out what speed to run the compressor at at any given point, which is a lot more efficient.

Usage

Using the controller is very easy - just give step an error number (difference between desired and current) and it'll give you an output value. To ensure consistent response you'll want to call pid.step at a set time interval.

For example to modulate temperature for a heater:

const PID = require("PID");
var pid = new PID({
  Pg : 1, // proportional gain
  Ig : 1, // integral gain
  Dg : 0, // differential gain
  Imin:-1,Imax:1 // range for clipping integral
});
var desiredTemperature = 20;

setInterval(function() {
  var currentTemperature = getCurrentTemperature();
  var out = pid.step(desiredTemperature - currentTemperature);
  setHeaterPower(0.5+out/2); // out is from -0.5 to 0.5
}, 1000);

The sign of the error and output value is important. You want the sign of the error given to pid.step to match the sign of the output you want, so in this heater example:

A higher out value means the heater turns on, making things hotter. So the error value should be positive if we're too cold (eg. we want to be hotter).

Tuning

Tuning PID systems is important for them to work correctly. There is a good explanation of this at https://pidexplained.com/how-to-tune-a-pid-controller/

To do this easily you probably want to be able to graph the response of the system over time, perhaps using the Graph Library

You need to do the following (using temperature as an example) - with Espruino you can change the PID values on the fly just by sending the relevant commands in the Web IDE's REPL:

1. Proportional

Set Integral and Derivative values to 0, which you can do with pid.Ig = pid.Dg = 0.

Increase the proportional value pid.Pg = ... until the system starts to oscillate when you change the desired temperature valye (with the output value oscillating between the full range of -1..1).

Now divide the proportional value in half and use that.

2. Integral

Once you've done the above, slowly increase the integral pid.Ig, giving time for it to react, and changing the desired temperature suddenly to see how it reacts.

You want the integral increased to the point where the desired temperature is reached quickly, but without oscillation. If there is oscillation then you need to turn the pid.Ig back down.

3. Derivative

The derivative can be used to dampen the response of the PID controller, allowing other values to be more aggressive while letting the derivative stop oscillation or overshoot.

However in many cases it can just be left at 0 (the default for the library).

Check out https://pidexplained.com/how-to-tune-a-pid-controller/ for more information.

Reference

// Call this to reset state to default (keeping gains intact)
PID.prototype.reset = function () { ... }

/* Call this with an error amount, ideally -1..1. An output in the range -1..1 is returned.
Ideally call this function with a fixed time period.
*/
PID.prototype.step = function (err) { ... }

/* Create a new PID object. 'options' can contain
{
  Pg : 1, // proportional gain
  Ig : 1, // integral gain
  Dg : 0, // differential gain
  Imin:-1,Imax:1 // range for clipping integral
}
*/
function (options) { ... }

Using

(No tutorials are available yet)

This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.