串口数据上传下发

技术交流群:233513714

 

 

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;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TooManyListenersException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.aotoso.control.Log.Log;
import com.aotoso.control.base.BaseController;
import com.aotoso.entity.FirstInformationManage.CarManageBean;
import com.aotoso.server.FirstInformationManage.CarManageService;
import com.aotoso.util.PageData;

/**
* 处理下发、串口上传的数据
*/
@Controller
@RequestMapping("/com")
public class PortCommunication extends BaseController implements SerialPortEventListener {
  // 获取串口
  public static SerialPort serialPort;
  // 创建输入流,用于获取串口传入的数据
  private InputStream inputStream;

  /**
  * 打开串口
  * @return
  */
  @RequestMapping(value = "/openCOM")
  public SerialPort OpenCOM(){
    System.out.println("打开串口");
    try {
      //找到串口名称为COM3的串口
      CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier("COM3");
      //设置串口通信名称(名称是随意命名的),阻塞时的毫秒数
      serialPort = (SerialPort)portIdentifier.open("TMR饲喂监控系统串口通信", 2000);
      //获取串口输入流
      inputStream = serialPort.getInputStream();
      //在打开串口的同时开启监听串口事件
      serialPort.addEventListener(this);
      //设置串口有数据的事件,当为true时有效
      serialPort.notifyOnDataAvailable(true);
      //设置串口通信参数,波特率9600、数据位8、停止位1、校验方式0表示无
      serialPort.setSerialPortParams(9600, 8, 1, 0);
      //设置流量控制为不受控制
      serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
      return serialPort;
    } catch (NoSuchPortException e) {
      System.out.println("端口不存在");
    } catch (PortInUseException e) {
      System.out.println("端口已经被占用");
    } catch (UnsupportedCommOperationException e) {
      System.out.println("端口操作命令不支持");
    } catch (TooManyListenersException e) {
      System.out.println("端口中数据读取异常");
    } catch (IOException e) {
      System.out.println("输入或输出异常");
    }
    return null;
  }

  /**
  * 关闭串口
  */
  @RequestMapping(value = "/CloseCom")
  public void CloseCom(){
    System.out.println("关闭串口");
    serialPort.close();
  }

  /**
  * 发送数据
  * @param by
  */
  public void outputInformationToTMR(byte[] by) {
    try{
      //准备一个输出流
      OutputStream outputStream = serialPort.getOutputStream();
      //向串口传送数据
      outputStream.write(by);
      //刷新此输出流并强制写出所有缓冲的输出字节
      outputStream.flush();
      //关闭输出流并释放所有和此流有关的系统资源
      outputStream.close();
    } catch (IOException e) {
      System.out.println("端口打开异常");
    }
  }

  /**
  * 监听串口(此方法继承自SerialPortEventListener)
  */
  @Override
  public void serialEvent(SerialPortEvent event) {
    switch (event.getEventType()) {
    case SerialPortEvent.BI: //通信中断
    case SerialPortEvent.OE: //溢位错误
    case SerialPortEvent.FE: //帧错误
    case SerialPortEvent.PE: //奇偶错误
    case SerialPortEvent.CD: //载波错误
    case SerialPortEvent.CTS: //清除发送
    case SerialPortEvent.DSR: //数据设备准备好
    case SerialPortEvent.RI: //振铃错误
    case SerialPortEvent.OUTPUT_BUFFER_EMPTY: //输出缓冲区已清空
      break;
    case SerialPortEvent.DATA_AVAILABLE: //有数据到达
      readCom();
      Log.LogForTXT("");
      break;
    }
  }

  /**
  * 接收串口中的数据
  */
  public void readCom(){
    try {
      //等待1毫秒,以便让数据读取完整
      Thread.sleep(100);
    } catch (InterruptedException e1) {
      e1.printStackTrace();
    }
    // buffer中的实际数据字节数
    int numBytes = 0;
    // 4k的buffer空间,缓存串口读入的数据
    byte[] readBuffer = new byte[4096];
    try {
      // 多次读取,将所有数据读入
      while (inputStream.available() > 0) {
        numBytes = inputStream.read(readBuffer);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(bytesToHexString(readBuffer));
  }

  /**
  * 将Hex格式的数据转换为16进制的字符串
  * @param by
  * @return string
  */
  public String bytesToHexString(byte[] by){
    StringBuilder stringBuilder = new StringBuilder("");
    for (int i = 0; i < by.length; i++) {
      int in = by[i] & 0xFF;
      String str = Integer.toHexString(in);
      if (str.length() < 2) {
        stringBuilder.append(0);
      }
      stringBuilder.append(str);
    }
    return stringBuilder.toString();
  }
}

posted @   大浪不惊涛  阅读(364)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
点击右上角即可分享
微信分享提示