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

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. JAVA遇见HTML——JSP篇:JSP基础语法

    动态网页和静态网页的区别: 静态网页 表现形式:网页中的内容是固定,不会更新. 所需技术:HTML,CSS 动态网页 表现形式:网页中的内容通过程序动态显示的,自动更新. 所需技术:HTML,CSS, ...

  2. linux实操_shell

    简单shell编写: 执行方式: (1)推荐 (2)不推荐

  3. Dapper+Mysql 使用LIKE模糊查询写法踩坑

    LIKE '%@Title%' 会解析成'%'@Title'%' 这里用拼接也是不行的'%'+@Title+'%' 只能用MySQL函数方法拼接 public dynamic GetListByFil ...

  4. Java集合--整体框架

    Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.*Java集合主要可以划分为4个部分:List列表.Set集合 ...

  5. SQL分表

    一.为什么要水平分表?简而言之,当单表数据量过大时,无法对其进行有效的维护,以及查询速度严重变慢时,我们就需要对其时行水平分表. 二.什么时候需要水平分表?在数据库结构的设计中,需要充分考虑后期数据的 ...

  6. chrome扩展开发实战入门之二-自动搜索

    目标:产生随机数,用于百度搜索:像看电视一样观看搜索结果 参考上一篇,新建目录hellocrx,其中三个文件:manifest.json  content_script.js 和jquery-3.4. ...

  7. js中对象的输出顺序

    前言:最近用for-in时,看到说for-in不能保证遍历的对象顺序,对此有些疑问,于是便研究了下,本文做简要说明. 现象 let obj = { a: 'a', b: 'b', 1: 1, 2: 2 ...

  8. 树莓派打造mini广播(FM)系统

    树莓派打造mini广播(FM)系统 注意相关法律限制功率大小和频段.,以下只能用于测试目的 github项目: https://github.com/miegl/PiFmAdv 安装: apt-get ...

  9. MySQL数据分析(16)— 数据操作之增删改查

    前面我们说学习MySQL要从三个层面,四大逻辑来学,三个层面就是库层面,表层面和数据层面对吧,数据库里放数据表,表里放数据是吧,大家可以回忆PPT中jacky的这图,我们已经学完了库层面和表层面,从本 ...

  10. 二十九、SELinux简介

    一.基础 1)访问模型 Linux原有访问模型:自主访问控制 DAC 安全隐患: 进程所能访问资源的范围 为用户所能访问的资源范围 后门: rootkit程序 进程被胁持: 基于进程作为跳板,就有了进 ...