串口通信RXTXcomm使用

 

一、串口通信原理

串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。 尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。典型地,串口用于ASCII码字符的传输。通信使用3根线完成,分别是地线、发送、接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。

windows 查询本地串口
设备管理器,找到本地COM端口,我电脑上是COM4端口

 

 

 


 

二、准备工作

准备工作
1.下载
地址: http://fizzed.com/oss/rxtx-for-java

这里的下载是根据jdk安装的位数下载,我之前下载的是W64的版本,电脑系统也是64的,但是代码跑不起来,后来才发现我电脑的JDK是32位的。

2、下载完成后将 rxtxParallel.dll 、 rxtxSerial.dll 、文件拷贝到放入<JAVA_HOME>\jre\bin中

复制RXTXcomm.jar文件到JAVA_HOME\jre\lib\ext目录下

这一步非常重要,把rxtxParallel.dll  rxtxSerial.dll这两个文件放到jdk的bin目录下面,如果你不放当你后面打包后运行打开串口会报找不到这两个文件的错误,百思不得齐解(困扰了我一个下午)

 

 

3、引入

 <dependency>
            <groupId>com.test</groupId>
            <artifactId>rxtxcomm</artifactId>
            <version>2.2</version>
            <scope>system</scope>
            <systemPath>${basedir}/lib/RXTXcomm.jar</systemPath>
        </dependency>
方式1 本地jar包直接引入
 <dependency>
            <groupId>org.bidib.jbidib.org.qbang.rxtx</groupId>
            <artifactId>rxtxcomm</artifactId>
            <version>2.2</version>
        </dependency>
方式2 maven引入

 

 三、代码实现串口通信

1、串口工具类

  1  
  2 public class SerialPortUtil {
  3     /**
  4      * 获得系统可用的端口名称列表(COM0、COM1、COM2等等)
  5      *
  6      * @return List<String>可用端口名称列表
  7      */
  8  
  9     @SuppressWarnings("unchecked")
 10     public static List<String> getSerialPortList() {
 11         List<String> systemPorts = new ArrayList<>();
 12         //获得系统可用的端口
 13         Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
 14         while (portList.hasMoreElements()) {
 15             String portName = portList.nextElement().getName();//获得端口的名字
 16             systemPorts.add(portName);
 17         }
 18         return systemPorts;
 19     }
 20  
 21     /**
 22      * 打开串口
 23      *
 24      * @param serialPortName 串口名称
 25      * @return SerialPort 串口对象
 26      * @throws NoSuchPortException               对应串口不存在
 27      * @throws PortInUseException                串口在使用中
 28      * @throws UnsupportedCommOperationException 不支持操作操作
 29      */
 30     public static SerialPort openSerialPort(String serialPortName)
 31             throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
 32         SerialPortParameter parameter = new SerialPortParameter(serialPortName);
 33         return openSerialPort(parameter);
 34     }
 35  
 36     /**
 37      * 打开串口
 38      *
 39      * @param serialPortName 串口名称
 40      * @param baudRate       波特率
 41      * @return SerialPort 串口对象
 42      * @throws NoSuchPortException               对应串口不存在
 43      * @throws PortInUseException                串口在使用中
 44      * @throws UnsupportedCommOperationException 不支持操作操作
 45      */
 46     public static SerialPort openSerialPort(String serialPortName, int baudRate)
 47             throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
 48         SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
 49         return openSerialPort(parameter);
 50     }
 51  
 52     /**
 53      * 打开串口
 54      *
 55      * @param serialPortName 串口名称
 56      * @param baudRate       波特率
 57      * @param timeout        串口打开超时时间
 58      * @return SerialPort 串口对象
 59      * @throws NoSuchPortException               对应串口不存在
 60      * @throws PortInUseException                串口在使用中
 61      * @throws UnsupportedCommOperationException 不支持操作操作
 62      */
 63     public static SerialPort openSerialPort(String serialPortName, int baudRate, int timeout)
 64             throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
 65         SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
 66         return openSerialPort(parameter, timeout);
 67     }
 68  
 69     /**
 70      * 打开串口
 71      *
 72      * @param parameter 串口参数
 73      * @return SerialPort 串口对象
 74      * @throws NoSuchPortException               对应串口不存在
 75      * @throws PortInUseException                串口在使用中
 76      * @throws UnsupportedCommOperationException 不支持操作操作
 77      */
 78     public static SerialPort openSerialPort(SerialPortParameter parameter)
 79             throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
 80         return openSerialPort(parameter, 2000);
 81     }
 82  
 83     /**
 84      * 打开串口
 85      *
 86      * @param parameter 串口参数
 87      * @param timeout   串口打开超时时间
 88      * @return SerialPort串口对象
 89      * @throws NoSuchPortException               对应串口不存在
 90      * @throws PortInUseException                串口在使用中
 91      * @throws UnsupportedCommOperationException 不支持操作操作
 92      */
 93     public static SerialPort openSerialPort(SerialPortParameter parameter, int timeout)
 94             throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
 95         //通过端口名称得到端口
 96         CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(parameter.getSerialPortName());
 97         //打开端口,(自定义名字,打开超时时间)
 98         CommPort commPort = portIdentifier.open(parameter.getSerialPortName(), timeout);
 99         //判断是不是串口
