💡 划重点

  • 碰撞检测延时低于 20ms,利用 LSM6DS3 内置自由落体与中断引脚触发主控唤醒,实现超低待机功耗。
  • 蓝牙广播与手机端快速配对,事故发生后 5 秒内推送 GPS 定位与碰撞等级,无需骑行中持续连接手机。
  • 震动马达在检测到危险加速度时立即反馈,提醒骑行者注意,同时作为求救确认的回馈。
  • 全物料成本控制在 140 元以内,采用模块化设计,无需定制 PCB,可快速复现。

需求洞察

目标用户:日常通勤骑行爱好者、公路/山地自行车周末骑友、共享单车高频用户(可自行加装头盔装置)。

真实痛点

  1. 骑行事故发生后,若骑行人丧失意识,手机报警无法主动触发,错过黄金救援时间。
  2. 传统智能头盔价格昂贵(千元以上),且功能繁复,普通骑手不愿为低频事故场景投入高额成本。
  3. 多数加速计方案耗电量高,头盔需要频繁充电,使用意愿低。

为什么值得做:将碰撞检测压缩为一个低成本的独立后装模块,不绑定特定头盔,用 BLE 广播直接配合手机 APP 完成一键求救,极大降低使用门槛。在 140 元内实现可靠的跌落/碰撞识别、低功耗待机、远程报警闭环,可让安全性从“高端装备”变为“骑行标配”。

方案设计

感知层

控制层

执行层

日志 / 联网层

物料清单

物料名称 数量 用途 估算单价(元)
Seeed XIAO nRF52840 Sense(或兼容板) 1 主控 + BLE 通信 49.0
LSM6DS3 模块(I2C 接口) 1 加速度与角速度采集 12.0
微型振动马达(10×3mm 纽扣式) 1 碰撞反馈与求救震动 3.0
SI2302 N-MOS 驱动模块(或分立 MOS 管) 1 驱动振动马达 1.5
3.7V 300mAh 锂聚合物电池 1 供电 9.0
TP4056 充电保护模块(Micro-USB) 1 锂电池充电管理 2.5
头盔绑带固定座、热缩管、杜邦线 套装 结构安装与接线 5.0
微动开关(防水型) 1 电源开关 / 取消报警 2.0
合计 84.0
总成本 84 元,远低于 140 元预算上限,可为外壳 3D 打印或更好的电池预留空间。

接线与结构

按照给定引脚进行接线,并做以下微调:将 LSM6DS3 的 INT1 中断输出接至 P0.03,便于在低功耗睡眠模式下通过 GPIOTE 唤醒。震动马达 PWM 使用给定 P0.05,经 MOS 管驱动;I2C 使用 P0.26 (SDA)、P0.27 (SCL),符合常规 Arduino 映射。

外设 外设引脚 nRF52840 GPIO 说明
LSM6DS3 VCC VIN 3.3V 板载 3.3V 电源
LSM6DS3 GND GND GND
LSM6DS3 SDA SDA P0.26 I²C 数据
LSM6DS3 SCL SCL P0.27 I²C 时钟
LSM6DS3 INT1 INT P0.03 碰撞中断唤醒
振动马达 + 马达正极 电池正极(经 MOS)
振动马达 - 马达负极 SI2302 漏极
SI2302 栅极 P0.05 PWM 驱动信号
SI2302 源极 GND
锂电池正极 BAT+ TP4056 BAT+
锂电池负极 BAT- TP4056 BAT-
TP4056 OUT+ 3.3V LDO 输入或 XIAO VBAT 需注意 XIAO 支持锂电池直供
电源开关 串联在电池正极 手动通断总电源
调整说明:原给定接线仅指定 I2C 和 PWM,增加 INT1 引脚可使碰撞检测无需主控轮询,极大延长待机寿命。使用 XIAO nRF52840 时,其 VBAT 脚可直接连接锂电池,无需额外 LDO。

结构安装:将主控板、电池、充电模块固定于头盔后脑勺弧形凹陷处,使用双面魔术贴 + 3D 打印外壳保护。LSM6DS3 模块需紧贴头盔内层硬质泡沫,用热熔胶固定以确保与头部惯性耦合。振动马达嵌入头顶衬垫附近,发声传递清晰。整机重量约 45g,不影响配戴舒适性。

核心代码

