Springboot 集成串口

1 关键代码

package com.stm.room.thirdApi.utils;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;

public class SerialCommunication implements SerialPortEventListener {

    private static final Logger logger = LogManager.getLogger(SerialCommunication.class);

    private SerialPort serialPort;
    private BufferedReader input;
    private OutputStream output;
    private static final int TIMEOUT = 2000; // 连接超时时间
    private String portName; // 串口名称
    private int baudRate; // 波特率
    private boolean connected = false;
    private SerialDataListener dataListener; // 数据监听器
    private boolean readLine = true;
    private boolean readHex = false; // 是否以16进制格式读取
    private Integer sleepTime = null; //读取延时时间


    public Integer getSleepTime() {
        return sleepTime;
    }

    public void setSleepTime(Integer sleepTime) {
        this.sleepTime = sleepTime;
    }

    public boolean isReadHex() {
        return readHex;
    }

    public void setReadHex(boolean readHex) {
        this.readHex = readHex;
    }

    public boolean isReadLine() {
        return readLine;
    }

    public void setReadLine(boolean readLine) {
        this.readLine = readLine;
    }

    public SerialCommunication(String portName, int baudRate) {
        this.portName = portName;
        this.baudRate = baudRate;
    }

    // 设置数据监听器
    public void setDataListener(SerialDataListener dataListener) {
        this.dataListener = dataListener;
    }

    // 初始化串口
    public void initialize() {
        try {
            // 获取串口标识
            CommPortIdentifier portId = findPortIdentifier();
            if (portId == null) {
                logger.error("Could not find COM port: {}", portName);
                return;
            }

            // 打开串口
            openSerialPort(portId);

            // 获取输入输出流
            input = new BufferedReader(new InputStreamReader(serialPort.getInputStream(), "UTF-8"));
            output = serialPort.getOutputStream();

            // 添加事件监听器
            setupEventListener();

            connected = true;
            logger.info("Connected to {} at {} baud", portName, baudRate);
        } catch (Exception e) {
            logger.error("Error initializing serial port: {}", e.getMessage(), e);
            reconnect();
        }
    }

