当前位置: 首页 > news >正文

Java串口开发

网上搜索了关于java串口开发的资料,发现都不是特别的全,故写下一些心得以帮助其他人能快速上手java串口开发,如有错漏之处,敬请指正
串口开发会用到一个javax.comm和RXTXcomm库,,javax.comm库不支持64位操作系统。该库仅适用于32位操作系统,所以接下来主要介绍的还是RXTXcomm库进行的串口开发

资源下载

RXTXcomm有32位的,也有64位的包,我们大多用到的都是64而且jdk都是1.8版本的
链接: 下载地址
在这里插入图片描述
这里注意选择2.2版本的,这个版本是支持64位的操作系统

在这里插入图片描述
下载完以后我们可以发现,目录下有一个jar文件,和对各个操作系统不同支持的系统文件,这里我们如果是在windwos64位的情况下只有的话,只需要用到RXTXcomm.jar和win64里面的dll文件即可

环境配置

下载完成以后,接下来我们需要将这个jar文件和lib文件引入到项目中

  1. 将rxtxSerial.dll文件放到JAVA_HOME\jre\bin下
  2. 将RXTXComm分别放在项目的lib目录下,和jre的ext目录下(JAVA_HOME\jre\lib\ext)在这里插入图片描述

下载完成以后我们可以简单的写一段测试代码检测下是否配置存在异常
这里我们可以采用虚拟串口的方式先进行简单的测试
在这里插入图片描述

