- 依赖的modbus包请看java与modbusTcp通讯
- JDK中配置串口通讯能力 提取码:hmfn
- 串口模拟工具 提取码: npqx
- 依赖串口协议包:
<dependency>
<groupId>org.rxtx</groupId>
<artifactId>rxtx</artifactId>
<version>2.1.7</version>
</dependency>
import com.serotonin.modbus4j.serial.SerialPortWrapper;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public abstract class AbstractSerialPortWrapper implements SerialPortWrapper {
private SerialPort serialPort = null;
private Integer baudRate;
private String port;
protected AbstractSerialPortWrapper(String port,Integer baudRate){
this.port = port;
this.baudRate = baudRate;
}
@Override
public void close() throws Exception {
if(serialPort != null){
serialPort.close();
}
}
@Override
public void open() throws Exception {
serialPort = serialPort(port);
}
@Override
public InputStream getInputStream() {
try {
if(serialPort != null){
return serialPort.getInputStream();
}
} catch (IOException e) {
throw new RuntimeException("对象空指针异常");
}
throw new RuntimeException("对象空指针异常");
}
@Override
public OutputStream getOutputStream() {
try {
if(serialPort != null){
return serialPort.getOutputStream();
}
} catch (IOException e) {
throw new RuntimeException("对象空指针异常");
}
throw new RuntimeException("对象空指针异常");
}
@Override
public int getBaudRate() {
return baudRate;
}
@Override
public int getFlowControlIn() {
return SerialPort.FLOWCONTROL_NONE;
}
@Override
public int getFlowControlOut() {
return SerialPort.FLOWCONTROL_NONE;
}
@Override
public int getDataBits() {
return SerialPort.DATABITS_8;
}
@Override
public int getStopBits() {
return SerialPort.STOPBITS_1;
}
@Override
public int getParity() {
return SerialPort.PARITY_EVEN;
}
public abstract SerialPort serialPort(String portName);
}
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class SerialPortSupport extends AbstractSerialPortWrapper {
public SerialPortSupport(String port,Integer baudRate){
super(port,baudRate);
}
/**
* 查找所有可用端口
*
* @return 可用端口名称列表
*/
@SuppressWarnings("all")
public static List<String> findPorts() {
// 获得当前所有可用串口
Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
List<String> portNameList = new ArrayList<String>();
// 将可用串口名添加到List并返回该List
while (portList.hasMoreElements()) {
String portName = portList.nextElement().getName();
portNameList.add(portName);
}
return portNameList;
}
@Override
public SerialPort serialPort(String portName) {
try {
// 通过端口名识别端口
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
// 打开端口,并给端口名字和一个timeout(打开操作的超时时间)
CommPort commPort = portIdentifier.open(portName, 2000);
// 判断是不是串口
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
try {
// 设置一下串口的波特率等参数 // 数据位:8 // 停止位:1 // 校验位:None
serialPort.setSerialPortParams(getBaudRate(), getDataBits(), getStopBits(), getParity());
} catch (UnsupportedCommOperationException e) {
throw new RuntimeException("打开串口异常");
}
return serialPort;
}
} catch (Exception e1) {
throw new RuntimeException("打开串口异常");
}
return null;
}
}
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.*;
import com.serotonin.modbus4j.serial.SerialPortWrapper;
import com.sotring.asd.modbus.suport.SerialPortSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
public class RtuMasterWrapper {
private static final Logger log = LoggerFactory.getLogger(RtuMasterWrapper.class);
private int slaveId;
private ModbusMaster rutMaster;
private boolean connected;
public RtuMasterWrapper(int slaveId) {
this.slaveId = slaveId;
log.info("slaveId: {}", slaveId);
}
public boolean connect() {
disconnect();
try {
SerialPortWrapper port = new SerialPortSupport("COM1",9600);
rutMaster = new ModbusFactory().createRtuMaster(port);
rutMaster.setTimeout(3000);
rutMaster.init();
connected = true;
} catch (ModbusInitException ex) {
log.error("connect error, try to disconnect...", ex);
disconnect();
}
return isConnected();
}
private void disconnect() {
if (rutMaster != null) {
rutMaster.destroy();
}
connected = false;
log.info("disconnect");
}
private boolean isConnected() {
return connected;
}
/**
* 读取单个线圈(01功能码)
* @param startOffset 读取地址
*/
public Boolean readCoils(int startOffset) throws ModbusTransportException {
ReadCoilsRequest request = new ReadCoilsRequest(slaveId,startOffset,1);
ReadCoilsResponse response = (ReadCoilsResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
} else if(response!= null){
return response.getBooleanData()[0];
}
connected = false;
return null;
}
/**
* 写入单个地址
* @param startOffset 写入地址
* @param value 写入值
*/
public void writeCoils(int startOffset,boolean value) throws ModbusTransportException {
WriteCoilRequest request = new WriteCoilRequest(slaveId,startOffset,value);
WriteCoilResponse response = (WriteCoilResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
}
}
/**
* 写多个线圈(01功能码)
* @param startOffset 写入开始地址
* @param value 写入值集合
* @throws ModbusTransportException
*/
public void writeCoilsMultiple(int startOffset,boolean[] value) throws ModbusTransportException {
WriteCoilsRequest request = new WriteCoilsRequest(slaveId,startOffset,value);
WriteCoilsResponse response = (WriteCoilsResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
}
}
/**
* 读取单个离散线圈(02功能码)
* @param startOffset 读取地址
*/
public Boolean readDiscrete(int startOffset) throws ModbusTransportException {
ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId,startOffset,1);
ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
} else if(response!= null){
return response.getBooleanData()[0];
}
connected = false;
return null;
}
/**
* 读取单个保持寄存器(03功能码)
* @param startOffset 读取地址
*/
public Short readHoldingRegisterValue(int startOffset) throws ModbusTransportException {
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, startOffset, 1);
log.info("Reading Holding Register, startAddress: {}", startOffset);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)rutMaster.send(request);
if (response != null && response.isException()) {
log.error("Modbus execution failed: \nslaveId: {}, startAddress: {}", slaveId, startOffset);
return null;
} else if (response != null && response.getShortData().length > 0) {
return response.getShortData()[0];
}
connected = false;
return null;
}
/**
* 读取多个保持寄存器(03功能码)
* @param startOffset 开始读取位置
* @param numberOfRegisters 读取个数
*/
public short[] readHoldingRegisterValues(int startOffset, int numberOfRegisters) throws ModbusTransportException {
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, startOffset, numberOfRegisters);
log.info("Reading Holding Registers, startAddress: {}, len: {}", startOffset, numberOfRegisters);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)rutMaster.send(request);
if (response != null && response.isException()) {
log.error("Modbus execution failed: \nslaveId: {}, startAddress: {}, len: {}", slaveId, startOffset, numberOfRegisters);
return null;
} else if (response != null) {
return response.getShortData();
}
connected = false;
return null;
}
/**
* 写入保持寄存器多个值(03功能码)
* @param startOffset 写入开始地址
* @param values 写入多个数据集合
*/
public void writeRegisterValues(int startOffset, short[] values) throws ModbusTransportException {
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, values);
log.info(String.format("WRITE Holding Register, startOffset: %d, values: %s",
startOffset, Arrays.toString(values)));
WriteRegistersResponse response = (WriteRegistersResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
}
}
/**
* 写入保持寄存器(03功能码)
* @param startOffset 写入地址
* @param value 写入值
*/
public void writeRegisterValue(int startOffset, short value) throws ModbusTransportException {
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, new short[]{value});
log.info(String.format("Writing Holding Register, startAddress: %d, value: %d", startOffset, value));
WriteRegistersResponse response = (WriteRegistersResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
}
}
/**
* 读取输入寄存器(04功能码)
* @param startOffset 读取地址
*/
public Short readInput(int startOffset) throws ModbusTransportException {
ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId,startOffset,1);
ReadInputRegistersResponse response = (ReadInputRegistersResponse) rutMaster.send(request);
if (response!= null && response.isException()) {
throw new ModbusTransportException(response.getExceptionMessage());
} else if(response!= null){
return response.getShortData()[0];
}
connected = false;
return null;
}
}