西門子PLC1200內使用SCL實現簡化版PID算法


西門子自帶的PID效果很好,但是會比較吃性能,使用次數有限,很多地方需要PID但不需要這么精准的PID,所以網上找個簡單的算法自己調用。

 

新建數據類型

 

 

 

前三個就是PID三個參數

 

 

新建FC塊:

 

 

#PIDInfo.Step += 1;
IF #PIDInfo.Step >= #PIDInfo.MaxStep-1 THEN
    #PIDInfo.Step := 0;
    #PIDInfo.Ek := #SetValue - #ActualValue;
    #PIDInfo.LocSum += #PIDInfo.Ek;          //累計誤差
    #PIDResult := #PIDInfo.Kp * #PIDInfo.Ek + (#PIDInfo.Ki * #PIDInfo.LocSum) + #PIDInfo.Kd * (#PIDInfo.Ek1 - #PIDInfo.Ek);
    #PIDInfo.Ek1 := #PIDInfo.Ek;
END_IF;

 

調用:

DB塊內增加變量

 

 Step和MaxStep用於控制掃描多少次調用一次,以及可以錯開調用

 

 左邊填入設置值,實際值,和剛才添加的變量,右邊輸出PID,PID輸出值沒有明確的范圍,自己用Limite限制范圍,調整P值讓輸出值在范圍內浮動

 

 附C#實現

class PID_Info
    {
        float Kp = 1;                       //比例系數Proportional
        float Ki = 0.2f;                       //積分系數Integral
        float Kd = 0.1f;                       //微分系數Derivative

        float Ek;                       //當前誤差
        float Ek1;                      //前一次誤差 e(k-1)
        float Ek2;                      //再前一次誤差 e(k-2)
        float LocSum;                   //累計積分位置


        public static float PID_Calc1(float SetValue, float ActualValue, PID_Info PID)
        {
            float PIDLoc;                                  //位置

            PID.Ek = SetValue - ActualValue;
            PID.LocSum += PID.Ek;                         //累計誤差

            PIDLoc = PID.Kp * PID.Ek + (PID.Ki * PID.LocSum) + PID.Kd * (PID.Ek1 - PID.Ek);

            PID.Ek1 = PID.Ek;
            return PIDLoc;
        }

        public float Calc1(float SetValue, float ActualValue)
        {
            return PID_Calc1(SetValue, ActualValue, this);
        }

        public static float PID_Inc(float SetValue, float ActualValue, PID_Info PID)
        {
            float PIDInc;                                  //增量

            PID.Ek = SetValue - ActualValue;
            PIDInc = (PID.Kp * PID.Ek) - (PID.Ki * PID.Ek1) + (PID.Kd * PID.Ek2);

            PID.Ek2 = PID.Ek1;
            PID.Ek1 = PID.Ek;
            return PIDInc;
        }

        public float Inc(float SetValue, float ActualValue)
        {
            return PID_Inc(SetValue, ActualValue, this);
        }
    }

 

 

算法來自

blog。csdn。net/weibo1230123/article/details/80812211


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM