RXTX for Java 进行串口开发

435 阅读2分钟

提前准备:

一、串口线

60da91dfdae82e23d65cb9b57657b95.jpg

二、驱动是否正常

image.png

三、我的刚开始不正常,卸载后重新安装驱动,

链接:pan.baidu.com/s/1P-xW-vFE…

提取码:dq5g

内附使用说明

image.png

一、下载 RXTX for Java

1.fizzed.com/oss/rxtx-fo… 下载对应系统资源(我以Windows-x64作为介绍)

image.png

二、安装 RXTX for Java

1.解压后长这样

image.png

2.查看install.txt ,安装帮助文档;按照文档将对应文件复制到文档所示位置

image.png

3.查看RXTXcommon.jar 是否在当前位置

image.png

4.没有需要重新添加一次jdk,删除再添加一次

image.png

三、代码实现通讯

package javax;

import cn.hutool.core.util.CharsetUtil;
import gnu.io.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;

public class SerialReader implements SerialPortEventListener {
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;

    public SerialReader(CommPortIdentifier portIdentifier) throws Exception {
//        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if (portIdentifier.isCurrentlyOwned()) {
            throw new Exception("串口已被占用");
        }

        serialPort = (SerialPort) portIdentifier.open(this.getClass().getName(), 2000);
        serialPort.addEventListener(this);
        serialPort.notifyOnDataAvailable(true);
        serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

        inputStream = serialPort.getInputStream();
        outputStream = serialPort.getOutputStream();
    }

    @Override
    public void serialEvent(SerialPortEvent event) {
        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                byte[] buffer = new byte[inputStream.available()];
                int numBytes = inputStream.read(buffer);
//                String hexString = bytesToHexString(buffer);
//                System.out.println("接收到数据:" + hexString);
                String receiveMessage = new String(buffer, 0, numBytes, CharsetUtil.GBK);
                System.out.println("接收到数据:" +receiveMessage);

                outputStream.write(("client receive message: "+receiveMessage).getBytes(CharsetUtil.GBK));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static String bytesToHexString(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        for (byte b : bytes) {
            String hex = String.format("%02X", b);
            builder.append(hex);
        }
        return builder.toString();
    }

    /**
     * @return    A HashSet containing the CommPortIdentifier for all serial ports that are not currently being used.
     */
    public static HashSet<CommPortIdentifier> getAvailableSerialPorts() {
        HashSet<CommPortIdentifier> h = new HashSet<CommPortIdentifier>();
        Enumeration thePorts = CommPortIdentifier.getPortIdentifiers();
        while (thePorts.hasMoreElements()) {
            CommPortIdentifier com = (CommPortIdentifier) thePorts.nextElement();
            switch (com.getPortType()) {
                case CommPortIdentifier.PORT_SERIAL:
                    try {
                        CommPort thePort = com.open("CommUtil", 50);
                        thePort.close();
                        h.add(com);
                    } catch (PortInUseException e) {
                        System.out.println("Port, " + com.getName() + ", is in use.");
                    } catch (Exception e) {
                        System.err.println("Failed to open port " + com.getName());
                        e.printStackTrace();
                    }
            }
        }
        return h;
    }

    public static void main(String[] args) {
        String portName = "COM3"; // 串口设备名称,根据实际情况修改
        try {
//            SerialReader serialReader = new SerialReader(portName);
            List<CommPortIdentifier> list = new ArrayList<>(getAvailableSerialPorts());
            new SerialReader(list.get(list.size()-1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、测试

1.串口调试助手V2.2 发送helloworld,发现接收到数据,则成功

链接:pan.baidu.com/s/1txOMINg-… 提取码:i7z4

image.png

image.png

五、判定串口传过来是一整条数据还是多条数据?

通常我们无法直接判断一整条数据或两条数据的边界。因为串口通信是以字节流的形式传输数据,不像网络通信那样可以明确分割数据包。

在处理串口数据时,你可能需要定义一些规则或协议来确定数据的开始和结束标志,以便从字节流中提取出完整的数据。

假设每条数据以换行符 \n 作为结束标志。

六、使用过程中遇到了一些错误,解决办法

在此文章中列出了我遇到的问题,以及解决办法

juejin.cn/spost/72606…