經(jīng)典的modbus協(xié)議幀如圖:
Modbus-TCP:由TCP頭+地址+PDU組成揍异,
Modbus-RTU:由地址+PDU+CRC校驗(yàn)組成
Modbus的PDU(Protocol Data Unit仁堪,協(xié)議數(shù)據(jù)單元)由功能碼+寄存器地址+寄存器數(shù)量(可選)+寄存器值組成螃宙,PDU在TCP和RTU兩種形式上是相同的墨微。
說明:
1:Modbus為一問一答協(xié)議,發(fā)送一個(gè)請(qǐng)求后要等待回復(fù)才能發(fā)送第二個(gè)請(qǐng)求辽剧。
2:Modbus-RTU的物理接口為串口排截。
3:Modbus-TCP的物理接口為以太網(wǎng)。
解釋:
因此如果客戶是提供的modbus-rtu協(xié)議挠蛉,那么其實(shí)是需要一個(gè)串口轉(zhuǎn)網(wǎng)絡(luò)的一個(gè)轉(zhuǎn)換模塊(去買這么一個(gè)硬件祭示,也就50多塊錢)(串口轉(zhuǎn)網(wǎng)絡(luò)RJ45轉(zhuǎn)ttl 網(wǎng)口轉(zhuǎn)串口RS232/485),這個(gè)模塊就可以把協(xié)議轉(zhuǎn)為tcp,
但是谴古,
但是质涛,
坑來了,
這個(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,就是過濾了校驗(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)
其中Seria Port就是串口址芯,那用這個(gè)通信的話就是modbus-rtu,
可以使用modbus-rtu連接,例如插入U(xiǎn)SB查看串口谷炸。
或者自己測試的時(shí)候可以在自己的電腦虛擬兩個(gè)串口北专,工具為(Launch Virtual Serial Port Driver Pro)
然后modbus tcp/ip,這個(gè)可以用很多工具鏈接了旬陡,很多上位機(jī)軟件(NetAssist)(Modbus Poll)都可以拓颓,程序的話java也提供了很多工具包,(com.digitalpetri.modbus modbus-master-tcp)(或者可以建立socket或者nio鏈接描孟,只不過這個(gè)需要解析格式(報(bào)文頭啊驶睦,校驗(yàn)碼,從機(jī)地址匿醒,功能碼這些))
然后modbus rtu Over tcp/ip : 這個(gè)通信還是 tcp的场航,但是數(shù)據(jù)是rtu的數(shù)據(jù),因此青抛,不能用常規(guī)的modbus-tcp建立鏈接的代碼建立鏈接旗闽,可以采用socket或者nio去建立鏈接酬核,只不過還是要去解析對(duì)應(yīng)的從機(jī)地址蜜另,功能碼,校驗(yàn)位嫡意,數(shù)據(jù)等举瑰。那可以用什么工具去建立鏈接呢,其實(shí)跟modbus-tcp差不多蔬螟,(NetAssist)(Modbus Poll)都可以的此迅;
我這里簡單列舉幾個(gè)例子:
就不用modbus-pull鏈接了,這個(gè)工具很好用旧巾,但是看不到具體發(fā)送的數(shù)據(jù)的細(xì)節(jié)耸序;
1:modbus-rtu-Over-tcp/ip
比如我從機(jī)地址1,兩個(gè)保持寄存器鲁猩,40001是寫入數(shù)據(jù)指令的坎怪,400002是讀取設(shè)備信號(hào)的
這里注意選這個(gè);
然后用上位機(jī)鏈接:
這里為什么要勾選【自動(dòng)發(fā)送校驗(yàn)位】呢廓握?
因?yàn)閞tu數(shù)據(jù)是需要發(fā)送校驗(yàn)位的搅窿,而校驗(yàn)位是需要一個(gè)算法計(jì)算出來的,我就讓這個(gè)軟件自動(dòng)幫我算隙券,如果你自己知道你發(fā)數(shù)據(jù)的校驗(yàn)位男应,那也是可以不用勾選直接自己填也行;
舉例:讀取40001地址的值:slaveId:01娱仔,功能碼03
舉例:寫入40002地址數(shù)據(jù)沐飘,功能碼06
解釋下rtu協(xié)議發(fā)送和接受反饋的這個(gè)數(shù)據(jù)格式:
modbus-rtu發(fā)送數(shù)據(jù)的格式:
modbus-rtu接受反饋信號(hào)的數(shù)據(jù)格式:
如果用modbus-pull工具的話,更直觀,
而且發(fā)送數(shù)據(jù)也賊簡單:
是不是耐朴,這里工具自動(dòng)幫我做了校驗(yàn)碼众弓,功能碼這些封裝,
懂了rtu數(shù)據(jù)格式后隔箍,可以用這個(gè)谓娃,一開始還是建議先用上面的那個(gè),方便加深學(xué)習(xí)蜒滩;
modbus-tcp發(fā)送數(shù)據(jù)的格式:
其實(shí)tcp除了沒有校驗(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)了竹握;
注意:
題外話:
1:幾個(gè)寄存器的區(qū)別
離散輸入寄存器 只讀 簡單的開關(guān)量狀態(tài)画株,如是否處于急停
輸入寄存器 只讀 數(shù)值類型的狀態(tài),如系統(tǒng)狀態(tài)啦辐,電量
線圈寄存器 可讀可寫 簡單的開關(guān)量控制谓传,如暫停運(yùn)動(dòng)
保持寄存器 可讀可寫 數(shù)值類型的控制指令,如移動(dòng)到站點(diǎn)/位姿
2:常用的功能碼
0x01: 讀線圈寄存器
0x02: 讀離散輸入寄存器
0x03: 讀保持寄存器
0x04: 讀輸入寄存器
0x05: 寫單個(gè)線圈寄存器
0x06: 寫單個(gè)保持寄存器
0x0f: 寫多個(gè)線圈寄存器
0x10: 寫多個(gè)保持寄存器
這其中有涉及到線圈芹关、離散輸入续挟、保持、輸入四種寄存器侥衬。
Modbus通訊協(xié)議學(xué)習(xí) - 認(rèn)識(shí)篇_pooooong的博客-CSDN博客_modbus通訊協(xié)議學(xué)習(xí)
freemodbus modbus TCP 學(xué)習(xí)筆記_xukai871105的博客-CSDN博客_freemodbus tcp