Java使用RXTX读取串口

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44613063/article/details/98593433

RXTX 是一个提供串口和并口通信的开源java类库,使用上与 sun 提供的 comm.jar 基本相同,编程时最明显的不同是要包含的包名由 javax.comm.* 改成了 gnu.io.*

准备工作

下载资源文件

首先下载RXTX库对应的资源文件。下载地址 http://fizzed.com/oss/rxtx-for-java 根据自己的系统下载对应的文件。

拷贝动态库

RXTX 的实现还需要依赖几个动态库,所以我们要先把动态库放到对应的 jdk 目录下面去。windows 和 linux 拷贝的文件不同:

  • window平台:
    拷贝 rxtxSerial.dll —> <JAVA_HOME>\jre\bin
    拷贝 rxtxParallel.dll —> <JAVA_HOME>\jre\bin
  • linux平台:
    拷贝 librxtxSerial.so —> <JAVA_HOME>/jre/lib/i386/
    拷贝 librxtxParallel.so —> <JAVA_HOME>/jre/lib/i386/

<JAVA_HOME> 为 jdk 安装路径

项目引入RXTXcomm.jar

拷贝 RXTXcomm.jar 到 <JAVA_HOME>\jre\lib\ext 目录中

或者自己手动导入到项目依赖中


实现代码

串口参数封装

package com.stu.rxtxuse;

import gnu.io.SerialPort;

public final class SerialParameter {
    // 串口名称
    private String serialPortName;
    // 波特率
    private int baudRate;
    // 数据位 默认8位
    private int dataBits;
    // 停止位
    private int stopBits;
    // 校验位
    private int parity;

    public SerialParameter(String serialPortName){
        this.serialPortName = serialPortName;
        this.baudRate = 9600;
        this.dataBits = SerialPort.DATABITS_8;
        this.stopBits = SerialPort.STOPBITS_1;
        this.parity = SerialPort.PARITY_NONE;
    }
    public SerialParameter(String serialPortName, int baudRate){
        this.serialPortName = serialPortName;
        this.baudRate = baudRate;
        this.dataBits = SerialPort.DATABITS_8;
        this.stopBits = SerialPort.STOPBITS_1;
        this.parity = SerialPort.PARITY_NONE;
    }

    public String getSerialPortName() {
        return serialPortName;
    }

    public void setSerialPortName(String serialPortName) {
        this.serialPortName = serialPortName;
    }

    public int getBaudRate() {
        return baudRate;
    }

    public void setBaudRate(int baudRate) {
        this.baudRate = baudRate;
    }

    public int getDataBits() {
        return dataBits;
    }

    public void setDataBits(int dataBits) {
        this.dataBits = dataBits;
    }

    public int getStopBits() {
        return stopBits;
    }

    public void setStopBits(int stopBits) {
        this.stopBits = stopBits;
    }

    public int getParity() {
        return parity;
    }

    public void setParity(int parity) {
        this.parity = parity;
    }
}

串口工具类封装

package com.stu.rxtxuse;

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.List;
import java.util.TooManyListenersException;

public class SerialTool {
    @SuppressWarnings("unchecked")
    public static List<String> getSerialPortList() {
        List<String> systemPorts = new ArrayList<>();
        //获得系统可用的端口
        Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();//获得端口的名字
            systemPorts.add(portName);
        }
        return systemPorts;
    }

    // 打开串口  *** 一系列情况,不断重写传递参数 ***
    public static SerialPort openSerialPort(String serialPortName)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        SerialParameter parameter = new SerialParameter(serialPortName);
        return openSerialPort(parameter);
    }

    public static SerialPort openSerialPort(String serialPortName, int baudRate)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        SerialParameter parameter = new SerialParameter(serialPortName, baudRate);
        return openSerialPort(parameter);
    }

    public static SerialPort openSerialPort(String serialPortName, int baudRate, int timeout)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        SerialParameter parameter = new SerialParameter(serialPortName, baudRate);
        return openSerialPort(parameter, timeout);
    }

    public static SerialPort openSerialPort(SerialParameter parameter)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        return openSerialPort(parameter, 2000);
    }

    public static SerialPort openSerialPort(SerialParameter parameter, int timeout)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        //通过端口名称得到端口
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(parameter.getSerialPortName());
        //打开端口,(自定义名字,打开超时时间)
        CommPort commPort = portIdentifier.open(parameter.getSerialPortName(), timeout);
        //判断是不是串口
        if (commPort instanceof SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            //设置串口参数(波特率,数据位8,停止位1,校验位无)
            serialPort.setSerialPortParams(parameter.getBaudRate(), parameter.getDataBits(), parameter.getStopBits(), parameter.getParity());
            System.out.println("开启串口成功,串口名称:" + parameter.getSerialPortName());
            return serialPort;
        } else {
            //是其他类型的端口
            throw new NoSuchPortException();
        }
    }
    // *** 最后一个即是最终结果 ***

    // 关闭串口
    public static void closeSerialPort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            System.out.println("关闭了串口:" + serialPort.getName());
        }
    }

    // 向串口发送数据
    public static void sendData(SerialPort serialPort, byte[] data) {
        OutputStream os = null;
        try {
            //获得串口的输出流
            os = serialPort.getOutputStream();
            os.write(data);
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 从串口读取数据
    public static byte[] readData(SerialPort serialPort) {
        InputStream is = null;
        byte[] bytes = null;
        try {
            //获得串口的输入流
            is = serialPort.getInputStream();
            //获得数据长度
            int bufflenth = is.available();
            while (bufflenth != 0) {
                //初始化byte数组
                bytes = new byte[bufflenth];
                is.read(bytes);
                bufflenth = is.available();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }

    // 给串口设置监听
    public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) throws TooManyListenersException {
        //给串口添加事件监听
        serialPort.addEventListener(listener);
        //串口有数据监听
        serialPort.notifyOnDataAvailable(true);
        //中断事件监听
        serialPort.notifyOnBreakInterrupt(true);
    }
}

串口读取

package com.stu.rxtxuse;

import java.util.TooManyListenersException;

import gnu.io.*;

public class SerialRead {
    public static void main(String[] args) 
    		throws TooManyListenersException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        //获得系统端口列表
        SerialTool.getSerialPortList();
        //开启端口COM4,波特率9600,根据自己的情况更改
        final SerialPort serialPort = SerialTool.openSerialPort("COM4", 9600);
        //设置串口的listener
        SerialTool.setListenerToSerialPort(serialPort, new SerialPortEventListener() {
            @Override
            public void serialEvent(SerialPortEvent arg0) {
            	// 解决数据断行
                try {
                    Thread.sleep(25);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                	// 数据通知
                    byte[] bytes = SerialTool.readData(serialPort);
                    System.out.println("收到的数据长度:"+bytes.length);
                    System.out.println("收到的数据:"+ new String(bytes));
                }
            }
        });
    }
}

读取串口信息的程序中,在中间加上了一个

try {
     Thread.sleep(25);
 } catch (InterruptedException e) {
     e.printStackTrace();
 }

可以有效解决数据读取断行问题,Thread.sleep() 中的时间要小于串口信息发送端的时间间隔。

我这里的传感器是 50ms 发送一次数据,所以程序中是 25ms

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44613063/article/details/98593433