最近筆者接了一個工控系統,其中PLC所使用的是Modbus TCP的通訊協定。
由於這個部分因為從來沒有接觸過,所以花了一點時間研究。
趁著現在記憶猶新,趕緊寫下來,方便日後對照,也讓讀者們能夠快速看懂Modbus TCP協定。
Modbus為工業上常用的通訊協定之一,也是目前工業領域通訊協定常用的標準協定。
一般來說,Modbus主要可以再細分為兩種協定(Modbus RTU 、Modbus ASCII 、Modbus TCP)
Modbus RTU 是一種為使用二進位表示法來進行資料的傳遞與交換,也是比較多人使用的,因為方便,也不需要轉換為ASCII
Modbus ASCII 則是一種對於人類來說,可讀性較高的協定。
而以上兩種方式在傳遞資料的結尾皆需要加上 CRC (錯誤檢查機制)。
其中 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。
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)
有任何家教、案子 或技術相關問題 請都歡迎聯繫我