← 所有文章

Modbus 有回應但數值不對的排查方法

· 站長

Modbus 已有回覆卻數值錯誤時,逐層核對功能碼、位址、資料型態、word 順序、倍率與資料品質。

先確認收到的是有效資料

通訊完成只代表一次交換已結束。你還要確認回覆來自正確站號、功能碼與資料長度都符合請求,並且不是例外回覆。本篇用逐層核對的方法,帶你找出「收到資料,數字卻不對」的原因。

  1. 記下從站型號、手冊版本、站號、功能碼、起始位址及讀取數量。

  2. 保存一次完整請求與回覆,同時記錄時間、原始 HEX 及設備面板顯示值。

  3. 先確認校驗結果與回覆格式;若是逾時、CRC 錯誤或例外碼,先處理通訊問題。

  4. 回覆有效後,依序查位址、型態、順序、倍率,最後才看 HMI 格式。

觀察到的情況 下一步
正常回覆但值固定不變 確認是否讀到狀態字或保留位址,並查看資料更新時間
回覆功能碼為 83H 這是 FC03 的例外回覆,先讀例外碼
值合理但比面板大 10 倍 核對手冊倍率及是否漏除以 10
偶爾跳出極大值 檢查跨暫存器資料一致性、順序與無效值定義

RTU 的 CRC 檢查與 TCP 的訊息格式不同。以下封包例子採 RTU;接收工具若已替你驗證 CRC,也要保存工具的檢查狀態。資料處理失敗時保留上次值可以方便觀察,但必須同時標記過期,不能讓舊值冒充新資料。

第一層核對位址與功能碼

手冊的暫存器編號與封包裡的位址不一定採同一個表示法。先確認手冊寫的是參考編號、零起算位址,還是十六進位位址。不要看到 40001 就直接送出十進位 40001。

手冊表示方式 已確認的定義 送出位址
40001 傳統 Holding Register 第一筆參考編號 0000H
40010 同一套傳統參考編號 0009H
Address 0 明確標示零起算位址 0000H
0010H 明確標示十六進位位址 0010H,即十進位 16

上表前兩列只適用於手冊採傳統 4xxxx 參考編號的情況。部分工具會自動減一,部分要求填封包位址。請用送出紀錄核對,避免手動減一後工具又減一次。

先用一筆有明確意義的資料測試

例如手冊明確指定某筆 Holding Register 是型號碼,就先以 FC03 讀取它。Input Register 通常用 FC04;功能碼與位址空間都要一致。不要用對控制設備寫入的方式猜位址。

請求內容示例,不含 CRC:01 03 00 00 00 01

上例只列出 RTU 封包前段,未附 CRC,不能直接當作完整框架送出。它表示站號 1、FC03、封包起始位址 0、讀取 1 個暫存器。數量的單位是 16 位元暫存器,不是 bytes。若讀 2 個,正常資料區應有 4 bytes;例外回覆則使用另一種格式。

參考:Modbus 官方規格 4.4 位址模型及 6.3 與 6.4 功能碼

第二層核對型態與排列

手冊型態 暫存器數量 你要怎麼解讀
UInt16 1 當作 0–65535 的整數
Int16 1 用 16 位元二補數解讀
UInt32 或 Int32 2 先依手冊排列兩個 words,再解讀有號或無號
Float32 2 先組回 32 位元位元樣式,再依 IEEE 754 解碼

同一筆 FFFFH 可表示 UInt16 的 65535 或 Int16 的 −1;設備也可能定義它為無效值。先查資料表,不能只因為數字很大就強制改成有號。

用已知測試值辨認順序

假設設備規定 Float32、較高 word 在前,25.0 的位元樣式為 41C80000H,兩個暫存器應依序為 41C8H、0000H。Modbus 每個暫存器在封包內高 byte 先傳;跨兩個暫存器的排列仍須依設備定義。

收到的兩個 words 核對方向
41C8 0000 符合本例較高 word 在前
0000 41C8 檢查是否需要交換兩個 words
C841 0000 檢查工具是否對 word 內兩個 bytes 做了交換

把 41C80000H 當成整數再做「數值轉浮點」,不會得到 25.0。這裡需要的是位元樣式重新解讀。請記錄原始資料,逐次只改一項順序設定,並用至少兩個已知且不同的值驗證。

一次請求讀齊完整的兩個暫存器,可以避免自行拆成兩次讀取造成的不一致;設備是否保證多字資料快照一致,仍要看手冊。

第三層核對倍率並完成驗收

假設有效回覆的資料區是 00 FD,得到十進位 253。手冊若指定 Int16、單位 0.1 °C,結果就是 25.3 °C;若指定一般整數或其他倍率,就不能套用這個除法。

工程值=解碼後數值 × 倍率+偏移
你保留的欄位 本例應看到
原始 HEX 00 FD
解碼型態與整數 Int16;253
倍率與偏移 0.1;0
工程值 25.3 °C
資料品質 本次回覆有效;有更新時間

工具串接順序

先在進位工具核對 HEX 與十進位,再用有號/無號工具確認資料寬度;若資料為 32 位元,再核對 word 順序及 Float32 解碼;最後才套倍率。類比原始值縮放工具只在設備明確回傳需要線性縮放的計數值時使用。

練習與答案

練習一:手冊以傳統參考編號標示 40003,工具要求零起算封包位址。答案為 2。練習二:FFF6H,Int16、單位 0.1 °C。答案為 −10 × 0.1=−1.0 °C。練習三:Float32 高 word 在前,41C8H、0000H。答案為 25.0。

完成判定

選擇兩個以上已知狀態比較:位址與手冊一致、原始字組可重現、型態與倍率有依據、面板與工程值差異在允收範圍內。再中斷一次通訊,確認畫面會標示失效或過期,且恢復後能更新。

參考:Modbus 官方規格 4.2 資料編碼與第 7 節例外回覆

參考:Schneider Modbus Data Formats 32 位元與 word 排列

操作完成後的確認與適用範圍

完成後應看到什麼結果

使用本篇 Int16、倍率 0.1 的範例,資料 00FDH 應先解碼為 253,再顯示 25.3 °C;FFF6H 應顯示 −1.0 °C。若手冊指定 Float32 高 word 在前,41C8H、0000H 應解碼為 25.0。

至少用兩個已知且不同的狀態比對,確認站號、功能碼、位址、型態、排列及倍率都有依據。每次有效讀取後更新時間應前進;中斷通訊時,工程值必須標記過期或失效。

失敗時先查哪裡

  1. 先保存請求與回覆。若是 CRC 錯誤、逾時或例外回覆,先處理通訊,暫時不要改倍率。

  2. 回覆有效但讀錯項目:查功能碼與封包位址,確認工具是否自動減一。

  3. 項目正確但值離譜:依序查 16/32 位元、有號/無號、word 順序與浮點解碼;最後查倍率及 HMI 顯示。

適用型號與限制

適用於 Modbus Holding Register 或 Input Register 數值判讀。Q06UDVCPU 搭配 QJ71C24N 可沿用此排查觀念;其他 PLC 或電腦主站也可使用,但其接收緩衝區與型態轉換方法依平台而異。

本篇封包例採 Modbus RTU。TCP 也可沿用位址與資料解碼觀念,但不能套用 RTU 的 CRC 或串列時間。未提供從站型號時,不能指定通用暫存器表;Float32 排列、倍率與無效碼都以該設備版本的手冊為準。

搭配使用的工具

系列延伸閱讀


使用 PLC 工具箱 →