← 所有文章

用 FIFO 追蹤輸送線產品 避免結果和產品對錯筆

· 站長

以容量五的簡化FIFO練習識別碼、空滿判斷、索引回繞與跳站事件。

為每個產品建立身分

輸送線上的結果對錯產品,通常不是檢測公式錯,而是產品進站與結果回來的順序沒有被記錄。你先替每件產品建立 product_id,再用固定容量 FIFO 保存順序;每個站點回饋都要帶有事件或站點狀態,不能只用一個 done 位元猜測。本文以容量 5、兩個站點、產品 P01~P05 示範。FIFO 內容是識別碼與 status 的資料列。

欄位 用途 規則
product_id 追溯產品 入線時遞增且不重複
status 目前站點狀態 WAIT/AT_S1/AT_S2/DONE/FAULT
head/tail 出入位置 只在成功出列或入列後更新
count 目前筆數 0 到 5,禁止超界
  1. 入線脈衝先檢查 count<5,再寫入 tail。

  2. 站點結果先更新 head 所指產品,完成且允許出列才移除。

  3. 每次事件記錄 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 匯出,確認能由事件重建整條路徑。

這項紀錄也能協助你分辨感測器漏脈衝與程式對位錯誤。

所以排查時先看事件紀錄,再看佇列資料,最後才調整感測器。

  1. 依序送入 P01~P05,逐次核對 count 由 1 增至 5。

  2. 先依序完成P01與P02,使P03成為head;故意不送P03的S1回饋。

  3. 明確核准P03的SKIP_S1,再送P03合法S2结果並出列;依序完成P04、P05。

  4. 重送一次 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 怎麼辦?答:只能依站點與順序建立受限協議,遇到漏件就停線,不能默默猜配。

參考:三菱 QnUCPU 使用手冊 程式執行與裝置資料

延伸閱讀


使用 PLC 工具箱 →