1 简介

  • 项目要求:读取串口信息,并输出展示相应的图像,本篇文章不深入谈前端的内容着重于后端遇到的问题。
  • 2021-01-08更新,发现一个重大的问题:如果有人能解决的话请在评论区回复:
    • 在连上串口后,当你突然把串口拔开,程序会报出很多异常,原因是SerialPortEventListener作为监听的接口无法被注销掉,如果使用serialPort进行注销,则主程序会崩溃(这种崩溃用Error或者Throwable接收不到)。看了底层源码,发现调用的是C++的API,所以可能没法解决。
    • 解决办法是:自己用C++写一个串口功能,然后在JAVA中用JNI调用吧。

2 开发阶段

2.1 RXTX包使用前的部署

  1. 下载该包
    也可以从百度云下载:https://pan.baidu.com/s/1Ruu90kNFi5QJcpwFcJB3LQ,提取码:4hpz

  2. 由于手动导入的时候我遇到了点问题,所以选择先将 RXTXcomm.jar 导入到本地仓库,然后在maven项目中引入
    手动导入的指令

mvn install:install-file -DgroupId=gnu.io -DartifactId=rxtx -Dversion=2.1.7 -Dpackaging=jar -Dfile=“G:\迅雷下载\rxtx-2.1-7-bins-r2\rxtx-2.1-7-bins-r2\RXTXcomm.jar”

然后再在maven项目中引入

<dependency><groupId>gnu.io</groupId><artifactId>rxtx</artifactId><version>2.1.7</version>
</dependency>
  1. 还需要复制dll
    复制 rxtxParallel.dll 和 rxtxSerial.dll 到 C:\Program Files\Java\jdk1.8.0_241\jre\bin 下,如果无法打包,可以将 jar 包复制到C:\Program Files\Java\jdk1.8.0_241\jre\lib 中

RXTX的使用过程:

2.2 获取所有可用的端口信息

  • CommPortIdentifier 类内部有三个主要的成员变量可以获取
  • 串口的名称类似于:“COM1”
  • 端口类型包括:I2C、并口、RS485、串口
// 获取当前所有可用的串口信息
Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
// 遍历所有的串口信息
while(portList.hasMoreElements()){// 获取下一个端口信息CommPortIdentifier com = (CommPortIdentifier) portList.nextElement();// 端口当前的拥有者,如果没有返回nullString currentOwner = com.getCurrentOwner();// 端口的名称String name = com.getName();// 端口的类型,需要解析int portType = com.getPortType();
}

2.3 解析端口类型的工具

