java基于RXTXcomm的串口程序

article/2025/10/6 19:43:14

准备工作

  • 首先下载官方提供的jar包和.dll文件,dll文件有两个,一个是rxtxSerial,一个是rxtxParallel,分别表示串口和并口。
  • 因为我开发串口,所以把rxtxSerial.dll放到了jdk1.8.0_171/jre/bin和jre1.8.0_171/bin目录下,官方说两个都放,我没有去验证只放其中一个有没有差别。直接按照官方的直接放了。
  • 接下来将jar包放入工程目录下的lib文件夹,并引用。

PS:在程序开发之前,强烈建议用测试工具测试设备是否已经可用。

程序包括的部分

  • 初始化对象以及设置监听的init函数
  • 监听消息的函数 serialEvent()(该函数来自实现的接口SerialPortEventListener)
  • 消息发送函数 send()
  • 消息接收的函数 receive()
  • 关闭函数 close()
  • 因为消息是16进制字符串,所以还有16进制字符串转byte数组以及byte数组转字符串函数
    (这两个函数随便网上copy的,不是我自己写的,只修改了一句)

程序参数

  • PORT_NAME = “COM3”,这个参数的参数值看的是设备连接上后的设备管理器端口部分查看端口
  • BIT_RATE = 9600;
    DATA_BITS = SerialPort.DATABITS_8;
    STOP_BIT = SerialPort.STOPBITS_1;
    PARITY_BIT = SerialPort.PARITY_NONE;
    这四个参数分别表示设备的比特率,数据位,停止位,和校验位,在设备使用说明上提供了。
  • serialPort,这个参数用来设置串口的参数
  • InputStream in;OutputStream out;这两个参数分别用来读写数据

代码部分

初始化部分基本参照官网代码,只是稍作修改。
整个过程

  • 根据端口名称获取端口对象
  • 判断对象是否被占用
  • 判断端口类型,其中1代表串口,如果是串口就打开串口,设置设备参数,设置输入输出流,以及设置数据监听
public void init() {try {CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(PORT_NAME);if (portIdentifier.isCurrentlyOwned()){System.out.println("Error: Port is currently in use");}else if(portIdentifier.getPortType()==1){serialPort = (SerialPort) portIdentifier.open(PORT_NAME,1000);serialPort.setSerialPortParams(BIT_RATE,DATA_BITS,STOP_BIT,PARITY_BIT);in = serialPort.getInputStream();out = serialPort.getOutputStream();serialPort.addEventListener(this);serialPort.notifyOnDataAvailable(true);}else{System.out.println("Error: Only serial ports are handled by this example.");}} catch (Exception e) {e.printStackTrace();}}

serialEvent函数,大概就是用来监听事件,他包括很多事件,但是我只判断一个,是否有是可用数据,如果存在可用数据就接收。

public void serialEvent(SerialPortEvent event) {switch (event.getEventType()){case SerialPortEvent.DATA_AVAILABLE:receive();break;}}

receive函数,用来接收收到的数据,这里比较好理解,通过上面初始化的输入流,将获取到的数据存入byte数组,并且将其转成字符串返回。

public String receive(){byte[] buffer = new byte[128];int data;String result = null;try{int len = 0;while ( ( data = in.read()) > -1 ){buffer[len++] = (byte) data;}byte[] copyValue = new byte[len];System.arraycopy(buffer,0,copyValue,0,len);result = ByteArrayToString(copyValue);}catch ( IOException e ){e.printStackTrace();}return result;}

send函数,send函数将要发送的16进制字符串消息转换成byte数组发送,并且让线程休眠1秒。

public void send(String message){try {byte[] bytes = hexStrToByteArray(message);out.write(bytes);Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}}

官网还有其他地方的收发数据都用到了线程,但是在写的过程中发现并没有使用线程的必要,所以我去掉了线程这个部分。如果发送的数据不是类似我的16进制字符串,完全可以去掉那两个转换代码,所以看情况适当修改。

