pNexus 38a70ccb8e chore(ble): 增强连接与发送日志,补充 README TODO
- 连接/断开事件打印详细信息
- 发送统计计数(成功/失败)
- README 补充 L1 标定、BR 通道排查、马达频率确认待办
2026-05-19 14:50:16 +08:00

GML670 Balance Board

当前目录是 GML670x4_V2。代码内的 CMake 项目名是 GML670_V2BLE 设备名是 GML670_System

这份 README 只描述当前 V2 工程已经落地的实现。更细的协议字段和示例帧见 BALANCE_BOARD_PROTOCOL.md


目录

  1. 产品概述
  2. 硬件组成
  3. 系统架构
  4. 功能需求与当前状态
  5. BLE 协议规格
  6. ADS1256 / CoP 规格
  7. 开发环境与板级配置
  8. 项目结构
  9. 构建与烧录
  10. 日志与当前约束

1. 产品概述

本工程是平衡板的 nRF5340 App Core 固件,当前版本的主链路很简单:

  • 上电后等待 2 秒,初始化 BLE NUS 传输层并启动广播
  • 初始化 ADS1256,完成一次 tare 去皮
  • 创建独立的传感器线程,循环读取 4 路差分输入
  • 在板端完成重量换算和 CoPCenter of Pressure,压力中心)解算
  • 通过 BLE NUS 持续上报 17 字节 CoP 二进制帧
  • 接收基站下发的阻力参数、Spotter 参数和心跳帧,并保存在内存里

当前实现已经把采样、解算和上行链路拆成了独立模块:main.c 只负责启动,BLE 在 src/ble_transport.cADS1256 在 src/ads1256.c,采样与 CoP 在 src/sensor.c

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 片选
DRDY P1.11 数据就绪输入
RESET P1.10 ADS1256 复位控制

虽然 app.overlay 里有 ads1256@0 节点,但当前实现没有走单独的 Zephyr ADS1256 驱动,实际访问路径还是 src/ads1256.c 里直接操作 spi1 和 GPIO alias。

3. 系统架构

4 路差分传感器
       |
       v
   ADS1256 + SPI1
       |
       v
   src/ads1256.c
       |
       v
   src/sensor.c (业务层)
       |
       +--> 去皮 / 17 次均值 / 死区抑制 / 重量换算 / CoP 解算
       |
       v
   src/comm_protocol.c (协议层)
       |
       +--> 上行:组包 CoP/标定响应帧,调用 ble_transport_send()
       +--> 下行:解析收到的帧,推入 msgq 供业务层消费
       |
       v
   src/ble_transport.c (传输层)
       |
       +--> BLE NUS Notify / Write,纯字节收发

src/main.c 本身不承载采样逻辑,它只按顺序调用 ble_transport_init()comm_protocol_init()ble_transport_adv_start()sensor_init()

4. 功能需求与当前状态

4.1 采样与解算

项目 说明 状态
4 路轮询采样 通过 ADS1256 MUX 依次读取 0x01 / 0x23 / 0x45 / 0x67 四组差分通道
tare 去皮 每路读取 17 个样本,排序后取中位数作为零点偏移
运行期滤波 每帧每通道采 17 次并取均值
死区抑制 去皮后的均值落在 -250 ~ 250 counts 时压到 0
重量换算 ADC_TO_FORCE_SCALE 已按 GML670 50 kg 传感器参数推导
CoP 解算 根据四角重量计算 cop_x / cop_y / force
有效力阈值 总重量低于 0.5 kg 时,CoP 坐标置零并清除 force_valid

4.2 BLE 通信

项目 说明 状态
BLE 角色 Peripheral,使用 NUS 私有服务
广播内容 广播包带 NUS UUID,扫描响应带设备名
连接参数请求 连接后请求 7.5-15 ms 区间
CoP 上行 固定 17 字节二进制帧,目标频率约 50 Hz
NUS 发送保护 仅在连接存在且通知已使能时发送,失败时短间隔重试 3 次
断线重广播 断开 1 秒后重新广播
NUS 下行解析 Resistance / Spotter / Heartbeat 三类帧已接收解析
编码器上行 协议已预留,主循环未发送 🔲

4.3 控制参数与保护逻辑