/*** @Description:获取通信端口类型名称* @author:Lu* @date:2015-8-29 上午11:35:32*/
public static String getPortTypeName(int portType) {switch (portType) {case CommPortIdentifier.PORT_I2C:return "I2C";case CommPortIdentifier.PORT_PARALLEL: // 并口return "Parallel";case CommPortIdentifier.PORT_RAW:return "Raw";case CommPortIdentifier.PORT_RS485: // RS485端口return "RS485";case CommPortIdentifier.PORT_SERIAL: // 串口return "Serial";default:return "unknown type";}
}

2.4 处理接收数据

  • 通过 CommPortIdentifier 类对象,打开端口,并获取到连接对象CommPort类的实例。该实例有个好用的子类 SerialPort类,可强转成该类
/*** 打开端口,注意操作顺序,输入流一定要先获取*/
private void openPort() {try {/*** open方法(应用程序名【随意命名】,阻塞时等待的毫秒数)* open方法打开通讯端口,获得一个CommPort对象,它使程序独占端口。* 如果端口正被其他应用程序占用,将使用CommPortOwnershipListener事件机制* 传递一个PORT_OWNERSHIP_REQUESTED事件。* 每个端口都关联一个InputStream和一个OutputStream,如果端口是用* open方法打开的,那么任何的getInputStream都将返回相同的数据流对象,除非 有close被调用。*/// open:(应用程序名【随意命名】,阻塞时等待的毫秒数)SerialPort serialPort = (SerialPort) commPortIdentifier.open("OpenPortServer", 2000);// 获取输入流inputStream = serialPort.getInputStream();// 设置串口监听,this对象即本类对象需要继承SerialPortEventListener接口。或者你在这里写一个匿名接口也行。接口内部函数的写法在下面serialPort.addEventListener(this);// 设置串口数据时间有效(可监听)serialPort.notifyOnDataAvailable(true);serialPort.notifyOnBreakInterrupt(true);// 设置串口通讯参数,可以参考SerialPort类的源码,里面有相关的常量// 波特率// 数据位个数// 停止位// 校验方式,0代表无奇偶校验,1代表偶校验,2代表偶校验serialPort.setSerialPortParams(9600, 8, 1, 0);} catch (PortInUseException e) {// 端口正在使用throw new RuntimeException(e);} catch (Exception e) {// 输入输出流错误throw new RuntimeException(e);}
}
  • 监听器

    • 监听器必须实现SerialPortEventListener接口,并通过serialPort.addEventListener(this);来注册监听器
    • 通过设置监听器来处理接收数据
    • 注意关闭操作的时候需要在 serialPort 中使用removeEventListener方法注销监听器,并且关闭输入流
  • 注意,上面获取到的InputStream的读取方法是阻塞方法,当没有数据的时候会阻塞等待数据的来临。
/*** 在这里进行连接状态判断** @param event 连接状态*/
@Override
public void serialEvent(SerialPortEvent event) {switch (event.getEventType()) {/*** 通讯中断*/case SerialPortEvent.BI: {}break;/*** 溢位错误*/case SerialPortEvent.OE: {}break;/*** 帧错误*/case SerialPortEvent.FE: {}break;/*** 奇偶校验错误*/case SerialPortEvent.PE: {}break;/*** 载波检测*/case SerialPortEvent.CD: {}break;/*** 清除发送*/case SerialPortEvent.CTS: {}break;/*** 数据设备准备好*/case SerialPortEvent.DSR: {}break;/*** 响铃侦测*/case SerialPortEvent.RI: {}break;/*** 输出缓冲区已清空*/case SerialPortEvent.OUTPUT_BUFFER_EMPTY: {}break;/*** 有数据到达*/case SerialPortEvent.DATA_AVAILABLE: {// InputStream 通过serialPort在上面的代码中已经获取到了,在这里通过InputStream 读取字节流即可。字节流的操作和咱们一般用法一致// 在这里进行读取操作byte[] bytes = new byte[255];try {int len = inputStream.read(bytes);// 然后就是其他操作了} catch (IOException e) {e.printStackTrace();}}break;default: {}break;}
}

3 打包和运行

我的项目主要是在 Windows 系统下运行的。
1)idea 使用maven打包,发现没有主程序,这需要在pom.xml 加入下面这个插件

 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>(你的启动类的全限定类名)com.wu.port.MySpringBootApplication</mainClass></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>

2)打包后,发现找不到RXTX的jar包,试了很久都是报这个错误。我的解决方法是:重新建立一个maven项目,把原来编的代码重新拷贝过来,然后再进行打包,发现就可以晕行了。
3)如果其他电脑要使用该项目,则必须要先安置好 .dll 文件,为此写一个批处理文件和 rxtxParallel.dll , rxtxSerial.dll , RXTXcomm.jar 放在一起

:: 本文件需要管理员权限运行
:: 获取当前路径
set cPath=%~dp0
cd /D cPath
:: 拷贝文件
copy rxtxParallel.dll %java_home%\jre\bin\  /y
copy rxtxSerial.dll %java_home%\jre\bin\  /y
copy RXTXcomm.jar %java_home%\jre\lib\ext\ /y

4)项目运行的批处理文件

:: 本文件不能以管理员身份运行,将本文件与jar包放置在一起
java -jar "%cd%\jar包名称"

