• Continued:
    Add a method to do one iteration of PID control

    PIDobj.prototype.update=function(){
      this.N++;
      var A=this.PID;
      var inp=this.Input();
      this.error=this.Setpoint-inp;
      this.integral+=this.error*this.Interval/­1000;
      if(this.integral<0)this.integral=0;
      if(this.integral>1)this.integral=1;
      this.derivative=(this.error-this.previou­s_error)*1000/this.Interval;
    var b=this.out+A.Dir*(A.P*this.integral+A.I*­this.error+A.D*this.derivative);
      if(b<0)b=0;if(b>1)b=1;
    
     this.Output(b);
     this.out=b;
     console.log(this.N,',',this.error.toFixe­d(4),',',inp.toFixed(4),",",b.toFixed(4)­,",",this.Setpoint.toFixed(4));
     var Q = E.openFile(this.PID.Fname, "a");
     Q.write(this.N,this.error.toFixed(4),inp­.toFixed(4),b.toFixed(4),this.Setpoint.t­oFixed(4)+"\r");
     Q.close();
      this.previous_error=this.error;
    };//end update
    
    

    And finally some code to test it all.

    function input1(){
    //  console.log("in ",analogRead("A1"));
      return analogRead("A1");
    }// end input;
    
    
    function output1(a){
    //  console.log("Out ",a);
      analogWrite('A4',a);
    }//end output
    
    function Testit(){
    //A1.mode('analog');
    //A4.mode('analog');
    output1(0.5); //1.0
      var PID1=new PIDobj(PID,0.5,input1,output1,1000);
      input1();
      PID1.start();
    }//end Testit
    
    Testit();
    
    

    For a simple test on an Espruino board I connected pin A4 to Pin A1.
    Some console output:

    >echo(0);
    =undefined
    1 , -0.0005 , 0.5005 , 0.0000 , 0.5000
    2 , 0.4802 , 0.0198 , 0.1441 , 0.5000
    3 , 0.3562 , 0.1438 , 0.2509 , 0.5000
    4 , 0.2493 , 0.2507 , 0.3652 , 0.5000
    5 , 0.1348 , 0.3652 , 0.4672 , 0.5000
    6 , 0.0322 , 0.4678 , 0.5602 , 0.5000
    7 , -0.0618 , 0.5618 , 0.6384 , 0.5000
    8 , -0.1399 , 0.6399 , 0.6965 , 0.5000
    9 , -0.1978 , 0.6978 , 0.7309 , 0.5000
    10 , -0.2329 , 0.7329 , 0.7409 , 0.5000
    11 , -0.2427 , 0.7427 , 0.7282 , 0.5000
    12 , -0.2297 , 0.7297 , 0.7065 , 0.5000
    13 , -0.2080 , 0.7080 , 0.6879 , 0.5000
    14 , -0.1899 , 0.6899 , 0.6707 , 0.5000
    15 , -0.1719 , 0.6719 , 0.6553 , 0.5000
    16 , -0.1563 , 0.6563 , 0.6412 , 0.5000
    17 , -0.1423 , 0.6423 , 0.6284 , 0.5000
    18 , -0.1291 , 0.6291 , 0.6168 , 0.5000
    19 , -0.1182 , 0.6182 , 0.6061 , 0.5000
    20 , -0.1067 , 0.6067 , 0.5965 , 0.5000
    21 , -0.0986 , 0.5986 , 0.5875 , 0.5000
    22 , -0.0884 , 0.5884 , 0.5797 , 0.5000
    23 , -0.0811 , 0.5811 , 0.5723 , 0.5000
    24 , -0.0739 , 0.5739 , 0.5656 , 0.5000
    25 , -0.0669 , 0.5669 , 0.5596 , 0.5000
    26 , -0.0605 , 0.5605 , 0.5542 , 0.5000
    27 , -0.0552 , 0.5552 , 0.5492 , 0.5000
    28 , -0.0498 , 0.5498 , 0.5448 , 0.5000
    29 , -0.0459 , 0.5459 , 0.5406 , 0.5000
    30 , -0.0415 , 0.5415 , 0.5369 , 0.5000
    
    

    Tuning the P, I, and D values is an art. Please consult Google.
    Things to try:

    1. Use an RC low-pass circuit between the output pin and the input pin. One or many stages of RC filter.
    2. Try setting the analogWrite() to a 50 Hz frequency and the pulse width of 1ms for a zero value and 2ms for a 1 value. Connect this output to a servo and use an accelerometer as the input. Mount the accelerometer on the servo arm and have some fun tilting it back and forth. (my parts are on order).
    3. Setup a temperature sensor and a solid state switch supplying current to a heating element to control an oven temperature.
      How to make input, output and setpoint appear to the user in Engineering units?



    2 Attachments

About