项目 说明 状态
Resistance 参数接收 接收 K / B / Tau 并保存到传输层静态变量
Spotter 参数接收 接收 threshold / enable 并保存到传输层静态变量
Heartbeat 接收 接收后刷新最近心跳时间戳
阻力闭环控制 参数已接入协议层,控制逻辑未落地 🔲
Spotter 保护动作 参数已接入协议层,保护动作未落地 🔲

4.4 传感器标定

标定分两级,通过 BLE 下行标定命令帧触发,平衡板执行后回复标定响应帧。帧格式详见 BALANCE_BOARD_PROTOCOL.md

L1 标定(单通道零点 + 增益)

基站                          平衡板
  │                              │
  │── START_L1 ─────────────────>│  进入 L1 模式
  │<──────────────── OK ─────────│
  │                              │
  │── TARE_CH (ch=0) ──────────>│  空载,记录零点
  │<──────────────── OK ─────────│
  │   ...对 ch=1,2,3 重复...     │
  │                              │
  │── GAIN_CH (ch=0, 10kg) ────>│  加载砝码,计算增益
  │<──────────────── OK ─────────│
  │   ...对 ch=1,2,3 重复...     │
  │                              │
  │── COMMIT_L1 ────────────────>│  写入 NVS
  │<──────────────── OK ─────────│

L2 标定(9 点网格空间修正)

L2 需要 L1 已完成。在 9 个已知位置分别放置标定负载,记录 CoP 误差用于空间修正。

基站                          平衡板
  │                              │
  │── START_L2 ─────────────────>│  进入 L2 模式
  │<──────────────── OK ─────────│
  │                              │
  │── RECORD_GRID (pt=0) ──────>│  在网格点 0 放置已知负载
  │<──────────────── OK ─────────│
  │   ...对 pt=1..8 重复...      │
  │                              │
  │── COMMIT_L2 ────────────────>│  写入 NVS
  │<──────────────── OK ─────────│

网格点编号(3×3,俯视):

  6 ── 7 ── 8
  │         │
  3 ── 4 ── 5
  │         │
  0 ── 1 ── 2

点 4 为板面中心。

状态与持久化

  • 标定数据通过 NVS 持久化,上电后自动加载
  • ERASE 命令可清除全部标定数据,回退到出厂默认
  • QUERY 命令返回当前各级标定的有效性标志
  • ABORT 可在任意阶段中止标定流程,已测量数据不写入 NVS

5. BLE 协议规格

平衡板工作在 BLE Peripheral 角色,通过 Nordic UART Service 与基站交换二进制帧。

  • 上行方向:平衡板 -> 基站,使用 NUS Notify
  • 下行方向:基站 -> 平衡板,使用 NUS Write
  • 广播内容:广播包带 NUS 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 = 6interval_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 总重量,单位 kg

更完整的字段说明和示例帧见 BALANCE_BOARD_PROTOCOL.md

6. ADS1256 / CoP 规格

6.1 初始化与采样流程

当前固件的 ADS1256 侧流程如下:

上电
  |
  +-- 配置 CS / DRDY / RESET GPIO
  +-- 绑定 SPI1,频率 500 kHz
  +-- 硬件复位 ADS1256
  +-- 发送 CMD_SDATAC,关闭连续输出模式
  +-- 写寄存器: STATUS=0x06, MUX=0x01, ADCON=0x07, DRATE=0xC0
  +-- 发送 CMD_SELFCAL
  +-- 回读关键寄存器做校验
  +-- tare 去皮
  |
  +-- 传感器线程循环
        |
        +-- 依次切换 4 路 MUX
        +-- 每路读 17 次并求均值
        +-- 扣除零点偏移
        +-- 死区抑制
        +-- 重量换算
        +-- CoP 解算
        +-- 打包 CoP 帧并发送

6.2 关键参数

项目 当前值 说明
SPI 频率 500 kHz spi_cfg.frequency = 500000
STATUS 0x06 ACAL=1BUFEN=1
PGA 64 ADCON = 0x07
采样率 3750 SPS DRATE = 0xC0
每帧均值次数 17 AVG_COUNT = 17
去皮窗口 17 每路取 17 点,中位数为零点
死区 ±250 counts DEADZONE_THRESHOLD = 250
板面半宽 100 mm BOARD_HALF_WIDTH_MM = 100.0f
板面半长 100 mm BOARD_HALF_LENGTH_MM = 100.0f
CoP 最小有效总重 0.5 kg COP_MIN_FORCE_THRESHOLD = 0.5f
调试日志频率 每 10 帧一次 目标运行状态下约 5 Hz