java使用RXTX的详细总结相关推荐

  1. java中char占的二进制,java数据类型与二进制详细介绍

    java数据类型与二进制详细介绍 在java中 Int 类型的变量占 4个字节 Long 类型的变量占8个字节 一个程序就是一个世界,变量是这个程序的基本单位. Java基本数据类型 1. 整数类型 ...

  2. java消费者模式_基于Java 生产者消费者模式(详细分析)

    生产者消费者模式是多线程中最为常见的模式:生产者线程(一个或多个)生成面包放进篮子里(集合或数组),同时,消费者线程(一个或多个)从篮子里(集合或数组)取出面包消耗.虽然它们任务不同,但处理的资源是相 ...

  3. java设置环境变量win7_Windows7系统配置java环境变量的详细教程

    作为java运行环境支撑,任何一个java开发人员都必须学会安装jdk以及java环境变量的配置.有用户询问小编win7系统配置java环境变量会难?其实只要掌握方法,就可以得心应手了.接下来小编向大 ...

  4. JAVA 正则表达式 (超详细,转)

    转 JAVA 正则表达式 (超详细,转) 2015年03月25日 10:27:57 阅读数:1514 在Sun的Java JDK 1.40版本中,Java自带了支持正则表达式的包,本文就抛砖引玉地介绍 ...

  5. JAVA MemCache 史无前例的详细讲解 看完包精通MEMCACHE

    JAVA MemCache 史无前例的详细讲解!看完包精通MEMCACHE! 分类: 高并发_性能2012-08-22 09:15 5051人阅读 评论(0) 收藏 举报 javastringobje ...

  6. java lam表达式_详细分析Java Lambda表达式

    在了解Lambda表达式之前我们先来区分一下面向对象的思想和函数式编程思想的区别 面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用他的方法来解决 函数时编程思想: 只要能获取到结果,谁去 ...

  7. Java基础-->一篇讲全Java常用类(详细易懂,建议收藏)

    Java基础–>一篇讲全Java常用类(详细易懂,建议收藏) 文章目录 Java基础-->一篇讲全Java常用类(详细易懂,建议收藏) 1.字符串相关的类 String类 概述 创建Str ...

  8. Java Scanner类的详细介绍(Java键盘输入)

    Java Scanner类的详细介绍(Java键盘输入) 一.Scanner类的简单使用 二.Scanner类的详细介绍 1.判断输入数据类型 2.next()与nextLine()的区别 3.求多个 ...

  9. Java字节码的详细讲解-刘宇

    Java字节码的详细讲解-刘宇 一.字节码的整体结构 二.字节码范围解析 2.1.魔数 2.2.版本信息 2.3.常量池(constant pool) 2.4.描述符规则 2.5.访问标志(Acces ...

  10. java生产线消费者,基于Java 生产者消费者模式(详细分析)

    生产者消费者模式是多线程中最为常见的模式:生产者线程(一个或多个)生成面包放进篮子里(集合或数组),同时,消费者线程(一个或多个)从篮子里(集合或数组)取出面包消耗.虽然它们任务不同,但处理的资源是相 ...

最新文章

  1. greenplum安装札记(待完善)
  2. java 随机数生成实现_Java中生成随机数的实现方法总结
  3. 从windows到linux的换行转换工具dos2unix
  4. Linux实战教学笔记45:NoSQL数据库之redis持久化存储(一)
  5. SpringBoot实战之SpringBoot自动配置原理
  6. System variables, logging and the Execute SQL Task...(zz)
  7. Git rebase 和 Git merge 的区别,你知道吗?
  8. java空类型方法无参_类的无参方法
  9. 让Salesforce用户管理变得更加容易的几种最佳实践
  10. centos6安装python_如何在CentOS6上安装Python2.7和Python3.3
  11. 中国程序员最应该感谢的几家公司
  12. hdu 2570 (贪心)
  13. 【图像隐写】基于matlab GUI DWT+SVD数字水印 【含Matlab源码 939期】
  14. C语言入门1(devC的安装)
  15. 国内外php主流开源cms汇总
  16. FLOWABLE流程引擎分析
  17. 国内it软件外包公司排行榜是怎么样的
  18. ftp server - sftpgo_v2.2.2_windows_x86_64的简单使用
  19. 解决pdf中翻译外文文献到word参考文献格式错误
  20. 腾讯云+CentOS 7.2+python:搭建微信公众号后台入门教程

热门文章

  1. 【语音定时播报系统】基于树莓派+百度语音合成打造语音定时播报系统
  2. 关于RS485的使用
  3. 在线画图工具,高效办公
  4. FPGA经典设计:再读正点原子SDRAM控制器
  5. 高雅复古立式钢琴音源 Native Instruments The Gentleman Kontakt
  6. Java如何实现代理服务器?
  7. COPRA RF 2005 SR1冷弯成型,轧辊设计 USB加密锁
  8. FFT蝶形算法的verilog实现专题——从FFT算法的定义开始入手
  9. 黄杏元《地理信息系统概论》考研复习考点精讲(一)
  10. 2001年李彦宏DoNews三篇搜索引擎Blog