串口数据上传下发
技术交流群: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();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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的强缓存和协商缓存
· 一文读懂知识蒸馏