首页 > 编程语言 > 详细

西门子PLC1200内使用SCL实现简化版PID算法

时间:2019-11-05 13:15:18      阅读:141      评论:0      收藏:0      [点我收藏+]

西门子自带的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

西门子PLC1200内使用SCL实现简化版PID算法

原文:https://www.cnblogs.com/gxrsprite/p/11797352.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!