西門子的PID控制算法-FB(功能塊)封裝主要應用于工業自動化和過程控制系統中,用于實現閉環控制。具體來說,它廣泛應用于需要維持某一設定值的過程變量,如溫度、壓力、流量、速度等的精確控制。
01主要應用場合
制造業:在制造過程中,許多參數如溫度、濕度、壓力等都需要被嚴格控制以確保產品質量。例如,在食品加工、化工生產、制藥等行業中,PID控制可以用來保持反應釜內的溫度穩定。能源管理:在電力、燃氣等能源供應系統中,通過PID控制可以有效地調節發電機組的輸出功率或供氣系統的壓力,以響應需求變化并減少能源浪費。暖通空調(HVAC):樓宇自動化的溫控系統中,PID控制器能夠根據室內溫度傳感器反饋的信息調整加熱器或冷卻器的工作狀態,從而達到節能的目的。水處理:污水處理廠利用PID控制來監控和調整各種水質參數,如pH值、溶解氧濃度等,確保排放標準達標。機器人技術:在機械臂的位置控制或者移動機器人的速度控制上,PID控制同樣扮演著重要角色。
02意義
提高精度:相較于開環控制系統,PID控制能夠更準確地跟蹤設定點,減少誤差。
增強穩定性:通過對比例、積分、微分三個參數的適當調整,可以使控制系統更加穩定,避免過調或震蕩現象。
適應性強:即使面對負載變動或外部干擾,良好的PID調節也能保證系統快速恢復到期望的工作狀態。
簡化編程與維護:使用預封裝的功能塊進行開發,可以大大縮短編程時間,并且由于其模塊化特性,便于后期維護和調試。
綜上所述,西門子提供的PID控制算法-FB塊封裝為工程師提供了一種高效、可靠的方法來構建復雜的自動化控制系統,對于提升生產效率和產品質量有著重要意義。
03FB塊
![](https://file1.elecfans.com/web3/M00/04/3A/wKgZPGdyDbeAOJI7AACMSP_ZAnQ095.png)
![56be69ac-c2c1-11ef-9310-92fbcf53809c.png](https://file1.elecfans.com/web3/M00/04/45/wKgZO2dyDbeAF01bAAE-zGhbN3Q297.png)
![56d3360c-c2c1-11ef-9310-92fbcf53809c.png](https://file1.elecfans.com/web3/M00/04/45/wKgZO2dyDbiASJlqAAB7aL9lHg8528.png)
![56dbe716-c2c1-11ef-9310-92fbcf53809c.png](https://file1.elecfans.com/web3/M00/04/3A/wKgZPGdyDbiAP4hQAAB8Ah9xQYs193.png)
![56ee26a6-c2c1-11ef-9310-92fbcf53809c.png](https://file1.elecfans.com/web3/M00/04/3A/wKgZPGdyDbiAKG7-AACJ5DWvPjA067.png)
IF #COM_
RST THEN //PID初始化
#sIan
teilAlt := #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;
#sRestlnt := 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(W
ORD_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>#DE
ADB_W THEN
#ER := #ErKp - #DEADB_W;
ELSE
#ER := 0.0;
END_IF;
#ErKp := #ER * #G
AIN;//偏差比例增益
#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;
#sRestlnt := 0.0;
ELSIF #MAN_ON THEN //手動值輸入時的積分量計算,用于手動切換自動無擾切換
#Ianteil := #sLmn - #Panteil - #DISV;
#sRestlnt := 0.0;
ELSE //積分計算
#Iant := (#rCYcle / #rTi) * (#ErKp + #sInvAlt) * 0.5 + #sRestlnt;
IF ((#Iant>0.0 AND #sbArwHLmOn) OR #INT_HOLD) OR (#Iant<0.0 AND #sbArwLLmOn)? THEN
? ? ? ? ? ? ? ? #Iant := 0.0;
? ? ? ? ? ? END_IF;
? ? ? ? ? ? #Ianteil := #sIanteilAlt + #Iant;//當前積分值:=上時刻積分值+本次積分量
? ? ? ? ? ? #sRestlnt := #sIanteilAlt - #Ianteil + #Iant;
? ? ? ? END_IF;
? ? ELSE
? ? ? ? #Ianteil := 0.0;
? ? ? ? #sRestlnt := 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;
? ? ? ? #Verstaerk := 0.0;
? ? ? ? #RueckAlt := 0.0;
? ? ? ? #RueckDiff := 0.0;
? ? ? ? #sRueck := 0.0;
? ? END_IF;
? ? 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_HLM 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<=#LMN_LLM THEN? ?//如果到達調節量下限
? ? ? ? ? ? #QLMN_LLM := TRUE;
? ? ? ? ? ? #dLmn := #LMN_LLM;
? ? ? ? ? ? #sbArwLLmOn := TRUE;
? ? ? ? ELSE
? ? ? ? ? ? #QLMN_LLM := FALSE;
? ? ? ? END_IF;
? ? END_IF;
? ? #sLmn := #dLmn;
? ? #dLmn := #dLmn * #LMN_FAC + #LMN_OFF;
? ? #LMN := #dLmn;
? ? #dLmn := #dLmn * 276.48;
? ? IF #dLmn >=32512.0 THEN
#dLmn := 32512.0;
ELSIF #dLmn <= -32512.0 THEN
? ? ? ? #dLmn := -32512.0;
? ? END_IF;
? ? #LMN_PER := INT_TO_WORD(DINT_TO_INT(REAL_TO_DINT(#dLmn)));
? ??
END_IF;
評論