【轉(zhuǎn)載】modbus-rtu和modbus-tcp和modbus-rtu-Over-tcp/ip

經(jīng)典的modbus協(xié)議幀如圖:


image.png

Modbus-TCP:由TCP頭+地址+PDU組成,
Modbus-RTU:由地址+PDU+CRC校驗(yàn)組成

Modbus的PDU(Protocol Data Unit,協(xié)議數(shù)據(jù)單元)由功能碼+寄存器地址+寄存器數(shù)量(可選)+寄存器值組成,PDU在TCP和RTU兩種形式上是相同的。


image.png

說(shuō)明:
1:Modbus為一問(wèn)一答協(xié)議,發(fā)送一個(gè)請(qǐng)求后要等待回復(fù)才能發(fā)送第二個(gè)請(qǐng)求。
2:Modbus-RTU的物理接口為串口。
3:Modbus-TCP的物理接口為以太網(wǎng)。
解釋?zhuān)?br> 因此如果客戶是提供的modbus-rtu協(xié)議,那么其實(shí)是需要一個(gè)串口轉(zhuǎn)網(wǎng)絡(luò)的一個(gè)轉(zhuǎn)換模塊(去買(mǎi)這么一個(gè)硬件,也就50多塊錢(qián))(串口轉(zhuǎn)網(wǎng)絡(luò)RJ45轉(zhuǎn)ttl 網(wǎng)口轉(zhuǎn)串口RS232/485),這個(gè)模塊就可以把協(xié)議轉(zhuǎn)為tcp,
但是,
但是,
坑來(lái)了,
這個(gè)轉(zhuǎn)換模塊,有可能是硬件原因,其實(shí)是有坑的,
它會(huì)把串口轉(zhuǎn)為網(wǎng)口,但是數(shù)據(jù)還是傳的modbus-rtu的數(shù)據(jù),
可以這樣理解,相當(dāng)于外面包了一層modbus-tcp,但是本質(zhì)還是rtu的數(shù)據(jù),
那我們可以用網(wǎng)絡(luò)連接(socket,或者nio去建立tcp連接),但是數(shù)據(jù)傳輸還是用的rtu的數(shù)據(jù)(請(qǐng)求數(shù)據(jù)或者響應(yīng)數(shù)據(jù)都是rtu格式的,需要進(jìn)行解析)。
真坑呀。
可能會(huì)有一個(gè)轉(zhuǎn)換的硬件設(shè)備,可以純粹的轉(zhuǎn)為tcp,就是過(guò)濾了校驗(yàn)碼這些,可能是我還不知道吧;

所以:這里就有了三個(gè)協(xié)議:
modbus-rtu:純粹的串口通信
modbus-tcp:TCP網(wǎng)絡(luò)通信
modbus rtu Over tcp/ip:是tcp網(wǎng)絡(luò)通信,但是本質(zhì)上還是rtu。
modbus仿真軟件就可以看到這三個(gè)協(xié)議:(ModbusSlaveSetup64Bit)

image.png

其中Seria Port就是串口,那用這個(gè)通信的話就是modbus-rtu,

可以使用modbus-rtu連接,例如插入U(xiǎn)SB查看串口。

image.png

或者自己測(cè)試的時(shí)候可以在自己的電腦虛擬兩個(gè)串口,工具為(Launch Virtual Serial Port Driver Pro)

image.png

然后modbus tcp/ip,這個(gè)可以用很多工具鏈接了,很多上位機(jī)軟件(NetAssist)(Modbus Poll)都可以,程序的話java也提供了很多工具包,(com.digitalpetri.modbus modbus-master-tcp)(或者可以建立socket或者nio鏈接,只不過(guò)這個(gè)需要解析格式(報(bào)文頭啊,校驗(yàn)碼,從機(jī)地址,功能碼這些))

然后modbus rtu Over tcp/ip : 這個(gè)通信還是 tcp的,但是數(shù)據(jù)是rtu的數(shù)據(jù),因此,不能用常規(guī)的modbus-tcp建立鏈接的代碼建立鏈接,可以采用socket或者nio去建立鏈接,只不過(guò)還是要去解析對(duì)應(yīng)的從機(jī)地址,功能碼,校驗(yàn)位,數(shù)據(jù)等。那可以用什么工具去建立鏈接呢,其實(shí)跟modbus-tcp差不多,(NetAssist)(Modbus Poll)都可以的;

