Java读取串口数据
本文主要实现读取员工刷卡信息
将淘宝买的刷卡IC卡读取器插入Windows笔记本的USB接口,安装驱动,设备管理器会自动添加一个模拟的COM3串口
本次使用的Java环境为
java version “1.8.0_112”
Java™ SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot™ 64-Bit Server VM (build 25.112-b15, mixed mode)
1. 下载java读取串口的所需依赖
下载地址TXTX for Java
2. 将下载文件解压后dll文件放入jdk的jre文件中
rxtxParallel.dll
,rxtxSerial.dll
copy to C:\Program Files\Java\jdk1.8.0_112\jre\bin
3. 新建Java项目
我使用的是创建一个JavaFX项目,因为只是写一个Demo,JavaFX和Java项目区别不大
在项目中创建一个lib包,将下载的RXTXcomm.jar
文件放入lib包中,将lib包设置为项目资源
IDEA设置:右键RXTXcomm.jar
,选择Add as Library...
即可
4. 新建读取串口的工具SerialTool
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Locale;
import java.util.TooManyListenersException;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
public class SerialTool {/*** 查找所有可用端口* @return 可用端口名称列表*/public static final ArrayList<String> findPort() {//获得当前所有可用串口@SuppressWarnings("unchecked")Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();ArrayList<String> portNameList = new ArrayList<String>();//将可用串口名添加到List并返回该Listwhile (portList.hasMoreElements()) {String portName = portList.nextElement().getName();portNameList.add(portName);}return portNameList;}/*** 打开串口* @param portName 端口名称* @param baudrate 波特率* @return 串口对象*/public static final SerialPort openPort(String portName, int baudrate) {try {//通过端口名识别端口CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);//打开端口,并给端口名字和一个timeout(打开操作的超时时间)CommPort commPort = portIdentifier.open(portName, 2000);//判断是不是串口if (commPort instanceof SerialPort) {SerialPort serialPort = (SerialPort) commPort;try {//设置一下串口的波特率等参数serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);} catch (UnsupportedCommOperationException e) {throw new RuntimeException("设置串口参数失败!打开串口操作未完成!");}System.out.println("Open " + portName + " successfully !");return serialPort;}else {//不是串口throw new RuntimeException("端口指向设备不是串口类型");}} catch (NoSuchPortException e1) {throw new RuntimeException("没有该端口对应的串口设备");} catch (PortInUseException e2) {throw new RuntimeException("端口已被占用");}}/*** 关闭串口* @param serialPort 待关闭的串口对象*/public static void closePort(SerialPort serialPort) {if (serialPort != null) {serialPort.close();serialPort = null;}}/*** 往串口发送数据* @param serialPort 串口对象* @param order 待发送数据*/public static void sendToPort(SerialPort serialPort, byte[] order) {try (OutputStream out = serialPort.getOutputStream()){out.write(order);out.flush();} catch (IOException e) {e.printStackTrace();}}/*** 从串口读取数据* @param serialPort 当前已建立连接的SerialPort对象* @return 读取到的数据*/public static byte[] readFromPort(SerialPort serialPort) {InputStream in = null;byte[] bytes = null;try {in = serialPort.getInputStream();int bufflenth = in.available(); //获取buffer里的数据长度while (bufflenth != 0) {bytes = new byte[bufflenth]; //初始化byte数组为buffer中数据的长度in.read(bytes);bufflenth = in.available();}} catch (IOException e) {e.printStackTrace();System.err.println("从串口读取数据时出错");} finally {try {if (in != null) {in.close();in = null;}} catch(IOException e) {e.printStackTrace();System.err.println("关闭串口对象输入流出错");}}System.out.println("读取成功");return bytes;}/*** 添加监听器* @param port 串口对象* @param listener 串口监听器*/public static void addListener(SerialPort port, DataAvailableListener listener){try {//给串口添加监听器port.addEventListener(new SerialPortListener(listener));//设置当有数据到达时唤醒监听接收线程port.notifyOnDataAvailable(true);//设置当通信中断时唤醒中断线程port.notifyOnBreakInterrupt(true);} catch (TooManyListenersException e) {e.printStackTrace();System.err.println("监听类对象过多");}}/*** 串口监听*/public static class SerialPortListener implements SerialPortEventListener {private DataAvailableListener mDataAvailableListener;public SerialPortListener(DataAvailableListener mDataAvailableListener) {this.mDataAvailableListener = mDataAvailableListener;}public void serialEvent(SerialPortEvent serialPortEvent) {switch (serialPortEvent.getEventType()) {case SerialPortEvent.DATA_AVAILABLE: // 1.串口存在有效数据if (mDataAvailableListener != null) {mDataAvailableListener.dataAvailable();}break;case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2.输出缓冲区已清空break;case SerialPortEvent.CTS: // 3.清除待发送数据break;case SerialPortEvent.DSR: // 4.待发送数据准备好了break;case SerialPortEvent.RI: // 5.振铃指示break;case SerialPortEvent.CD: // 6.载波检测break;case SerialPortEvent.OE: // 7.溢位(溢出)错误break;case SerialPortEvent.PE: // 8.奇偶校验错误break;case SerialPortEvent.FE: // 9.帧错误break;case SerialPortEvent.BI: // 10.通讯中断System.out.println("与串口设备通讯中断");break;default:break;}}}/*** 串口存在有效数据监听*/public interface DataAvailableListener {/*** 串口存在有效数据*/void dataAvailable();}public static byte[] hex2Bytes(String hex) {if (hex == null || hex.length() == 0) {return null;}char[] hexChars = hex.toCharArray();byte[] bytes = new byte[hexChars.length / 2]; // 如果 hex 中的字符不是偶数个, 则忽略最后一个for (int i = 0; i < bytes.length; i++) {bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16);}return bytes;}/*** byte[]转十六进制字符串** @param array* byte[]* @return 十六进制字符串*/public static String byteArrayToHexString(byte[] array) {if (array == null) {return "";}StringBuffer buffer = new StringBuffer();for (int i = 0; i < array.length; i++) {buffer.append(byteToHex(array[i]));}return buffer.toString();}/*** byte转十六进制字符** @param b* byte* @return 十六进制字符*/public static String byteToHex(byte b) {String hex = Integer.toHexString(b & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}return hex.toUpperCase(Locale.getDefault());}public static String stringToAscii(String value){StringBuffer sbu = new StringBuffer();char[] chars = value.toCharArray();for (int i = 0; i < chars.length; i++) {if(i != chars.length - 1){sbu.append((int)chars[i]).append(",");}else {sbu.append((int)chars[i]);}}return sbu.toString();}
}
5. 读写串口测试
import gnu.io.SerialPort;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import sample.utils.*;import java.util.ArrayList;public class Controller {@FXMLButton writeButton;@FXMLTextArea readTextarea;@FXMLTextArea writeTextarea;@FXMLTextField comName;// 串口SerialPort port = null;/** 开启串口**/@FXMLpublic void startCom() {if(port != null){Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "串口已经打开:" + port.getName());alert.show();return;}ArrayList<String> findPorts = SerialTool.findPort();if(findPorts.isEmpty()){Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "未找到串口信息!");alert.show();return;}String portName = findPorts.get(0);//默认打开第一个串口// 设置使用的串口comName.setText(portName);try {port = SerialTool.openPort(portName, 9600);//打开串口} catch (RuntimeException e){Alert alert = new Alert(Alert.AlertType.ERROR, e.getMessage());alert.show();return;}SerialTool.addListener(port, () -> {byte[] data = null;try {if (port == null) {System.out.println("串口对象为空,监听失败!");} else {// 读取串口数据data = SerialTool.readFromPort(port);String resultHEX = SerialTool.byteArrayToHexString(data);readTextarea.setText(resultHEX);}} catch (Exception e) {Alert alert = new Alert(Alert.AlertType.ERROR, "发生了一个异常:".concat(e.getMessage()));alert.show();}});Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "串口开启成功!");alert.show();}/** 写入串口数据**/@FXMLpublic void writeCom() {if(port == null){Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "请先开启串口!");alert.show();return;}String content = writeTextarea.getText();if(content == null || content.trim().length() <=0){Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "请填写写入的数据!");alert.show();return;}//设定发送字符串byte[] bs = SerialTool.hex2Bytes(content);SerialTool.sendToPort(port, bs);//写入,写入应该在监听器打开之后而不是之前Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "写入成功!");alert.show();}
}
完成后实际界面如下:
6. 结尾
我写的demo源码地址
源码网盘下载地址 提取码:pz8i
参考文档-java串口通信demo
Java读取串口数据相关推荐
- java 读取串口数据
串口资料 链接:https://pan.baidu.com/s/1jVO47WF7pCO6kDLezsBZ0g 提取码:hgwn 这段时间遇到了读取串口数据的需求,吭哧吭哧搞了两三天才搞出来,惭愧,所 ...
- java获取已经打开的串口的输出流_使用Java读取串口的程序(转)
这个简单的程序包括以下文件: IMU.java (主程序) ReadBuffer.java (从缓冲区读取一个消息) ReadSerial.java (读取串口数据并放入缓冲区) SerialBuff ...
- RXTXcomm.jar 读取串口数据时报 Underlying input stream returned zero bytes 异常解决方法
RXTXcomm.jar 读取串口数据时报 Underlying input stream returned zero bytes 异常解决方法 一.示例程序 1.依赖 2.示例代码 3.测试读取文件 ...
- java读写串口数据
本博文参考自https://www.cnblogs.com/Dreamer-1/p/5523046.html 最近接触到了串口及其读写,在此记录java进行串口读写的过程. 1.导入串口支持包 需要下 ...
- 如何在QT中读取串口数据
总是能在别人的博客中学到太多太多,谢谢各位对知识的无私共享,谢谢大家 前言 去年我使用Qt编写串口通信程序时,将自己的学习过程写成了教程(Qt编写串口通信程序全程图文讲解),但是由于时间等原因,我只实 ...
- python串口通信_python 读取串口数据的示例
python3 读取串口数据 demo 最近在写一个demo,zigbee串口连接树莓派,树莓派使用串口通信接受zigbee穿过来得值.其中我是用的树莓派是3代B+,zigbee每隔三秒钟从串口输出数 ...
- linux java串口读写权限_解决linux下java读取串口之权限问题 No permission to create lock file. | 学步园...
在终端或IDE中运行java读取串口程序时,总是报告如下信息: [lhwtouch@localhost root]$ java Main Experimental: JNI_OnLoad called ...
- web前端读取串口数据
来自扫码枪应用适配的经验及扩展. 查了好多资料,发现实现思路不外乎以下几种: 1.使用服务端开发语言开发一个读取串口数据的本地服务模块,并实现websocket长连接支持,前端开启长连接到该服务,根据 ...
- python监听串口数据_python 读取串口数据的示例
python3 读取串口数据 demo 最近在写一个demo,zigbee串口连接树莓派,树莓派使用串口通信接受zigbee穿过来得值.其中我是用的树莓派是3代B+,zigbee每隔三秒钟从串口输出数 ...
最新文章
- [codevs 1913] 数字梯形问题
- FPGA设计心得(10)关于行为仿真的一点观点
- 泰尔指数r语言_还在用Excel算区位基尼系数?用geo.gini吧!
- 10月12日云栖精选夜读:【直击2017杭州·云栖大会】TECH INSIGHT企业迁云实战专场...
- java时序图工具_基于时序数据库,实现百亿级话单实时全景监控分析
- Codeforces Round #318 (Div. 2) B 	 Bear and Three Musketeers (暴力)
- java 文件下载,中文表名,中文内容
- 如何优雅的实现一个靠谱的RTSP播放器?
- SAP License:凭证冲销
- 读书-算法《程序设计导引及在线实践》-简单计算题1:鸡兔同笼
- GWR4软件怎么用+结果解读+结果在ArcGIS中可视化
- 一个清华学子写的关于directshow的学习心得
- JAVA中 万物皆对象
- android模拟器安装教程视频教程,安卓模拟器安装教程 安卓模拟器怎么安装
- Steam 界面布局出错的问题
- Tableau 南丁格尔玫瑰图
- 什么是SEO?SEO的区别在哪里?
- 诗歌赏析 - 兰花草
- Y400本本SSD装win10与机械硬盘上的系统组成双系统
- [内核分析]LXR安装心得(0.9.1版)
热门文章
- 让员工都是决策者!受到丰田集团启发:让企业少花500万的诀窍
- 善用思维导图来整理发散的思维
- HTML5 小练习1—仿MPG游戏商城
- 准大四生,现在是七月中旬,要为秋招准备什么?
- 程序员撩妹专用~~~好看的H5立方体创意相册,资源免费!!!程序员送给女孩子的礼物,非常适合送给小姐姐!
- linux 手机root原理,手机root原理
- SpringBoot-端点详解
- python联机麻将_python麻将和牌算法
- 大数据可视化大屏实例
- 高数_什么叫做方程的特解以及通解(微分方程)