1. 程式人生 > >物聯網RTU(Modbus TCP協議)Java介面開發及Modbus Slave模擬使用

物聯網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}}

參考:

相關推薦

聯網RTUModbus 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種動作:展開(右邊向右),合攏(左邊向右),收縮(右邊向左)這三種動作受接收端的控制。 合攏:表