← 所有文章

請求 接受 完成與失敗 如何設計 PLC 模組間握手

· 站長

以請求識別碼與保持到確認的旗標,建立接受、處理、成功及失敗的完整交接。

先把問題拆開 定義狀態 請求與完成條件

先把這篇當成兩個虛擬模組:Sender送出工作資料,Receiver處理後回報結果。你會以ReqId追蹤同一筆工作,並在每個掃描週期觀察訊號。本文固定規則是Done代表成功、Fail代表失敗,兩者互斥;逾時也必須走Fail,不能用Done掩蓋問題。

項目 應定義 不要混淆
Req 提出工作 已被接收
Accept 等待收件確認 完成結果
Busy 等待處理 可覆蓋新資料
Done/Fail 等待結果 同時成立

教學先用虛擬狀態與監看欄位,不接實體輸出。每一步都寫前置、操作、預期結果與失敗先查位置;這樣你在工程軟體中才能逐項核對,而不是只看最後一盞燈。

建立流程 先做狀態表 再寫轉移

先建立Req、ReqId、Accept、Busy、Done、Fail、ResultAck及各自的識別碼。Sender寫好資料後保持Req,Receiver在IDLE看見尚未處理的ReqId時鎖存請求,接受時複製快照。Accept保持到Sender清除Req,不用一掃描脈衝跨任務傳遞。Done或Fail保持到ResultAck核對同一ReqId;確認完才回IDLE。

  1. 建立 Req、ReqId、Accept、Busy、Done、Fail、DoneId、FailId、ErrorCode。

  2. ReqId=17 保持到 Accept,確認只接受一次。

  3. Busy 期間送 ReqId=18,依規格拒絕,不覆蓋 17。

  4. 完成三步後核對 DoneId=17;逾時則 FailId=17。

完成後應看到:狀態、操作請求、資料欄位與虛擬輸出一致。若不同,先查是否有其他程式段改寫狀態、在錯誤分支清除記憶,或取樣時機不一致。

資料接收失敗而尚未接受時,應帶原ReqId回覆拒絕原因;已接受後的執行失敗才使用Fail。識別碼回捲與重啟要有會話編號或等效規則,不能讓舊結果碰巧等於新請求。此握手是本文自訂協議,不是任何模組內建的固定旗標。

具體合成案例 逐掃描核對正常與邊界

案例ReqId=17:S2保持請求,S3接受並鎖定資料,S4送出方看到Accept後清除Req,接收方繼續工作。S5仍處理,S6成功後保持Done與DoneId=17;S7送出方保存結果並回ResultAck=17,S8接收方清除結果回IDLE。Fail採相同確認流程。

掃描/條件 判斷 狀態 應看到的結果
S1 Req=0 IDLE 無待辦
S2 Req=1 Id=17 REQUEST 鎖存待接受請求
S3 資料檢查通過 BUSY Accept=1 鎖定快照
S4 Sender清Req BUSY 清Accept 繼續處理
S5 尚未完成 BUSY 保持原工作
S6 成功且未逾時 RESULT Done=1 Fail=0 Id=17
S7 ResultAck=17 RESULT 確認結果已取走
S8 確認完成 IDLE 清結果 可接受下一件

本例每次只採用一個狀態轉移,故障優先於一般操作;取消、停止與完成的細節依下列固定案例核對。不同設備改用其他政策時,文字、事件表與程式必須一起修改。

把晚到回覆與重複請求分開測試

先從最容易觀察的成功路徑開始。把兩個模組的旗標排在同一監看表,逐次記錄誰改了哪個欄位。送出方提出請求後,資料保持不變;接收方接受時複製自己的工作資料。兩份資料的用途不同,接收方後續計算應只讀工作快照,不能再次讀取可能已被畫面編輯的來源欄位。

再故意延後送出方讀取結果。接收方已完成,但送出方暫時沒有執行,成功旗標和結果識別碼都應保持,不能在一個掃描後消失。送出方恢復後先保存結果,再回覆結果確認。接收方看到相同識別碼的確認,才清除結果;確認其他工作不能清掉這一筆。

