Files
balance-board/README.md
T
pNexus 5492a98687 feat(gml670-v2): 添加工程骨架与构建配置
基于 V1 副本新建 V2 工程,包含 CMakeLists.txt、Kconfig、prj.conf、
app.overlay、README.md 及 ADS1256/GML670 参考数据手册。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 17:36:39 +08:00

280 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GML670 Balance Board
> 当前目录是 `GML670x4_V1`。代码内的 CMake 项目名为 `GML670_V2`BLE 设备名为 `GML670_System`。
>
> 本文档是当前工程的总入口说明,重点覆盖已落地的固件行为。更细的协议字段和示例帧见 [BALANCE_BOARD_PROTOCOL.md](./BALANCE_BOARD_PROTOCOL.md)。
---
## 目录
1. [产品概述](#1-产品概述)
2. [硬件组成](#2-硬件组成)
3. [系统架构](#3-系统架构)
4. [功能需求与当前状态](#4-功能需求与当前状态)
5. [BLE 协议规格](#5-ble-协议规格)
6. [ADS1256 / CoP 规格](#6-ads1256--cop-规格)
7. [开发环境与板级配置](#7-开发环境与板级配置)
8. [项目结构](#8-项目结构)
9. [构建与烧录](#9-构建与烧录)
10. [日志与当前约束](#10-日志与当前约束)
---
## 1. 产品概述
本工程是平衡板的 nRF5340 App Core 固件,当前版本的核心能力是:
- 通过 ADS1256 轮询 4 路传感器输入
- 在板端完成去皮、中值滤波和 CoPCenter of Pressure,压力中心)解算
- 通过 BLE NUS 以二进制帧持续上报 CoP 数据
- 接收基站下发的阻力参数、Spotter 模式和心跳帧
当前实现的上行主数据是固定 17 字节的 CoP 帧,发送频率为 50 Hz。阻力、Spotter、Heartbeat 的下行协议已经接入接收路径,但控制逻辑还没有继续向执行器或保护动作落地。
## 2. 硬件组成
当前仓库里能直接确认的硬件如下:
| 器件 | 型号 / 对象 | 接口 | 作用 | 状态 |
|------|-------------|------|------|------|
| 主控 | nRF5340 DK App Core | - | 运行 BLE、SPI 采样和 CoP 解算 | ✅ |
| ADC | ADS1256 | SPI1 | 4 路多通道采样 | ✅ |
| 传感器输入 | 4 路差分输入 | ADS1256 MUX | 用于压力类信号采样 | ✅ |
| 基站链路 | Nordic UART Service | BLE | 上报 CoP、接收控制参数 | ✅ |
| 编码器链路 | 预留 | BLE 协议 | 编码器上行帧结构已定义,固件未发送 | 🔲 |
### ADS1256 相关引脚
`app.overlay` 当前把 ADS1256 绑定到 `spi1`,连线如下:
| 信号 | nRF5340 引脚 | 说明 |
|------|--------------|------|
| SCK | `P1.15` | `spi1` 时钟 |
| MOSI | `P1.13` | `spi1` 主发从收 |
| MISO | `P1.14` | `spi1` 主收从发 |
| CS | `P1.12` | 片选,`GPIO_ACTIVE_LOW` |
| DRDY | `P1.11` | 数据就绪输入 |
| RESET | `P1.10` | ADS1256 复位控制 |
## 3. 系统架构
```text
4 路传感器输入
|
v
ADS1256
|
v
SPI1
|
v
nRF5340 App Core
|
+--> tare / 7 点中值滤波 / CoP 解算
|
+--> BLE NUS Notify --> 基站
|
+<-- BLE NUS Write <-- 基站
| | |
| | +-- Heartbeat
| +------------ Spotter 参数
+--------------------- Resistance 参数
```
当前主循环完成 4 路轮询采样、滤波、CoP 解算和上行发送。下行方向只负责解析三类控制帧并保存参数,参数接收后会记录到内存并打印日志,不会继续驱动执行机构。
## 4. 功能需求与当前状态
### 4.1 采样与解算
| 项目 | 说明 | 状态 |
|------|------|------|
| 4 路轮询采样 | 通过 ADS1256 MUX 依次读取 `0x01 / 0x23 / 0x45 / 0x67` 四组通道 | ✅ |
| tare 去皮 | 启动阶段每路取 7 个样本,中值作为零点偏移 | ✅ |
| 中值滤波 | 每路保留最近 7 个样本,排序后取中位数 | ✅ |
| 死区抑制 | 中值落在 `-80 ~ 80` 时压到 `0` | ✅ |
| CoP 解算 | 根据四角力值计算 `cop_x / cop_y / force` | ✅ |
| 力值标定 | `ADC_TO_FORCE_SCALE` 仍为占位值 `1.0f` | 🔲 |
### 4.2 BLE 通信
| 项目 | 说明 | 状态 |
|------|------|------|
| BLE 角色 | `Peripheral`,使用 NUS 私有服务 | ✅ |
| 广播 | 广播包带 NUS UUID,扫描响应带设备名 | ✅ |
| 连接参数请求 | 连接后请求 `7.5-15 ms` 区间 | ✅ |
| CoP 上行 | 固定 17 字节二进制帧,50 Hz | ✅ |
| 断线重广播 | 断开 1 秒后重新广播 | ✅ |
| NUS 下行解析 | Resistance / Spotter / Heartbeat 三类帧已接收解析 | ✅ |
| 编码器上行 | 协议已预留,主循环未发送 | 🔲 |
### 4.3 控制参数与保护逻辑
| 项目 | 说明 | 状态 |
|------|------|------|
| Resistance 参数接收 | 接收 `K / B / Tau` 并保存到内存 | ✅ |
| Spotter 参数接收 | 接收 `threshold / enable` 并保存到内存 | ✅ |
| Heartbeat 接收 | 接收后刷新时间戳 | ✅ |
| 阻力闭环控制 | 参数已接入协议层,控制逻辑未落地 | 🔲 |
| Spotter 保护动作 | 参数已接入协议层,保护动作未落地 | 🔲 |
## 5. BLE 协议规格
平衡板工作在 BLE `Peripheral` 角色,通过 Nordic UART Service 与基站交换二进制帧。
- 上行方向:平衡板 -> 基站,使用 NUS `Notify`
- 下行方向:基站 -> 平衡板,使用 NUS `Write`
- 广播行为:广播包包含 NUS 128-bit UUID,扫描响应包含设备名 `GML670_System`
### 5.1 NUS UUID
| 项目 | UUID | 方向 | 说明 |
|------|------|------|------|
| Service | `6E400001-B5A3-F393-E0A9-E50E24DCCA9E` | - | NUS 主服务 |
| TX Characteristic | `6E400003-B5A3-F393-E0A9-E50E24DCCA9E` | 平衡板 -> 基站 | Notify,上报 CoP 数据 |
| RX Characteristic | `6E400002-B5A3-F393-E0A9-E50E24DCCA9E` | 基站 -> 平衡板 | Write,下发控制参数 |
### 5.2 连接参数
| 参数 | 当前值 | 说明 |
|------|--------|------|
| 广播模式 | `BT_LE_ADV_CONN_FAST_2` | 上电和断线后通过同一入口启动 |
| 连接间隔请求 | `7.5-15 ms` | `interval_min = 6``interval_max = 12` |
| 从站延迟 | `0` | 不跳过连接事件 |
| 监督超时 | `4000 ms` | `timeout = 400` |
### 5.3 帧类型总览
| 类型名 | 值 | 方向 | 长度 | 频率 | 说明 |
|--------|----|------|------|------|------|
| `PROTO_TYPE_COP` | `0x01` | 平衡板 -> 基站 | `17` | `50 Hz` | CoP 上行帧 |
| `PROTO_TYPE_ENCODER` | `0x02` | 平衡板 -> 基站 | `13` | TBD | 编码器上行帧,预留 |
| `PROTO_TYPE_RESISTANCE` | `0x10` | 基站 -> 平衡板 | `15` | 按需 | 阻力参数帧 |
| `PROTO_TYPE_SPOTTER` | `0x11` | 基站 -> 平衡板 | `8` | 按需 | Spotter 参数帧 |
| `PROTO_TYPE_HEARTBEAT` | `0x20` | 基站 -> 平衡板 | `4` | `~1 Hz` | 心跳帧 |
### 5.4 当前上行主帧
CoP 帧固定 17 字节,结构如下:
| 字节偏移 | 字段 | 类型 | 说明 |
|----------|------|------|------|
| `0` | `sync0` | `uint8` | 固定 `0xAA` |
| `1` | `sync1` | `uint8` | 固定 `0x55` |
| `2` | `type` | `uint8` | 固定 `0x01` |
| `3` | `seq` | `uint8` | 包序号,循环递增 |
| `4` | `flags` | `uint8` | `bit0` 表示 `force_valid` |
| `5-8` | `cop_x` | `float32 LE` | 压力中心 X 坐标,单位 mm |
| `9-12` | `cop_y` | `float32 LE` | 压力中心 Y 坐标,单位 mm |
| `13-16` | `force` | `float32 LE` | 总压力,单位 N |
更完整的协议示例帧和字段说明见 [BALANCE_BOARD_PROTOCOL.md](./BALANCE_BOARD_PROTOCOL.md)。
## 6. ADS1256 / CoP 规格
### 6.1 初始化与采样流程
当前固件的 ADS1256 侧流程如下:
```text
上电
|
+-- 配置 CS / DRDY / RESET GPIO
+-- 绑定 SPI1,频率 500 kHz
+-- 关闭 ADS1256 连续输出
+-- 配置 STATUS / MUX / ADCON / DRATE
+-- 执行自校准
+-- tare 去皮
|
+-- 主循环
|
+-- 轮询 4 路 MUX
+-- 读取 ADC 原始值
+-- 扣除零点偏移
+-- 7 点中值滤波
+-- 死区抑制
+-- CoP 解算
+-- 打包 CoP 帧并发送
```
### 6.2 关键参数
| 项目 | 当前值 | 说明 |
|------|--------|------|
| SPI 频率 | `500 kHz` | `spi_cfg.frequency = 500000` |
| 中值滤波窗口 | `7` | `MEDIAN_WINDOW = 7` |
| 死区 | `±80` | `-80 < median_val < 80` 时压到 `0` |
| 主循环周期 | `20 ms` | `k_msleep(20)` |
| CoP 上行频率 | `50 Hz` | 与主循环周期一致 |
| 板面半宽 | `200 mm` | `BOARD_HALF_WIDTH_MM = 200.0f` |
| 板面半长 | `200 mm` | `BOARD_HALF_LENGTH_MM = 200.0f` |
| CoP 最小有效总力 | `50 N` | `COP_MIN_FORCE_THRESHOLD = 50.0f` |
| 力值换算系数 | `1.0f` | `ADC_TO_FORCE_SCALE` 仍是占位值 |
### 6.3 CoP 判定规则
- 四路滤波后 ADC 值先通过 `ADC_TO_FORCE_SCALE` 转成力值
- 总力小于 `50 N` 时,`cop_x``cop_y``0.0f`
- 此时 `flags.bit0 = 0`,表示 CoP 坐标没有物理意义
- 总力达到阈值后,再根据四个角点坐标做加权平均
## 7. 开发环境与板级配置
当前工程采用标准 Zephyr / NCS 应用结构,目标板为 `nrf5340dk/nrf5340/cpuapp`
`prj.conf` 当前可以直接确认的配置点包括:
- `CONFIG_BT=y`,启用 BLE
- `CONFIG_BT_PERIPHERAL=y`,工作在外设角色
- `CONFIG_BT_NUS=y`,启用 Nordic UART Service
- `CONFIG_BT_DEVICE_NAME="GML670_System"`,设置广播设备名
- 日志走 RTT`CONFIG_USE_SEGGER_RTT=y`
- 关闭 UART Console`CONFIG_CONSOLE=n``CONFIG_UART_CONSOLE=n`
- 关闭串口驱动:`CONFIG_SERIAL=n`
`app.overlay` 当前只保留了 SPI1 和 ADS1256 控制 GPIO 的定义,没有额外启用 UART 控制台复用。
## 8. 项目结构
当前阅读和维护时最关键的文件如下:
| 路径 | 说明 |
|------|------|
| `src/main.c` | 主流程,包含 BLE、ADS1256 采样、滤波、CoP 解算和发送 |
| `src/protocol.h` | 二进制协议结构、常量、几何参数和阈值 |
| `app.overlay` | SPI1、CS、DRDY、RESET 的板级连线 |
| `prj.conf` | BLE、日志和控制台相关配置 |
| `BALANCE_BOARD_PROTOCOL.md` | 协议专项说明、字段表和示例帧 |
## 9. 构建与烧录
在已经配置好 Zephyr / NCS 环境的前提下,可以直接在工程根目录执行:
```bash
west build -b nrf5340dk/nrf5340/cpuapp -p always .
west flash
```
如果只是重新编译当前应用,默认目标仍然是 `nrf5340dk/nrf5340/cpuapp`
## 10. 日志与当前约束
### 10.1 日志
当前日志走 RTT,不占用 UART Console。启动后可以看到如下类型的信息:
- 启动 banner
- tare 开始和结束
- 下行 Resistance 参数日志
- 下行 Spotter 参数日志
- Heartbeat 接收路径已接入,默认 `INF` 级别下不会单独打印
### 10.2 当前约束
- 阻力参数、Spotter 参数和 Heartbeat 当前只做到协议接收、内存保存和日志打印
- 编码器上行帧只在协议头里预留,主循环没有产生这类数据
- `ADC_TO_FORCE_SCALE = 1.0f` 仍是占位值,真实力值需要结合实物标定修正
- CoP 当前依赖四角传感器的固定几何布局,默认使用 `200 mm x 200 mm` 半尺寸
- 主循环固定为 `20 ms` 周期,当前 README 中所有频率描述都以这一实现为准