通过借鉴高人博客,总结如下:

1. TcpMaster类,用于生成ModbusMaster主类

package sun.sunboat;
public class TcpMaster { private static ModbusFactory modbusFactory; static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
} /**
* 获取master
*
* @return master
*/
public static ModbusMaster getMaster() {
IpParameters params = new IpParameters();
params.setHost("localhost");
params.setPort(502);
params.setEncapsulated(false);//这个属性确定了协议帧是否是通过tcp封装的RTU结构,采用modbus tcp/ip时,要设为false, 采用modbus rtu over tcp/ip时,要设为true
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
try {
//设置超时时间
master.setTimeout(1000);
//设置重连次数
master.setRetries(3);
//初始化
master.init();
} catch (ModbusInitException e) {
e.printStackTrace();
}
return master;
} /**
* 获取master
*
* @return master
*/
public static ModbusMaster getMaster(String ipAdd) {
IpParameters params = new IpParameters();
params.setHost(ipAdd);
params.setPort(502);
params.setEncapsulated(true);
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
try {
//设置超时时间
master.setTimeout(1000);
//设置重连次数
master.setRetries(3);
//初始化
master.init();
} catch (ModbusInitException e) {
e.printStackTrace();
}
return master;
} }

2. 读取类Modbus4jReader

package sun.sunboat;
public class Modbus4jReader {
//获取master
//private static ModbusMaster master = TcpMaster.getMaster();
private ModbusMaster master = null;
public Modbus4jReader(ModbusMaster master) {
this.master = master;
}
/**
* 读(线圈)开关量数据
*
* @param slaveId slaveId
* @param offset 位置
* @return 读取值
*/
public boolean[] readCoilStatus(int slaveId, int offset, int numberOfBits)
throws ModbusTransportException, ErrorResponseException, ModbusInitException { ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfBits);
ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);
boolean[] booleans = response.getBooleanData();
return valueRegroup(numberOfBits, booleans);
} /**
* 开关数据 读取外围设备输入的开关量
*/
public boolean[] readInputStatus(int slaveId, int offset, int numberOfBits)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, offset, numberOfBits);
ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);
boolean[] booleans = response.getBooleanData();
return valueRegroup(numberOfBits, booleans);
} /**
* 读取保持寄存器数据
*
* @param slaveId slave Id
* @param offset 位置
*/
public short[] readHoldingRegister(int slaveId, int offset, int numberOfBits)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, offset, numberOfBits);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);
return response.getShortData();
} /**
* 读取外围设备输入的数据
*
* @param slaveId slaveId
* @param offset 位置
*/
public short[] readInputRegisters(int slaveId, int offset, int numberOfBits)
throws ModbusTransportException, ErrorResponseException, ModbusInitException { ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, offset, numberOfBits);
ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);
return response.getShortData();
} /**
* 批量读取 可以批量读取不同寄存器中数据
*/
public void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException { BatchRead<Integer> batch = new BatchRead<Integer>();
batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED));
batch.addLocator(1, BaseLocator.inputStatus(1, 0));
batch.setContiguousRequests(true);
BatchResults<Integer> results = master.send(batch);
System.out.println("batchRead:" + results.getValue(0));
System.out.println("batchRead:" + results.getValue(1));
} private boolean[] valueRegroup(int numberOfBits, boolean[] values) {
boolean[] bs = new boolean[numberOfBits];
int temp = 1;
for (boolean b : values) {
bs[temp - 1] = b;
temp++;
if (temp > numberOfBits)
break;
}
return bs;
}
}

3. 写入类