import gnu.io.*;import java.io.*;public class SerialTest {public static void main(String[] args) {// 串口名称,根据实际情况修改String portName = "COM3";// 波特率,根据实际情况修改int baudRate = 9600;try {// 获取串口实例CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);if (portIdentifier.isCurrentlyOwned()) {System.out.println("Error: Port is currently in use");} else {// 打开串口并设置波特率CommPort commPort = portIdentifier.open(SerialTest.class.getName(), 2000);if (commPort instanceof SerialPort) {SerialPort serialPort = (SerialPort) commPort;serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);// 获取输出流并发送数据OutputStream outputStream = serialPort.getOutputStream();outputStream.write("Hello World".getBytes());// 关闭串口serialPort.close();} else {System.out.println("Error: Only serial ports are handled by this example.");}}} catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | IOException ex) {System.out.println("Error: " + ex.getMessage());}}
}

可以看到,我们已经能够正常的将数据发送至串口

不过也有的可能会出现以下的错误信息
在这里插入图片描述
这边我分别使用了32位1.8和64位1.8进行了测试,发现32位没有出现这个问题,当使用1.8,361和1,8,382版本的时候都出现了这个问题,181却可以正常使用,如果大家遇到这个问题的时候,可以使用小版本较低的jdk1.8进行使用
在这里插入图片描述

打包

经过上面的安装和设置,我们已经可以使用java RXTX库进行串口开发了,如果需要进行打包操作的话,并且在maven环境下使用的话,可以使用我下面提供的代码
我们前面将RXTXcomm的jar添加到了lib包下面,所以打包的时候可以借助maven-shade插件将lib包也一起进行打包

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.0</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><createDependencyReducedPom>false</createDependencyReducedPom><transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>mainClass</mainClass></transformer></transformers></configuration></execution></executions></plugin><plugin><groupId>com.googlecode.addjars-maven-plugin</groupId><artifactId>addjars-maven-plugin</artifactId><version>1.0.5</version><executions><execution><goals><goal>add-jars</goal></goals><configuration><resources><resource><directory>${basedir}/lib</directory></resource></resources></configuration></execution></executions></plugin></plugins></build>

使用mvn package命令即可将项目项目打包成jar的形式在这里插入图片描述

最后

使用java进行串口开发的场景使用并不多,如果涉及到这方面的需求,可以根据我下面提供代码进行修改即可完成开发,同时我也会将我使用到的一切工具或代码上传到资源供大家下载使用。接下来我还会写一篇关于java smslib包相关的文章(实现手机通讯模块短信收发功能)

北斗

以下是我针对北京神州天鸿的北斗卫星电台编写的操作代码,提供给有需要的小伙伴

/*** @program: scada* @description: 操作串口使用北斗进行短信的收发* @author: Dongrui* @create: 2023-06-06 14:42**/
public class Beidou implements SerialPortEventListener {/*** 端口*/String port;/*** 波特率*/int baudRate;/*** 超时时间*/int timeOut = 2000;//    输入和输出流public static InputStream inputStream;public static OutputStream outputStream;/*** @param port     端口* @param baudRate 波特率*/public Beidou(String port, int baudRate) {this.port = port;this.baudRate = baudRate;System.out.println(port + " " + baudRate);initSerialPort();}/*** @param port     端口* @param baudRate 波特率* @param timeout  超时时间*/public Beidou(String port, int baudRate, int timeout) {this.port = port;this.baudRate = baudRate;this.timeOut = timeout;System.out.println(port + " " + baudRate);initSerialPort();}/*** 初始化串口*/private void initSerialPort() {SerialPort serialPort = null;try {CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(port);serialPort = (SerialPort) portIdentifier.open("BDSerialCommunication", timeOut);serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);// 获取输入输出流inputStream = serialPort.getInputStream();outputStream = serialPort.getOutputStream();
//            添加串口事件监听器serialPort.addEventListener(this);serialPort.notifyOnDataAvailable(true);// 设置当通信中断时唤醒中断线程serialPort.notifyOnBreakInterrupt(true);} catch (NoSuchPortException e) {Logger.getInstance().logError("not found port:" + port, null, null);} catch (PortInUseException e) {Logger.getInstance().logError("port:" + port + " in use", null, null);} catch (IOException e) {Logger.getInstance().logError("port:" + port + " get stream fail", null, null);} catch (TooManyListenersException e) {Logger.getInstance().logError("port:" + port + " too many listeners", null, null);} catch (UnsupportedCommOperationException e) {Logger.getInstance().logError("port:" + port + " not support param," +"baudRate:" + baudRate, null, null);}}/*** 生成校验码** @param str* @return*/private static char checkSum(String str) {int result = str.charAt(0);for (int i = 1; i < str.length(); i++) {result = str.charAt(i) ^ result;}return (char) result;}/*** 发送短信** @param senderID                    收信方id:1表示本机id,2表示随机id,3表示公司,4表示广播;其中,2和3仅仅适用于管理型用户终端,4仅仅适用于网管中心控制用户终端* @param recipientAddress            收信方地址,当收信方为神州天鸿终端时,收信方地址为神州天鸿终端的id好* @param confidentialityRequirements 保密要求:1表示不保密,2表示保密* @param receiptFlag                 回执标志,0表示不需要回执,1表示需要回执,这里的回执可能是系统回执或通信回执* @param messageContent              电文内容,字符与数字用ascii码表示,汉字用gb2312码表示(两个字节表示一个汉字),电文内容的长度最多不超过200个字节* @throws IOException*/public void sendMessage(int senderID, int recipientAddress, int confidentialityRequirements, int receiptFlag, String messageContent) throws IOException {int length = messageContent.getBytes("GB2312").length;
//        发送短信的指令String instructions = "$TTCA" + "," + senderID + "," + recipientAddress + "," + confidentialityRequirements + "," + receiptFlag + "," + length + "," + messageContent + ",";
//      生成校验码char checksum = checkSum(instructions);//        发送至串口的字符串String str = instructions + checksum + "\r\n";Logger.getInstance().logInfo("北斗操作串口发送短信:" + str, null, null);
//      写至串口outputStream.write(str.getBytes());outputStream.flush();}/*** 查询状态输出频度** @return* @throws IOException* @throws InterruptedException*/public void queryStatus() throws IOException, InterruptedException {queryStatus(0);}/*** 状态输出频度** @param stateOutputFrequency 时间间隔,单位为秒,范围0~255,当状态输出频度为0时,表示只向外设输出一次状态信息* @return* @throws IOException* @throws InterruptedException*/public void queryStatus(int stateOutputFrequency) throws IOException, InterruptedException {String instructions = "$QSTA" + "," + stateOutputFrequency + ",";char checksum = checkSum(instructions);String str = instructions + checksum + "\r\n";
//        往串口发送数据outputStream.write(str.getBytes());outputStream.flush();}/*** 定位申请** @param confidentialityRequirements 保密要求* @param positioningType             定位类型* @param heightMeasurementMethod     测高方式* @param knownElevation              已知高程* @param serviceFrequency            服务频度*/public void positioningApplication(int confidentialityRequirements, int positioningType, int heightMeasurementMethod, int knownElevation, int antennaHeight, int serviceFrequency) throws IOException, InterruptedException {String data = "$PAPP" + "," + confidentialityRequirements + "," + positioningType + "," + knownElevation + "," + heightMeasurementMethod + "," + knownElevation + "," + antennaHeight + "," + serviceFrequency + ",";System.out.println(data);char checksum = checkSum(data);String str = data + checksum + "\r\n";outputStream.write(str.getBytes());outputStream.flush();}@Overridepublic void serialEvent(SerialPortEvent serialPortEvent) {if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {try {int availableBytes = inputStream.available();byte[] buffer = new byte[availableBytes];inputStream.read(buffer);// 处理接收到的数据String receivedData = new String(buffer);handleSerialPortData(receivedData);System.out.println("Received data: " + receivedData);} catch (IOException e) {e.printStackTrace();}}}private void handleSerialPortData(String response) {//加入自己的业务代码即可}}

声光报警器

以下为操作声光报警器的代码,提供给需要的小伙伴

public static void main(String[] args) {String portName = "COM3"; // 替换为您的串口号int baudRate = 9600; // 根据您的设备设置正确的波特率try {// 打开串口SerialPort serialPort = (SerialPort) CommPortIdentifier.getPortIdentifier(portName).open("SerialCommunicationExample", 2000);serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);// 获取输入输出流InputStream inputStream = serialPort.getInputStream();OutputStream outputStream = serialPort.getOutputStream();// 发送指令String hexCommand = "7EFF063A000101EF";byte[] commandBytes = hexStringToByteArray(hexCommand);outputStream.write(commandBytes);outputStream.flush();//            // 接收响应
//            byte[] buffer = new byte[1024];
//            int bytesRead = inputStream.read(buffer);
//            System.out.println("收到的数据" + bytesRead);
//            String response = byteArrayToHexString(buffer, bytesRead);
//            System.out.println("Received response: " + response);
//
//            // 关闭串口
//            serialPort.close();} catch (Exception e) {e.printStackTrace();}}// 将十六进制字符串转换为字节数组private static byte[] hexStringToByteArray(String hexString) {int len = hexString.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)+ Character.digit(hexString.charAt(i + 1), 16));}return data;}// 将字节数组转换为十六进制字符串private static String byteArrayToHexString(byte[] bytes, int length) {StringBuilder sb = new StringBuilder();for (int i = 0; i < length; i++) {sb.append(String.format("%02X", bytes[i]));}return sb.toString();}

相关文章:

Java串口开发

网上搜索了关于java串口开发的资料,发现都不是特别的全,故写下一些心得以帮助其他人能快速上手java串口开发,如有错漏之处&#xff0c;敬请指正 串口开发会用到一个javax.comm和RXTXcomm库,&#xff0c;javax.comm库不支持64位操作系统。该库仅适用于32位操作系统,所以接下来主…...

Python nohup 启动python脚本,后台没有日志

一、情况 1.linux上运行python脚本&#xff0c;前台运行打印日志&#xff0c;后台使用nohup不打印日志。 前台运行 ./xxx.py 后台运行 nohup python ./xxx.py > xxx.log 2>&1 &二、排查思路 2.1 脚本是否有问题 首先看自己写的python脚本是否存在问题。因为…...

完美解决微信小程序使用复选框van-checkbox无法选中

由于小程序使用了vant-ui框架&#xff0c;导致checkbox点击无法选中问题 <van-checkbox value"{{ checked }}" shape"square"><view class"check-content"><view class"checktext">我已阅读并同意>《用户协议》…...

IDEA报错:类文件具有错误的版本 61.0,应为52.0

springboot项目启动报错&#xff1a; 类文件具有错误的版本 61.0,应为52.0 请删除该文件或确保该文件位于正确的类路径子目录中 查阅了网上的很多资料&#xff0c;普遍原因说是springboot版本过高&#xff0c;高于3.0 需要在pom文件中降低版本 也有说是idea的maven配置java版…...

Linux 挂载局域网内共享目录

Linux 挂载局域网内共享目录 1、安装samba服务端2、samba服务端配置3、添加samba服务访问账户4、防火墙5、重启服务6、windows访问7、linux访问 1、安装samba服务端 sudo apt-get install -y samba yum install -y samba2、samba服务端配置 vim /etc/samba/smb.conf在文档尾部…...

FFmpeg解码32k大分辨率出现如下错误:Picture size 32768x32768 is invalid

最近找到一张32k的jpeg图片&#xff0c;尝试用ffmpeg来进行解码&#xff0c;命令如下&#xff1a; ffmpeg -i enflame_32768-32768-420.jpg 32.yuv结果出现Picture size 32768x32768 is invalid的错误&#xff1a; 找到报错的代码文件imgutils.c&#xff0c;以及函数&#x…...

EasyExcel+POI制作带有有效性校验及下拉联动的Excel模板

文章目录 1.背景2.实现功能的Excel特性2.1.特性介绍2.2.下拉框联动2.3.单元格自动匹配Id2.4.错误提示 3.代码实现3.1.基础流程代码3.2.名称管理器配置3.3.有效性配置3.4.函数填充3.5.其他补充 4.总结 1.背景 最近在做一个CRM系统的人员销售目标导入的相关需求&#xff0c;需要…...

Unity怎么制作魔法火焰特效?Unity制作魔法火焰特效方法

Unity制作魔法火焰特效方法&#xff1a; 在第一次玩Supergiant Games的RPG游戏《Hades》时&#xff0c;游戏的美术和视觉效果让人非常吃惊。受此启发&#xff0c;希望能够尝试制作类似风格的作品。 工作流程 整个工作从制作简单的火焰贴图开始。首先&#xff0c;我使用PhotoS…...

双基证券:房地产基本面仍处下行通道 政策有望促进走稳

摘要 【双基证券&#xff1a;房地产基本面仍处下行通道 方针有望促进走稳】双基证券表明&#xff0c;2023年5、6、7月商品房及二手房销量继续走弱&#xff0c;引发商场关注。咱们从各城市环线、住所户型、小区物业费的维度盯梢了房地产出售数据的走势&#xff0c;当前新房出售…...

31、springboot 配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口

配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口 ★ 设置HTTP服务端口&#xff1a; - server.port或者SERVER_PORT环境变量——总结来说&#xff0c;其实就是要配置server.port外部配置属性。▲ 同样遵守如下优先级&#xff1a; 这些都是外部配置源&#x…...

会计如何使用ChatGPT提高工作效率

文章目录 ChatGPT改变了会计行业微软重新定义了PC交互应对ChatGPT带来的冲击给财务人员的建议总结 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社…...

【TypeScript】类型推论和类型别名

类型推断 TypeScript 的类型推断是一种编译器能够自动分析代码并确定变量的类型的功能。它允许你在声明变量时省略类型注释&#xff0c;让 TypeScript 根据变量的值来推断出合适的类型。 以下是 TypeScript 类型推断的一些示例和情况&#xff1a; 基本类型推断&#xff1a; …...

字节码调教的入口 —— JVM 的寄生插件 javaagent 那些事

Java Instrumentation 包 Java Instrumentation 概述 Java Instrumentation 这个技术看起来非常神秘&#xff0c;很少有书会详细介绍。但是有很多工具是基于 Instrumentation 来实现的&#xff1a; APM 产品: pinpoint、skywalking、newrelic、听云的 APM 产品等都基于 Instru…...

Blender卡通着色入门

当想到 Blender 和 3D 设计时&#xff0c;你的想法可能会转向风格化渲染或照片级渲染和 VFX。 但是&#xff0c;你是否知道 Blender 还可以创建可与 2D 动漫风格和漫画书类似的图形&#xff1f; 推荐&#xff1a;用 [NSDT编辑器 快速搭建可编程3D场景 1、什么是卡通着色&#x…...

性能调优篇 一、Jvm监控及诊断工具-命令行篇

目录 一、概述1、简单命令行工具 二、jps&#xff1a;查看正在运行的Java程序1、是什么&#xff1f;2、测试3、基本语法 三、jstat&#xff1a;查看jvm统计信息 一、概述 性能诊断是软件工程师 1、简单命令行工具 二、jps&#xff1a;查看正在运行的Java程序 1、是什么&…...

Docker部署MongoDB 5.0.5

1、查看目录 rootwielun:~# tree mongo mongo ├── conf │ └── mongod.conf ├── data ├── docker-compose.yml └── logrootwielun:~# cd mongo rootwielun:~/mongo# chmod 777 log2、配置docker-compose.yml rootwielun:~/mongo# cat docker-compose.yml ve…...

Day18-2-地狱回调-Promise-async-await技术

文章目录 Promise技术一 回调函数二 异步任务三 回调地狱是什么?四 如何解决回调地狱1 PromisePromise基本用法使用Promise解决地狱回调2 async/awaitPromise技术 一 回调函数 当一个函数作为参数传入另一个函数中,并且它不会立即执行,只有当满足一定条件后该函数才可以执…...

echarts范围限制下性能问题

最近实习遇到一个问题&#xff0c;需要对折线图的数据进行范围限制&#xff0c;比如将超过100的设置为100&#xff0c;低于0的设置为0&#xff1b; 原来的代码是创建一个数组&#xff0c;然后遍历原数组&#xff0c;超过的push100&#xff0c;低于0的push0&#xff0c;在中间的…...

wazuh环境配置以及案例复现

目录 wazuh环境配置wazuh案例复现 wazuh环境配置 一、wazuh配置 1.1进入官网下载OVA启动软件 Virtual Machine (OVA) - Installation alternatives (wazuh.com) 1.2点击启动部署&#xff0c;傻瓜式操作 1.3通过账号&#xff1a;wazuh-user&#xff0c;密码&#xff1a;wazuh进…...

解决el-select回显异常 显示option选项的value 而不是显示label

1、问题 回显的value和选项value类型不同 form中v-model"form.userId"是字符串类型 option中:value“item.userId” 选项id是数字类型 2、办法 :value“item.userId” 改为 :value“item.iduserId‘’”&#xff08;转换成字符串&#xff09; <el-form-item l…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...