100         if (commPort instanceof SerialPort) {
101             SerialPort serialPort = (SerialPort) commPort;
102             //设置串口参数(波特率,数据位8,停止位1,校验位无)
103             serialPort.setSerialPortParams(parameter.getBaudRate(), parameter.getDataBits(), parameter.getStopBits(), parameter.getParity());
104             System.out.println("开启串口成功,串口名称:" + parameter.getSerialPortName());
105             return serialPort;
106         } else {
107             //是其他类型的端口
108             throw new NoSuchPortException();
109         }
110     }
111  
112  
113     /**
114      * 关闭串口
115      *
116      * @param serialPort 要关闭的串口对象
117      */
118     public static void closeSerialPort(SerialPort serialPort) {
119             serialPort.close();
120             System.out.println("关闭了串口:" + serialPort.getName());
121  
122     }
123  
124     /**
125      * 向串口发送数据
126      *
127      * @param serialPort 串口对象
128      * @param data       发送的数据
129      */
130     public static void sendData(SerialPort serialPort, byte[] data) {
131         OutputStream os = null;
132         try {
133             //获得串口的输出流
134             os = serialPort.getOutputStream();
135             os.write(data);
136             os.flush();
137         } catch (IOException e) {
138             e.printStackTrace();
139         } finally {
140             try {
141                 if (os != null) {
142                     os.close();
143                 }
144             } catch (IOException e) {
145                 e.printStackTrace();
146             }
147         }
148     }
149  
150     /**
151      * 从串口读取数据
152      *
153      * @param serialPort 要读取的串口
154      * @return 读取的数据
155      */
156     public static byte[] readData(SerialPort serialPort) {
157         InputStream is = null;
158         byte[] bytes = null;
159         try {
160             //获得串口的输入流
161             is = serialPort.getInputStream();
162             //获得数据长度
163             int bufflenth = is.available();
164             while (bufflenth != 0) {
165                 //初始化byte数组
166                 bytes = new byte[bufflenth];
167                 is.read(bytes);
168                 bufflenth = is.available();
169             }
170         } catch (IOException e) {
171             e.printStackTrace();
172         } finally {
173             try {
174                 if (is != null) {
175                     is.close();
176                 }
177             } catch (IOException e) {
178                 e.printStackTrace();
179             }
180         }
181         return bytes;
182     }
183  
184     /**
185      * 给串口设置监听
186      *
187      * @param serialPort serialPort 要读取的串口
188      * @param listener   SerialPortEventListener监听对象
189      * @throws TooManyListenersException 监听对象太多
190      */
191     public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) throws TooManyListenersException {
192         //给串口添加事件监听
193         serialPort.addEventListener(listener);
194         //串口有数据监听
195         serialPort.notifyOnDataAvailable(true);
196         //中断事件监听
197         serialPort.notifyOnBreakInterrupt(true);
198     }
199 }
SerialPortUtil

