物聯網RTU(Modbus TCP協議)Java介面開發及Modbus Slave模擬使用
在物聯網體系中,經常用到RTU(遠端終端單元),RTU是負責對現場訊號、工業裝置的監測和控制,通常由訊號輸入/出模組、微處理器、有線/無線通訊裝置、電源及外殼等組成,由微處理器控制,並支援網路系統。
在物聯網應用平臺上,需要通過RTU與現場裝置對接,採集現場資料、控制裝置,通過網路與RTU連線,主要是採用Modbus TCP協議。
Modbus是應用於電子控制器上的一種通用語言。通過此協議,控制器相互之間、控制器經由網路(例如乙太網)和其它裝置之間可以通訊。它已經成為一種通用工業標準。有了它,不同廠商生產的控制裝置可以連成工業網路,進行集中監控。此協議定義了一個控制器能認識使用的訊息結構,而不管它們是經過何種網路進行通訊的。它描述了一個控制器請求訪問其它裝置的過程,如何迴應來自其它裝置的請求,以及怎樣偵測錯誤並記錄。它制定了訊息域格局和內容的公共格式。
物聯網應用軟體開發,需要與RTU介面,為了方便軟體開發,降低對物聯網裝置的依賴,Modbus模擬軟體也就出現,對此,物聯網開發人員應該很熟悉,但是對於普通網際網路開發人員,還是很陌生的,為此,此文介紹ModbusTCP模擬軟體使用和基於Netty的RTU java介面開發。
1、ModbusTCP模擬
ModbusSlave(軟體官方網站地址)是一個從站裝置模擬軟體,它用於接收主裝置的命令包,並回送資料包;可用於測試和除錯Modbus主站裝置,便於觀察Modbus通訊過程中的各種報文。ModbusPoll及ModbusSlave支援ModbusRTU, ASCII,TCP/IP等協議。
首先,瞭解MODBUS支援的部分功能程式碼,以十進位制表示,如下表所示。
程式碼 | 中文名稱 | 英文名稱 | 位操作/字操作 | 運算元量 |
---|---|---|---|---|
01 | 讀線圈狀態 | READ COIL STATUS | 位操作 | 單個或多個 |
02 | 讀離散輸入狀態 | READ INPUT STATUS | 位操作 | 單個或多個 |
03 | 讀保持暫存器 | READ HOLDING REGISTER | 字操作 | 單個或多個 |
04 | 讀輸入暫存器 | READ INPUT REGISTER | 字操作 | 單個或多個 |
05 | 寫線圈狀態 | WRITE SINGLE COIL | 位操作 | 單個 |
06 | 寫單個保持暫存器 | WRITE SINGLE REGISTER | 字操作 | 單個 |
15 | 寫多個線圈 | WRITE MULTIPLE COIL | 位操作 | 多個 |
16 | 寫多個保持暫存器 | WRITE MULTIPLE REGISTER | 字操作 | 多個 |
引數設定:
點選選單“Setup”中“Slave Definition.. F2”進行引數設定,會彈出如下圖對話方塊
其中:
(1)Slave ID:裝置ID;
(2)Function:對應上表所對應的Modbus功能,例如本文所選用的“03 Holding Register…”,與下文Java程式碼“見類ReadHoldingRegistersResponse ”所對應。
(3)Address:暫存器地址;
(4)Quantity:數量。
開啟ModbusSlave軟體,為方便起見,本文采用預設的地址(localhost,與下文第二段程式碼對應“見類ClientForTests ”),功能碼,暫存器數量,單擊Connection->connect,在彈出的視窗設定connection為TCP/IP,埠Port設定為30502,點選OK,如下圖所示,從端配置完畢。
注意:
(1)本文連線Connection採用Modbus TCP/IP協議;
(2)網路地址為本地地址,127.0.0.1;
(3)埠與下文第二段程式碼“見類ClientForTests”中的地址和埠設定為“30502”;
(4)選擇“Ignore Unit ID”,如果不選擇,測試程式返回空值。
2、基於Netty實現RTU介面
本文Java程式碼,來源於modjn(https://github.com/klymenek/modjn),基於Netty 4.x實現Modbus TCP客戶端和服務端(Modbus TCP client/server implementation in Java with Netty 4.x)。
package de.gandev.modjn.example;
import de.gandev.modjn.ModbusClient;
import de.gandev.modjn.entity.exception.ConnectionException;
import de.gandev.modjn.entity.exception.ErrorResponseException;
import de.gandev.modjn.entity.exception.NoResponseException;
import de.gandev.modjn.entity.func.response.ReadCoilsResponse;
import de.gandev.modjn.entity.func.response.ReadHoldingRegistersResponse;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author XiaoYW
*
*/
public class TestModbusSlave {
public static void main(String[] args) {
ModbusClient modbusClient = ClientForTests.getInstance().getModbusClient();
ReadCoilsResponse readCoils = null;
try {
readCoils = modbusClient.readCoils(12321, 5);
} catch (NoResponseException | ErrorResponseException | ConnectionException ex) {
Logger.getLogger(Example.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage());
}
System.out.println(readCoils);
ReadHoldingRegistersResponse readHolding = null;
try {
readHolding = modbusClient.readHoldingRegisters(2200,10);
} catch (NoResponseException | ErrorResponseException | ConnectionException ex) {
Logger.getLogger(Example.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage());
}
System.out.println(readHolding);
modbusClient.close();
}
}
客戶端測試程式碼,如下文所示。
package de.gandev.modjn.example;
import de.gandev.modjn.ModbusClient;
import de.gandev.modjn.entity.exception.ConnectionException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author ares
*/
public class ClientForTests {
private final ModbusClient modbusClient;
private ClientForTests() {
modbusClient = new ModbusClient("localhost" /*
* "192.168.1.55"
*/, 30502); //ModbusConstants.MODBUS_DEFAULT_PORT);
try {
modbusClient.setup();
} catch (ConnectionException ex) {
Logger.getLogger(ClientForTests.class.getName()).log(Level.SEVERE, null, ex);
}
}
public ModbusClient getModbusClient() {
return modbusClient;
}
public static ClientForTests getInstance() {
return ClientAndServerHolder.INSTANCE;
}
private static class ClientAndServerHolder {
private static final ClientForTests INSTANCE = new ClientForTests();
}
}
以Java應用程式執行,執行結果:
ReadCoilsResponse{byteCount=1, coilStatus={0, 3}}
ReadHoldingRegistersResponse{byteCount=20,
inputRegisters={register_0=2, register_1=0, register_2=0, register_3=3, register_4=0, register_5=0, register_6=8, register_7=0, register_8=0, register_9=0}}
參考:
相關推薦
物聯網RTU(Modbus TCP協議)Java介面開發及Modbus Slave模擬使用
在物聯網體系中,經常用到RTU(遠端終端單元),RTU是負責對現場訊號、工業裝置的監測和控制,通常由訊號輸入/出模組、微處理器、有線/無線通訊裝置、電源及外殼等組成,由微處理器控制,並支援網路系統。 在物聯網應用平臺上,需要通過RTU與現場裝置對接,採
《連載 | 物聯網框架ServerSuperIO教程》- 7.自控通訊模式開發及注意事項
目 錄 7. 自控通訊模式開發及注意事項... 2 7.1 概述... 2 7.2 通訊機制說明... 2 7.3 裝置驅動開發注意事項... 3 7.3.1 實時傳送資料... 3 7.
《連載 | 物聯網框架ServerSuperIO教程》- 6.併發通訊模式開發及注意事項
目 錄 6. 併發通訊模式開發及注意事項... 2 6.1 概述... 2 6.2 通訊機制說明... 2 6.3 裝置驅動開發注意事項... 3 6.3.1 實時傳送資料... 3 6.3.
三、 TCP(傳輸控制協議)
我想 機器 ref ack 大小 機制 以及 請求 傳輸 它建立在網際層協議(IP)提供的數據包傳輸技術之上,。TCP使應用程序可使用連續的數據進行通信。除非由於網絡故障導致連接中斷或凍結,TCP都能保證數據流完好地傳輸。而不會發生丟包 ,重包或是亂序的問題。 1 TC
傳輸層(Udp協議 Tcp協議)
傳輸層是負責資料能夠從傳送端傳輸接收端。負責端與端之間的傳輸。端與端就相當於是兩個程序之間的資料傳輸。 埠號 埠號是傳輸層協議的內容: 埠號是一個2位元組16位的無符號整數;(0-65535之間一個數字,0-1023不推薦使用) 埠號用來標識一個程序,告訴作業系統,當前資料要交給哪一個程序
各種工業乙太網比較(EtherCAT,EtherNet/IP,ProfiNet,Modbus-TCP,Powerlink)
EtherCAT(乙太網控制自動化技術)是一個以乙太網為基礎的開放架構的現場匯流排系統,EterCAT名稱中的CAT為ControlAutomation Technology(控制自動化技術)首字母的縮寫。最初由德國倍福自動化有限公司(Beckhoff AutomationGmbH)研發。EtherCAT為系
國內物聯網平臺(3)——QQ物聯·智慧硬體開放平臺
國內物聯網平臺(3)——QQ物聯·智慧硬體開放平臺 作者:馬智 平臺定位 將QQ帳號體系、好友關係鏈、QQ訊息通道及音視訊服務等核心能力提供給可穿戴裝置、智慧家居、智慧車載、傳統硬體等領域的合作伙
國內物聯網平臺(2)——阿里雲物聯網套件
國內物聯網平臺(2)——阿里雲物聯網套件 作者:馬智 架構 資料通道 為裝置和物聯網應用程式提供釋出和接收訊息的安
國內物聯網平臺(1)——百度物接入IoT Hub
國內物聯網平臺(1)——百度物接入IoT Hub 作者:馬智 物接入IoT Hub - 架構 全託管的雲服務,幫助建立裝置與雲端之間安
從零開始搭建物聯網平臺(7):使用Vue編寫前端頁面
摘要: Vue我也是剛開始學的,看了兩天的文件就開始著手做這件事了,所以對vue瞭解不太深入,沒有能力說的的太詳細萬一是錯誤的不就誤導別人了,所以只對幾個相對來說比較主要的點說明一下。 搭建開發環境: 老生常談的話題!首先自然是要安裝nodejs,這個直接去官網下載安裝即可,再使用命令n
從零開始搭建物聯網平臺(6):訊息的持久化
遇到的問題: 查看了EMQ文件發現並不提供訊息的持久化功能,MQTT協議是按照裝置一直線上設計的,資料都是儲存在記憶體裡的,但是考慮到使用者上傳感測器資料不可能接收了就扔掉,那樣就沒法檢視歷史資料了,所以使用者上傳的訊息必須要能夠儲存下來,以便檢視歷史資料,這樣一來持久化功能就需要我們自己來實現
從零開始搭建物聯網平臺(5):搭建後臺服務(一)
資料庫的設計: 後臺使用Django web框架實現,Django和python怎麼用就不介紹了,東西太多了,看完下面的這些部落格就可以了,差不多就夠了https://www.cnblogs.com/wupeiqi/articles/4938499.html 資料庫設計: &
從零開始搭建物聯網平臺(4):訂閱系統主題獲取裝置上下線訊息
$SYS-系統主題 先來看一段EMQ對於系統主題的介紹:EMQ 訊息伺服器週期性釋出自身執行狀態、MQTT 協議統計、客戶端上下線狀態到 $SYS/ 開頭系統主題。$SYS 主題路徑以 “$SYS/brokers/{node}/” 開頭,’${node}’ 是 Erlang
《物聯網框架ServerSuperIO教程》- 23.動態資料介面增加快取,提高資料輸出到OPCServer和(實時)資料庫的效率
22.1 概述及要解決的問題 裝置驅動有DeviceDynamic介面,可以繼承並增加新的實時資料屬性,每次通訊完成後更新這些屬性資料。原來是通過DeviceDynamic介面實體類反射的方式獲得最新的實時資料,並輸出到關係資料庫、實時資料庫和OPC Server等介面。 但是
TCP/IP之TCP協議:流量控制(滑動視窗協議)
一、流量控制(滑動視窗協議) 1、流量控制是管理兩端的流量,以免會產生髮送過塊導致收端溢位,或者因收端處理太快而浪費時間的狀態。用的是:滑動視窗,以位元組為單位 2、視窗有3種動作:展開(右邊向右),合攏(左邊向右),收縮(右邊向左)這三種動作受接收端的控制。 合攏:表示已經收到相應位元組的確認了 展開:表
使用 Python3 接入阿里雲物聯網平臺(原物聯網套件)
阿里雲官方提供的 DEMO,無Python接入 阿里雲物聯網平臺(原物聯網套件) 的例子,不便於我們在電腦端做虛擬終端的相關測試,本文介紹一種基於使用Python3、MQTT-TCP連線通訊 接入阿里雲物聯網平臺(原物聯網套件)。 開發語言:Python3.5 開發環境:
國外物聯網平臺(1):亞馬遜AWS IoT
國外物聯網平臺(1)——亞馬遜AWS IoT 馬智 平臺定位 AWS IoT是一款託管的雲平臺,使互聯裝置可以輕鬆安全地與雲應用程式及其他裝置互動。 AWS IoT可支援數十億臺裝置和數萬億條訊息,並且可以對這些訊息進行處理並將其安全可靠地路由至 AWS 終端節點和其他裝置。應
關於c++(客戶端)和JAVA(服務端)的TCP通訊(基於stomp協議)(一)
最近在做軟體外掛的更新服務,其中涉及到客戶端和服務端通訊,採取服務端推送的形式進行更新資料包的推送。 經過商討後採取TCP通訊,由於服務端是JAVA的,客戶端是C++。 在http://wenku.baidu.com/view/5eb31ea1284ac850ad0242
【視訊傳輸】二、Opencv結合socket進行視訊傳輸(TCP協議)
博文由來:筆者突發奇想,做採集4個USB攝像頭畫面小實驗時,卻遇到了在電腦上最多隻能同時開啟3個這樣頭痛的問題(個人分析認為是電腦的問題),故出此下策,在客戶端掛1個,伺服器掛3個攝像頭,利用socket進行視訊傳輸,本篇文章是利用的是TCP協議。筆者拙見,
TCP/IP之TCP協議——流量控制(滑動視窗協議)
一、流量控制(滑動視窗協議) 1、流量控制是管理兩端的流量,以免會產生髮送過塊導致收端溢位,或者因收端處理太快而浪費時間的狀態。用的是:滑動視窗,以位元組為單位 2、視窗有3種動作:展開(右邊向右),合攏(左邊向右),收縮(右邊向左)這三種動作受接收端的控制。 合攏:表