Learning Objectives
- 分辨組合邏輯與順序控制,用步驟與轉移描述一個流程
- 說出 SFC 的基本規則:步驟、轉移、動作
- 用步驟位元與 SET/RST 在階梯圖寫出順序控制
- 處理停止時回到初始狀態,以及「等條件消失再轉移」
先做這個,再做那個
前幾課的程式大多是組合邏輯:輸出只看「現在」的輸入。可是很多機器的動作有先後順序:
- 紅綠燈:綠 3 秒 → 黃 1 秒 → 紅 2 秒 → 回到綠。三個燈都沒有按鈕,同樣的輸入在不同時間要有不同的輸出。
- 加工站:輸送帶送來工件 → 到位停下 → 沖壓 1 秒 → 送走 → 等下一個。
這種控制叫順序控制。思考方式是把流程切成步驟(step):
| 名詞 | 意思 | 紅綠燈的例子 |
|---|---|---|
| 步驟 | 機器正在做的一件事;同一時間只有一個(或一組)步驟有效 | 「綠燈」步驟 |
| 動作 | 步驟有效時要做的事 | 綠燈亮 |
| 轉移 | 從一個步驟換到下一個的條件 | 綠燈亮滿 3 秒 |
這就是程式設計裡的狀態機。IEC 61131-3 的順序功能圖(SFC)就是把它畫成圖的語言:
╔═══════╗ 初始步驟(雙框)
║ S0 綠 ║── 動作:綠燈
╚═══╤═══╝
┼ T0:綠燈滿 3 秒
┌───┴───┐
│ S1 黃 │── 動作:黃燈
└───┬───┘
┼ T1:黃燈滿 1 秒
┌───┴───┐
│ S2 紅 │── 動作:紅燈
└───┬───┘
┼ T2:紅燈滿 2 秒 → 回到 S0
SFC 的規則:一個轉移只有在它上面的步驟有效、而且條件成立時才會觸發;觸發後,上面的步驟關閉、下面的步驟啟動。 流程也可以分岔:選擇分支(依條件走其中一條,例如良品走左邊、不良品走右邊)和並行分支(幾個步驟同時進行,全部完成才匯合)。
逐步看:用 Python 寫紅綠燈的狀態機
用字典描述每個步驟的時間與下一步,迴圈每轉一次代表過了 1 秒。注意 step 永遠只有一個值:同一時間只有一個步驟。
在階梯圖裡寫順序:步驟位元
階梯圖沒有「步驟」這種東西,常見的做法是每個步驟用一個內部位元 M(M0.0、M0.1…)代表它是否有效, 用 SET 與 RST 做轉移:
‖ M0.0 綠燈步驟 T0 (S) M0.1 ← 轉移:啟動下一步
‖────| |──────────| |────────────────────────┬─(R) M0.0 ← 同時關閉這一步
‖ M0.0
‖────| |───────────────────────────────── TON T0 3000 ← 這一步的計時
‖ M0.0
‖────| |───────────────────────────────────────( ) Q0.2 ← 動作:綠燈
| 部分 | 寫法 |
|---|---|
| 初始步驟 | 開機或按啟動、且沒有任何步驟有效時,SET 第一個步驟位元 |
| 轉移 | 「目前步驟位元」串聯「轉移條件」→ SET 下一步、RST 這一步 |
| 動作 | 步驟位元 → 輸出線圈(或計時器) |
| 停止、急停 | RST 所有步驟位元,回到初始狀態 |
輸出一律由步驟位元驅動,不要在好幾條 rung 裡 SET/RST 同一個輸出,否則很難找出是誰把燈打開的。
另一種寫法是用一個字組存步驟編號(MOV 1、MOV 2…),再用比較接點判斷「現在是第幾步」,ST 裡就是 CASE Step OF。
感測器轉移:輸送帶加工站
紅綠燈的轉移條件都是時間;工廠裡更多的轉移條件是感測器。下一個例子是輸送帶加工站:
| 步驟 | 位元 | 動作 | 轉移到下一步的條件 |
|---|---|---|---|
| 輸送 | M0.0 | 輸送帶轉 | 光電感測器偵測到箱子(I0.2=1) |
| 加工 | M0.1 | 輸送帶停、沖壓氣缸動作 | 加工滿 1 秒 |
| 送出 | M0.2 | 輸送帶轉 | 箱子離開感測器(I0.2=0) |
注意「送出」步驟的轉移:剛進入送出步驟時,箱子還停在感測器前面,I0.2 仍然是 1。 如果送出步驟一開始就回到輸送步驟,輸送步驟馬上又看到 I0.2=1,同一個箱子會被加工第二次。 所以要等感測器變回 0(箱子走了)才轉移。這種「等條件消失」的轉移在順序控制裡很常見。
下面的範例先用 Python 的步驟編號寫一次(像 ST 的 CASE),再到階梯圖練習。
逐步看:用步驟編號寫加工站
step 是步驟編號,每一秒依目前的步驟檢查各自的轉移條件。注意同一圈只會走 if/elif 其中一條:一次只處理目前這一步。
小測驗:步驟與轉移
下面哪一個最需要順序控制?
SFC 裡,一個轉移什麼時候會觸發?
用 Python 跑紅綠燈的狀態機 5 秒,會印出什麼?
DUR = {"G": 2, "Y": 1, "R": 1}
NEXT = {"G": "Y", "Y": "R", "R": "G"}
step, t, out = "G", 0, ""
for s in range(5):
out += step
t += 1
if t >= DUR[step]:
step, t = NEXT[step], 0
print(out)
小測驗:在階梯圖實作
用步驟位元寫順序控制時,按下停止(或急停復歸後)通常要怎麼處理?
為什麼建議「輸出只由步驟位元驅動」,而不是在好幾條 rung 裡 SET/RST 同一個輸出?
重點整理
- 順序控制:把流程切成步驟,步驟有效時做動作,轉移條件成立時換到下一步;同一時間只有一個步驟(或一組並行步驟)有效。
- SFC:初始步驟(雙框)、步驟、轉移、動作;轉移只在前一步驟有效且條件成立時觸發。可以有選擇分支與並行分支。
- 階梯圖實作:每個步驟一個 M 位元;轉移=目前步驟串聯條件 → SET 下一步、RST 這一步;動作=步驟位元驅動輸出。
- 也可以用一個字組存步驟編號,ST 用
CASE。 - 停止時 RST 所有步驟回到初始狀態;感測器轉移有時要等條件消失(箱子離開)才轉移,避免重複觸發。
下一課進入類比量:4~20 mA、數值換算與 PID 的概念。