整个代码

/*** @author:ms.y* @create 2019/1/24-8:48*/
public class CommUtil implements SerialPortEventListener{private static final String PORT_NAME = "COM3";private static final int BIT_RATE = 9600;public static final int DATA_BITS = SerialPort.DATABITS_8;public static final int STOP_BIT = SerialPort.STOPBITS_1;public static final int PARITY_BIT = SerialPort.PARITY_NONE;private static SerialPort serialPort;private static InputStream in;private static OutputStream out;private static CommUtil commUtil;private CommUtil(){}public static CommUtil getInstance(){if(commUtil==null){commUtil = new CommUtil();commUtil.init();}return commUtil;}public void init() {try {CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(PORT_NAME);if (portIdentifier.isCurrentlyOwned()){System.out.println("Error: Port is currently in use");}else if(portIdentifier.getPortType()==1){serialPort = (SerialPort) portIdentifier.open(PORT_NAME,1000);serialPort.setSerialPortParams(BIT_RATE,DATA_BITS,STOP_BIT,PARITY_BIT);in = serialPort.getInputStream();out = serialPort.getOutputStream();serialPort.addEventListener(this);serialPort.notifyOnDataAvailable(true);}else{System.out.println("Error: Only serial ports are handled by this example.");}} catch (Exception e) {e.printStackTrace();}}public void send(String message){try {byte[] bytes = hexStrToByteArray(message);out.write(bytes);Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}}public void serialEvent(SerialPortEvent event) {switch (event.getEventType()){case SerialPortEvent.DATA_AVAILABLE:receive();break;}}public String receive(){byte[] buffer = new byte[128];int data;String result = null;try{int len = 0;while ( ( data = in.read()) > -1 ){buffer[len++] = (byte) data;}byte[] copyValue = new byte[len];System.arraycopy(buffer,0,copyValue,0,len);result = ByteArrayToString(copyValue);}catch ( IOException e ){e.printStackTrace();}return result;}public void close(){try {in.close();out.close();serialPort.notifyOnDataAvailable(false);serialPort.removeEventListener();serialPort.close();} catch (IOException e) {e.printStackTrace();}}//16进制转byte数组public byte[] hexStrToByteArray(String str) {if (str == null) {return null;}if (str.length() == 0) {return new byte[0];}byte[] byteArray = new byte[str.length() / 2];for (int i = 0; i < byteArray.length; i++) {String subStr = str.substring(2 * i, 2 * i + 2);byteArray[i] = ((byte) Integer.parseInt(subStr, 16));}return byteArray;}public String ByteArrayToString(byte[] by) {String str = "";for (int i = 0; i < by.length; i++) {String hex = Integer.toHexString(by[i] & 0xFF);if (hex.length() == 1) {hex = "0" + hex;}str += hex.toUpperCase();}return str;}public static void main ( String[] args ){CommUtil commUtil = CommUtil.getInstance();commUtil.send("8101060108080302FF");commUtil.send("8101060108080301FF");}
}附上官方参考文档地址:[串口通信示例](http://rxtx.qbang.org/wiki/index.php/Examples)

隔了几年再看这个代码,发现几个不太好的地方,本来想改的,但是没设备,就算了。
打算改的一个就是初始化那部分,单例对象一次创建,那么初始化感觉没必要写成非静态的,比较好的处理方法是静态块。
这一整个程序在当初的设计就是设计实验,所以定位就是单线程使用,所以不会出现问题,如果需要加上多线程,需要相应的做更改。


http://chatgpt.dhexx.cn/article/VnwlyeQk.shtml

相关文章

51单片机串口多机通信的原理与编程实现

51单片机串口多机通信 需要用的的寄存器 (了解的可直接跳到下一节&#xff09; TMOD 定时器/计数器模式控制寄存器TCON 定时器控制寄存器SCON 串口控制寄存器PCON 电源控制位寄存器IE 中断中断使能寄存器 补充说明&#xff0c;TH1 预置值计算&#xff0c;中断源 波特率计算公式…

Java串口通信详解

序言 说到开源&#xff0c;恐怕很少有人不挑大指称赞。学生通过开源代码学到了知识&#xff0c;程序员通过开源类库获得了别人的成功经验及能够按时完成手头的工程&#xff0c;商家通过开源软件赚到了钱……&#xff0c;总之是皆大欢喜。然而开源软件或类库的首要缺点就是大多缺…

Java串口通信(RXTX)

这几天要用到串口通信,而我最会的Java,所以我就去学了一下怎么用Java进行串口通信 用的jar包是RXTX官网:http://rxtx.qbang.org/ 下载地址:http://fizzed.com/oss/rxtx-for-java 下载好Jar包后,首先需要配置,这里我用的Eclipse Window->Preferences->Java->Build …

十一、串口通信的基本原理与应用

通常用&#xff1a;SMOD 0&#xff0c;0xfd 利用51单片机的串行接口与上位机建立传输信道进行数据的收发。采用8位UART模式&#xff0c;即模式1&#xff0c;波特率为9600BPS。数据发送采用查询方式&#xff0c;数据接收采用中断方式。 系统上电初始化之后&#xff0c;单片机向…

【超简单的串口通信的工作原理】

下图是电脑收到单片机经过串口发送的信息&#xff0c; 那么电脑是如何与单片机进行串口通信的呢&#xff1f; 首先&#xff0c;任何一种通信都要包括硬件物理接口和软件通信协议。 串口通信物理接口如下图。单片机通过发送端将数据从左往右一位一位按顺序发送&#xff1b;且在…

串口通信基本原理

目录 串口通信连线&#xff1a; 串口通信时序&#xff1a; 起始位&#xff1a; 数据位&#xff1a; 校验位&#xff1a; 停止位&#xff1a; 总结&#xff1a; 串口通信特点&#xff1a; 基于串口的通讯接口&#xff1a; 串口通信连线&#xff1a; 任何通信都要有信息…

一篇短文让你彻底理解什么是串口通信

1 并行与串行通信 机器的通信方式有两种&#xff0c;分别是并行通信与串行通信。 并行通信&#xff1a;并行通信是指多比特数据同时通过并行线进行传送&#xff0c;这样数据传送速度大大提高&#xff0c;但并行传送的线路长度受到限制&#xff0c;因为长度增加&#xff0c;干…

Java RXTX 实现串口通信

目录 串口&#xff08;通信&#xff09;概述 串口调试助手 RXTX 下载与依赖 Java 开发实战 串口(通信)概述 1、串口通信是指串口按位&#xff08;bit&#xff09;发送和接收字节 2、串口通信可以在使用一根线发送数据的同时用另一根线接收数据 3、串口通信常用的协议包括…

串口通信原理

并行通信是指数据的各个位用多条数据线同时进行传输 优点&#xff1a;传输速度快 缺点&#xff1a;占用引脚资源多 串行通信是将数据分成一位一位的形式在一条传输线上逐个传输 优点&#xff1a;通信线路简单、占用引脚资源少 缺点&#xff1a;传输速度慢 同步通信&#xf…

串口通讯基本原理 【详细】

串口通信的基本知识 本文介绍了串口通讯的基本概念、数据格式、通讯方式、典型的串口通讯标准等内容。 串口通讯&#xff0c;RS232,RS485&#xff0c;停止位&#xff0c;奇校验&#xff0c;偶校验 1 串口通讯 串口通讯(Serial Communication)&#xff0c;是指外设和计算…

串口通信的基本原理详解

目录 串口通信 串口通信的两种基本方式 异步数据的数据发送过程 异步通信的数据接收过程 9针串口&#xff08;DB9&#xff09; TTL与RS232区别 TTL: RS232&#xff1a; 串口通信的数据格式 通讯方式 偶校验与奇校验 停止位 波特率&#xff08;波特率就是每秒钟传输…

串口通信原理详解

串口通信是一种串行异步通信&#xff0c;通信双方以字符帧作为数据传输单位&#xff0c;字符帧按位依次传输&#xff0c;每个位占固定的时间长度。两个字符帧之间的传输时间间隔可以是任意的&#xff0c;即传输完一个字符帧之后&#xff0c;可以间隔任意时间再传输下一个字符帧…

14_串口通信原理

通信方式的两种: 并行通讯: 传输原理:数据各个位同时传输。 优点:速度快 缺点:占用引脚资源多 串行通信: 传输原理:数据按位顺序传输。 优点:占用引脚资源少 缺点:速度相对较慢 串行通信: 按照数据传送方向,分为: 单工:数据传输只支持数据在一个方向上传输。 半双工:…

【Linux】基于美信串行解串器实现UART串口通信

文章目录 前言一、环境介绍二、硬件配置1. MAX967632. MAX96752F 三、串口通信协议1. 帧格式2. 同步帧3. 应答帧4. 包格式&#xff08;包由帧组成&#xff09; 四、内核模块实现 前言 车载项目中串行/解串器是十分常见的外设&#xff0c;目前常用的有两种标准&#xff1a;GMSL…

毫米波雷达图解算法原理(基于TI雷达)

毫米波雷达数据处理原理 前言基础bin文件解读 以下我们取1帧进行操作&#xff1a;对数据矩阵进行操作前的转换——开始计算结果矩阵一维FFT&#xff08;距离&#xff09;二维FFT&#xff08;速度&#xff09;角度维FFT &#xff08;假设利用结果已经获取目标&#xff09;对目标…

【阵列信号处理】DOA估计算法

DOA估计中的ESPRIT算法 ESPRIT算法时一种利用子空间旋转法估计DOA参数的方法&#xff0c;其算法的基本思想是将阵列在结构上分成两个完全一致的子列&#xff0c;两个子列相应阵元偏移的距离相等&#xff0c;也就是说阵列的阵元被分成一对对的形式&#xff0c;而且每一对之间具…

Hector SLAM 原理详解、算法解析

目录 1.原理详解 2.算法解析 1.原理详解 Hector整体算法很直接&#xff0c;就是将激光点与已有的地图“对齐”&#xff0c;即扫描匹配。扫描匹配就是使用当前帧与已经有的地图数据构建误差函数&#xff0c;使用高斯牛顿法得到最优解和偏差量。其工作是实现激光点到栅格地图的转…

MPU 6050姿态角度融合算法

1、介绍 1.1 姿态角&#xff08;Euler角&#xff09;pitch yaw roll介绍 飞行器的姿态角并不是指哪个角度&#xff0c;是三个角度的统称。它们是&#xff1a;俯仰、滚转、偏航。你可以想象是飞机围绕XYZ三个轴分别转动形成的夹角。 地面坐标系&#xff08;earth-surface inert…

linemod算法过程理解

一、提取模板 1、预处理 使用高斯模糊预处理将要作为模板的RGB图 2、模板梯度计算 分别计算RGB三个通道中每个像素点x和y方向的梯度&#xff08;sobel算子&#xff09;&#xff0c;取幅值最大的作为该像素的梯度&#xff0c;若梯度幅度值小于阈值&#xff0c;则被舍弃 3、梯度离…

MATLAB函数angle、unwrap

一、angle 相位角 语法 P angle&#xff08;Z&#xff09;描述 P angle&#xff08;Z&#xff09;返回复数数组Z的每个元素的相角&#xff08;以弧度为单位&#xff09;。角度介于π之间。对于复数Z&#xff0c;幅值R和相角theta由下式给出 R 绝对值&#xff08;Z&#xff0…