package sun.sunboat;
public class Modbus4jWriter {
// 获取Master
//private static ModbusMaster tcpMaster = TcpMaster.getMaster();
private ModbusMaster tcpMaster = null;
public Modbus4jWriter(ModbusMaster master) {
this.tcpMaster = master;
}
/**
* 写单个(线圈)开关量数据
*
* @param slaveId slave的ID
* @param writeOffset 位置
* @param writeValue 值
* @return 是否写入成功
*/
public boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)
throws ModbusTransportException, ModbusInitException {
// 创建请求
WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
// 发送请求并获取响应对象
WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
return !response.isException();
} /**
* 写多个开关量数据(线圈)
*
* @param slaveId slaveId
* @param startOffset 开始位置
* @param bdata 写入的数据
* @return 是否写入成功
*/
public boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)
throws ModbusTransportException, ModbusInitException {
// 创建请求
WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
// 发送请求并获取响应对象
WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
return !response.isException(); } /***
* 保持寄存器写单个
*
* @param slaveId slaveId
* @param writeOffset 开始位置
* @param writeValue 写入的数据
*/
public boolean writeRegister(int slaveId, int writeOffset, short writeValue)
throws ModbusTransportException, ModbusInitException {
// 创建请求对象
WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
// 发送请求并获取响应对象
WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);
return !response.isException(); } /**
* 保持寄存器写入多个模拟量数据
*
* @param slaveId modbus的slaveID
* @param startOffset 起始位置偏移量值
* @param sdata 写入的数据
* @return 返回是否写入成功
*/
public boolean writeRegisters(int slaveId, int startOffset, short[] sdata)
throws ModbusTransportException, ModbusInitException {
// 创建请求对象
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
// 发送请求并获取响应对象
WriteRegistersResponse response = (WriteRegistersResponse) tcpMaster.send(request);
return !response.isException();
} /**
* 根据类型写数据(如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long)
*
* @param value 写入值
* @param dataType com.serotonin.modbus4j.code.DataType 类型定义在com.serotonin.modbus4j.code.DataType类中
*/ public void writeHoldingRegister(int slaveId, int offset, Number value, int dataType) throws ModbusTransportException, ErrorResponseException, ModbusInitException { // 类型 BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType); tcpMaster.setValue(locator, value); } }

4. 依赖项

    <dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.4</version>
</dependency>

modbus4j中使用modbus tcp/ip和modbus rtu over tcp/ip模式的更多相关文章

  1. 我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp)

    我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp) 分类: [自动化]2007-07-19 10:04 34038人阅读 评论(38) 收藏 举报 vb嵌入式dostcp ...

  2. 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(一)

    转自:http://blog.csdn.net/thebestleo/article/details/52269999 首先我要说明一下,本人新手一枚,本文仅为同样热爱学习的同学提供参考,有不 对的地 ...

  3. 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(二)

    由于感觉上一次写的篇幅过长,所以新开一贴,继续介绍Modbus TCP/IP的初步认识, 书接上回 3).03(0x03)功能码--------读保持寄存器 请求与响应格式 这是一个请求读寄存器108 ...

  4. Modbus教程| Modbus协议,ASCII和RTU帧,Modbus工作

    转载自:https://www.rfwireless-world.com/Tutorials/Modbus-Protocol-tutorial.html 这个Modbus教程涵盖了modbus协议基础 ...

  5. Modbus通信协议 【 初识 Modbus】

    Modbus协议     Modbus 协议是应用于电子控制器上的一种通用语言.通过此协议,控制器相互之间.控制器经由网络(例如以太网)和其它设备之间可以通信.它已经成为一通用工业标准.有了它,不同厂 ...

  6. TCP/IP协议(二)tcp/ip基础知识

    今天凌晨时候看书,突然想到一个问题:怎样做到持续学习?然后得出这样一个结论:放弃不必要的社交,控制欲望,克服懒惰... 然后又有了新的问题:学习效率时高时低,状态不好怎么解决?这也是我最近在思考的问题 ...

  7. 用批处理文件进行TCP/IP设置,方便在家与办公IP切换

    在公司用公司分配的固定IP上网,回家后又要将本本设置为家里的固定IP上网,每次都要手动重复一个过程: 打开网络中心,选择本地连接,进入属性然后选择IPV4进行TCP/IP的设置,填入IP,子网掩码DN ...

  8. TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节

    1.静态IP选路 1.1.一个简单的路由表 选路是IP层最重要的一个功能之一.前面的部分已经简单的讲过路由器是通过何种规则来根据IP数据包的IP地址来选择路由.这里就不重复了.首先来看看一个简单的系统 ...

  9. TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议

    把这三个协议放到一起学习是因为这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP得到要传输的数 ...

随机推荐

  1. 将自己写的组件封装成类似element-ui一样的库,可以cdn引入

    在写好自己的组件之后 第一步 修改目录结构 在根目录下创建package文件夹,用于存放你要封装的组件 第二部 在webpack配置中加入 pages与publicpath同级 pages: { in ...

  2. IP协议首部结构介绍

    当提交给数据链路层进行传送时,一个 I P分片或一个很小的无需分片的 I P数据报称为分组.数据链路层在分组前面加上它自己的首部,并发送得到的帧.I P只考虑它自己加上的 I P首部,对报文本身既不检 ...

  3. Python----常用的__doc__、__name__、__file__的使用

    各自的作用: __doc__:获取到注释内容 __name__:获取到函数的名称 __file__:获取到当前的文件路径 示例代码: #!/usr/bin/env python # -*- codin ...

  4. [Google Guava] 2.4-集合扩展工具类

    原文链接 译文链接 译者:沈义扬,校对:丁一 简介 有时候你需要实现自己的集合扩展.也许你想要在元素被添加到列表时增加特定的行为,或者你想实现一个Iterable,其底层实际上是遍历数据库查询的结果集 ...

  5. 12、生命周期-@Bean指定初始化和销毁方法

    12.生命周期-@Bean指定初始化和销毁方法 Bean的生命周期:创建->初始化->销毁 容器管理bean的生命周期 我们可以自定义初始方法和销毁方法,容器在bean进行到当期那生命周期 ...

  6. JavaScript中的变量提升和严格模式

    1.什么是变量提升 所谓的变量提升指的是:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体(作用域)的最顶部. //先声明后使用 var x; console.log(x) ...

  7. Django:将模型注册到后台的几种方法

    from django.contrib import admin from .models import * #将模型注册到后台: #方法一:将模型直接注册到后台 # admin.site.regis ...

  8. 应用webservice实现公网天气查询

    1. wsdl网址:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl 2. URL:http://www.webxml.com.cn/zh ...

  9. Java安全(加密、摘要、签名、证书、SSL、HTTPS)

    对于一般的开发人员来说,很少需要对安全领域内的基础技术进行深入的研究,但是鉴于日常系统开发中遇到的各种安全相关的问题,熟悉和了解这些安全技术的基本原理和使用场景还是非常必要的.本文将对非对称加密.数字 ...

  10. puppeteer学习笔记合集

    官方英文版API入口(如果你英文好的话):https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md. 汉化版API入口(网上有 ...