我這里簡(jiǎn)單列舉幾個(gè)例子:

就不用modbus-pull鏈接了,這個(gè)工具很好用,但是看不到具體發(fā)送的數(shù)據(jù)的細(xì)節(jié);

1:modbus-rtu-Over-tcp/ip

比如我從機(jī)地址1,兩個(gè)保持寄存器,40001是寫(xiě)入數(shù)據(jù)指令的,400002是讀取設(shè)備信號(hào)的

image.png

image.png

這里注意選這個(gè);

然后用上位機(jī)鏈接:

image.png

這里為什么要勾選【自動(dòng)發(fā)送校驗(yàn)位】呢?

因?yàn)閞tu數(shù)據(jù)是需要發(fā)送校驗(yàn)位的,而校驗(yàn)位是需要一個(gè)算法計(jì)算出來(lái)的,我就讓這個(gè)軟件自動(dòng)幫我算,如果你自己知道你發(fā)數(shù)據(jù)的校驗(yàn)位,那也是可以不用勾選直接自己填也行;

舉例:讀取40001地址的值:slaveId:01,功能碼03

image.png

舉例:寫(xiě)入40002地址數(shù)據(jù),功能碼06

image.png

解釋下rtu協(xié)議發(fā)送和接受反饋的這個(gè)數(shù)據(jù)格式:

modbus-rtu發(fā)送數(shù)據(jù)的格式:

image.png

modbus-rtu接受反饋信號(hào)的數(shù)據(jù)格式:

image.png

如果用modbus-pull工具的話,更直觀,

image.png

而且發(fā)送數(shù)據(jù)也賊簡(jiǎn)單:

image.png

是不是,這里工具自動(dòng)幫我做了校驗(yàn)碼,功能碼這些封裝,

懂了rtu數(shù)據(jù)格式后,可以用這個(gè),一開(kāi)始還是建議先用上面的那個(gè),方便加深學(xué)習(xí);

modbus-tcp發(fā)送數(shù)據(jù)的格式:

image.png

其實(shí)tcp除了沒(méi)有校驗(yàn)位,跟rtu的區(qū)別就是前面多了這個(gè)報(bào)文頭,

其實(shí)就是5個(gè)0和1個(gè)6;

而且是不需要勾選CRC校驗(yàn)的,因?yàn)閠cp不需要校驗(yàn),在報(bào)文頭就會(huì)有校驗(yàn)了;

注意:

image.png

題外話:

1:幾個(gè)寄存器的區(qū)別

離散輸入寄存器 只讀 簡(jiǎn)單的開(kāi)關(guān)量狀態(tài),如是否處于急停
輸入寄存器 只讀 數(shù)值類(lèi)型的狀態(tài),如系統(tǒng)狀態(tài),電量
線圈寄存器 可讀可寫(xiě) 簡(jiǎn)單的開(kāi)關(guān)量控制,如暫停運(yùn)動(dòng)
保持寄存器 可讀可寫(xiě) 數(shù)值類(lèi)型的控制指令,如移動(dòng)到站點(diǎn)/位姿

2:常用的功能碼

0x01: 讀線圈寄存器
0x02: 讀離散輸入寄存器
0x03: 讀保持寄存器
0x04: 讀輸入寄存器

0x05: 寫(xiě)單個(gè)線圈寄存器
0x06: 寫(xiě)單個(gè)保持寄存器
0x0f: 寫(xiě)多個(gè)線圈寄存器
0x10: 寫(xiě)多個(gè)保持寄存器

這其中有涉及到線圈、離散輸入、保持、輸入四種寄存器。

Modbus通訊協(xié)議學(xué)習(xí) - 認(rèn)識(shí)篇_pooooong的博客-CSDN博客_modbus通訊協(xié)議學(xué)習(xí)

freemodbus modbus TCP 學(xué)習(xí)筆記_xukai871105的博客-CSDN博客_freemodbus tcp

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容