# PID Control Object (with questions)

• A standard way to implement a feedback control system is the Proportional, Integral, Derivative (PID) control algorithm.
Think of things to control and how different the control action can be.
Driving a car. Use a compass module as the input and a motor to steer the wheels. As a driver you turn and hold the steering wheel until the new heading is achieved. Does a boat work the same way?
When piloting an airplane you turn the yoke to tilt the plane over about 15 degrees and then neutralize the yoke. The plane will circle until you turn the yoke to level the plane. (I’m ignoring rudder action)
When riding a bicycle or motorcycle, once in motion, the controls act opposite to that of a car. Turn right and the bike tilts to the left and you the bike turns left.
So how to implement PID control?
We need:

1. An input sensor such as a compass module, a thermistor, a thermocouple, an accelerometer, a piezo-gyro etc.
2. An output device that can be controlled using either a 0 to 3 Volt Voltage or a pulse width (servo motor).
3. The PID algorithm implemented in Espruino.
https://en.wikipedia.org/wiki/PID_contro­ller

previous_error = 0
integral = 0
start:
error = setpoint - measured_value
integral = integral + error*dt
derivative = (error - previous_error)/dt
output = Kp*error + Ki*integral + Kd*derivative
previous_error = error
wait(dt)
goto start

Suppose the setpoint is 0.5 and the measured value is 1.0. Then errpr= 0.5 – 1.0 = -0.5. Let dt = 1 second, then integral = 0.0 – 0.5 * 1 = -0.5 and derivative= (-0.5 -0.0 )/1 = -0.5.

I think we have a problem since in an Espruino world analog inputs and outputs work between 0.0 and 1.0. I tried coding this and ran into this problem.
Another link from a University course just seems to confuse the issue.
http://www.cds.caltech.edu/~murray/cours­es/cds101/fa02/caltech/astrom-ch6.pdf
I recall from a course taken many years ago that the PID algorithm can be expressed in a differential form so that the change in output is expressed as a function of the PID terms.
doutput = P*sumof(error) + I *error + D*derivative,
Where:
P=Kp= the proportional gain,
I=Ki= the integral gain, and
D=Kd= the derivative gain.
Maybe a math GURU can properly insert the dt values into the equation.

First let’s setup a PID object:

``````//The PID is an object that could be supplied as a stringified file or client
//request using http. For development it is coded here.
var PID={
Dir:1,//direction +1 or -1
P:0.1,//proportional gain
I:0.1,//integral gain
D:0.1,//derivative gain
Fname:"PID.CSV" //a file to record results in CSV format on the SD card
};

``````

The Dir field is used to reverse the control action.
The Fname field is used to record a CSV file.
Now implement an object to use the PIS information and extend it.

``````//The constructor for PIDobj
function PIDobj(pid,setpoint,input,output,interva­l){
this.Interval=interval; //How often to apply algorithm
this.Input=input; // a function that returns the process value
this.Output=output; //a function that applies the output
this.PID=pid; // a pointer to the PID object
this.error=0;
this.Setpoint=setpoint;
this.integral=0;
this.derivative=0;
this.previous_error=0;
this.id=0;
this.out=0;
this.N=0; // a counter for the CSV file
}//end TimeObj

//exports =PIDobj;

``````

Adding a method to setup and start the timer

``````PIDobj.prototype.start = function() {
this.N=0;
var Q = E.openFile(this.PID.Fname, "w");
Q.write("N,Error,Input,Output,Setpoint\r­");
Q.close();
if (this.id) return;
this.id = setInterval( this.update.bind(this), this.Interval );
};//end start

``````

Add a method to stop the timer

``````PIDobj.prototype.stop=function(){
if (this.id) {
clearInterval(this.id);
this.id = null;
console.log(this.PID.Fname, "Finished");
console.log(process.memory().usage);
}//endif this.id
};//end stop

``````