modbus4j中使用modbus tcp/ip和modbus rtu over tcp/ip模式
通过借鉴高人博客,总结如下:
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模式的更多相关文章
- 我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp)
我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp) 分类: [自动化]2007-07-19 10:04 34038人阅读 评论(38) 收藏 举报 vb嵌入式dostcp ...
- 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(一)
转自:http://blog.csdn.net/thebestleo/article/details/52269999 首先我要说明一下,本人新手一枚,本文仅为同样热爱学习的同学提供参考,有不 对的地 ...
- 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(二)
由于感觉上一次写的篇幅过长,所以新开一贴,继续介绍Modbus TCP/IP的初步认识, 书接上回 3).03(0x03)功能码--------读保持寄存器 请求与响应格式 这是一个请求读寄存器108 ...
- Modbus教程| Modbus协议,ASCII和RTU帧,Modbus工作
转载自:https://www.rfwireless-world.com/Tutorials/Modbus-Protocol-tutorial.html 这个Modbus教程涵盖了modbus协议基础 ...
- Modbus通信协议 【 初识 Modbus】
Modbus协议 Modbus 协议是应用于电子控制器上的一种通用语言.通过此协议,控制器相互之间.控制器经由网络(例如以太网)和其它设备之间可以通信.它已经成为一通用工业标准.有了它,不同厂 ...
- TCP/IP协议(二)tcp/ip基础知识
今天凌晨时候看书,突然想到一个问题:怎样做到持续学习?然后得出这样一个结论:放弃不必要的社交,控制欲望,克服懒惰... 然后又有了新的问题:学习效率时高时低,状态不好怎么解决?这也是我最近在思考的问题 ...
- 用批处理文件进行TCP/IP设置,方便在家与办公IP切换
在公司用公司分配的固定IP上网,回家后又要将本本设置为家里的固定IP上网,每次都要手动重复一个过程: 打开网络中心,选择本地连接,进入属性然后选择IPV4进行TCP/IP的设置,填入IP,子网掩码DN ...
- TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节
1.静态IP选路 1.1.一个简单的路由表 选路是IP层最重要的一个功能之一.前面的部分已经简单的讲过路由器是通过何种规则来根据IP数据包的IP地址来选择路由.这里就不重复了.首先来看看一个简单的系统 ...
- TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
把这三个协议放到一起学习是因为这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP得到要传输的数 ...
随机推荐
- python 获取指定字符前面或后面的所有字符
要求:获取某个字符指定字符的前面或后面的所有字符内容 示例: URL = https://www.baid/v2/user/login (1)想要获取v2的数据:v2/user/login print ...
- SVN(subversion )服务端和客户端的下载安装使用
SVN(subversion)官方网站: http://subversion.apache.org/packages.html 一.服务端下载 1.百度搜关键字:subversion 进入subve ...
- JQuery 实践--扩展JQuery
Why扩展JQuery通过扩展可以利用JQuery所提供的现有代码基础.避免从头编写代码 有效扩展JQuery的规则扩展JQuery的两种形式: $上直接定义实用工具函数 和JQuery包装集进行操作 ...
- Windows开发:窗口最大化问题
MoveWindow(0, 0, 1920, 1080)和SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0)的区别 MoveWindow(, , , ); 我们可以分 ...
- Verilog Tricks
1,可用generate产生512*FIFO 2,Vivado的warning也要全部排除 3,小module测完再往大module加 4,复位和IDLE处的置零操作一定要写全了 5,设计通信接收机时 ...
- 数据库学习之二--SQL语句以及数据类型
一.SQL语句种类: 1. DDL(Data Definition Language,数据定义语言)用来创建或者删除存储数据用的数据库以及数据库中的表;包含以下几种指令: a. CREATE:CREA ...
- Spring Boot and Rabbit MQ 异常的时候消息的状态
我们有一个处理消息的方法. 在处理消息的时候出现了异常,那出现异常后这个消息会怎么处理呢. 根据我们的实际情况的观察,如果出现了异常. 但是你没有捕获或者处理异常,这个消息会一直存在,并且你的系统会持 ...
- 线段树QWQ
一直没碰过线段树,个人认为好长好难,不过这几天做题遇到了裸的线段树的题,TAT. 线段树我理解就是把二叉树的左右节点现在分别看成是两个区间. 那么现在这两个区间的端点怎么存放?怎么能够把这个区间里的数 ...
- arcpy workspace already in transaction mode
arcpy workspace already in transaction mode RuntimeError: workspace already in transaction mode 同一个工 ...
- insmod mknod
insmod module 會在 /proc/devices/ 下產生 major number 及 device name ---------------------------- mknod 會使 ...