Modbus 協定說明
Modbus 主要分成兩種 Modbus ASCii 跟 Modbus RTU
跟篇主要也是在寫 Modbus RTU ,不過是以傳輸功能為主
Modbus傳輸主要為1個Master對多個Slave,此時就用slave (通常是終端 Device)
的ID做識別,如果Master傳輸的ID對應到該Slave的ID,如果格式正確該Slave就會回應
因此在Modbus傳輸中,每個Slave都是被動的,不斷的在監聽是否有收到請求。
首先先講傳輸格式
Master發出 Query封包
Slave ID | Fuction | Register Addr | Request byte | CRC | |||
01 | 03 | 00 | 00 | 00 | 02 | C4 | 0B |
Slave ID通常Device上或Datasheet中都會寫,有一些要自己設定
Fuction功能碼 列幾個常用的
01: 讀取當前 digital out status
02: 讀取當前 digital input status
03: 讀取當前 analog out status
04: 讀取當前 analog input status
05: 寫入單個 digital input value
06: 寫入單個 analog input value
15: 寫入多個 digital input value
16: 寫入多個 analog input value
不過實際上要怎麼用,還是要以 Datasheet 上規範的為主
Register Addr 站存器位置 這部分也是要參照Datasheet 上規範的位置來做存曲
每個區間存的數值都代表不同的意義
Request byte 要求的資料量: 這邊的1byte對應到Slave端回應的 1 word
例如 Master下 00 02 = 向Slave要求 2個word = request 4byte data
CRC 錯誤檢查碼 : 詳細的說明在這篇 Modbus RTU CRC
Slave端回應的封包
Slave ID | Fuction | Data byte | data | CRC | ||||
01 | 03 | 04 | 00 | 00 | 00 | 01 | 3B | F3 |
前兩Byte都是Echo Master端的訊息
Data byte : 此範例 Master要求 2 words的資料,因此Slave回 4byes
最後是 CRC
在舉一個例子 如果是 寫入 非讀取 Command Slave端則會 Echo完整的封包內容
Master:
Slave ID | Fuction | Register Addr | Request byte | CRC | |||
01 | 06 | 00 | 00 | 00 | 1E | 09 | C2 |
Slave:
Slave ID | Fuction | Register Addr | Request byte | CRC | |||
01 | 06 | 00 | 00 | 00 | 1E | 09 | C2 |
最後如果是Master要求的封包是有問題的,Slave則會回應錯誤封包格式 佔5byte
例如:
Master:
Slave ID | Fuction | Register Addr | Request byte | CRC | |||
11 | 03 | 00 | 6B | 00 | 03 | 76 | 87 |
如果要求的位置不合法 Slave則會回應如下
Slave ID | Fuction | Error Code | CRC | |
11 | 83 | 02 | C1 | 34 |
如果反還是錯誤的封包,Fuction為 83
Error則對應下表,來得知是哪種類型的錯誤
Error Code | meaning |
01 | 不支援的功能 |
02 | 不合法的地址 |
03 | 不合法的數值 |
04 | Slave 設備失效 |
05 | 命令執行中 |
06 | Slave忙碌中 |
以下為實際運行結果
首先進入選單會顯示目前要做的功能
輸入2 設定當前流量值為30,
前8byte為Master送出封包 後8byte為Slave返還封包(Echo master端封包)
故意把訊息拆成1個byte 1個byte 呈現方便觀察
最後顯示設定功訊息
接著 讀取當前設定的流量值,Slave返還後解析封包得到當前設定值為30
最後是測試送出不合法訊息
Slave端回應的function為 131 轉換為 16進制為83H 表示是錯誤訊息封包
引用於:https://home.gamer.com.tw/creationDetail.php?sn=3662059
留言
張貼留言