為每個產品建立身分
輸送線上的結果對錯產品,通常不是檢測公式錯,而是產品進站與結果回來的順序沒有被記錄。你先替每件產品建立 product_id,再用固定容量 FIFO 保存順序;每個站點回饋都要帶有事件或站點狀態,不能只用一個 done 位元猜測。本文以容量 5、兩個站點、產品 P01~P05 示範。FIFO 內容是識別碼與 status 的資料列。
| 欄位 | 用途 | 規則 |
|---|---|---|
| product_id | 追溯產品 | 入線時遞增且不重複 |
| status | 目前站點狀態 | WAIT/AT_S1/AT_S2/DONE/FAULT |
| head/tail | 出入位置 | 只在成功出列或入列後更新 |
| count | 目前筆數 | 0 到 5,禁止超界 |
入線脈衝先檢查 count<5,再寫入 tail。
站點結果先更新 head 所指產品,完成且允許出列才移除。
每次事件記錄 product_id、station、sequence,供事後對照。
定義滿 空與站點跳過
本例規則:count=0 時不可讀 head;count=5 時新產品進入被拒絕並產生 QUEUE_FULL,不覆蓋最早資料。產品可跳過 S1,但要把 status 明確寫成 SKIP_S1,再等待 S2;不可把「沒有 S1 結果」解讀成 P03 已完成。重複訊號以 event_id 去重,同一產品同一站點相同 event_id 第二次只記錄 DUPLICATE,不再次推進 FIFO。
| 掃描事件 | FIFO 順序 | count | 處置 |
|---|---|---|---|
| E1 P01 入線 | P01 | 1 | 寫入 tail=0 |
| E2 P02 入線 | P01,P02 | 2 | 正常 |
| E3 P03 入線 | P01,P02,P03 | 3 | 正常 |
| E4 P01 S1完成 | P01,P02,P03 | 3 | 更新 P01,不出列 |
| E5 P01等待S2 | P01,P02,P03 | 3 | 仍由P01佔head,不出列 |
| E6 P01 S2完成 | P02,P03 | 2 | P01 完成後出列 |
注意:FIFO 保證的是進入順序,不保證所有站點都同步回報。若 S2 回報的是 P02,但 head 是 P01,先停下並記錄 OUT_OF_ORDER;本教學即使有ID也不允許跳過head;多站並行需另設站點映射及結果暫存。
偽碼與錯配防護
教學偽碼,非指定PLC語法,所有資料由一個流程更新:
若入線事件:
若count<CAPACITY:寫queue[tail];tail回繞;count加一
否則報QUEUE_FULL,不覆寫
若結果事件:
若事件已處理:只回確認,不改資料
否則若count=0:報孤立回饋
否則:p:=queue[head]
若ID與站點順序合法:更新p;queue[head]:=p;保存已處理事件ID
否則報OUT_OF_ORDER,不出列
若count>0:
若queue[head].status=DONE且允許出列:head回繞;count減一
使用巢狀條件避免依賴AND短路;滿佇列同次入出時,本例先拒絕入列,再處理出列。
| 防護 | 可觀察證據 | 錯誤結果 |
|---|---|---|
| ID 對照 | event.product_id=queue[head].id | 拒絕,不出列 |
| 重複去重 | event_id 已存在 | 只記錄,不重算 |
| 滿佇列 | count=5 | 停入線並報警 |
| 空佇列 | count=0 | 拒絕結果,報孤立回饋 |
| 跳站 | status=SKIP_S1 | S2 結果仍對同一 ID |
若站點回饋沒有產品 ID,你要在站點入口建立 handshake_token,送出產品時鎖定 token,若設備支援回傳token,必須相符才更新;若連token都不支援,只能使用單筆在途且遇失聯即停下核對的受限協議。token 不同時,先停止佇列推進並保留現場資料。入列感測器的機械抖動要以一次脈衝或去彈跳時間處理,不能用連續高電位反覆入列。當產品被跳過站點,仍要產生可追溯的 SKIP 事件;當產品回流重測,應建立新的流程序號但沿用 product_id,否則報表會把同一件產品當成兩件。容量與逾時要在啟動前檢查,避免執行中才發現佇列無法容納。
五件產品的驗收演練
本篇 FIFO 只示範 head 產品的簡化處理,並非可同時容納多站結果的完整流水線實作;實作需為每筆資料寫回陣列。P03 必須先收到明確 SKIP_S1,才允許接受 S2 結果。感測器兩件同時出現需由硬體雙通道或位置編碼分辨,去彈跳只能消除抖動,不能產生兩個事件。
完整追蹤還要考慮輸送線速度與事件延遲。產品入列時記錄進站掃描編號或時間戳,站點回饋時先用 ID 對照,再檢查該站是否已完成;站點完成的先後不能改變 FIFO 的產品順序。若 P03 卡在 S1,P04 的結果回來,系統應保持 P03 為 head 並把 P04 事件放進待確認區,不能丟掉也不能套用。待確認區也要有容量,滿時停線並報警。產品從線體被取走時,操作員選擇實際 ID,PLC 記錄 TAKEAWAY 原因後才出列;禁止只按一個「取走」按鈕讓 head 無條件消失。每日開機先檢查 count、每筆 ID、站點狀態與頭尾索引是否一致,不一致就進復原畫面。透過這些規則,即使有抖動、漏訊號、重測或人工介入,報表仍能指出哪件產品在哪一站等待,而不是產生看似合理卻無法追溯的錯配數字。
測試資料最好保留入列與出列事件,並以 count 變化核對每一次加一或減一;只要事件數與 count 對不起來,就先停線查明。
當產品在兩站之間暫停,不能因輸送帶停止就自動完成。單一感測器若無法分辨緊鄰兩件,去彈跳也無法補出第二件;應檢查最小間距與可辨識的感測或位置資訊,再決定事件來源是否足夠。
如果必須允許超過容量的產品暫停在線外,請另設待入列區並標記位置;待 FIFO 有空位時才依實際重新確認的順序入列,不能把在線外產品假設已經占用 head。
復歸完成後重新計算 count 與索引,再開放新的入線事件;復歸前收到的結果一律暫存並標為待核對。
完成驗收後,把每次錯配警報的 product_id、station 與 event_id 匯出,確認能由事件重建整條路徑。
這項紀錄也能協助你分辨感測器漏脈衝與程式對位錯誤。
所以排查時先看事件紀錄,再看佇列資料,最後才調整感測器。
依序送入 P01~P05,逐次核對 count 由 1 增至 5。
先依序完成P01與P02,使P03成為head;故意不送P03的S1回饋。
明確核准P03的SKIP_S1,再送P03合法S2结果並出列;依序完成P04、P05。
重送一次 P03 的相同 event_id,確認完成數不增加。
五件產品的驗收演練 續
把 FIFO 當成資料結構而非幾個暫存器的排列。容量 5 時,head、tail 都要以 0、1、2、3、4 循環;本實作使用count判斷空與滿。P01~P05 入列後 head=0、tail=0、count=5;P01 完成出列後 head=1、tail=0、count=4,此時 P06 可寫入索引 0,順序變成 P02、P03、P04、P05、P06。若只比較 head=tail 判斷空滿,就會把「全滿」誤判成空,這是回繞時最危險的錯誤。
第三件產品 P03 缺少 S1 回饋時,不能直接把 P04 的 S1 結果套給 head。你可以設定每站等待逾時,例如 2000 ms;逾時後 P03 狀態改為 STATION_FAULT,保留在佇列並停線,或依規格改 SKIP_S1。只有明確的 SKIP 事件才可進下一站。產品被人工取走也必須有 TAKEAWAY 事件,完成或報廢後才出列。每個事件至少包含 product_id、station、event_id、result,四者任一不符就記錄錯配,不更新統計。
完成後應看到什麼結果
五件產品各有唯一 ID;每站結果都能回到正確 ID;P03 缺回饋時佇列順序不變;所有產品完成後 count=0,完成數=5,重複回饋不增加統計。
失敗時先查哪裡
先查入線邊沿是否重複,再查 head/tail/count 是否同時被多段邏輯寫入,接著查結果是否真的含 product_id,最後查跳站、取走與故障復歸是否有明確事件。
適用型號與限制
適用於 Q06UDVCPU 等以資料暫存器或結構陣列實作追蹤的控制器;FIFO 容量、索引回繞、保持資料與通訊事件格式須按工程規格實作。偽碼須依目標 PLC 的語法與資料配置實作。
常見問題與來源
FAQ
問:為何不用產品到站順序直接配結果?答:站點可能跳站、逾時或重送,必須用 ID 核對。
問:FIFO 滿了能覆蓋最舊產品嗎?答:除非規格允許丟棄且已記錄,否則應停入線並報警。
問:結果沒有 ID 怎麼辦?答:只能依站點與順序建立受限協議,遇到漏件就停線,不能默默猜配。