2、初始化串口,以及监听串口发送过来的数据,然后监听到一条就保存一条到数据库中去

 1     private SerialPort serialPort;
 2 /**
 3      * 初始化串口
 4      *
 5      * @throws IOException
 6      */
 7     @SuppressWarnings("unchecked")
 8     public void initDriverSerialPort() {
 9         SqlSession session = MybatisUtils.getSession();
10         SerialPortMapper mapper = session.getMapper(SerialPortMapper.class);
11         rfid_print.setDisable(false);
12  
13         try {
14             //打开串口,然后获取所有串口的一个集合,然后通过获取文本框里面的内容来选择串口
15             serialPort = SerialPortUtil.openSerialPort(port_comboBox.getValue());
16             if (serialPort !=null){
17                 new Alert(Alert.AlertType.NONE, "打开端口成功", new ButtonType[]{ButtonType.CLOSE}).show();
18             }else {
19                 new Alert(Alert.AlertType.NONE, "未找到该端口,打开失败", new ButtonType[]{ButtonType.CLOSE}).show();
20             }
21 //             启动一个线程发送10次6463
22             new Thread(() -> {
23                 String s = "6463";
24                 byte[] bytes = s.getBytes();
25                 SerialPortUtil.sendData(serialPort, bytes);//发送数据
26                 try {
27                     Thread.sleep(1000);
28                 } catch (InterruptedException e) {
29                     e.printStackTrace();
30                 }
31             }).start();
32             //设置串口的listener
33             SerialPortUtil.setListenerToSerialPort(serialPort, event -> {
34                 //数据通知
35                 if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
36                     byte[] bytes = SerialPortUtil.readData(serialPort);
37                     System.out.println("收到的数据长度:{}" + bytes.length);
38                     String s = new String(bytes);
39                     String[] split = s.split(",");
40                     Serialport1 serialport1=new Serialport1();
41                     serialport1.setCarCode(split[0]);
42                     serialport1.setTime(split[1]);
43                     serialport1.setYup(split[2]);
44                     serialport1.setYdown(split[3]);
45                     serialport1.setYtest(split[4]);
46                     serialport1.setZup(split[5]);
47                     serialport1.setZdown(split[6]);
48                     serialport1.setZtest(split[7]);
49                     serialport1.setLightOnUp(split[8]);
50                     serialport1.setLightUpDown(split[9]);
51                     serialport1.setLightOnTest(split[10]);
52                     serialport1.setStatus(split[11]);
53                     int i = mapper.setSerialport(serialport1);
54                     System.out.println("成功插入"+i+"条数据!!!");
55                     session.commit(); //提交事务,重点!不写的话不会提交到数据库
56                     session.close();
57  
58                 }
59  
60             });
61         } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException e) {
62             e.printStackTrace();
63         }
64     }
初始化串口

3、关闭串口

    /**
     * 关闭串口
     *
     * @throws IOException
     */
    public void closeDriverSerialPort() {
        SerialPortUtil.closeSerialPort(serialPort);
        new Alert(Alert.AlertType.NONE, "关闭端口成功", new ButtonType[]{ButtonType.CLOSE}).show();
    }
关闭串口

4、如果连接成功控制台就会打印消息,打开串口成功,关闭串口com2

 

 

 

测试工具

虚拟串口工具 Configure Virtual Serial Port Driver
串口通信工具 友善串口调试助手

 

————————————————
转自:https://blog.csdn.net/qq_40042416/article/details/124682542

https://blog.csdn.net/xiaowanzi321/article/details/125620155

posted on 2023-01-12 11:21  腾逸  阅读(538)  评论(0编辑  收藏  举报