    private CommPortIdentifier findPortIdentifier() {
        Enumeration<?> portEnum = CommPortIdentifier.getPortIdentifiers();
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
            if (currPortId.getName().equals(portName)) {
                return currPortId;
            }
        }
        return null;
    }

    private void openSerialPort(CommPortIdentifier portId) throws Exception {
        serialPort = (SerialPort) portId.open(this.getClass().getName(), TIMEOUT);
        serialPort.setSerialPortParams(baudRate,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
    }

    private void setupEventListener() throws Exception {
        serialPort.addEventListener(this);
        serialPort.notifyOnDataAvailable(true);
    }

    // 串口事件监听
    @Override
    public void serialEvent(SerialPortEvent event) {
        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                if (sleepTime != null) {
                    Thread.sleep(sleepTime);
                }
                String receivedData = readDataFromSerial();
                if (receivedData != null && !receivedData.isEmpty()) {
                    processReceivedData(receivedData);
                }
            } catch (Exception e) {
                logger.error("Error reading from serial port: {}", e.getMessage(), e);
                reconnect();
            }
        }
    }

    private String readDataFromSerial() throws Exception {
        if (readHex) {
            return readHexData();
        } else if (readLine) {
            return readLineData();
        } else {
            return readRawData();
        }
    }

    private String readHexData() throws Exception {
        StringBuilder hexBuffer = new StringBuilder();
        byte[] buffer = new byte[1024];
        int bytesRead;

        while (serialPort.getInputStream().available() > 0 &&
                (bytesRead = serialPort.getInputStream().read(buffer)) != -1) {
            for (int i = 0; i < bytesRead; i++) {
                hexBuffer.append(String.format("%02X ", buffer[i]));
            }
        }

        return hexBuffer.toString().trim();
    }

    private String readLineData() throws Exception {
        StringBuilder buffer = new StringBuilder();
        String line;

        while (serialPort.getInputStream().available() > 0 &&
                input.ready() &&
                (line = input.readLine()) != null) {
            buffer.append(line).append("\n");
        }

        return buffer.toString().trim();
    }

    private String readRawData() throws Exception {
        StringBuilder buffer = new StringBuilder();
        char[] cache = new char[1024];
        int bytesRead;

        while (serialPort.getInputStream().available() > 0 &&
                (bytesRead = input.read(cache, 0, cache.length)) != -1) {
            buffer.append(new String(cache, 0, bytesRead));
        }

        return buffer.toString().trim();
    }

    private void processReceivedData(String receivedData) {
        logger.info("Received: {}", receivedData);

        if (dataListener != null) {
            if (readHex) {
                dataListener.onDataReceived(receivedData);
            } else {
                // 文本数据按行回调
                for (String dataLine : receivedData.split("\n")) {
                    dataListener.onDataReceived(dataLine);
                }
            }
        }
    }

    // 发送数据
    public void sendData(String data) {
        try {
            if (connected) {
                output.write(data.getBytes());
                output.flush();
                logger.info("Sent: {}", data);
            } else {
                logger.error("Not connected to serial port.");
            }
        } catch (Exception e) {
            logger.error("Error sending data: {}", e.getMessage(), e);
            reconnect();
        }
    }

    public void sendData(byte[] data) {
        try {
            if (connected) {
                output.write(data);
                output.flush();
                if (this.isReadHex()) {
                    logger.info("Sent hex data: {}", bytesToHex(data));
                } else {
                    logger.info("Sent Msg byte.size {} data: {}", data.length, new String(data, "UTF-8"));
                }
            } else {
                logger.error("Not connected to serial port.");
            }
        } catch (Exception e) {
            logger.error("Error sending data: {}", e.getMessage(), e);
            reconnect();
        }
    }

    private String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }

    // 关闭串口
    public synchronized void close() {
        try {
            if (serialPort != null) {
                serialPort.removeEventListener();
                if (input != null) input.close();
                if (output != null) output.close();
                serialPort.close();
                connected = false;
                logger.info("Disconnected from {}", portName);
            }
        } catch (Exception e) {
            logger.error("Error closing serial port: {}", e.getMessage(), e);
        }
    }

    // 掉线重连
    private void reconnect() {
        close();
        logger.info("Attempting to reconnect in 5 seconds...");
        try {
            Thread.sleep(5000);
            initialize();
        } catch (InterruptedException e) {
            logger.error("Reconnection interrupted: {}", e.getMessage(), e);
            Thread.currentThread().interrupt();
        }
    }

    public static void main(String[] args) {
        test();
    }

    
    private static void test() {
        // 默认串口号和波特率
        String portName = "COM3";
        int baudRate = 9600;


        // 创建串口通信实例
        SerialCommunication serialComm = new SerialCommunication(portName, baudRate);
        serialComm.setReadHex(true); // 设置为16进制读取模式
        serialComm.setSleepTime(500);
        // 设置数据监听器
        serialComm.setDataListener(data -> {
            System.out.println("Hex data received: " + data);
            // 这里可以添加16进制数据的处理逻辑
        });

        // 初始化串口
        serialComm.initialize();

        // 示例:发送16进制数据
        try {
            serialComm.sendData(SerialTool.hex2Bytes("EFAA01AA0300ADEF55"));

            Thread.sleep(10000);
        } catch (InterruptedException e) {
            logger.error("Main thread interrupted", e);
            Thread.currentThread().interrupt();
        } finally {
            serialComm.close();
        }
    }
}

2 接口

package com.stm.room.thirdApi.utils;

public interface SerialDataListener {
    void onDataReceived(String data);
}

3 需要用的jar和dll

mfz-rxtx-2.2-20081207-win-x64 自行下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值