
一、Modbus Tcp協(xié)議
1、實現(xiàn)與配置
- 實現(xiàn)方式和ModbusRtu大體一致,只是報文不一樣
- 配置方式:新建產(chǎn)品時通訊協(xié)議選擇ModbusTcp或者ModbusTcpOverRtu協(xié)議,然后參考網(wǎng)關(guān)與子設(shè)備文檔配置
- 注意:
- 設(shè)備作為客戶端Client連接,請選擇ModbusTcpOverRtu,連接方式參考Tcp協(xié)議設(shè)備接入文檔,設(shè)備需要主動發(fā)送注冊包;
- 設(shè)備作為服務(wù)端Server連接,需要在設(shè)備詳情配置Modbus主機和端口,還需要配置輪詢?nèi)蝿?wù),系統(tǒng)每一分鐘會去主動連接該設(shè)備并下發(fā)輪詢指令讀取數(shù)據(jù),如果要下發(fā)寫指令,可以在指令下發(fā)配置,配置好后選擇相關(guān)指令手動下發(fā);
- 設(shè)備作為客戶端Client連接,請選擇ModbusTcpOverRtu,連接方式參考Tcp協(xié)議設(shè)備接入文檔,設(shè)備需要主動發(fā)送注冊包;
2、Modbus Tcp報文
Modbus TCP 報文由以下幾個主要部分組成:
- MBAP 報文頭(Modbus Application Protocol Header):
- 事務(wù)標識符(Transaction Identifier):用于匹配請求和響應(yīng),通常由客戶端生成。
- 協(xié)議標識符(Protocol Identifier):固定為 0,表示 Modbus 協(xié)議。
- 長度(Length):后續(xù)數(shù)據(jù)的字節(jié)長度,包括單元標識符和 PDU (Protocol Data Unit)。
- 單元標識符(Unit Identifier):用于標識從站設(shè)備。
- PDU(Protocol Data Unit):
- 功能碼(Function Code):指示要執(zhí)行的操作,如讀取、寫入等。
- 數(shù)據(jù)(Data):根據(jù)功能碼的不同,包含相應(yīng)的操作數(shù)據(jù)。
讀取保持寄存器的請求報文可能如下:
事務(wù)標識符:0x0001
協(xié)議標識符:0x0000
長度:0x0006
單元標識符:0x01
功能碼:0x03
起始地址:0x0000
寄存器數(shù)量:0x0002
響應(yīng)報文中,如果成功讀取到數(shù)據(jù)
事務(wù)標識符:0x0001
協(xié)議標識符:0x0000
長度:0x0005
單元標識符:0x01
功能碼:0x03
字節(jié)計數(shù):0x04
數(shù)據(jù):0x000A 0x000B
事務(wù)標識符:
范圍值:0x0000 ~ 0xFFFF 即是 0-65535,如果超出范圍,會從0開始計算
最重要作用:作為報文的流水號
客戶端發(fā)送請求時會生成一個唯一的事務(wù)標識符,服務(wù)器在響應(yīng)時使用相同的事務(wù)標識符。這使得客戶端能夠?qū)⑹盏降捻憫?yīng)與之前發(fā)送的請求準確關(guān)聯(lián)起來,確保數(shù)據(jù)的對應(yīng)性和準確性。例如,客戶端同時發(fā)送了多個不同的請求,如果沒有事務(wù)標識符,客戶端將難以區(qū)分每個響應(yīng)對應(yīng)的是哪個請求。
采用順序遞增的方式為每個對設(shè)備狀態(tài)的讀取請求分配事務(wù)標識符。
這里建議每個設(shè)備都記錄一下自己的事務(wù)標識符,以便遞增。
例如在redis中記錄這個設(shè)備A輪詢時的事務(wù)標識符,從0開始,想客戶端下發(fā)一條報文(客戶端應(yīng)答后),事務(wù)標識符自動+1
知道65535后,從0開始計算。客戶端并不會識別事務(wù)標識符,如果重復了客戶端也會有回復。
二、各功能碼示例
1. 0x01:讀線圈(云端輪詢)
請求:00 01 00 00 00 06 01 01 00 02 00 04(云端) 00 01:事務(wù)標識符 00 00:Modbus TCP協(xié)議 00 06:后面有00 06個字節(jié)數(shù)據(jù) 01:單元標識符 01:功能碼(讀線圈) 00 02:開始讀的數(shù)據(jù)的地址。從00 02開始讀數(shù)據(jù)。 00 04:注意這里不是讀到00 04,而是從開始位置讀00 04個數(shù)據(jù)。 這段報文就是請求讀從 00 00 開始的 00 08 個數(shù)據(jù)。
回應(yīng):00 01 00 00 00 04 01 01 01 0E(設(shè)備) 00 01:事務(wù)標識符 00 00:Modbus TCP協(xié)議 00 04:后面有00 04個字節(jié)數(shù)據(jù) 01:單元標識符 01:功能碼 01:后面有01個字節(jié)的數(shù)據(jù) 0E:表示所讀地址的線圈全是2的位置是0,其余是1 說明:線圈是只有00和01兩種格式,所以圖中從2的位置開始讀到的4位數(shù)據(jù)是:1110(二進制),轉(zhuǎn)化為十六進制就是0E