第三個練習是逾時之後收到晚到結果。送出方已經回報等待逾時,不代表接收方一定停止了工作。這時把晚到結果放進待核對紀錄,依原識別碼判斷是否已完成,不要直接寫到下一件工作的畫面。若工作有實際副作用,未確認結果之前盲目重試可能做兩次。

同一請求長時間保持,也不應被反覆接受。接收方記錄已接受的識別碼及目前狀態,當工作進行中或結果待確認時拒絕新接受。回到待機後,送出方需完成舊請求解除,再以新識別碼開始下一件。這個回到空閒的過程,是握手的一部分,不是多餘延遲。

最後測試重啟。若只有送出方重新啟動,它可能忘了正在等哪一件;若只有接收方重新啟動,它可能忘了哪些工作已完成。因此要先對帳會話、請求識別碼與結果狀態,再開放新的工作。單靠成功位元仍為一,無法證明那就是這次請求的結果。

失敗先查 適用限制與常見問題

在Q系列中可用步進狀態或等效旗標實作握手;實際裝置位址與保持設定請依專案配置。先用暫存器監看每一掃描:Req、Accept、Busy、Done、Fail、ReqId、DoneId、ErrorCode。看到Done時應確認Fail=0且DoneId等於ReqId;看到Fail時應先記錄錯誤碼再復歸。

三個常見問題

Req一定要脈衝嗎?本例保持到Accept才清除。Done代表成功嗎?本例是,而且要核對DoneId;Fail表示失敗,兩者互斥。忙碌能覆蓋資料嗎?本例拒絕新工作,不排隊、不覆蓋原快照。

送出方的操作順序也要寫進測試:先準備資料、增加 ReqId、保持 Req,再等待 Accept;收到 Accept 後不可任意改寫快照。若等待超過上限,送出方要把此次工作標為未完成,保存逾時原因,不能把 Busy 清掉後立刻送出另一件而讓晚到的 Done 對錯。接收方每次回報都帶 DoneId 或 FailId,並在結果確認後回到IDLE。若事件脈衝可能被另一任務漏讀,可改用事件序號或保持到確認,但要避免確認本身被重複計算。測試時故意讓 Req 在接收方忙碌、完成同掃描送新 Req、以及 Reset 發生在 Busy 中,逐項確認規格結果。

實作時可把協議畫成兩條泳道:Sender 只寫 Req 與資料,Receiver 只寫 Accept、Busy、Done、Fail;回覆欄位由 Receiver 寫、Sender 讀。若同一欄位兩邊都寫,除錯時無法知道誰覆蓋誰。請再加入版本或資料長度欄位,接收方先檢查長度再接受。完成後 Sender 應以 DoneId 比對等待中的 ReqId,對不上就記錄晚到回覆,不要直接更新目前畫面。

故障演練時,在Receiver忙碌中刻意送新Id,應得到獨立RejectId與RejectReason,原工作不受影響;不要用原工作的Fail欄位回報另一件請求。再測完成與逾時同時成立,本例逾時優先,保持Fail與原ReqId。接收方失聯時,送出方記錄未知結果,不能自行清除對方Busy後假裝可重試。

操作驗收與適用限制

驗收時固定記三個結果:成功為Done=1、Fail=0且DoneId=ReqId;失敗為Fail=1、Done=0且FailId=ReqId;忙碌時新Req不得改寫原資料。限制是本文只示範握手概念,實際旗標位址、保持範圍、通訊更新週期仍須依Q系列專案與模組手冊確認。

請用三次測試收尾:正常完成、處理中重送Req、逾時。每次保存ReqId與ErrorCode,重新RUN後確認是否需要保留結果;若專案要求斷電保持,請另行設定保持裝置並檢查初始化是否會覆寫。

適用型號與限制:概念可套用具備位元與狀態資料的 PLC;實際指令、資料型別、計時單位、模式切換與復歸行為必須依目標 CPU、工程軟體和設備規格確認。

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

延伸閱讀


使用 PLC 工具箱 →