基于JAVA实现modbus rtu通信(一)_java modbus rtu_草莓蓝的博客-CSDN博客

前言

本次实现modbus rtu数据读写,在做java的modbus rtu通信时查了好多资料,大多数都是用modbus4j+rxtx实现,不过这种实现方式有一个弊端,就是需要调用dll,而且跨平台不兼容,这对于一个强迫症来说是致命的,本次记录另一种跨平台实现方案。

实现方式

        使用modbus4j实现modbus通信,同时使用jssc来实现串口数据读写。

Maven依赖

    <repositories>        <repository>            <releases>                <enabled>false</enabled>            </releases>            <snapshots>                <enabled>true</enabled>            </snapshots>            <id>ias-snapshots</id>            <name>Infinite Automation Snapshot Repository</name>            <url>https://maven.mangoautomation.net/repository/ias-snapshot/</url>        </repository>        <repository>            <releases>                <enabled>true</enabled>            </releases>            <snapshots>                <enabled>false</enabled>            </snapshots>            <id>ias-releases</id>            <name>Infinite Automation Release Repository</name>            <url>https://maven.mangoautomation.net/repository/ias-release/</url>        </repository>    </repositories>    <dependencies>        <dependency>            <groupId>io.github.java-native</groupId>            <artifactId>jssc</artifactId>            <version>2.9.4</version>        </dependency>        <dependency>            <groupId>com.infiniteautomation</groupId>            <artifactId>modbus4j</artifactId>            <version>3.0.4</version>        </dependency>     </dependencies>

其中jssc是用来实现串口通信的库,可以根据操作系统自动识别。

代码实现

串口的输入流实现类 SerialInputStream.java

import jssc.SerialPort; import java.io.IOException;import java.io.InputStream; public class SerialInputStream extends InputStream {     private SerialPort serialPort;    private int defaultTimeout = 50;     public SerialInputStream(SerialPort sp) {        serialPort = sp;    }     public void setTimeout(int time) {        defaultTimeout = time;    }     @Override    public int read() throws IOException {        return read(defaultTimeout);    }     public int read(int timeout) throws IOException {        byte[] buf = new byte[1];        try {            if (timeout > 0) {                buf = serialPort.readBytes(1, timeout);            } else {                buf = serialPort.readBytes(1);            }            return buf[0];        } catch (Exception e) {            throw new IOException(e);        }    }     @Override    public int read(byte[] buf) throws IOException {        return read(buf, 0, buf.length);    }     @Override    public int read(byte[] buf, int offset, int length) throws IOException {         if (buf.length < offset + length) {            length = buf.length - offset;        }         int available = this.available();         if (available > length) {            available = length;        }         try {            byte[] readBuf = serialPort.readBytes(available);            System.arraycopy(readBuf, 0, buf, offset, readBuf.length);            return readBuf.length;        } catch (Exception e) {            throw new IOException(e);        }    }     public int blockingRead(byte[] buf) throws IOException {        return blockingRead(buf, 0, buf.length, defaultTimeout);    }     public int blockingRead(byte[] buf, int timeout) throws IOException {        return blockingRead(buf, 0, buf.length, timeout);    }     public int blockingRead(byte[] buf, int offset, int length) throws IOException {        return blockingRead(buf, offset, length, defaultTimeout);    }     public int blockingRead(byte[] buf, int offset, int length, int timeout) throws IOException {        if (buf.length < offset + length) {            throw new IOException("Not enough buffer space for serial data");        }         if (timeout < 1) {            return read(buf, offset, length);        }         try {            byte[] readBuf = serialPort.readBytes(length, timeout);            System.arraycopy(readBuf, 0, buf, offset, length);            return readBuf.length;        } catch (Exception e) {            throw new IOException(e);        }    }     @Override    public int available() throws IOException {        int ret;        try {            ret = serialPort.getInputBufferBytesCount();            if (ret >= 0) {                return ret;            }        } catch (Exception e) {            //TODO 异常处理        }        return 0;    }}

串口输出流实现类 SerialOutputStream.java

import jssc.SerialPort;import jssc.SerialPortException; import java.io.IOException;import java.io.OutputStream; public class SerialOutputStream extends OutputStream {    SerialPort serialPort;     public SerialOutputStream(SerialPort sp) {        serialPort = sp;    }     @Override    public void write(int b) throws IOException {        try {            serialPort.writeInt(b);        } catch (SerialPortException e) {            throw new IOException(e);        }    }     @Override    public void write(byte[] b) throws IOException {        write(b, 0, b.length);     }     @Override    public void write(byte[] b, int off, int len) throws IOException {        byte[] buffer = new byte[len];        System.arraycopy(b, off, buffer, 0, len);        try {            serialPort.writeBytes(buffer);        } catch (SerialPortException e) {            throw new IOException(e);        }    } }

modbus4j的串口实现类

 import com.serotonin.modbus4j.serial.SerialPortWrapper;import jssc.SerialPort;import jssc.SerialPortException;import lombok.extern.slf4j.Slf4j; import java.io.InputStream;import java.io.OutputStream; @Slf4jpublic class SerialPortWrapperImpl implements SerialPortWrapper {    private final SerialPort port;    private final int baudRate;    private final int dataBits;    private final int stopBits;    private final int parity;    private final int flowControlIn;    private final int flowControlOut;     public SerialPortWrapperImpl(String commPortId, int baudRate, int dataBits, int stopBits, int parity, int flowControlIn,                                 int flowControlOut) {         this.baudRate = baudRate;        this.dataBits = dataBits;        this.stopBits = stopBits;        this.parity = parity;        this.flowControlIn = flowControlIn;        this.flowControlOut = flowControlOut;         port = new SerialPort(commPortId);     }     @Override    public void close() throws Exception {        port.closePort();        log.debug("Serial port {} closed", port.getPortName());    }     @Override    public void open() {        try {            port.openPort();            port.setParams(this.getBaudRate(), this.getDataBits(), this.getStopBits(), this.getParity());            port.setFlowControlMode(this.getFlowControlIn() | this.getFlowControlOut());            log.debug("Serial port {} opened", port.getPortName());        } catch (SerialPortException e) {            log.error("Error opening port : {} for {} ", port.getPortName(), e.getMessage());        }    }     @Override    public InputStream getInputStream() {        return new SerialInputStream(port);    }     @Override    public OutputStream getOutputStream() {        return new SerialOutputStream(port);    }      @Override    public int getBaudRate() {        return baudRate;    }     @Override    public int getFlowControlIn() {        return flowControlIn;    }     @Override    public int getFlowControlOut() {        return flowControlOut;    }     @Override    public int getDataBits() {        return dataBits;    }     @Override    public int getStopBits() {        return stopBits;    }     @Override    public int getParity() {        return parity;    }}

上面这个是比较关键的串口实现,到这里已经可以和网上的modbus4j资料完成采集,具体实现下节实现


原网址: 访问
创建于: 2023-08-31 10:35:30
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论