使用 Modbus Coil/Register 編號與實際通訊時的資料位置常常讓人混淆,有時為何要減 1? 減 40001?
Coil/Register 編號在制定時,以人們習慣的1為開始,而實際通訊時卻以 0 開始,在這裡就產生了得減 1 的問題。又因為把各種點的類型以5位數方式加到了編碼數值上,因此依照不同點類型得減去 40001、減 30001、減 10001或減 1 才能對應到實際通訊位置。
然而必須留意的是增加的類型數值 1xxxxx、3xxxxx、4xxxxx 等與讀取的功能碼關係並不完全一致,例如3xxxxx要用功能碼 04 讀取,4xxxxx卻要用功能碼 03 讀取,這也是讓常讓初學者混淆的

以下就Coil/Register 編號5碼對應到實際資料位置與點類型、功能碼對照表

Coil/Register 編號 資料位置
(16進制)
資料位置
(10進制)
型式  名稱  讀取功能碼  寫入功能碼
1 - 9999 0000 - 270E 0 - 9998 讀寫 Coil 01 Read Coil Status 05 Force Single Coil
15 Force Multiple Coils
10001 - 19999 0000 - 270E 0 - 9998 唯讀 Input 02 Read Input Status  
30001 - 39999 0000 - 270E 0 - 9998 唯讀 Input Register 04 Read Input Registers  
40001 - 49999 0000 - 270E 0 - 9998 讀寫 Holding Register 03 Read Holding Registers
23 Read/Write 4X Registers
06 Preset Single Register
16 Preset Multiple Registers
23 Read/Write 4X Registers

 

Modbus通訊資料位置實際上為16位元,數值範圍可以到 0~65535,當位置超過 9998 時會溢出五碼的編號類型碼,因此有人以六碼的數值表示,此時就得由 - 40001、-30001、-10001 對改為應到 - 400001、-300001、-100001 對應到實際通訊地址了(補充說明:原廠手冊並未找到關於六碼標碼的描述,其出處待確認)

以下就Coil/Register 編號6碼對應到實際資料位置與點類型、功能碼對照表

Coil/Register 編號 資料位置
(16進制)
資料位置
(10進制)
型式  名稱  讀取功能碼  寫入功能碼
000001 - 065536 0000 - FFFF 0 - 65535 讀寫 Coil 01 Read Coil Status 05 Force Single Coil
15 Force Multiple Coils
100001 - 165536 0000 - FFFF 0 - 65535 唯讀 Input 02 Read Input Status  
300001 - 365536 0000 - FFFF 0 - 65535 唯讀 Input Register 04 Read Input Registers  
400001 - 465536 0000 - FFFF 0 - 65535 讀寫 Holding Register 03 Read Holding Registers
23 Read/Write 4X Registers
06 Preset Single Register
16 Preset Multiple Registers
23 Read/Write 4X Registers

為求直觀,元米科技 MODBUS 免費通訊程式(https://www.icdt.com.tw/main/index.php/2013-07-09-05-16-50/modbus-free-software)一律使用 0~65535 的資料位置來做為讀寫位置,因此對應到實際設備時,必須留意是否需要 - 40001、-30001、-10001、-1 或 - 400001、-300001、-100001 以對應到設備記憶體編號

MODBUS 通訊協議的功能碼需要留意部分:

  • 功能碼 01、02、03、04 都能一次讀取多個點,但必須留意 01 與 02 每個點僅佔一個位元,03 與 04 每個點則佔十六個位元,對於部分通訊資料緩衝區較小的設備,過長的封包可能無法正常回應
  • 功能碼 05 與 06 一次只能寫出一個點,寫出指令與回應指令一模一樣
  • 功能碼 05 以數值 FF00 代表 1,0000 代表 0
  • 功能碼 15 與 16 一次能寫出多個點,但一樣得留意設備端可以接受一次寫入的點數,以及設備端是否支援這個功能碼
  • 功能碼 23 可以在一個封包同時做寫入與讀取動作,但支援該功能碼的設備端可能更少
  • 實作設備端時,對於不支援的功能碼或無效位置等錯誤應該回應異常響應代碼(參考 https://modbus.org/docs/PI_MBUS_300.pdf Appendix A Exception Responses),才能使客戶端明白錯誤原因,不至於陷入長時間等待,影響整體通訊響應時間

要進一步理解 MODBUS 通訊協定請參閱 https://modbus.org/docs/PI_MBUS_300.pdf

也可以搭配 Wireshark 進行分析 https://www.icdt.com.tw/main/index.php/2013-07-09-05-19-03/197-wireshark-modbus-tcp

以上資料參考自 https://modbus.org/docs/PI_MBUS_300.pdf 如有錯誤或需要補充的歡迎來信 eric.icdt@msa.hinet.net