求助用西门子做PID调节

求助用西门子做PID调节,第1张

给你个PID控制算法的程序段,该程序是西门子PLC的SCL程序。带"_IN"与带"_OUT"的变量,如果前缀是一样的,要求连接同一个变量。这段程序已经在温度控制上运行通过了。

FUNCTION FC1 : VOID

VAR_INPUT

Run:BOOL //True-运行,False-停止

Auto:BOOL //True-自动,False-手动

ISW:BOOL //True-积分有效,False-积分无效

DSW:BOOL //True-微分有效,False-微分无效

SetMV:REAL //手动时的开度设定值

SVSW:REAL //当设定值低于SVSW时,开度为零

PV:REAL //测量值

SV:REAL //设定值

DeadBand:REAL //死区大小

PBW:REAL //比例带大小

IW:REAL //积分带大小

DW:REAL //微分带大小

dErr_IN:REAL //误差累积

LastPV_IN:REAL //上一控制周期的测量值

END_VAR

VAR_OUTPUT

MV:REAL //输出开度

dErr_OUT:REAL //误差累积

LastPV_OUT:REAL//上一控制周期的测量值

END_VAR

VAR

Err:REAL //误差

dErr:REAL //误差累积

PBH:REAL //比例带上限

PBL:REAL //比例带下限

PVC:REAL //测量值在一个控制周期内的变化率,即测量值变化速率

P:REAL //比例项

I:REAL //积分项

D:REAL //微分项

END_VAR

IF Run=1 THEN

IF Auto=1 THEN

IF SV>=SVSW THEN

Err:=SV-PV

PBH:=SV+PBW

PBL:=SV-PW

IF PV<PBL THEN

MV:=1

ELSIF PV>PBH THEN

MV:=0

ELSE

P=(PBH-PV)/(PBH-PBL) //计算比例项

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////以下为积分项的计算//////////////////////////////////////////////////////////////

IF ISW=1 THEN

dErr:=dErr_IN

IF (PV<(SV-DeadBand)) OR (PV>(SV+DeadBand)) THEN

IF (dErr+Err)<(0-IW) THEN

dErr:=0-IW

ELSIF (dErr+Err)>IW THEN

dErr:=IW

ELSE

dErr:=dErr+Err

END_IF

END_IF

I:=dErr/IW

dErr_OUT:=dErr

ELSE

I:=0

END_IF

/////////////////////////////////////////////以上为积分项的计算//////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////以下为微分项的计算//////////////////////////////////////////////////////////////

IF DSW=1 THEN

PVC:=LastPV_IN-PV

D:=PVC/DW

LastPV_OUT:=PV

ELSE

D:=0

END_IF

/////////////////////////////////////////////以上为微分项的计算//////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

IF (P+I+D)>1 THEN

MV:=1

ELSIF (P+I+D)<0 THEN

MV:=0

ELSE

MV:=P+I+D

END_IF

END_IF

ELSE

MV:=0

END_IF

ELSE

MV:=SetMV

END_IF

ELSE

MV:=0

END_IF

END_FUNCTION

剑指工控微信技术群,很多人都在问PID的复杂的微积分算法如何形成程序的?我在这里把STEP7 里FB41源代码和注释给大家贴出来,让大家学习一下,FB41是积分PID。另外如果大家习惯了STEP7的PID也可以通过这个源代码移植到别的控制器上。

FUNCTION_BLOCK "CONT_C"

TITLE ='continuous PID controller'

AUTHOR : Jiansiting

FAMILY : JZGK

NAME : CONT_C

VERSION : '2.0'

KNOW_HOW_PROTECT

VAR_INPUT

COM_RST : BOOL := FALSE//完全重启动

MAN_ON : BOOL := TRUE//手动值打开

PVPER_ON : BOOL := FALSE//外设过程变量打开

P_SEL : BOOL := TRUE//比例作用打开

I_SEL : BOOL := TRUE//积分作用打开

INT_HOLD : BOOL := FALSE//积分作用保持

I_ITL_ON : BOOL := FALSE//积分作用初始化

D_SEL : BOOL := FALSE//微分作用打开