2. 0x03:讀保持寄存器
請求:00 01 00 00 00 06 01 03 00 02 00 04(云端) 00 01:事務(wù)標識符 00 00:Modbus TCP協(xié)議 00 06:后面有00 06個字節(jié)數(shù)據(jù) 01:單元標識符 03:功能碼(讀保持寄存器) 00 02:開始讀的數(shù)據(jù)的地址。從00 02開始讀數(shù)據(jù)。 00 04:注意這里不是讀到00 04,而是從開始位置讀00 04個寄存器數(shù)據(jù)。 回應(yīng):00 01 00 00 00 0B 01 03 08 00 00 00 37 00 00 00 00(設(shè)備) 00 01:事務(wù)標識符 00 00:Modbus TCP協(xié)議 00 09:后面有00 09個字節(jié)數(shù)據(jù) 01:單元標識符 03:功能碼 08:后面有08個字節(jié)的數(shù)據(jù),后面的數(shù)據(jù)每兩位表示一個寄存器數(shù)據(jù)。 00 00:第一個寄存器數(shù)據(jù) 00 37:第二個寄存器數(shù)據(jù),圖中我寫入的數(shù)據(jù)是55(十進制),這里是十六進制數(shù)據(jù) 00 00:第三個寄存器數(shù)據(jù) 00 00:第四個寄存器數(shù)據(jù)

3.寫(單)多個線圈
首先,將Modbus Slave中的從站地址設(shè)置為:01,寄存器線圈類型設(shè)置為:01 Coil Status(0x)。設(shè)置完成后單擊“OK”連接主站,并修改線圈的狀態(tài)。

最后,連接網(wǎng)絡(luò)調(diào)試助手,并將示例中的報文復制到網(wǎng)絡(luò)調(diào)試助手中單擊“發(fā)送”,可以觀察到Modbus Slave中對應(yīng)的線圈狀態(tài)改變。


4.寫(單)多個保持寄存器
首先,將Modbus Slave中的從站地址設(shè)置為:01,寄存器線圈類型設(shè)置為:03 Holding Register(4x)。設(shè)置完成后單擊“OK”連接主站,并修改寄存器的值(此處輸入的值為十進制)。

最后,連接網(wǎng)絡(luò)調(diào)試助手,并將示例中的報文復制到網(wǎng)絡(luò)調(diào)試助手中單擊“發(fā)送”,可以觀察到Modbus Slave中對應(yīng)的保持寄存器的值改變(此處會自動轉(zhuǎn)換成十進制顯示)。

