Modbus 藉由乙太網路 TCP/IP 的方式來進行傳遞資料,叫做 Modbus TCP
此種通訊格式不需要計算CRC,取而代之的是使用識別碼的方式來進行資料驗證。
在學習 Modbus協定之前,我們需要先了解每一個Byte各代表的意思為何
以下為 Modbus TCP request 的封包格式:
TCP Header | Address | Function Code | Start register addr | data |
6bytes | 1byte | 1byte | 2byte | N bytes |
其中我們會發現 TCP Header 一共佔了6Byte。
這6個Byte主要是由三個欄位所組成,每一個欄位都佔2Byte。
本次通訊的識別碼(Transaction ID):會產生2個Byte的隨機值,用來識別該次通訊。
通訊方式(Protocal ID):基本上都是0,用來表示採用哪種通訊協定。0表示為 Modbus / TCP
資料長度(Length):用來定義從Address開始 ~ data欄位結束,所佔的總長度為何。
共佔1Byte,用來記錄該次通訊要存取 slave端位址
共佔1Byte,用來定義該次通訊是要做哪種操作。
其中常見的Function Code有以下幾種:
01: 讀取當前 digital out status
02: 讀取當前 digital input status
03: 讀取當前 analog out status
04: 讀取當前 analog input status
05: 寫入單個 digital out value
06: 寫入單個 analog out value
15: 寫入多個 digital out value
16: 寫入多個 analog out value
共佔2Byte,用來定義暫存器起始位址
長度為非固定,由傳送的資料長度而定。
以上為每一個欄位的解說,接下來筆者擷取了一張從WireShark所側錄到的 Modbus封包來做解說。
上圖為, 由WireShark所側錄到的Modbus封包,用來開啟LED指示燈的控制代碼。
從ac開始到 01結束是整個Modbus的封包內容。
封包內容如下:ac 70 00 00 00 06 58 06 00 c8 00 01
其中我們剛剛有說到,Modbus的Header 共佔 6Byte,也就是:
本次通訊的識別碼(Transaction ID):ac 70
通訊方式(Protocal ID):00 00
資料長度(Length):00 06
其中 06代表接下來一共有 6Byte的封包內容
上述的三個欄位均為Modbus的Header,每一個都佔2Byte,共佔6Byte。
slave端位址(Address):58
操作碼(Function Code):06
代表寫入單一數值
暫存器起始位址(Start register addr):00 c8
傳送資料(Data): 00 01
最後,附上一張Modbus控制的表格來做個結束。
操作碼 06: 寫入LED開燈資訊
Transaction ID | Protocal ID | Length | Address | Function Code | Start register addr | Data |
ac 70 |
00 00 |
00 06 |
58 |
06 |
00 c8 |
00 01 |
意思為:Master要求寫入資料到裝置位址58的暫存器位址 00c8,寫入的資訊為 00 01。