
我是这样做的,在实际应用中感觉还行(一个用控制风机频率来实现加温结果恒定的系统):
第一步:先用被控对象目标测量值与设定值都除以量程,(相当于换成百分比了,程序里过程为LAD2,15-16行,F8:27—F8:31/850---F8:35,设定F8:77-F8:33/850—F8:37);
第二步:用换成百分比的设定值减测量值,(LAD3中第1行,F8:11存储),用相减的结果乘以I值(F8:73存储I值,积分系数);
第三步:再计算一个换成百分比的设定值减测量值,乘以0.1后乘以I值后除以P值,然后将此数值和主程序值相加(F8:15,初始切换到自动PID调节时此值为0,见LAD2第18行,自动后每个周期加一次此数),同时把结果也存储到F8:15中(如果调节目标的测量值和实际值之差小于0.2,则将F8:15赋值0,相当于不再累加LAD2第59行);
第四步:将第二步和第四步的值相减存储于F8:17中,并判断其是否大于1,大于1则赋值1;(F8:15和值系数也需要这样一个判读和赋值,不过基本上不可能)
第五步:将计算结果在主程序中(LAD2第20行)乘以输出幅度(输出为风机频率,最大50赫兹),然后在在上一周期输出值基础上累加(LAD2第61行)。
第六步:将上述计算结果换算成模块的输出信号值(先除以输出幅度,变换为百分比,标度变换系数12483)
上述内容自己看着都别扭,简单点讲就是将调节目标的实际值和设定值转换为百分比后取差,然后将差值的1/10×I÷P后再求差,结果累加到输出上去。P值越大,差值越大,I值越大,差值越小,每个扫描周期累加一次,直到实际值和设定值接近。
我用的PLC是AB的MicroLogix1200系列,不知道你能打开不?
typedef struct{float limit //输出限幅
float target //设置量
float feedback //实测量
float Kp //比例系数
float Ki //积分系数
float Kd //微分系数
float eSum //误差积分
float e0 //当前误差
float e1 //上一次误差
}PIDType
#define max(a, b) (a>b? a:b)
#define min(a, b) (a<b? a:b)
#define range(x, a, b) (min(max(x, a), b))
float pid_pos_update(PIDType *p)
{
float pe, ie, de
float out=0
//计算当前误差
p->e0 = p->target - p->feedback
//误差积分
p->eSum += p->e0
//误差微分
de = p->e0 - p->e1
pe = p->e0
ie = p->eSum
p->e1 = p->e0
//数据增量
out = pe*(p->Kp) + ie*(p->Ki) + de*(p->Kd)
//输出限幅
out = range(out, -p->limit, p->limit)
return out
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)