CYCLE : TIME := T#1S//采样时间

SP_INT : REAL := 0.0//内部设定值

PV_IN : REAL := 0.0//过程变量输入

PV_PER : WORD := W#16#0//外设过程变量

MAN : REAL := 0.0//手动值

GAIN : REAL := 2.0//比例增益

TI : TIME := T#20S//积分复位时间

TD : TIME := T#10S//微分时间

TM_LAG : TIME := T#2S//微分作用时间延时

DEADB_W : REAL := 0.0//死区带宽

LMN_HLM : REAL := 100.0//积分值上限

LMN_LLM : REAL := 0.0//积分值下限

PV_FAC : REAL := 1.0//过程变量因子

PV_OFF : REAL := 0.0//过程变量偏移量

LMN_FAC : REAL := 1.0//调节值因子

LMN_OFF : REAL := 0.0//调节值偏移量

I_ITLVAL : REAL := 0.0//积分作用的初始化值

DISV : REAL := 0.0//干扰变量

END_VAR

VAR_OUTPUT

LMN : REAL := 0.0//调节值

LMN_PER : WORD := W#16#0//外设调节值

QLMN_HLM : BOOL := FALSE//达到调节值上限

QLMN_LLM : BOOL := FALSE//达到调节值下限

LMN_P : REAL := 0.0//比例分量

LMN_I : REAL := 0.0//积分分量

LMN_D : REAL := 0.0//微分分量

PV : REAL := 0.0//

ER : REAL := 0.0//误差信号

END_VAR

VAR

sInvAlt : REAL := 0.0//上周期比例偏差值

sIanteilAlt : REAL := 0.0//上周期积分值

sRestInt : REAL := 0.0//上周期积分偏差量(浮点数计算偏差)

sRestDif : REAL := 0.0//上周期微分偏差量(浮点数计算偏差)

sRueck : REAL := 0.0//

sLmn : REAL := 0.0//上周期调节值

sbArwHLmOn : BOOL := FALSE//上周期达到调节值上限

sbArwLLmOn : BOOL := FALSE//上周期达到调节值下限

sbILimOn : BOOL := TRUE//备用-本程序没有使用该变量

END_VAR

VAR_TEMP

rCycle : REAL //采样时间浮点值

Iant : REAL //积分增量

Diff : REAL //积分量

Istwert : REAL //过程变量浮点值

ErKp : REAL //偏差比例值

rTi : REAL //积分时间浮点值

rTd : REAL //微分时间浮点值

rTmLag : REAL //微分作用时间延时浮点值

Panteil : REAL //比例值

Ianteil : REAL //积分值

Danteil : REAL //微分值

Verstaerk : REAL //

RueckDiff : REAL //

RueckAlt : REAL //上周期积分量

dLmn : REAL //调节量

gf : REAL //Hilfwert

rVal : REAL //Real Hilfsvariable

END_VAR

IF COM_RST THEN //PID初始化

sIanteilAlt := I_ITLVAL

LMN := 0.0

QLMN_HLM := FALSE

QLMN_LLM := FALSE

LMN_P := 0.0

LMN_I := 0.0

LMN_D := 0.0

LMN_PER := W#16#0

PV := 0.0

ER := 0.0

sInvAlt := 0.0

sRestInt := 0.0

SRestDif := 0.0

sRueck := 0.0

sLmn := 0.0

sbArwHLmOn := FALSE

sbArwLLmOn := FALSE

ELSE

rCycle := DINT_TO_REAL( TIME_TO_DINT( CYCLE ) ) / 1000.0 //采样时间转换为浮点数值

Istwert := DINT_TO_REAL( INT_TO_DINT( WORD_TO_INT ( PV_PER ) ) ) * 0.003616898

Istwert := Istwert * PV_FAC + PV_OFF //外设输入转换为浮点数值

IF NOT PVPER_ON THEN //过程变量选择

Istwert := PV_IN

END_IF

PV := Istwert

ErKp := SP_INT - PV //计算偏差

IF ErKp <-DEADB_W THEN

ER := ErKp + DEADB_W

ELSIF ErKp >DEADB_W THEN

ER := ErKp - DEADB_W

