PLC PID 控制入門:參數怎麼調?為什麼你的溫控一直震盪
PID 是工業界用了近百年的控制演算法,到現在仍然是絕大多數溫度、壓力、流量、pH 控制的主力。但它也是最常被亂調的東西——「加大一點試試看」調了三天還在震盪,這種場面每個做自動化的人都見過。
這篇不談微分方程,只講你在現場真正需要知道的事。
一、先問一個問題:你真的需要 PID 嗎?
如果你的執行器只有「開」和「關」兩種狀態——電熱管、加藥泵(定量泵)、增氧機、壓縮機——那你要的多半是遲滯控制(ON/OFF + 死區),不是 PID。
對一個只能全開或全關的加熱器做 PID,結果就是它在設定值附近瘋狂啟停,繼電器和接觸器很快就報廢。
PID 的前提是:執行器可以「連續調節輸出量」。 比例閥、變頻器、SCR 電力調整器、比例加藥泵——這些才是 PID 的對象。
快速判斷:
| 執行器 | 該用什麼 |
|---|---|
| 電磁閥(開/關)、定量加藥泵、增氧機 | 遲滯控制(見計時器與防抖) |
| 電熱管(繼電器切換) | 遲滯,或 PWM 時間比例(週期式輸出) |
| 變頻器、比例閥、SCR、比例泵 | PID |
二、P、I、D 各自在幹嘛(白話版)
假設你要把水溫控制在 30°C,現在是 25°C。
P(比例):看「現在差多少」
差 5 度,就給比較大的輸出;差 1 度,就給小一點。差多少、給多少。
P 太小 → 反應遲鈍,永遠爬不上去。
P 太大 → 反應過度,衝過頭又拉回來,開始震盪。
因為當溫度接近 30°C 時,誤差趨近於零,輸出也趨近於零——但你需要「持續的加熱」才能維持 30°C(熱會散失)。所以它會卡在 29.2°C 之類的地方,永遠差一點點。
這就是為什麼需要 I。
I(積分):看「差了多久」
誤差一直存在,積分項就一直累加,輸出愈來愈大——直到誤差被消滅。它負責把最後那一點點誤差吃掉。
I 太弱(積分時間太長) → 誤差消得很慢。
I 太強(積分時間太短) → 累積過快、過衝、震盪。
D(微分):看「變化多快」
如果溫度正在快速上升,D 會提前踩煞車,避免衝過頭。它預測未來。
因為微分項會放大雜訊。感測器讀值只要跳動一下,D 就會產生一個很大的輸出脈衝——輸出開始抽搐,執行器跟著抖。
溫度控制(慢速、慣性大)通常只用 PI 就夠了。 D 主要用在需要快速響應、且訊號乾淨的場合(例如伺服位置控制)。
如果你一定要用 D,先確保訊號有濾波。
三、現場調參:不用算模型的做法
教科書會教你 Ziegler-Nichols 法(把 P 加大到持續震盪,量週期,套公式)。它有用,但需要讓設備真的震盪起來——在很多現場那是不能接受的(震盪的加藥泵可能讓 pH 超標排放)。
比較安全的實務手法:
步驟 1:先把 I 和 D 關掉,只調 P
- 從一個很保守的小 P 開始
- 逐步加大,觀察對設定值變化的反應
- 加到「稍微會過衝一點點,但很快穩定」就停
- 如果開始持續震盪 → 退回一半
步驟 2:加入 I,消除穩態誤差
- 從很長的積分時間開始(弱的 I)
- 慢慢縮短,直到穩態誤差在可接受時間內被消除
- 一旦看到過衝變大或開始震盪,積分時間就拉回去
步驟 3:D 通常不用加
除非過衝真的無法接受,而且訊號夠乾淨。加的話從很小開始。
溫度系統的時間常數可能是十幾分鐘甚至數小時。你改完參數三十秒就說「沒用」再改一次——那不是調參,那是在製造混亂。
改一個 → 給它時間 → 觀察一個完整的響應 → 再改下一個。 這件事急不得。
四、積分飽和(Integral Windup)——最常見的兇手
如果你的系統「啟動時嚴重過衝」「設定值改變後要很久才穩定」「執行器明明已經全開了還是控制不好」,兇手通常是這個。
假設冷水槽從 10°C 要加熱到 60°C。誤差是 50 度,非常大。
加熱器早就 100% 全開了——它不可能再開更大。但 PID 不知道這件事,積分項還在持續累加,累積成一個巨大的數字。
等到溫度終於到達 60°C、誤差變成 0,積分項還是那個巨大的數字,所以輸出仍然是 100%。
結果:溫度衝到 75°C,然後花很久才降回來。
這就是積分飽和。它不是參數調錯,是程式沒寫好。
對策(三個都要做)
- 輸出限幅——把輸出限制在 0~100%(這是基本的)
- 抗飽和(Anti-windup)——當輸出已經達到上限或下限時,停止累加積分項。這是關鍵的一行。
- 積分項本身也要限幅——雙重保險
// ST 實作要點:抗積分飽和
error := setPoint - processValue;
// 只有在輸出「沒有飽和」時才累加積分
IF NOT outputSaturated THEN
integral := integral + error * dt;
END_IF;
// 積分項自身限幅(雙重保險)
IF integral > integralMax THEN integral := integralMax; END_IF;
IF integral < integralMin THEN integral := integralMin; END_IF;
output := Kp * error + Ki * integral;
// 輸出限幅,並標記是否飽和
outputSaturated := FALSE;
IF output > 100.0 THEN
output := 100.0;
outputSaturated := TRUE;
ELSIF output < 0.0 THEN
output := 0.0;
outputSaturated := TRUE;
END_IF;
西門子
PID_Compact 有輸出上下限設定並自動處理積分;三菱的 PID 指令也有相關參數。所以請優先使用原廠功能塊,不要自己手刻 PID——除非你有很好的理由。原廠的已經處理了抗飽和、無擾動切換、自動整定等一堆你想不到的細節。
如果你在別人的程式裡看到手刻的 PID,而且沒有抗飽和邏輯——那大概就是它控不好的原因。
五、還有三個實務細節,少一個都會出事
1. 手動/自動的「無擾動切換」(Bumpless Transfer)
從手動模式切到自動時,如果 PID 的積分項沒有預先對齊當時的輸出值,輸出會瞬間跳到一個完全不同的值——閥門猛然全開或全關,現場會嚇一跳,而且可能撞壞東西。
正確做法:手動模式時,持續把積分項設定成「目前的手動輸出值」。這樣切到自動的瞬間,輸出是連續的。
2. 取樣週期要固定
PID 的積分與微分都是對時間的運算。如果你的 PID 呼叫週期忽快忽慢(例如放在主程式裡,而主程式的掃描時間會變),積分算出來的值就是錯的。
正確做法:放在固定週期的中斷程式或定時任務中(西門子的 Cyclic Interrupt OB、三菱的固定週期執行類型)。
3. 設定值變化要「緩升」(Setpoint Ramping)
操作員把設定值從 30°C 一口氣改成 60°C,誤差瞬間變成 30 度,PID 會給出一個巨大的輸出——這對設備是很大的衝擊,而且很容易過衝。
正確做法:讓設定值以固定斜率慢慢爬升(例如每分鐘 2°C),而不是階躍變化。
六、什麼時候該放棄 PID
- 製程有很大的延遲(Dead Time)——例如加藥後要 3 分鐘才反映在 pH 值上。PID 在大延遲系統上會很難調,愈調愈震。這時候要考慮加大死區、放慢控制週期,或改用其他策略。
- 執行器只能開關——用遲滯控制。
- 製程本身是分批的(Batch)——例如「進水 → 加藥 → 攪拌 → 沉澱 → 排水」。那是狀態機的工作,不是 PID(見 ST 結構化文本的 CASE 狀態機範例)。
小結
- 執行器不能連續調節,就不要用 PID——用遲滯控制
- P 快、I 準、D 穩;但溫度控制通常 PI 就夠,D 會放大雜訊
- 調參順序:先 P,再 I,D 通常不加。一次改一個,而且要等它穩定
- 積分飽和是頭號兇手——輸出飽和時必須停止累加積分
- 優先用原廠 PID 功能塊,它們已經處理了你想不到的細節
- 別忘了:無擾動切換、固定取樣週期、設定值緩升
我們建了一套 20 題基準測試,題目全部來自真實案場,並且公開了完整結果——包含難看的那幾項: 編譯通過率 80~95%、品牌指令混用 0%、整體全對 55~65%。
還有一個對我們自己不利的發現:AI review 幫得上找出可疑點,但 finding 本身也會誤報、必須經規則層與測試結果校正;它更不能可靠地「修好」程式。
→ 我們把 AI 寫 PLC 的準確率量出來了:20 題基準測試
加藥、溫控、曝氣的 PID,我們實際在調
AI 工具內建 pH/ORP 加藥 PID、溶氧控制、溫室降溫序列等控制塊,已含輸出限幅、抗積分飽和與加藥逾時報警——這些是現場實務,不是教科書預設值。
免費試用 AI PLC 工具 →免費會員每月 15 點 · 不需信用卡
易歐特科技有限公司 · 工業自動化 PLC 程式設計與環控系統整合 · 委託開發