Java使用modbus-master-tcp实现modbus tcp通讯
作者:左搜
这篇文章主要为大家详细介绍了另外一种Java语言的modbux tcp通讯方案,那就是modbus-master-tcp,文中的示例代码讲解详细,需要的可以了解下
引言
modbus tcp通讯Java的方案之前已经讲解过一种,modbus4j实现Java语言的modbus tcp协议通讯。从上一个方案中我们不难发现modbus4j的通讯实现方式是同步的。实际应用中可能会读取大量的数据。同步处理对于应用的响应还是不太友好的。本博客主要讲解另外一种Java语言的modbux tcp通讯方案。那就是modbus-master-tcp。
一、创建一个demo项目
创建一个简单的maven项目,项目结构图如下:
二、pom.xml maven依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.leftso.demo.modbus</groupId> <artifactId>demo-modbus-master-slave</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>com.digitalpetri.modbus</groupId> <artifactId>modbus-master-tcp</artifactId> <version>1.1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
pom.xml注意,需要将java的编译版本指定到1.8.因为只有1.8以后才支持lambda表达式。
配置完成后,我们观察引入的依赖包:
观察可以发现,modbus-master-tcp项目的底层是基于netty框架开发。天然的支持异步处理。在性能方面有很好的提升。
三、编写modbus tcp读取案例
package com.leftso.demo.modbus; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import com.digitalpetri.modbus.codec.Modbus; import com.digitalpetri.modbus.master.ModbusTcpMaster; import com.digitalpetri.modbus.master.ModbusTcpMasterConfig; import com.digitalpetri.modbus.requests.ReadCoilsRequest; import com.digitalpetri.modbus.requests.ReadDiscreteInputsRequest; import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest; import com.digitalpetri.modbus.requests.ReadInputRegistersRequest; import com.digitalpetri.modbus.responses.ReadCoilsResponse; import com.digitalpetri.modbus.responses.ReadDiscreteInputsResponse; import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse; import com.digitalpetri.modbus.responses.ReadInputRegistersResponse; import io.netty.buffer.ByteBuf; import io.netty.util.ReferenceCountUtil; /*** * modbus TCP协议Java通讯读取例子 * * @author xqlee * */ public class SimpleMasterExample { static ModbusTcpMaster master; /** * 获取TCP协议的Master * * @return */ public static void initModbusTcpMaster() { if (master == null) { // 创建配置 ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder("localhost").setPort(502).build(); master = new ModbusTcpMaster(config); } } /*** * 释放资源 */ public static void release() { if (master != null) { master.disconnect(); } Modbus.releaseSharedResources(); } /** * 读取HoldingRegister数据 * * @param address * 寄存器地址 * @param quantity * 寄存器数量 * @param unitId * id * @return 读取结果 * @throws InterruptedException * 异常 * @throws ExecutionException * 异常 */ public static Number readHoldingRegisters(int address, int quantity, int unitId) throws InterruptedException, ExecutionException { Number result = null; CompletableFuture<ReadHoldingRegistersResponse> future = master .sendRequest(new ReadHoldingRegistersRequest(address, quantity), unitId); ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理 if (readHoldingRegistersResponse != null) { ByteBuf buf = readHoldingRegistersResponse.getRegisters(); result = buf.readFloat(); ReferenceCountUtil.release(readHoldingRegistersResponse); } return result; } /** * 读取InputRegisters模拟量数据 * * @param address * 寄存器开始地址 * @param quantity * 数量 * @param unitId * ID * @return 读取值 * @throws InterruptedException * 异常 * @throws ExecutionException * 异常 */ public static Number readInputRegisters(int address, int quantity, int unitId) throws InterruptedException, ExecutionException { Number result = null; CompletableFuture<ReadInputRegistersResponse> future = master .sendRequest(new ReadInputRegistersRequest(address, quantity), unitId); ReadInputRegistersResponse readInputRegistersResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理 if (readInputRegistersResponse != null) { ByteBuf buf = readInputRegistersResponse.getRegisters(); result = buf.readFloat(); ReferenceCountUtil.release(readInputRegistersResponse); } return result; } /** * 读取Coils开关量 * * @param address * 寄存器开始地址 * @param quantity * 数量 * @param unitId * ID * @return 读取值 * @throws InterruptedException * 异常 * @throws ExecutionException * 异常 */ public static Boolean readCoils(int address, int quantity, int unitId) throws InterruptedException, ExecutionException { Boolean result = null; CompletableFuture<ReadCoilsResponse> future = master.sendRequest(new ReadCoilsRequest(address, quantity), unitId); ReadCoilsResponse readCoilsResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理 if (readCoilsResponse != null) { ByteBuf buf = readCoilsResponse.getCoilStatus(); result = buf.readBoolean(); ReferenceCountUtil.release(readCoilsResponse); } return result; } /** * 读取readDiscreteInputs开关量 * * @param address * 寄存器开始地址 * @param quantity * 数量 * @param unitId * ID * @return 读取值 * @throws InterruptedException * 异常 * @throws ExecutionException * 异常 */ public static Boolean readDiscreteInputs(int address, int quantity, int unitId) throws InterruptedException, ExecutionException { Boolean result = null; CompletableFuture<ReadDiscreteInputsResponse> future = master .sendRequest(new ReadDiscreteInputsRequest(address, quantity), unitId); ReadDiscreteInputsResponse discreteInputsResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理 if (discreteInputsResponse != null) { ByteBuf buf = discreteInputsResponse.getInputStatus(); result = buf.readBoolean(); ReferenceCountUtil.release(discreteInputsResponse); } return result; } public static void main(String[] args) { try { // 初始化资源 initModbusTcpMaster(); // 执行操作 // 读取模拟量 System.out.println(readHoldingRegisters(0, 4, 1)); System.out.println(readInputRegisters(0, 4, 1)); // 读取开关量 System.out.println(readCoils(0, 1, 1)); System.out.println(readDiscreteInputs(0, 1, 1)); System.out.println(readDiscreteInputs(2, 1, 1)); // 释放资源 release(); } catch (Exception e) { e.printStackTrace(); } } }
上面的代码中模拟量的读取需要注意,根据实际类型来读取相应的类型,例子中读取的double类型数据
四、运行上面的案例演示modbus tcp数据读取
首先打开软件Modbus Slave(没有的可以百度下载)。启动连接:
连接完成后,创建四个文档如下图所示:
好了,现在运行我们刚才编写的Java demo程序,SimpleMasterExample:
通过执行结果可以看到与Modbus Slave软件中的文档数据一致。
以上就是Java使用modbus-master-tcp实现modbus tcp通讯的详细内容,更多关于Java modbustcp通讯的资料请关注脚本之家其它相关文章!