• 使用Java进行串口SerialPort通讯


    1.准备工作

           在进行串口连接通讯前,必须保证你当前操作电脑上有可用且闲置的串口。因为一般的电脑上只有一个或者两个串口,如COM1或COM2,但大多数情况下,这些串口可能会被其他的程序或者应用所占用,所以此时我们可以借助工具,在我们的电脑上建立虚拟串口。
           先下载一个叫Virtual Serial Port的软件,通过这个软件可以创建新的虚拟串口,如下图所示:
    通过图中的添加串口即可进行新虚拟串口的创建,并且一般都是成对创建。
     
    有了虚拟串口之后,为了方便测试新建串口是否可用,我们可以再下载一款串口测试软件,我用的是一个串口调试助手,如下图:
    通过测试,发现我所添加的虚拟串口COM3和COM4是可以用的,那么接下来,我们就可以关闭其中一个,通过我们的JAVA程序来进行与该虚拟串口的信息交互了。
     

     

    2.JAVA程序的操作

    在进行程序编写之前,我们需要下载几个文件,才能使我们的程序进行串口通讯的操作。
         首先需要下载如下图中的三个文件:
    并将RXTXcomm.jar这个包通过集成工具的构建路径添加到我们的项目之中;其次将 rxtxParallel.dll 和 rxtxSerial.dll 这两个文件放到我们的JDK安装目录中的bin文件夹中。
         这两个文件必须添加到指定位置,否则后面程序在运行时将会报错找不到文件。(需要注意:这几个文件按操作系统分32位和64位,各位需要根据自己电脑的系统下载对应的版本,不然也会报错).
     
    接下来可以开始我们的代码编写了,为了方便使用,我们肯定是需要有一个SerialPort串口工具类,如下:
    1.  
      package com.cams.CaMSMobileService.SerialPort;
    2.  
       
    3.  
      import gnu.io.CommPort;
    4.  
      import gnu.io.CommPortIdentifier;
    5.  
      import gnu.io.NoSuchPortException;
    6.  
      import gnu.io.PortInUseException;
    7.  
      import gnu.io.SerialPort;
    8.  
      import gnu.io.SerialPortEventListener;
    9.  
      import gnu.io.UnsupportedCommOperationException;
    10.  
       
    11.  
      import java.io.IOException;
    12.  
      import java.io.InputStream;
    13.  
      import java.io.OutputStream;
    14.  
      import java.util.ArrayList;
    15.  
      import java.util.Enumeration;
    16.  
      import java.util.TooManyListenersException;
    17.  
       
    18.  
      import com.cams.CaMSMobileService.SerialPort.exception.NoSuchPort;
    19.  
      import com.cams.CaMSMobileService.SerialPort.exception.NotASerialPort;
    20.  
      import com.cams.CaMSMobileService.SerialPort.exception.PortInUse;
    21.  
      import com.cams.CaMSMobileService.SerialPort.exception.ReadDataFromSerialPortFailure;
    22.  
      import com.cams.CaMSMobileService.SerialPort.exception.SendDataToSerialPortFailure;
    23.  
      import com.cams.CaMSMobileService.SerialPort.exception.SerialPortInputStreamCloseFailure;
    24.  
      import com.cams.CaMSMobileService.SerialPort.exception.SerialPortOutputStreamCloseFailure;
    25.  
      import com.cams.CaMSMobileService.SerialPort.exception.SerialPortParameterFailure;
    26.  
      import com.cams.CaMSMobileService.SerialPort.exception.TooManyListeners;
    27.  
       
    28.  
      public class SerialPortManager {
    29.  
       
    30.  
      /**
    31.  
      * 查找所有可用端口
    32.  
      *
    33.  
      * @return 可用端口名称列表
    34.  
      */
    35.  
      @SuppressWarnings("unchecked")
    36.  
      public static final ArrayList<String> findPort() {
    37.  
      // 获得当前所有可用串口
    38.  
      Enumeration<CommPortIdentifier> portList = CommPortIdentifier
    39.  
      .getPortIdentifiers();
    40.  
      ArrayList<String> portNameList = new ArrayList<String>();
    41.  
      // 将可用串口名添加到List并返回该List
    42.  
      while (portList.hasMoreElements()) {
    43.  
      String portName = portList.nextElement().getName();
    44.  
      portNameList.add(portName);
    45.  
      }
    46.  
      return portNameList;
    47.  
      }
    48.  
       
    49.  
      /**
    50.  
      * 打开串口
    51.  
      *
    52.  
      * @param portName
    53.  
      * 端口名称
    54.  
      * @param baudrate
    55.  
      * 波特率
    56.  
      * @return 串口对象
    57.  
      * @throws SerialPortParameterFailure
    58.  
      * 设置串口参数失败
    59.  
      * @throws NotASerialPort
    60.  
      * 端口指向设备不是串口类型
    61.  
      * @throws NoSuchPort
    62.  
      * 没有该端口对应的串口设备
    63.  
      * @throws PortInUse
    64.  
      * 端口已被占用
    65.  
      */
    66.  
      public static final SerialPort openPort(String portName, int baudrate)
    67.  
      throws SerialPortParameterFailure, NotASerialPort, NoSuchPort,
    68.  
      PortInUse {
    69.  
      try {
    70.  
      // 通过端口名识别端口
    71.  
      CommPortIdentifier portIdentifier = CommPortIdentifier
    72.  
      .getPortIdentifier(portName);
    73.  
      // 打开端口,设置端口名与timeout(打开操作的超时时间)
    74.  
      CommPort commPort = portIdentifier.open(portName, 2000);
    75.  
      // 判断是不是串口
    76.  
      if (commPort instanceof SerialPort) {
    77.  
      SerialPort serialPort = (SerialPort) commPort;
    78.  
       
    79.  
      try {
    80.  
      // 设置串口的波特率等参数
    81.  
      serialPort.setSerialPortParams(baudrate,
    82.  
      SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
    83.  
      SerialPort.PARITY_NONE);
    84.  
      } catch (UnsupportedCommOperationException e) {
    85.  
      throw new SerialPortParameterFailure();
    86.  
      }
    87.  
      return serialPort;
    88.  
      } else {
    89.  
      // 不是串口
    90.  
      throw new NotASerialPort();
    91.  
      }
    92.  
      } catch (NoSuchPortException e1) {
    93.  
      throw new NoSuchPort();
    94.  
      } catch (PortInUseException e2) {
    95.  
      throw new PortInUse();
    96.  
      }
    97.  
      }
    98.  
       
    99.  
      /**
    100.  
      * 关闭串口
    101.  
      *
    102.  
      * @param serialport
    103.  
      * 待关闭的串口对象
    104.  
      */
    105.  
      public static void closePort(SerialPort serialPort) {
    106.  
      if (serialPort != null) {
    107.  
      serialPort.close();
    108.  
      serialPort = null;
    109.  
      }
    110.  
      }
    111.  
       
    112.  
      /**
    113.  
      * 向串口发送数据
    114.  
      *
    115.  
      * @param serialPort
    116.  
      * 串口对象
    117.  
      * @param order
    118.  
      * 待发送数据
    119.  
      * @throws SendDataToSerialPortFailure
    120.  
      * 向串口发送数据失败
    121.  
      * @throws SerialPortOutputStreamCloseFailure
    122.  
      * 关闭串口对象的输出流出错
    123.  
      */
    124.  
      public static void sendToPort(SerialPort serialPort, byte[] order)
    125.  
      throws SendDataToSerialPortFailure,
    126.  
      SerialPortOutputStreamCloseFailure {
    127.  
      OutputStream out = null;
    128.  
      try {
    129.  
      out = serialPort.getOutputStream();
    130.  
      out.write(order);
    131.  
      out.flush();
    132.  
      } catch (IOException e) {
    133.  
      throw new SendDataToSerialPortFailure();
    134.  
      } finally {
    135.  
      try {
    136.  
      if (out != null) {
    137.  
      out.close();
    138.  
      out = null;
    139.  
      }
    140.  
      } catch (IOException e) {
    141.  
      throw new SerialPortOutputStreamCloseFailure();
    142.  
      }
    143.  
      }
    144.  
      }
    145.  
       
    146.  
      /**
    147.  
      * 从串口读取数据
    148.  
      *
    149.  
      * @param serialPort
    150.  
      * 当前已建立连接的SerialPort对象
    151.  
      * @return 读取到的数据
    152.  
      * @throws ReadDataFromSerialPortFailure
    153.  
      * 从串口读取数据时出错
    154.  
      * @throws SerialPortInputStreamCloseFailure
    155.  
      * 关闭串口对象输入流出错
    156.  
      */
    157.  
      public static byte[] readFromPort(SerialPort serialPort)
    158.  
      throws ReadDataFromSerialPortFailure,
    159.  
      SerialPortInputStreamCloseFailure {
    160.  
      InputStream in = null;
    161.  
      byte[] bytes = null;
    162.  
      try {
    163.  
      in = serialPort.getInputStream();
    164.  
      // 获取buffer里的数据长度
    165.  
      int bufflenth = in.available();
    166.  
      while (bufflenth != 0) {
    167.  
      // 初始化byte数组为buffer中数据的长度
    168.  
      bytes = new byte[bufflenth];
    169.  
      in.read(bytes);
    170.  
      bufflenth = in.available();
    171.  
      }
    172.  
      } catch (IOException e) {
    173.  
      throw new ReadDataFromSerialPortFailure();
    174.  
      } finally {
    175.  
      try {
    176.  
      if (in != null) {
    177.  
      in.close();
    178.  
      in = null;
    179.  
      }
    180.  
      } catch (IOException e) {
    181.  
      throw new SerialPortInputStreamCloseFailure();
    182.  
      }
    183.  
      }
    184.  
      return bytes;
    185.  
      }
    186.  
       
    187.  
      /**
    188.  
      * 添加监听器
    189.  
      *
    190.  
      * @param port
    191.  
      * 串口对象
    192.  
      * @param listener
    193.  
      * 串口监听器
    194.  
      * @throws TooManyListeners
    195.  
      * 监听类对象过多
    196.  
      */
    197.  
      public static void addListener(SerialPort port,
    198.  
      SerialPortEventListener listener) throws TooManyListeners {
    199.  
      try {
    200.  
      // 给串口添加监听器
    201.  
      port.addEventListener(listener);
    202.  
      // 设置当有数据到达时唤醒监听接收线程
    203.  
      port.notifyOnDataAvailable(true);
    204.  
      // 设置当通信中断时唤醒中断线程
    205.  
      port.notifyOnBreakInterrupt(true);
    206.  
      } catch (TooManyListenersException e) {
    207.  
      throw new TooManyListeners();
    208.  
      }
    209.  
      }
    210.  
      }
    有了工具类之后,接下来我们就可以开始测试串口通讯了,如下:
     
    到这里串口通讯测试的也差不多了。可能自己做的项目中需要自己做两个串口,一个client端和一个server端。为了使串口操作变的可视化,大家也可以使用JFrame来进行操作窗口模拟,这里就不做多的介绍了。
  • 相关阅读:
    关于vue无法侦听数组及对象属性的变化的解决方案
    web js导出csv 文件(使用a标签)
    微信小程序-获取用户信息和openid,session_key,
    H5适配 iponex
    项目使用iconfont图标
    锚点链接,组件库中锚点实现
    前端的调试工具和node调试工具
    前端模块化 CommonJS AMD CMD ES6
    支付宝小程序
    个人创用 UA 列表
  • 原文地址:https://www.cnblogs.com/soundcode/p/9392110.html
Copyright © 2020-2023  润新知