先認出例外回覆 才決定要不要重試
看到Modbus回覆,不代表本次讀取成功。正常讀取會帶回資料,例外回覆則把原功能碼最高位設為一,再帶一個例外碼。收到例外只能證明通訊鏈上有設備回報問題;經過閘道時,這個回報可能由閘道產生,不能因此宣稱下游儀表已回應。先保存原始封包,再判斷誰回報、哪一筆請求失敗,以及上次量測值還能否使用。
本篇所有十六進位封包都是離線構造的PDU,不含RTU站號與CRC,也不含TCP的MBAP。例子83 06表示功能碼03的例外回覆,例外碼為06;它不是要求寫入功能碼06。把功能碼與例外碼放在不同欄,就能避免維修時說出「設備回06」卻沒有人知道指哪個欄位。
| 離線回覆PDU | 原請求功能 | 例外碼 | 首要分類 |
|---|---|---|---|
| 83 06 | 03 讀Holding Registers | 06 | 設備忙碌 |
| 83 0A | 03 | 0A | 閘道未能分配通訊路徑 |
| 83 0B | 03 | 0B | 閘道未取得目標回覆 |
| 86 05 | 06 寫單暫存器 | 05 | 已接受、仍在處理;須查設備語意 |
Modbus規範將05及06的描述放在程式命令的特殊使用情境。本篇表格用常見功能碼構造解析練習,不宣稱任意設備都會對這些功能回覆05或06。實際產品若另有定義,應記下手冊章節與韌體版本;不能從例外碼名稱自行推導一個不存在的完成查詢指令。
05是等待完成 06是等待可處理
05 Acknowledge表示設備接受請求,但需要較長處理時間。收到後先把該交易標為處理中,而不是完成,也不要立即把相同寫入再送一次。接著只能使用設備文件提供的完成查詢或狀態機制;若文件沒有說明,保存交易並升級確認,不要猜一個Holding Register作完成位。規範提到的Poll Program Complete不能被當成所有產品通用的任意讀取。
06 Server Device Busy表示設備正在忙於較長操作。對已確認可安全重送的讀取,可採有限次數、有限總時間的等待;寫入則另外判斷重送是否會重複觸發動作。設定值寫同一數字可能可重複,但若該位址代表清零、加一次計數或開始配方,同一封包再送可能造成第二次動作。回覆逾時也不等於設備一定沒有執行。
| 項目 | 05處理 | 06處理 |
|---|---|---|
| 應用狀態 | 已接受、尚待完成證據 | 本次未取得正常處理結果 |
| 下一步 | 使用原廠完成查詢 | 按原廠建議等候,符合條件再重送 |
| 寫入結果 | 不可立即標完成 | 不可只因稍後恢復就補報成功 |
| 超出總期限 | 標為結果待確認並告警 | 停止本輪重試並保留故障記錄 |
自訂教學政策:讀取忙碌後最多額外重送兩次,第一次等200 ms,第二次等400 ms,每次回覆期限500 ms。三次嘗試都用滿期限時,最壞預算為3×500+200+400=2100 ms。這是應用排程範例,不是Modbus規定值;設備的操作耗時、輪詢週期與其他站點需求可能要求完全不同的設定。
0A查路由 0B查下游回覆鏈
0A Gateway Path Unavailable指向閘道無法配置輸入到輸出之間的內部通訊路徑。先查請求進入哪個TCP端點、Unit ID映射哪個串列埠、該埠是否啟用,以及同時進來的請求是否超出佇列能力。路由錯誤時增加逾時通常沒有幫助;佇列壅塞時一味縮短重試間隔反而使問題加重。
0B Gateway Target Device Failed to Respond表示閘道沒有取得目標設備回覆。這仍不能單憑一個碼斷定設備壞掉。下游站號、通訊格式、RS485極性、電源、請求支援度或回覆時間都可能相關。把閘道發送及接收計數與同一時間的原始交易對上,才知道請求是否進入指定埠、是否真的送出,以及是否看到但拒收了不完整訊框。
| 自訂路由項目 | 預定值 | 故障時保存 |
|---|---|---|
| TCP端點 | 192.0.2.10:502 | 連線識別、時間、Transaction ID |
| Unit ID | 7 | 原始MBAP欄位 |
| 輸出埠 | Serial 2 | 實際路由表與啟用狀態 |
| 下游站號 | 12 | 映射後站號、發送記錄 |
| 串列格式 | 19200、8E1 | 實際匯出設定,不只抄筆記 |
這張映射表是虛構案例,Unit ID 7轉成站號12必須由實際閘道支援並設定。若產品只做原樣轉送,就不能套用這張表。IP使用文件示例網段,不要求連線。即使TCP能建立,也只證明到閘道的連線層可用;Serial 2與站號12仍需各自的證據。
把兩筆故障做成可交接的時間線
第一筆範例在10:00:00送出讀取,10:00:00.050收到83 06,等200 ms後再次讀取,10:00:00.300得到有效值253。記錄第一筆Busy與第二筆成功,資料時間戳只在後者通過位址、數量及型別檢查後更新。不要把第一次忙碌時間當成新資料時間,也不要讓重試成功抹掉故障統計。
第二筆同樣讀取卻收到83 0B。先記錄閘道回報時間與下游逾時設定,查看Serial 2發送數有沒有增加;若沒有,回查映射與佇列。若發送有增加但接收為零,才順著下游供電、接線、站號與格式調查。若接收有資料但CRC錯誤,保存錯誤計數和原始資料,不要把有電氣活動當成有效回覆。
資料顯示採自訂規則:最後有效值可保留供追溯,但必須帶最後成功時間與失敗狀態;超過允許新鮮度後顯示過期。舉例最後有效值在0秒取得,新鮮度上限2秒,到2.1秒仍未有有效回覆,就算TCP仍連線也要標過期。控制是否可繼續使用舊值,必須由製程需求決定,不能由通訊文章替所有設備作相同決策。
| 驗收情境 | 完成後應看到 | 不合格徵象 |
|---|---|---|
| 06後恢復 | 新值與成功時間一起更新,Busy計數保留 | 只有值更新、時間未變 |
| 0B持續 | 停止本輪重試、保留最後值及失敗品質 | 無限重送、其他站餓死 |
| 05超期限 | 結果待確認,保留原交易 | 沒有完成證據卻顯示寫入成功 |
| 晚到回覆 | 依交易身分與取消狀態決定接納 | 舊回覆覆蓋新交易資料 |
完成排查後再保存設定版本、故障前後紀錄、改動理由與復原方法。一次只改一個參數,避免同時改站號、逾時與鮑率後無法判斷原因。上述流程可先用離線日誌與測試替身驗證,不需對真實機台發送寫入。
FAQ與適用範圍
FAQ1:收到例外碼就代表RS485接線正常嗎?不一定。TCP閘道可能自行回報下游沒有回覆;只有有效下游回覆及其記錄才能支持該段已完成通訊。
FAQ2:05可否直接重送直到正常?不可把它當固定策略。它表示請求已被接受,須按設備提供的完成查詢確認,避免重複動作。
FAQ3:06等多久才重試?先用原廠處理時間與忙碌規則。本文200及400 ms僅示範有限退避,並不適用所有設備;總重試期限也要明訂。
FAQ4:0A和0B都換線就好嗎?不是。0A先看閘道內部路由與資源;0B沿下游發送、接收及解析鏈找證據。換線前應知道是哪一段有問題。
本文適用於能取得原始Modbus交易與設備文件的診斷工作。它沒有選定Q系列的某條指令、錯誤裝置或閘道韌體,不代表Q06UDVCPU與QJ71C24N會直接產生上述例外碼;要先確認實際Modbus實作及通訊程式如何傳遞錯誤。請求結構、格式校驗和成功條件仍以所用功能碼為準。
參考:Modbus Application Protocol V1.1b3,第7章例外回覆;05/06特殊使用語意及0A/0B分類。