Java使用modbus-master-tcp实现modbus tcp通讯

 更新时间:2023年12月27日 10:43:35   作者:左搜  
这篇文章主要为大家详细介绍了另外一种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通讯的资料请关注脚本之家其它相关文章!

相关文章

  • Java实战角色权限后台脚手架系统的实现流程

    Java实战角色权限后台脚手架系统的实现流程

    只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+Springboot+Maven+myBaits-Plus+Vue+Element-UI+Mysql实现一个角色权限后台脚手架系统,大家可以在过程中查缺补漏,提升水平
    2022-01-01
  • 详解Java中使用externds关键字继承类的用法

    详解Java中使用externds关键字继承类的用法

    子类使用extends继承父类是Java面向对象编程中的基础知识,这里我们就来详解Java中使用externds关键字继承类的用法,需要的朋友可以参考下
    2016-07-07
  • Spring Boot项目中使用OpenAI-Java的示例详解

    Spring Boot项目中使用OpenAI-Java的示例详解

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,这篇文章主要介绍了Spring Boot项目中使用OpenAI-Java的示例详解,需要的朋友可以参考下
    2023-04-04
  • Java中断线程的方法

    Java中断线程的方法

    这篇文章主要介绍了Java中断线程的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-05-05
  • SpringBoot jar包大小优化问题及解决

    SpringBoot jar包大小优化问题及解决

    这篇文章主要介绍了SpringBoot jar包大小优化问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Jenkins Pipline实现及原理示例解析

    Jenkins Pipline实现及原理示例解析

    这篇文章主要为大家介绍了Jenkins Pipline实现及原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • spring+Jpa多数据源配置的方法示例

    spring+Jpa多数据源配置的方法示例

    这篇文章主要介绍了spring+Jpa多数据源配置的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 浅谈Java线程并发知识点

    浅谈Java线程并发知识点

    本文主要对Java线程并发的知识点进行简单介绍。具有很好的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • 鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件的实例代码

    鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件的实例代码

    这篇文章主要介绍了鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • IDEA自定义Maven archetype的方法步骤

    IDEA自定义Maven archetype的方法步骤

    在创建Maven的项目时我们发现了一个很不方便的问题,就是每次创建Maven的工程的时候,都需要选择一个骨架,本文主要介绍了IDEA自定义Maven archetype的方法步骤,感兴趣的可以了解一下
    2022-03-03

最新评论