CEM5861G-Dashboard 是一个基于 Vue3 开发的 CEM5861G 上位机,可实时可视化雷达数据,同时提供一个用户友好的界面来读取和设置雷达的各种运行参数

在线使用:https://cem.babyfang.cn
附件为离线版,打开 index.html 即可使用
核心组件介绍
App.vue
作为应用的根组件,负责整合所有子组件,并管理它们之间的数据流和事件通信。它维护一些全局状态,如最新接收到的数据、历史图表数据、日志消息以及参数响应等。
SerialPortControl.vue
这是与硬件进行串口通信的核心模块。它封装了 Web Serial API 的所有操作,包括连接、断开、数据读写以及最关键的数据帧解析。
数据帧解析
- 帧头识别:在接收到的字节流中查找帧头
0x55 0xA5。 - 长度解析:根据帧头后的两个字节解析出整个数据帧的长度。
- 校验和验证:计算接收到数据的校验和,并与帧尾的校验和进行比对,确保数据完整性和正确性。
- 功能码/命令码识别:根据帧的特定字节(功能码、命令码1、命令码2)识别数据帧的类型。
- 雷达主动上报数据帧 (
0x03 0x81 0x00):解析出目标 ID、状态、距离、速度、角度、信号强度等详细信息。解析后的结构化数据通过data-received事件发送给App.vue,最终由DataDisplay和ChartComponent使用。 - 雷达响应上位机命令帧 (
0x02): - 参数配置响应 (
0x02 0x80 xx):将原始数据字节(例如0x00 0xC8)提取出来,通过parameter-response事件发送给App.vue。 - 控制命令响应 (
0x02 0x20 xx):恢复默认参数、保存参数到 Flash 等命令的响应,发出command-response事件。 - 错误处理:处理校验和错误、帧长度不足、未知帧类型等异常情况,并发出日志和 Toast 提示。
ConfigPanel.vue
提供一个用户界面来显示和修改雷达的各项运行参数
使用 parameters 数组定义所有可配置的雷达参数,包括其 key 、 label 、 type (number/select)、 default 值、对应的读取命令 ( readCmd )、设置命令前缀 ( setCmdPrefix ) 和接收响应命令 ( receiveCmd )
readParameter(param)负责构建并发送指定参数的读取命令到串口setParameter(param)负责根据用户输入的参数值,构建包含数据和校验和的设置命令,发送到串口。它会根据参数类型(number或select) 和dataLength将数值转换为相应的字节序列(例如,将十进制 200 转换为0x00 0xC8)
数据处理流程详解
整个项目的数据处理流程可以概括为以下几个关键环节:
1. 串口连接与原始数据接收
-
触发:用户点击
SerialPortControl中的“连接串口”按钮。 -
过程:
SerialPortControl调用navigator.serial.requestPort()请求用户选择串口设备。- 成功后,
port.open()打开串口连接。 - 获取
reader和writer流,并通过reader.read()开始持续监听传入的原始字节流。
2. 字节流到数据帧的组装与校验
-
模块:
SerialPortControl.vue的readData方法。 -
过程:
- 接收到的字节会不断追加到一个
receivedBuffer(Uint8Array) 中。 - 循环检查
receivedBuffer,查找特定的帧头 (0x55 0xA5)。 - 一旦找到帧头,根据帧头后的数据长度字段 (
receivedBuffer[2] << 8) | receivedBuffer[3]),计算出完整的帧长度。 - 检查
receivedBuffer中是否已有足够的数据构成完整帧。 - 如果数据足够,截取完整帧,并计算其校验和。
- 将计算出的校验和与接收到的帧尾校验和进行比对。
- 成功:将完整的、校验和正确的帧传递给
parseFrame方法进行进一步解析。 - 失败:记录校验和错误或帧格式错误日志,并从
receivedBuffer中移除当前帧(或只移除一个字节继续查找,以避免死循环)。
- 接收到的字节会不断追加到一个
-
输出:一个或多个完整且校验和正确的二进制数据帧 (
Uint8Array)。
3. 数据帧的结构化解析
-
模块:
SerialPortControl.vue的parseFrame方法。 -
过程:
-
接收一个完整的二进制数据帧。
-
从帧中提取出功能码 (
frame[4])、命令码1 (frame[5]) 和命令码2 (frame[6]),以及实际的数据部分。 -
根据功能码和命令码判断帧的类型:
-
主动上报数据帧 (
0x03 0x81 0x00):将数据部分按照雷达协议的定义(例如,距离占 2 字节,速度占 2 字节等)解析成对应的十进制数值、符号数等。 -
命令响应帧 (
0x02):- 如果是参数配置响应 (
0x02 0x80 xx),直接提取其数据部分字节(例如[0x00, 0xC8]),封装成一个对象,并通过parameter-response事件发送。 - 如果是控制命令响应 (
0x02 0x20 xx),则根据命令码2判断是哪种控制命令的响应,并根据协议判断响应状态(通常数据部分为0x01表示成功)。
- 如果是参数配置响应 (
-
-
发出相应的事件 (
data-received,parameter-response,command-response),将解析后的结构化数据或原始数据部分传递给App.vue。
-
-
输出:
- 结构化雷达目标数据对象(例如
{ distance: 200, speed: 50, ... }) - 参数响应数据对象(例如
{ functionCode: 0x02, commandCode1: 0x80, commandCode2: 0x03, data: Uint8Array([0x00, 0xC8]) }) - 控制命令响应状态(例如
{ status: 'SUCCESS', commandName: 'OTA' })
- 结构化雷达目标数据对象(例如
4. 数据在组件间的传递与更新
-
模块:
App.vue作为中央事件总线和数据管理器。 -
过程:
-
App.vue接收到SerialPortControl发出的各种事件:data-received-> 更新latestReceivedData(ref),并添加到historyChartData(ref) 数组。parameter-response-> 更新lastParameterResponse(ref)。command-response-> 处理控制命令的响应,触发 Toast 提示。log-message-> 添加到allLogMessages(ref) 数组。show-toast-> 调用showToast函数显示 Toast。
-
这些
ref变量的变化会触发 Vue 的响应式系统。
-
5. UI 更新与数据展示
-
模块:
DataDisplay.vue,ChartComponent.vue,LogDisplay.vue,ConfigPanel.vue。 -
过程:
DataDisplay接收latestDataprop,当latestData变化时,其模板会自动更新,显示最新的雷达数据。ChartComponent接收chartDataprop,当chartData数组变化时,它会重新渲染或更新图表,展示历史数据趋势。LogDisplay接收logMessagesprop,当新日志添加时,列表会自动更新。ConfigPanel中的watch监听props.parameterResponse。当lastParameterResponse在App.vue中更新时,ConfigPanel会收到新值。ConfigPanel内部会根据响应的functionCode、commandCode1、commandCode2找到对应的参数,并解析newResponse.data中的字节数据(例如0x00 0xC8会被解析为十进制的 200),然后直接更新parameters数组中该参数的value属性(例如matchedParam.value = parsedValue;)。- 由于
ConfigPanel模板中的输入框是使用v-model.number="param.value"绑定到parameters数组中对象的value属性,当matchedParam.value更新时,Vue 的响应式系统会自动检测到这个变化,并自动填充输入框。 - 所有组件发出的
show-toast事件最终都会被App.vue捕获,并通过Toastify-JS库在右上角显示弹出消息。
6. 数据发送与参数设置
-
触发:用户在
ConfigPanel中点击“读取”或“设置”按钮。 -
过程:
ConfigPanel根据用户选择的参数和输入的值,结合预定义的命令前缀,构建完整的二进制命令数据包(包括数据字节和校验和)。ConfigPanel发出send-serial-data事件,将要发送的Uint8Array数据传递给App.vue。App.vue接收到事件后,调用serialControlRef.value.sendData()方法,将数据转发给SerialPortControl。SerialPortControl的sendData方法通过writer.value.write(data)将二进制数据写入串口。
开源
https://github.com/klxf/CEM5861G-Dashboard
本项目使用 Apache License 2.0 许可协议开源,你可以自由使用、修改和分发本项目的代码,但需要遵守该协议的条款。


全部评论