ELSE

ER := 0.0

END_IF

ErKp := ER * GAIN //偏差比例增益

rTi := DINT_TO_REAL( TIME_TO_DINT( TI ) ) / 1000.0

rTd := DINT_TO_REAL( TIME_TO_DINT( TD ) ) / 1000.0

rTmLag := DINT_TO_REAL( TIME_TO_DINT( TM_LAG ) ) / 1000.0

IF rTi rCycle * 0.5 THEN //积分时间必须 >= 采样时间的0.5倍

rTi := rCycle * 0.5

END_IF

IF rTd rCycle THEN //微分时间必须 >= 采样时间

rTd := rCycle

END_IF

IF rTmLag rCycle * 0.5 THEN //微分作用延时时间必须 >= 采样时间的0.5倍

rTmLag := rCycle * 0.5

END_IF

IF P_SEL THEN //比例作用投入

Panteil := ErKp

ELSE

Panteil := 0.0

END_IF

IF I_SEL THEN //积分作用投入

IF I_ITL_ON THEN //积分初始化

Ianteil := I_ITLVAL

sRestInt := 0.0

ELSIF MAN_ON THEN //手动值输入时的积分量计算,用于用于手动切换自动无扰切换

Ianteil := sLmn - Panteil - DISV

sRestInt := 0.0

ELSE //积分计算

Iant := ( rCycle / rTi ) * ( ErKp + sInvAlt ) * 0.5 + sRestInt

IF ( ( Iant >0.0 AND sbArwHLmOn ) OR INT_HOLD ) OR ( Iant <0.0 AND sbArwLLmOn )THEN //抗积分饱和

Iant := 0.0

END_IF

Ianteil := sIanteilAlt + Iant //当前积分值 := 上时刻积分值 + 本次积分量

sRestInt := sIanteilAlt - Ianteil + Iant

END_IF

ELSE

Ianteil := 0.0

sRestInt := 0.0

END_IF

Diff := ErKp

IF NOT MAN_ON AND D_SEL THEN //微分作用投入

Verstaerk := rTd / ( rCycle * 0.5 + rTmLag )

Danteil := ( Diff - sRueck ) * Verstaerk

RueckAlt := sRueck

RueckDiff := rCycle / rTd * Danteil + sRestDif

sRueck := RueckDiff + RueckAlt

sRestDif := RueckAlt - sRueck + RueckDiff //同积分一样计算微分误差量

ELSE //

Danteil := 0.0

sRestDif := 0.0

sRueck := Diff

END_IF

dLmn := Panteil + Ianteil + Danteil + DISV //PID输出

IF MAN_ON THEN //PID手动之打开

dLmn := MAN

ELSE

IF NOT I_ITL_ON AND I_SEL THEN //干扰量处理

IF Ianteil >LMN_HLM - DISV AND dLmn >LMN_HLM AND dLmn - LMN_D >LMN_HLM THEN

rVal := LMN_HLM - DISV

gf := dLmn - LMN_HLM

rVal := Ianteil - rVal

IF rVal >gf THEN

rVal := gf

END_IF

Ianteil := Ianteil - rVal

ELSIF Ianteil <LMN_LLM - DISV AND dLmn <LMN_LLM AND dLmn - LMN_D <LMN_LLM THEN

rVal := LMN_LLM - DISV

gf := dLmn - LMN_LLM

rVal := Ianteil - rVal

IF rVal <gf THEN

rVal := gf

END_IF

Ianteil := Ianteil - rVal

END_IF

END_IF

END_IF

LMN_P := Panteil

LMN_I := Ianteil

LMN_D := Danteil

sInvAlt := Erkp

sIanteilAlt := Ianteil

sbArwHLmOn := FALSE

sbArwLLmOn := FALSE

IF dlmn >= LMN_HLM THEN //调节辆限幅(上限)

QLMN_HLM := TRUE

QLMN_LLM := FALSE

dlmn := LMN_HLM

sbArwHLmOn := TRUE

ELSE

QLMN_HLM := FALSE

IF dLmn = 32512.0 THEN

dLmn := 32512.0

ELSIF dLmn


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11757588.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存