美文网首页
RXTX实现JAVA串口编程

RXTX实现JAVA串口编程

作者: tuacy | 来源:发表于2019-06-26 20:29 被阅读0次

           给大家分项下用RXTX库实现JAVA串口编程。

    一 准备工作

    1.1 下载资源文件

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

    RXTX-FOR-JAVA.png
    • Windows-x64 对应windows 64位系统。
    • Windows-x86 对应windows 32位系统。
    • Windows-ia64 这种用的比较少,我们不管。
    • Linux-x86_64 对应Linux 64位系统。
    • Linux-i386 对应Linux 32位系统。

           每个文件下面都有我们下面需要的所有文件。

    1.1 拷贝动态库

           RXJX的实现还需要依赖几个动态库,所以我们要先把动态库放到对应的jdk目录下面去。window和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/

    1.2 项目引入RXTXcomm.jar

           RXTXcomm.jar文件引入到工程代码里面去。

           比如我们把RXTXcomm.jar文件放到工程目录下resource/jar目录下面去。然后在pom.xml中把RXTXcomm.jar引入进来。

            <!-- 串口jar -->
            <dependency>
                <groupId>gnu.io</groupId>
                <artifactId>com-lib</artifactId>
                <version>2.2</version>
                <scope>system</scope>
                <systemPath>${project.basedir}/src/main/resources/jar/RXTXcomm.jar</systemPath>
            </dependency>
    

    二 实现代码

           前面准备工作做好了,接下来就是代码实现,好多代码咱们也是从网上copy过来的,这里我就直接贴代码了。

    2.1 串口参数的简单封装

    package com.pilot.ioserver.basic.pbl.port.serialPort;
    
    import gnu.io.SerialPort;
    
    /**
     * @name: SerialPortParameter
     * @author: tuacy.
     * @date: 2019/6/26.
     * @version: 1.0
     * @Description: 串口参数
     */
    public final class SerialPortParameter {
    
        /**
         * 串口名称(COM0、COM1、COM2等等)
         */
        private String serialPortName;
        /**
         * 波特率
         * 默认:115200
         */
        private int baudRate;
        /**
         * 数据位 默认8位
         * 可以设置的值:SerialPort.DATABITS_5、SerialPort.DATABITS_6、SerialPort.DATABITS_7、SerialPort.DATABITS_8
         * 默认:SerialPort.DATABITS_8
         */
        private int dataBits;
        /**
         * 停止位
         * 可以设置的值:SerialPort.STOPBITS_1、SerialPort.STOPBITS_2、SerialPort.STOPBITS_1_5
         * 默认:SerialPort.STOPBITS_1
         */
        private int stopBits;
        /**
         * 校验位
         * 可以设置的值:SerialPort.PARITY_NONE、SerialPort.PARITY_ODD、SerialPort.PARITY_EVEN、SerialPort.PARITY_MARK、SerialPort.PARITY_SPACE
         * 默认:SerialPort.PARITY_NONE
         */
        private int parity;
    
        public SerialPortParameter(String serialPortName) {
            this.serialPortName = serialPortName;
            this.baudRate = 115200;
            this.dataBits = SerialPort.DATABITS_8;
            this.stopBits = SerialPort.STOPBITS_1;
            this.parity = SerialPort.PARITY_NONE;
        }
    
        public SerialPortParameter(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;
        }
    }
    
    

    2.2 串口工具类的简单封装

    package com.pilot.ioserver.basic.pbl.port.serialPort;
    
    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;
    
    /**
     * @name: SerialPortUtil
     * @author: tuacy.
     * @date: 2019/6/26.
     * @version: 1.0
     * @Description: 串口工具类
     */
    public class SerialPortUtil {
    
        /**
         * 获得系统可用的端口名称列表(COM0、COM1、COM2等等)
         *
         * @return List<String>可用端口名称列表
         */
    
        @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;
        }
    
        /**
         * 打开串口
         *
         * @param serialPortName 串口名称
         * @return SerialPort 串口对象
         * @throws NoSuchPortException               对应串口不存在
         * @throws PortInUseException                串口在使用中
         * @throws UnsupportedCommOperationException 不支持操作操作
         */
        public static SerialPort openSerialPort(String serialPortName)
                throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
            SerialPortParameter parameter = new SerialPortParameter(serialPortName);
            return openSerialPort(parameter);
        }
    
        /**
         * 打开串口
         *
         * @param serialPortName 串口名称
         * @param baudRate       波特率
         * @return SerialPort 串口对象
         * @throws NoSuchPortException               对应串口不存在
         * @throws PortInUseException                串口在使用中
         * @throws UnsupportedCommOperationException 不支持操作操作
         */
        public static SerialPort openSerialPort(String serialPortName, int baudRate)
                throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
            SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
            return openSerialPort(parameter);
        }
    
        /**
         * 打开串口
         *
         * @param serialPortName 串口名称
         * @param baudRate       波特率
         * @param timeout        串口打开超时时间
         * @return SerialPort 串口对象
         * @throws NoSuchPortException               对应串口不存在
         * @throws PortInUseException                串口在使用中
         * @throws UnsupportedCommOperationException 不支持操作操作
         */
        public static SerialPort openSerialPort(String serialPortName, int baudRate, int timeout)
                throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
            SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
            return openSerialPort(parameter, timeout);
        }
    
        /**
         * 打开串口
         *
         * @param parameter 串口参数
         * @return SerialPort 串口对象
         * @throws NoSuchPortException               对应串口不存在
         * @throws PortInUseException                串口在使用中
         * @throws UnsupportedCommOperationException 不支持操作操作
         */
        public static SerialPort openSerialPort(SerialPortParameter parameter)
                throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
            return openSerialPort(parameter, 2000);
        }
    
        /**
         * 打开串口
         *
         * @param parameter 串口参数
         * @param timeout   串口打开超时时间
         * @return SerialPort串口对象
         * @throws NoSuchPortException               对应串口不存在
         * @throws PortInUseException                串口在使用中
         * @throws UnsupportedCommOperationException 不支持操作操作
         */
        public static SerialPort openSerialPort(SerialPortParameter 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();
            }
        }
    
    
        /**
         * 关闭串口
         *
         * @param serialPort 要关闭的串口对象
         */
        public static void closeSerialPort(SerialPort serialPort) {
            if (serialPort != null) {
                serialPort.close();
                System.out.println("关闭了串口:" + serialPort.getName());
            }
        }
    
        /**
         * 向串口发送数据
         *
         * @param serialPort 串口对象
         * @param data       发送的数据
         */
        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();
                }
            }
        }
    
        /**
         * 从串口读取数据
         *
         * @param serialPort 要读取的串口
         * @return 读取的数据
         */
        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;
        }
    
        /**
         * 给串口设置监听
         *
         * @param serialPort serialPort 要读取的串口
         * @param listener   SerialPortEventListener监听对象
         * @throws TooManyListenersException 监听对象太多
         */
        public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) throws TooManyListenersException {
            //给串口添加事件监听
            serialPort.addEventListener(listener);
            //串口有数据监听
            serialPort.notifyOnDataAvailable(true);
            //中断事件监听
            serialPort.notifyOnBreakInterrupt(true);
        }
    
    
    }
    
    

    2.3 测试类

           我们简单的写一个单元测试类

    package com.pilot.ioserver.basic.pbl.port.serialPort;
    
    import gnu.io.*;
    import org.junit.Test;
    
    import java.util.List;
    import java.util.TooManyListenersException;
    
    /**
     * @name: SerialPortUtilTest
     * @author: tuacy.
     * @date: 2019/6/26.
     * @version: 1.0
     * @Description: 串口测试代码
     */
    public class SerialPortUtilTest {
    
        /**
         * 测试获取串口列表
         */
        @Test
        public void getSystemPortList() {
    
            List<String> portList = SerialPortUtil.getSerialPortList();
            System.out.println(portList);
    
        }
    
        /**
         * 测试串口打开,读,写操作
         */
        @Test
        public void serialPortAction() {
            try {
                final SerialPort serialPort = SerialPortUtil.openSerialPort("COM2", 115200);
                //启动一个线程每2s向串口发送数据,发送1000次hello
                new Thread(() -> {
                    int i = 1;
                    while (i < 1000) {
                        String s = "hello";
                        byte[] bytes = s.getBytes();
                        SerialPortUtil.sendData(serialPort, bytes);//发送数据
                        i++;
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
                //设置串口的listener
                SerialPortUtil.setListenerToSerialPort(serialPort, event -> {
                    //数据通知
                    if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                        byte[] bytes = SerialPortUtil.readData(serialPort);
                        System.out.println("收到的数据长度:" + bytes.length);
                        System.out.println("收到的数据:" + new String(bytes));
                    }
                });
                try {
                    // sleep 一段时间保证线程可以执行完
                    Thread.sleep(3 * 30 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    

    三 测试

           代码写完了,接下来就是验证了。我是在window条件下验证测试的,也在网上找了两个工具,一个模拟串口工具,一个串口命令工具。为了方便大家我们把这两个工具放一起又重新上传在csdn上了。下载地址 https://download.csdn.net/download/wuyuxing24/11260170

    3.1 虚拟串口

            使用虚拟串口工具,虚拟两个串口。比如这里我们虚拟了COM1和COM2出来。

    虚拟串口工具.png

    3.2 运行单元测试代码

            运行我们上面编写的测试代码(测试代码我们连接COM2)。同时启动串口调试工具,测试下串口的收发。

    串口

           这样我们就用RXTX简单的实现了串口的收发逻辑。其他更加高级的用法大家可以去看看RXTX的文档。

    相关文章

      网友评论

          本文标题:RXTX实现JAVA串口编程

          本文链接:https://www.haomeiwen.com/subject/ervhcctx.html