New PID library with digital anti-windup and process control

Fork of PID_modified by Chun Feng Huang

PID.cpp

Committer:
benson516
Date:
2016-10-25
Revision:
2:b9610a2d2ea0
Parent:
1:4df4895863cd
Child:
3:d8646d8c994f

File content as of revision 2:b9610a2d2ea0:

#include "PID.h"

PID::PID(float Kp_in, float Ki_in, float Kd_in,  float Sampletime_in){
    
    // Parameters
    Outputlimit_bool = false;
    Inputlimit_bool = false;
    AntiWindUp_bool = false;
    outputLimits_H = 0.0;
    outputLimits_L = 0.0;
    inputLimits_H = 0.0;
    inputLimits_L = 0.0; 
    feedbackvalue = 0.0; 
    
    // Feedback gain 
    Kp = Kp_in;
    Ki = Ki_in;
    Kd = Kd_in;
    
    // Sampling time
    Ts = Sampletime_in; 
    
    // Variables
    error[0] = 0.0;
    error[1] = 0.0;
    error_I = 0.0;
    //
    reference = 0.0;
    output = 0.0;
     

     
}

void PID::SetOutputLimits(float setoutputLimits_H, float setoutputLimits_L){
    Outputlimit_bool = true;
    outputLimits_H = setoutputLimits_H;
    outputLimits_L = setoutputLimits_L;    
}

void PID::SetInputLimits(float setinputLimits_H, float setinputLimits_L){
    Inputlimit_bool = true;
    inputLimits_H = setinputLimits_H;
    inputLimits_L = setinputLimits_L;     
}

void PID::EnableAntiWindUp(float Ka_)
{
    AntiWindUp_bool = true;
    Ka = Ka_;
}

void PID::Compute(float reference_in, float feedbackvalue_in){

    if(Inputlimit_bool == true){
        if( reference_in > inputLimits_H){
            reference = inputLimits_H;
        }else if( reference_in < inputLimits_L){
            reference = inputLimits_L;
        }else{
            reference = reference_in;
        }
        
    }else{
        reference = reference_in;
    }
    
    // bypass
    feedbackvalue = feedbackvalue_in;
    
    error[0] = reference - feedbackvalue;
    // output = output + ( Kp + Ki + Kd )*error[0] + ( -Kp - 2.0*Kd )*error[1] + Kd*error[2];
    output = Kp*error[0] + Ki*error_I;
    
    // Delay 1
    error[1] = error[0];  
    
    // Integration
    error_I += Ts*error[0];
    
    // Output satuation
    if(Outputlimit_bool && AntiWindUp_bool){
        if( output >= outputLimits_H){
            output = output - (output - outputLimits_H)*Ka;
            //output = outputLimits_H;
        }else if( output <= outputLimits_L){
            output = output - (output - outputLimits_L)*Ka;
            //output = outputLimits_L;
        }
    }else{
        // output = output;
    }
            
}