JAVA使用RXTXcomm进行串口通信(一)

article/2025/10/31 19:42:02

1.引入RXTXcomm.JAR包
在这里插入图片描述

  • 首先下载相应的jar文件
    压缩包包括:RXTXcomm.jar(64位环境)、win32com.dll和javax.comm.properties。
    下载地址:https://www.aliyundrive.com/s/JSeSQsAyYeZ
    点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
    介绍:RXTXcomm.jar提供了通讯用的java API,win32com.dll提供了供RXTXcomm.jar调用的本地驱动接口,javax.comm.properties是这个驱动的类配置文件

  • 拷贝RXTXcomm.jar到<JAVA_HOME>\jre\lib\ext目录下面;

  • 拷贝javax.comm.properties到<JAVA_HOME>\jre\lib目录下面;

  • 拷贝win32com.dll到<JAVA_HOME>\jre\bin目录下面;

2.启动类

package com.datago.serialport;import com.datago.serialport.controller.boot.MyLister;
import com.datago.serialport.controller.boot.PortInit;
import com.datago.serialport.controller.boot.SerialPortUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.annotation.PreDestroy;@SpringBootApplication
public class SerialPortApplication {public static void main(String[] args) {SpringApplication.run(SerialPortApplication.class, args);}@PreDestroypublic void destory() {//关闭应用前,关闭端口SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();serialPortUtil.removeListener(PortInit.serialPort, new MyLister());serialPortUtil.closePort(PortInit.serialPort);}
}

3.启动程序打开串口通信,添加端口监听

package com.datago.serialport.controller.boot;import gnu.io.SerialPort;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;import java.util.ArrayList;/*** @ProjectName serial-port* @Package com.datago.serialport.controller.boot* @Name PortInit* @Author HB* @Date 2022/7/13 09:55* @Version 1.0*/
@Component
public class PortInit implements ApplicationRunner {public static SerialPort serialPort = null;@Value("${portname}")private String portname;@Overridepublic void run(ApplicationArguments args) {//查看所有串口SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();ArrayList<String> port = serialPortUtil.findPort();System.out.println("发现全部串口:" + port);System.out.println("打开指定portname:" + portname);//打开该对应portname名字的串口SerialPort serialPort = serialPortUtil.openPort(portname, 9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);this.serialPort=serialPort;//给对应的serialPort添加监听器serialPortUtil.addListener(serialPort, new MyLister());System.out.println("可以正常发送数据");}
}

4.监听类

package com.datago.serialport.controller.boot;import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import lombok.SneakyThrows;import java.util.Date;/*** @ProjectName serial-port* @Package com.datago.serialport.controller.boot* @Name MyLister* @Author HB* @Date 2022/7/13 10:38* @Version 1.0*/
public class MyLister implements SerialPortEventListener {@Override@SneakyThrowspublic void serialEvent(SerialPortEvent arg0) {if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();SerialPort serialPort = PortInit.serialPort;byte[] bytes = serialPortUtil.readFromPort(serialPort);serialPortUtil.sendToPort(serialPort,"-----nihao-----".getBytes());String byteStr = new String(bytes, 0, bytes.length).trim();System.out.println("================start============");System.out.println(new Date() + "读到的字节数组:-----" + byteStr);String needData = printHexString(bytes);System.out.println(new Date()+"字节数组转字符串:------"+needData);String s = hexStringToString(needData).trim();if (s.equals("1")){//关闭应用前,关闭端口serialPortUtil.removeListener(serialPort, new MyLister());serialPortUtil.closePort(serialPort);System.out.println("==================close=====================");}System.out.println(new Date()+"16进制字符串转字符串:------"+hexStringToString(needData));System.out.println("================end=============");}}//字节数组转字符private String printHexString(byte[] b) {StringBuffer sdf = new StringBuffer();for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = "0" + hex;}sdf.append(hex.toUpperCase() + " ");}return sdf.toString().trim();}//16进制转换为String类行字符串public static String hexStringToString(String s) {if (s == null || s.equals("")) {return null;}s = s.replace(" ", "");byte[] baKeyword = new byte[s.length() / 2];for (int i = 0; i < baKeyword.length; i++) {try {baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));} catch (Exception e) {e.printStackTrace();}}try {s = new String(baKeyword, "UTF-8");new String();} catch (Exception e) {e.printStackTrace();}return s;}}

5.串口通信工具类

package com.datago.serialport.controller.boot;import gnu.io.*;
import lombok.extern.slf4j.Slf4j;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;/*** @ProjectName serial-port* @Package com.datago.serialport.controller.boot* @Name SerialPortUtil* @Author HB* @Date 2022/7/13 09:58* @Version 1.0*/
@Slf4j
public class SerialPortUtil {private static SerialPortUtil serialPortUtil = null;static {//在该类被ClassLoader加载时就初始化一个serialTool对象if (serialPortUtil == null) {serialPortUtil = new SerialPortUtil();}}//私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象private SerialPortUtil() {}/*** 获取提供服务的SerialTool对象*/public static SerialPortUtil getSerialPortUtil() {if (serialPortUtil == null) {serialPortUtil = new SerialPortUtil();}return serialPortUtil;}/*** 查询所有可用端口*/public ArrayList<String> findPort() {//获取当前所有可用串口Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();ArrayList<String> portNameList = new ArrayList<>();//将可用串口名添加到List并返回该Listwhile (portList.hasMoreElements()) {String portName = portList.nextElement().getName();portNameList.add(portName);}return portNameList;}/*** 打开串口*/public SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbatis) {try {//通过端口名识别端口CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);//打开端口,并给端口名字一个timeout(打开操作的超时时间)CommPort commPort = portIdentifier.open(portName, 2000);//判断是不是串口if (commPort instanceof SerialPort) {SerialPort serialPort = (SerialPort) commPort;//设置一下串口的波特率等参数try {serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);} catch (UnsupportedCommOperationException e) {e.printStackTrace();}log.info("Open-------------{}" + portName + "sucessfully");return serialPort;} else {log.error("不是串口----------{}");}} catch (NoSuchPortException e) {log.error("没有找到端口--------------{}");e.printStackTrace();} catch (PortInUseException e) {log.error("端口被占用--------------{}");e.printStackTrace();}return null;}/*** 关闭串口*/public void closePort(SerialPort serialPort) {if (serialPort != null) {serialPort.close();}}/*** 往串口发送数据*/public void sendToPort(SerialPort serialPort, byte[] order) {OutputStream out = null;try {out = serialPort.getOutputStream();out.write(order);out.flush();} catch (IOException e) {e.printStackTrace();} finally {try {if (out != null) {out.close();}} catch (IOException e) {e.printStackTrace();}}}/**从串口读取数据*/public byte[] readFromPort(SerialPort serialPort){InputStream in=null;byte[] bytes=null;try {in=serialPort.getInputStream();int bufflenth=in.available();while (bufflenth!=0){bytes=new byte[bufflenth];in.read(bytes);bufflenth=in.available();}}catch (IOException e){e.printStackTrace();}finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}return  bytes;}/**添加监听器*/public void addListener(SerialPort port,SerialPortEventListener listener){try {//给串口添加监听器port.addEventListener(listener);//设置当有数据到时唤醒监听接收线程port.notifyOnDataAvailable(true);//设置当通信中断时唤醒中断线程port.notifyOnBreakInterrupt(true);}catch (TooManyListenersException e){log.error("太多监听器-------------{}");e.printStackTrace();}}/**删除监听器*/public void removeListener(SerialPort port,SerialPortEventListener listener){//删除串口监听器port.removeEventListener();}
}

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

相关文章

SpringBoot使用RXTX连接串口教程及遇到的坑总结

文章目录 SpringBoot使用RXTX连接串口教程及遇到的坑总结一、所用环境及依赖二、部署流程2.1 下载RXTXComm包2.2 部署RXTXComm包 三、编写串口使用程序3.1 编写RXTXConfig.java3.2 编写实体类SerialPortEntity3.3 编写监听器SerialPortListener3.4 编写工具类SerialPortUtil3.5…

【计算机基础|计算机组成原理】【10】海明校验码

海明校验码 海明校验码思路 偶校验&#xff1a;1010 → 01010&#xff0c;能发现奇数位错误&#xff0c;但无法确定是哪一位出错 → 1个校验位只能携带2种状态信息&#xff1a;对/错 海明码设计思路&#xff1a;将信息位分组进行偶校验 → 多个校验位能携带多种状态信息&#x…

计算机组成原理汉明校验,海明校验码(计算机组成原理11)

海明校验码 视频链接地址&#xff1a; https://www.bilibili.com/video/BV1BE411D7ii?fromsearch&seid6420326887479343502 前言 在本篇中&#xff0c;你将掌握 海明码的基本思想 海明码的求解步骤和全校验码 在计算机内部进行存储、计算的数据都是以二进制形式传送&#…

海明校验码纠错设计原理

本文不阐述海明码计算方式&#xff0c;为了节省您的时间&#xff0c;请先学习海明码/奇偶校验是如何计算的&#xff0c;如果好奇其海明码的纠错设计思路再来看此文章&#xff01; 信息为位数为n&#xff0c;校验位数为k&#xff0c;正确状态占1位&#xff0c;所以总位数&#…

2.21 海明校验码

海明校验码 需要了解海明码的编码规则&#xff0c;要会计算需要多少位校验位。 海明码的编码规则 校验位&#xff1a; 校验位的位置是有规律的。都是位于2n。 比如20(1),21(2),22(4)。。都是校验位。 信息位&#xff1a;不是校验位的其他位置。 举个例子 当信息位有1位&am…

【软考学习7】数据校验——海明校验码、循环校验码、奇偶校验码

一、检错、纠错和码距 1.1 检错 从接收的报文中&#xff0c;检查出错误。 1.2 纠错 从接收的报文中检查出错误&#xff0c;并改正错误。 一般通过加冗余信息&#xff08;增大码距&#xff09;来实现。 1.3 码距 码距是整个编码系统中任意两个码字的最小距离。 也就是说&a…

超详细的海明校验码方法解读

海明校验码原理&#xff1a;在有效的信息为中加入几个校验位形成海明码&#xff0c;使码距[rjazgj1] 比较均匀地拉大&#xff0c;并把海明码的每个二进制位分配到几个奇偶校验组[rjazgj2] 中。当某一位出错后&#xff0c;就会引起有关的几个校验位的值发生变化&#xff0c;这不…

海明校验码原理以及作用机制的介绍

什么是海明校验码&#xff1f; 由Richard Hamming于1950年提出、还被广泛采用的一种很有效的校验方法&#xff0c;是只要增加少数几个校验位&#xff0c;就能检测出二位同时出错、亦能检测出一位出错并能自动恢复该出错位的正确值的有效手段&#xff0c;后者被称为自动纠错。 它…

海明校验码的计算及检验

海明校验码的计算及检验 目录 海明校验码的计算及检验知识背景计算海明校验码步骤一&#xff1a;计算校验码位数步骤二&#xff1a;确定校验组步骤三&#xff1a;计算校验码的值得出海明校验码 利用海明校验码校验数据其他 总结 最近和兄弟探讨一个海明校验码的题目&#xff0c…

海明校验码举例

海明校验码举例&#xff1a; 编制ASCII字符M的海明校验码。 解&#xff1a;M的ASCII码为A6A5A4A3A2A1A01001101 M为7位那么海明码最少需要2i&#xff0c;也就是说需要&#xff0c;才能表示出来&#xff0c;&#xff08;238&#xff09; 用哪些信息位分别被哪些校验位效验如…

计算机底层:海明校验码。

计算机底层&#xff1a;海明校验码。 海明校验码是由奇偶校验码中的偶校验延申出来的&#xff1a; 计算机底层&#xff1a;奇偶校验码_srhqwe的博客-CSDN博客 了解海明校验码之前需要先了解奇偶校验码。 海明校验码设计思路&#xff1a; 需要知道&#xff1a;多个校验位就能携…

海明校验码

1. 海明码的特点&#xff1a; 其中m表示数据位的位数&#xff0c;k表示海明校验码的位数 k位海明校验码一共可以表示种校验信息结果&#xff0c;其中有一种要用来表示没有出错的情况&#xff0c;则其余还剩-1种结果&#xff0c;为了使校验结果可以指出任一位出错的位置&#x…

计算机组成原理学习笔记:海明校验码

概述 海明校验码又可以称为汉明校验码, 这只是一个音译的问题, 作者是 Richard Hamming海明校验码对于信息纠错这个领域的贡献十分巨大&#xff0c;Richard Hamming 获得了1968年的图灵奖内容主要包括&#xff1a;海明校验码的思想、如何构建海明校验码、如何使用海明校验码 …

海明码校验【简单详细】

海明码 1.什么是海明码: 一个名叫Richard Hanming老爷爷在1950年提出的检验纠错方法&#xff0c;它具有一位纠错能力。 2.海明码的计算方法: 设欲检测的二进制代码为n位,K为检测位(提供纠错),总共nk位代码 当中检测位满足的关系: 2 k 2^{k} 2k>(nk1) 此关系也是求不同代码长…

一文看懂海明校验码及其计算方法(详细总结)

网上看了好几篇文章后终于算是捋明白了&#xff0c;但是看到的这些资源要么说得云里雾里&#xff0c;要么干脆说得有问题&#xff08;然后还被点了好多赞。。。&#xff09;&#xff0c;无论如何这些都容易误导小白。作为C站多年老潜水员&#xff0c;我还是把海明校验码的要点总…

ResNets

ResNets 背景&#xff1a; 非常非常深的神经网络是很难训练的&#xff0c;因为存在梯度消失和梯度爆炸问题。 《转载更改》 https://blog.csdn.net/qq_29893385/article/details/81207203 ResNets是由残差块&#xff08;Residual block&#xff09;构建的 首先解释一下什么是…

正确定位混淆后Crash代码行数

Android--定位混淆后Crash代码行数 一、需求背景二、前期准备三、对混淆日志进行还原四、示例 一、需求背景 打包时需要对代码进行混淆&#xff0c;目的是增加安全性&#xff0c;防⽌反编译。但这会导致App崩溃时&#xff0c;抓到的日志堆栈中显示的代码行数对应不上&#xff…

repalce

1、replace基本用法 <script>/*要求将字符串中所有的a全部用A代替*/var str "javascript is great script language!";//只会将第一个匹配到的a替换成Aconsole.log(str.replace("a", "A")); // > jAvascript is great script language…

Android studio 4.2新特性及升级异常

Android studio 版本及特性系列目录 Android 12 终于来了&#xff0c;你准备好了吗&#xff1f;Android studio 4.2新特性Android studio 4.1新特性Android Studio 4.0新特性及升级异常Android Studio3.6. 插件搜索不到终极解决方案 Android studio 4.2新特性 前言升级异常Gra…

强化学习的学习之路(五十一)2021-02-20 Retrace

作为一个新手&#xff0c;写这个强化学习-基础知识专栏是想和大家分享一下自己学习强化学习的学习历程&#xff0c;希望对大家能有所帮助。这个系列后面会不断更新&#xff0c;希望自己在2021年能保证平均每日一更的更新速度&#xff0c;主要是介绍强化学习的基础知识&#xff…