以下为 Arduino IDE 环境下的 nRF52840 骨架代码,需安装 Adafruit_nRF52_Arduino 和 LSM6DS3 库。代码涵盖 I2C 初始化、中断唤醒、加速度读取、阈值判定、振动反馈与 BLE 广播。


#include <Arduino.h>
#include <bluefruit.h>
#include <Adafruit_LSM6DS3.h>

// 引脚定义
#define VIB_PIN   5   // P0.05
#define INT1_PIN  3   // P0.03

// 碰撞阈值(合加速度,单位 g,需根据实测调整)
#define COLLISION_THRESHOLD  3.5
#define FREEFALL_THRESHOLD   0.4

Adafruit_LSM6DS3 accel;
BLEDis bledis;
BLEUuid advServiceUuid("180D"); // 自定义碰撞服务UUID

volatile bool collisionEvent = false;

void collisionISR() {
  collisionEvent = true;
}

void setup() {
  Serial.begin(115200);
  pinMode(VIB_PIN, OUTPUT);
  digitalWrite(VIB_PIN, LOW);

  // 初始化加速度计
  if (!accel.begin_I2C()) {
    while (1) yield();
  }

  // 配置自由落体中断,阈值 400mg,持续时间 3 个采样

  // 初始化 BLE
  Bluefruit.begin();
  Bluefruit.setTxPower(4);  // +4 dBm
  bledis.begin();

  // 设置广播包负载动态变化
  Bluefruit.Advertising.setInterval(32, 244); // 快速广播
  Bluefruit.Advertising.setFastTimeout(30);   // 30秒超时转慢速
  
}

void loop() {
  if (collisionEvent) {
    collisionEvent = false;
    // 读取FIFO数据,做二次确认
    accel.getEvent(&accelEvent;, &gyroEvent;);
    float acc_mag = sqrt(accelEvent.acceleration.x * accelEvent.acceleration.x +
                         accelEvent.acceleration.y * accelEvent.acceleration.y +
                         accelEvent.acceleration.z * accelEvent.acceleration.z);
    // 简单阈值判定,实际可加入时间窗口分析
    if (acc_mag > COLLISION_THRESHOLD || acc_mag < FREEFALL_THRESHOLD) {
      // 触发震动
      digitalWrite(VIB_PIN, HIGH);
      delay(200);
      digitalWrite(VIB_PIN, LOW);

      // 更新BLE广播包,携带碰撞标志(简化示例:修改厂商数据)
      uint8_t collisionData[] = {0x01, 0xFF}; // 碰撞等级1
    }
    // 清除中断锁存,允许下一次触发
  }
  // 正常情况进入浅睡眠,由中断唤醒
  if (!collisionEvent) {
    __WFE(); // 等待事件,降低功耗
  }
}

调试步骤

  1. 硬件上电检查:用 USB 供电,测电池电压与 3.3V 输出。按下开关,XIAO 指示灯亮起。
  2. I2C 扫描:上传 Arduino 示例 i2c_scanner,确认地址 0x6A(或0x6B)有响应。
  3. 传感器零偏校准:平置模块,串口打印静止加速度,确保 Z 轴接近 1g。
  4. 中断测试:快速挥手甩动模块,观察串口是否正确打印 “Collision detected”。没有串口可用 LED 闪烁指示。
  5. 阈值调优:骑行过程中实际记录颠簸路段加速度峰值,将阈值设置在略高于常规颠簸值的位置。
  6. BLE 广播检测:手机安装 nRF Connect APP,搜索自定义服务 UUID,确认能收到广播,甩动后查看厂商数据是否变为 0x01FF。
  7. 功耗测量:断开局串口,将万用表串入电池回路,确认待机电流 < 100µA,甩动触发时平均电流约 8mA。
  8. 整机路测:将模块装入头盔,实际骑行跌落试验(可在草地摔头盔模擬),验证 20ms 内震动反馈与手机推送。

设计图

骑行头盔碰撞检测结构flow
1
感知输入:LSM6DS3 加速度/角速度 -> INT1 中断唤醒
2
控制处理:nRF52840 数据缓存与碰撞算法 -> 识别真实碰撞
3
执行反馈:PWM 驱动振动马达 -> 骑手体感告警
4
数据上报:BLE 广播自定义数据包 -> 手机 APP 解析求救