Java实现使用Modbus4j+seroUtils读取Mudbus RTU/ASCII Over TCP/IP连接设备数据
使用Modbus4j+seroUtils读取风速风向仪数据,现有设备IP,端口号,从机地址,寄存器读取开始地址,读取的寄存器数量。没有上述jar包可以自行搜索,网上资源挺多
import cn.hutool.core.date.DateUtil;
import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author chengy
*/
@Component
public class ModbusUtil {
private static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
/**
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
* @param offset 寄存器读取开始地址
* @param quantity 读取的寄存器数量
* @return
*/
public Map<Integer, Integer> getTCPValue(String ip, int port, int slaveId, int offset, int quantity) {
// 创建读取量大小的Map集合
Map<Integer, Integer> resultMap = new HashMap<>(quantity);
try {
// 设置主机TCP参数
TcpParameters tcpParameters = new TcpParameters();
// 设置TCP的ip地址
InetAddress address = InetAddress.getByName(ip);
// TCP参数设置ip地址
tcpParameters.setHost(address);
// TCP设置长连接
tcpParameters.setKeepAlive(true);
// TCP设置端口,这里设置是默认端口502
tcpParameters.setPort(port);
// 创建一个主机
ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
Modbus.setAutoIncrementTransactionId(true);
try {
if (!master.isConnected()) {
// 开启连接
master.connect();
}
// 读取对应从机的数据,功能码03
int[] registerValues = master.readHoldingRegisters(slaveId, offset, quantity);
// 数据组装
for (int value : registerValues) {
resultMap.put(offset++, value);
}
} catch (Exception e) {
throw new RuntimeException("建立连接失败," + ip + ":" + port + "设备不在线");
} finally {
master.disconnect();
}
} catch (Exception e) {
throw new RuntimeException("初始化连接失败," + ip + ":" + port + "设备不在线");
}
return resultMap;
}
/**
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
* @param offset 寄存器读取开始地址
* @param quantity 读取的寄存器数量
* @return
*/
public short[] getRtuValue(String ip, int port, int slaveId, int offset, int quantity) {
short[] result = new short[2];
IpParameters params = new IpParameters();
params.setHost(ip);
params.setPort(port);
//这个属性确定了协议帧是否是通过tcp封装的RTU结构,采用modbus tcp/ip时,要设为false, 采用modbus rtu over tcp/ip时,要设为true
params.setEncapsulated(true);
com.serotonin.modbus4j.ModbusMaster master = modbusFactory.createTcpMaster(params, true);// TCP 协议
try {
//设置超时时间
master.setTimeout(1000);
//设置重连次数
master.setRetries(3);
//初始化
master.init();
try {
ReadHoldingRegistersRequest request = null;
request = new ReadHoldingRegistersRequest(slaveId, offset, quantity);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);
if (response.isException())
throw new RuntimeException("读取风速设备数据失败" + response.getExceptionMessage());
else
result = response.getShortData();
} catch (ModbusTransportException e) {
throw new RuntimeException("读取风速设备数据失败");
}
} catch (ModbusInitException e) {
throw new RuntimeException("建立风速设备连接失败");
} finally {
// 关闭长连接,防止占用
master.destroy();
}
return result;
}
/**
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
* @param offset 寄存器写入开始地址
* @param writeValue 寄存器写入的值
* @return
*/
public Boolean writeTCPValue(String ip, int port, int slaveId, int offset, int writeValue) {
// 设置主机参数
IpParameters params = new IpParameters();
params.setHost(ip);
params.setPort(port);
params.setEncapsulated(false);
// 获取TCPMaster
com.serotonin.modbus4j.ModbusMaster master = modbusFactory.createTcpMaster(params, true);
try {
//设置超时时间
master.setTimeout(1000);
//设置重连次数
master.setRetries(3);
//初始化
master.init();
// 创建请求对象
WriteRegisterRequest request = new WriteRegisterRequest(slaveId, offset, writeValue);
WriteRegisterResponse response = (WriteRegisterResponse) master.send(request);
if (response.isException()) {
return false;
} else {
return true;
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("灯杆数据写入失败");
} finally {
// 关闭长连接,防止占用
master.destroy();
}
}
/**
* 更新灯杆目前时间
*
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
*/
public void updateLampTime(String ip, int port, int slaveId) {
// 时
writeTCPValue(ip, port, slaveId, 2, DateUtil.hour(new Date(), true));
// 分
writeTCPValue(ip, port, slaveId, 1, DateUtil.minute(new Date()));
// 秒
writeTCPValue(ip, port, slaveId, 0, DateUtil.second(new Date()));
}
/**
* 测试当前IP是否能连接上
*/
public boolean testConn(String ip) {
try {
// 测试设备是否在线
InetAddress address = InetAddress.getByName(ip);
return address.isReachable(5000);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
* @param offset 寄存器读取开始地址
* @param quantity 读取的寄存器数量
* @return
*/
public boolean[] getCoilsValue(String ip, int port, int slaveId, int offset, int quantity) {
boolean[] registerValues;
try {
// 设置主机TCP参数
TcpParameters tcpParameters = new TcpParameters();
// 设置TCP的ip地址
InetAddress address = InetAddress.getByName(ip);
// TCP参数设置ip地址
tcpParameters.setHost(address);
// TCP设置长连接
tcpParameters.setKeepAlive(true);
// TCP设置端口,这里设置是默认端口502
tcpParameters.setPort(port);
// 创建一个主机
ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
Modbus.setAutoIncrementTransactionId(true);
try {
if (!master.isConnected()) {
// 开启连接
master.connect();
}
// 读取对应从机的数据,功能码01
registerValues = master.readCoils(slaveId, offset, quantity);
} catch (Exception e) {
throw new RuntimeException("建立连接失败,防洪泵设备不在线");
} finally {
master.disconnect();
}
} catch (Exception e) {
throw new RuntimeException("初始化连接失败,防洪泵设备不在线");
}
return registerValues;
}
/**
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
* @param offset 寄存器写入开始地址
* @param writeValue 寄存器写入的值
* @return
*/
public void writeCoilValue(String ip, int port, int slaveId, int offset, boolean writeValue) {
try {
// 设置主机TCP参数
TcpParameters tcpParameters = new TcpParameters();
// 设置TCP的ip地址
InetAddress address = InetAddress.getByName(ip);
// TCP参数设置ip地址
tcpParameters.setHost(address);
// TCP设置长连接
tcpParameters.setKeepAlive(true);
// TCP设置端口,这里设置是默认端口502
tcpParameters.setPort(port);
// 创建一个主机
ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
Modbus.setAutoIncrementTransactionId(true);
try {
if (!master.isConnected()) {
// 开启连接
master.connect();
}
// 读取对应从机的数据,功能码05
master.writeSingleCoil(slaveId, offset, writeValue);
} catch (Exception e) {
throw new RuntimeException("建立连接失败,防洪泵设备不在线");
} finally {
master.disconnect();
}
} catch (Exception e) {
throw new RuntimeException("初始化连接失败,防洪泵设备不在线");
}
}
/**
* @param ip 远程服务机地址
* @param port 端口号
* @param slaveId 从机地址
* @param offset 寄存器读取开始地址
* @param quantity 读取的寄存器数量
* @return
*/
public boolean[] getDiscreteInputValue(String ip, int port, int slaveId, int offset, int quantity) {
boolean[] registerValues;
try {
// 设置主机TCP参数
TcpParameters tcpParameters = new TcpParameters();
// 设置TCP的ip地址
InetAddress address = InetAddress.getByName(ip);
// TCP参数设置ip地址
tcpParameters.setHost(address);
// TCP设置长连接
tcpParameters.setKeepAlive(true);
// TCP设置端口,这里设置是默认端口502
tcpParameters.setPort(port);
// 创建一个主机
ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
Modbus.setAutoIncrementTransactionId(true);
try {
if (!master.isConnected()) {
// 开启连接
master.connect();
}
// 读取对应从机的数据,功能码02
registerValues = master.readDiscreteInputs(slaveId, offset, quantity);
} catch (Exception e) {
throw new RuntimeException("建立连接失败,防洪泵设备不在线");
} finally {
master.disconnect();
}
} catch (Exception e) {
throw new RuntimeException("初始化连接失败,防洪泵设备不在线");
}
return registerValues;
}
}
相关文章:Java实现ModbusTCP通信