公司需要使用串口来进行通讯,但是之前又不了解串口,于是网上查找资料后,找到如下代码,使用的jdk版本太高好像是不可以的;


代码示例

pom文件

     <dependency><groupId>org.rxtx</groupId><artifactId>rxtx</artifactId><version>2.1.7</version></dependency>

SerialPortUtil

public class SerialPortUtil {private static final Logger logger = LoggerFactory.getLogger(SerialPortUtil.class);private static SerialPortUtil serialPortUtil = null;static {//在该类被ClassLoader加载时就初始化一个SerialTool对象serialPortUtil = new SerialPortUtil();}public SerialPortUtil() {}/*** 获取提供服务的SerialTool对象* @return serialPortUtil*/public static SerialPortUtil getSerialPortUtil() {if (serialPortUtil == null) {serialPortUtil = new SerialPortUtil();}return serialPortUtil;}/*** 查找所有可用端口* @return 可用端口名称列表*/public ArrayList<String> findPort() {//获得当前所有可用串口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 波特率  19200* @param databits 数据位  8* @param parity   校验位(奇偶位)  NONE :0* @param stopbits 停止位 1* @return 串口对象* //     * @throws SerialPortParameterFailure 设置串口参数失败* //     * @throws NotASerialPort             端口指向设备不是串口类型* //     * @throws NoSuchPort                 没有该端口对应的串口设备* //     * @throws PortInUse                  端口已被占用*/public SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbits) {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, databits, stopbits, parity);} catch (UnsupportedCommOperationException e) {}System.out.println("Open " + portName + " sucessfully !");return serialPort;} else {logger.error("不是串口");}} catch (NoSuchPortException e1) {logger.error("没有找到端口");e1.printStackTrace();} catch (PortInUseException e2) {logger.error("端口被占用");e2.printStackTrace();}return null;}/*** 关闭串口* @param serialPort 待关闭的串口对象*/public void closePort(SerialPort serialPort) {if (serialPort != null) {serialPort.close();}}/*** 往串口发送数据* @param serialPort 串口对象* @param order      待发送数据* //       * @throws SendDataToSerialPortFailure        向串口发送数据失败* //       * @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错*/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();}}}/*** 从串口读取数据* @param serialPort 当前已建立连接的SerialPort对象* @return 读取到的数据* //     * @throws ReadDataFromSerialPortFailure     从串口读取数据时出错* //     * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错*/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 {if (in != null) {in.close();}} catch (IOException e) {e.printStackTrace();}}return bytes;}/*** 添加监听器* @param port     串口对象* @param listener 串口监听器* //     * @throws TooManyListeners 监听类对象过多*/public void addListener(SerialPort port, SerialPortEventListener listener) {try {//给串口添加监听器port.addEventListener(listener);//设置当有数据到达时唤醒监听接收线程port.notifyOnDataAvailable(true);//设置当通信中断时唤醒中断线程port.notifyOnBreakInterrupt(true);} catch (TooManyListenersException e) {
//            throw new TooManyListeners();logger.error("太多监听器");e.printStackTrace();}}/*** 删除监听器* @param port     串口对象* @param listener 串口监听器* //     * @throws TooManyListeners 监听类对象过多*/public void removeListener(SerialPort port, SerialPortEventListener listener) {//删除串口监听器port.removeEventListener();}/*** 设置串口的Listener* @author mar* @date 2021/8/20 11:04* @param serialPort* @param listener*/public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener){try {//给串口添加事件监听serialPort.addEventListener(listener);} catch (TooManyListenersException e) {e.printStackTrace();}//串口有数据监听serialPort.notifyOnDataAvailable(true);//中断事件监听serialPort.notifyOnBreakInterrupt(true);}
}

MyLister

import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import lombok.SneakyThrows;import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Date;public class MyLister implements SerialPortEventListener {@SneakyThrows@Overridepublic void serialEvent(SerialPortEvent arg0) {if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();byte[] bytes = serialPortUtil.readFromPort(PortInit.serialPort);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() + "【字节数组转16进制字符串】:-----" + needData);System.out.println(new Date() + "【16进制字符串转字符串】:" + hexStringToString(needData));System.out.println("===========end===========");}}/*** 字节数组转16进制字符串* @param b 字节数组* @return 16进制字符串*/public static String printHexString(byte[] b) {StringBuilder sbf = new StringBuilder();for (byte value : b) {String hex = Integer.toHexString(value & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sbf.append(hex.toUpperCase()).append(" ");}return sbf.toString().trim();}/*** 十六进制字符串转byte[]* @param hex 十六进制字符串* @return byte[]*/public static byte[] hexStr2Byte(String hex) {if (hex == null) {return new byte[] {};}// 奇数位补0if (hex.length() % StaticConstant.TWO != 0) {hex = "0" + hex;}int length = hex.length();ByteBuffer buffer = ByteBuffer.allocate(length / 2);for (int i = 0; i < length; i++) {String hexStr = hex.charAt(i) + "";i++;hexStr += hex.charAt(i);byte b = (byte) Integer.parseInt(hexStr, 16);buffer.put(b);}return buffer.array();}/*** 16进制转换成为string类型字符串* @param s 待转换字符串*/public static String hexStringToString(String s) {if (s == null || "".equals(s)) {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, StandardCharsets.UTF_8);} catch (Exception e1) {e1.printStackTrace();}return s;}}

打开串口的方法:使用map存储串口,将COM设置为key,SerialPort设为对应的value,这样就可以存储打开的多个串口。

    public static SerialPort serialPort = null;public static Map<String,SerialPort> map = new HashMap<>();.@Autowiredprivate SerialPortUtil serialPortUtil;/*** 打开串口* @param comValue 串口名称COMX* @param baudRate 波特率* @return*/public int openSerial(String comValue, Integer baudRate){try {serialPort = serialPortUtil.openPort(comValue, baudRate, SerialPort.DATABITS_8, SerialPort.PARITY_NONE, SerialPort.PARITY_ODD);serialPortUtil.addListener(serialPort, new MyLister());map.put(comValue,serialPort);serialPort = null;return 200;} catch (Exception e) {return 400;}}

关闭串口的方法:根据COM值,找到之前存放在map中的SerialPort然后进行关闭,关闭后删除map中的本次对应的值

 public int closeSerial(String comValue) {try {final SerialPort serialPort = map.get(comValue);SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();System.out.println("准备关闭:"+serialPort);serialPortUtil.removeListener(serialPort, new MyLister());serialPortUtil.closePort(serialPort);map.keySet().removeIf(key -> key.equals(comValue));System.out.println("关闭串口:"+serialPort+"成功!");return 200;}catch (Exception e){return 400;}}

关闭项目时,销毁所有已打开的端口(需要放在启动类下面,XXX为你存储map的类名)

    @PreDestroypublic void destory() {//关闭应用前 关闭端口SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();for (SerialPort serialPort:XXX.map.values()) {serialPortUtil.removeListener(serialPort, new MyLister());serialPortUtil.closePort(serialPort);System.out.println("关闭"+serialPort+"成功!");}}

小白第一次,打开端口,关闭端口在原博主的代码上更改了一些,有Bug的话,可以指出,我再学习学习!

​​​​​​​​​​​​​​原文链接http://t.csdn.cn/9GIqU

使用java操控串口相关推荐

  1. 利用Java实现串口全双工通讯

    一个嵌入式系统通常需要通过串口与其主控系统进行全双工通讯,譬如一个流水线控制系统需要不断的接受从主控系统发送来的查询和控制信息,并将执行结果或查询结果发送回主控系统.本文介绍了一个简单的通过串口实现全 ...

  2. java linux 串口_Linux Java 串口通信 | 学步园

    费了好大的劲搞定Linux系统上用Java写串口通信的问题. jdk中没有原生的串口api,网上找了半天的资料,大概知道了:Linux系统上用Java写串口程序,有两个包比较常用,一个是当年sun官方 ...

  3. Java实现串口通信的小样例

    用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip.当中要用到三个文件,配置例如以下: 1.comm.jar放置到 JAVA_HOME ...

  4. java 全双工服务器_利用Java实现串口全双工通讯_JAVA实例教程_IT部落

    本文介绍了一个简单的通过串口实现全双工通讯的Java类库,该类库大大的简化了对串口进行操作的过程 一个嵌入式系统通常需要通过串口与其主控系统进行全双工通讯,譬如一个流水线控制系统需要不断的接受从主控系 ...

  5. java获取已经打开的串口的输出流_使用Java读取串口的程序(转)

    这个简单的程序包括以下文件: IMU.java (主程序) ReadBuffer.java (从缓冲区读取一个消息) ReadSerial.java (读取串口数据并放入缓冲区) SerialBuff ...

  6. linux java串口读写权限_解决linux下java读取串口之权限问题 No permission to create lock file. | 学步园...

    在终端或IDE中运行java读取串口程序时,总是报告如下信息: [lhwtouch@localhost root]$ java Main Experimental: JNI_OnLoad called ...

  7. java串口发送十六进制数,本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下1.介绍使用Java实现的串口通信程序,支持十六进制数据的发送与接收。 源码:...

    本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下 1.介绍 使用Java实现的串口通信程序,支持十六进制数据的发送与接收. 源码:SerialPortDemo 效果图如下: ...

  8. Java读取串口数据

    本文主要实现读取员工刷卡信息 将淘宝买的刷卡IC卡读取器插入Windows笔记本的USB接口,安装驱动,设备管理器会自动添加一个模拟的COM3串口 本次使用的Java环境为 java version ...

  9. java 采用串口通信实现LED屏发送数据中文乱码问题

    java 采用串口通信实现LED屏发送数据中文乱码问题 1.定义:Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(1024)) ...

最新文章

  1. 双圆弧插值算法(三,代码实现)
  2. Redis 很屌,不懂使用规范就糟蹋了
  3. 高斯混合模型图像聚类、图像生成、可视化分析实战
  4. 【jQuery】复选框的全选、反选,推断哪些复选框被选中
  5. 为什么说下一个十年的主战场在Serverless?
  6. linux为已有磁盘扩容 kvm,KVM虚拟磁盘扩容
  7. 多商铺购物车查询 排除重复商家
  8. zookeeper:Too many connections 故障处理记录
  9. Docker大书房:什么是Docker?怎么用?
  10. 【Linux】五分钟搞定 Linux 文档全部知识,就看这篇文章
  11. linux安装python3环境_linux安装python3环境并配置虚拟环境
  12. java mvc接收json_java相关:SpringMVC中controller接收json数据的方法
  13. 唯美毕业论文答辩PPT模板
  14. python利用PIL及openpyxl实现图片转为excel表格
  15. Javascript DOM readyState 属性
  16. 如何计算做T的收益?
  17. 2022年第三次面试,含泪整理万字面试题。
  18. Java 程序员 5 家大厂的面试总结(已拿Offer)
  19. SIM800C使用HTTPS进行GET
  20. 鸿蒙系统10月上市,科技六点半 : 鸿蒙系统 10 月上市 / 国行 Switch 在路上

热门文章

  1. EXCEL如何直接sum() 或 average() 一些存在错误值的列?
  2. 瞎搞系列-超分辨率进程
  3. 山西寿阳一中2021年高考成绩查询,寿阳大小事┃2018年寿阳一中高考情况,再创历史新高!...
  4. Java web 服务器连接MySQL数据库代码
  5. python3 for循环怎么用_python遍历循环 python三个for循环怎么使用
  6. 微信登录分享不回调WXEntryActivity
  7. 国仁网络资讯:短视频运营中各种常见的拍摄手法,一一揭秘。
  8. Asp.Net MVC实现优酷(youku)Web的上传
  9. ros中cpp节点创建
  10. JDK1.8安装以及环境变量配置(win10)