6.3 CoP 判定规则

  • 四路去皮后的 ADC 值先乘 ADC_TO_FORCE_SCALE,换算成重量
  • 总重量低于 0.5 kg 时,cop_xcop_y0.0f
  • 此时 flags.bit0 = 0,表示 CoP 坐标没有物理意义
  • 总重量达到阈值后,再根据四角坐标做加权平均

当前四路传感器与板面坐标的映射如下:

通道 位置 X Y
S0 右前 FR +100 +100
S1 右后 BR +100 -100
S2 左后 BL -100 -100
S3 左前 FL -100 +100

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",设置广播设备名
  • CONFIG_BT_NUS_SECURITY_ENABLED=n,关闭 NUS 安全限制
  • 日志走 RTTCONFIG_USE_SEGGER_RTT=y
  • 关闭 UART ConsoleCONFIG_CONSOLE=nCONFIG_UART_CONSOLE=n
  • 关闭 UART 日志后端:CONFIG_LOG_BACKEND_UART=n
  • 关闭串口驱动:CONFIG_SERIAL=n

app.overlay 当前只保留了 SPI1、ADS1256 设备节点和三根控制 GPIO 的定义,没有把 UART Console 复用回来。

8. 项目结构

当前阅读和维护时最关键的文件如下:

路径 说明
src/main.c 启动入口,负责初始化 BLE、协议层和传感器子系统
src/ads1256.c ADS1256 SPI 读写、复位、寄存器配置和校验
src/sensor.c 采样线程、tare、均值滤波、重量换算和 CoP 计算
src/comm_protocol.c 协议收发解析层:上行组包、下行解析、msgq 分发
src/ble_transport.c BLE 广播、NUS 字节收发、断线重广播
inc/comm_protocol.h 帧格式定义、标定子命令码、下行消息队列类型和协议 API
app.overlay SPI1、CS、DRDY、RESET 的板级连线
prj.conf BLE、日志和控制台相关配置
BALANCE_BOARD_PROTOCOL.md 协议专项说明、字段表和示例帧

9. 构建与烧录

在已经配置好 Zephyr / NCS 环境的前提下,可以直接在工程根目录执行:

west build -b nrf5340dk/nrf5340/cpuapp -p always .
west flash

如果只是重新编译当前应用,默认目标仍然是 nrf5340dk/nrf5340/cpuapp

10. 日志与当前约束

10.1 日志

当前日志走 RTT,不占用 UART Console。启动后可以看到如下类型的信息:

  • 启动 banner
  • BLE transport 初始化结果
  • ADS1256 关键寄存器回读结果
  • tare 开始和结束
  • Resistance / Spotter 下行参数日志
  • 周期性的四角重量、总重、CoP 和帧耗时日志

Heartbeat 接收路径已经接入,但默认 DBG 级别下才单独打印。

10.2 当前约束

  • 阻力参数、Spotter 参数和 Heartbeat 目前只做到协议接收、内存保存和日志留痕
  • 编码器上行帧只在协议头里预留,当前没有实际数据源
  • 传感器线程没有额外 k_msleep() 节流,实际帧率由 ADS1256 采样和 BLE 发送耗时共同决定
  • README 中的频率描述按当前 3750 SPS + 4 通道 * 17 次均值 这套实现估算,目标运行频率约 50 Hz
  • 当前实现默认四角传感器是固定几何布局,半宽和半长都是 100 mm

10.3 TODO

  • L1 增益标定:当前使用理论推导值 ADC_TO_FORCE_SCALE,实测 10 kg 砝码显示 9 kg(约 10% 误差),需用已知砝码通过标定命令校准每通道增益
  • BR 通道硬件排查:静止无马达状态下 BR 通道有 ±4600 counts 异常抖动(其余通道仅 ±500),疑似接触不良或安装松动
  • 马达振动频率确认:当前 IIR 截止 1.2 Hz,若实际振动低于帧率一半(23.5 Hz)存在混叠,可能需要在 ADC 级做抗混叠或调整采样策略
S
Description
No description provided
Readme 914 KiB
Languages
C 98.5%
CMake 1.5%