💡 划重点
- 碰撞检测延时低于 20ms,利用 LSM6DS3 内置自由落体与中断引脚触发主控唤醒,实现超低待机功耗。
- 蓝牙广播与手机端快速配对,事故发生后 5 秒内推送 GPS 定位与碰撞等级,无需骑行中持续连接手机。
- 震动马达在检测到危险加速度时立即反馈,提醒骑行者注意,同时作为求救确认的回馈。
- 全物料成本控制在 140 元以内,采用模块化设计,无需定制 PCB,可快速复现。
需求洞察
目标用户:日常通勤骑行爱好者、公路/山地自行车周末骑友、共享单车高频用户(可自行加装头盔装置)。
真实痛点:
- 骑行事故发生后,若骑行人丧失意识,手机报警无法主动触发,错过黄金救援时间。
- 传统智能头盔价格昂贵(千元以上),且功能繁复,普通骑手不愿为低频事故场景投入高额成本。
- 多数加速计方案耗电量高,头盔需要频繁充电,使用意愿低。
为什么值得做:将碰撞检测压缩为一个低成本的独立后装模块,不绑定特定头盔,用 BLE 广播直接配合手机 APP 完成一键求救,极大降低使用门槛。在 140 元内实现可靠的跌落/碰撞识别、低功耗待机、远程报警闭环,可让安全性从“高端装备”变为“骑行标配”。
方案设计
感知层
- 六轴惯性传感器 LSM6DS3 持续监控三轴加速及角速度。
- 利用传感器内置的“自由落体”与“唤醒中断”功能,通过 INT1 引脚连接 nRF52840 的任意 GPIO(本方案使用 P0.03),当加速度矢量发生剧烈变化时硬件中断唤醒主控,无需主控轮询,实现待机电流 < 20µA。
- 正常工作模式下以 200Hz 采样率运行,通过 I2C 将实时加速度值送入缓存。
控制层
- 主控采用 nRF52840(推荐开发板:Seeed XIAO nRF52840 Sense 或合宙 NiceRF52840),运行碰撞识别状态机。
- 主流程:中断唤醒后读取加速度 FIFO 中预碰撞与碰撞窗口的数据,计算合加速度和角速度变化率,判定是否为真实碰撞(过滤骑行颠簸)。
- 碰撞确认后立即触发震动马达并启动 BLE 广播,广播包中包含设备 ID、碰撞等级和粗略位置请求。
执行层
- 震动马达通过 P0.05 输出 PWM 驱动,使用 N 沟道 MOS 管驱动一枚微型纽扣振动电机,碰撞时短震 100ms,随后周期性蜂鸣震动提醒周围人员。
- 若骑行者在抢救时效内未取消报警(双击头盔开关或手机确认),设备自动进入求救广播模式,以最大功率广播直到电量耗尽或被手机成功连接。
日志 / 联网层
- nRF52840 内置 BLE 5.0,支持长距离编码 PHY,在空旷地带可靠广播距离约 50 米。
- 手机端 APP 扫描特定服务 UUID 的广播包,解析碰撞数据并自动调取手机 GPS,向紧急联系人发送求救短信或服务器 API。
- 可通过 BLE GATT 服务将碰撞事件日志同步至手机,包含时间戳、加速度峰值曲线和角速度波形,用于事后分析。
物料清单
| 物料名称 | 数量 | 用途 | 估算单价(元) |
|---|---|---|---|
| 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(); // 等待事件,降低功耗
}
}
调试步骤
- 硬件上电检查:用 USB 供电,测电池电压与 3.3V 输出。按下开关,XIAO 指示灯亮起。
- I2C 扫描:上传 Arduino 示例
i2c_scanner,确认地址 0x6A(或0x6B)有响应。 - 传感器零偏校准:平置模块,串口打印静止加速度,确保 Z 轴接近 1g。
- 中断测试:快速挥手甩动模块,观察串口是否正确打印 “Collision detected”。没有串口可用 LED 闪烁指示。
- 阈值调优:骑行过程中实际记录颠簸路段加速度峰值,将阈值设置在略高于常规颠簸值的位置。
- BLE 广播检测:手机安装 nRF Connect APP,搜索自定义服务 UUID,确认能收到广播,甩动后查看厂商数据是否变为 0x01FF。
- 功耗测量:断开局串口,将万用表串入电池回路,确认待机电流 < 100µA,甩动触发时平均电流约 8mA。
- 整机路测:将模块装入头盔,实际骑行跌落试验(可在草地摔头盔模擬),验证 20ms 内震动反馈与手机推送。
设计图
骑行头盔碰撞检测结构flow
1
感知输入:LSM6DS3 加速度/角速度 -> INT1 中断唤醒
→
2
控制处理:nRF52840 数据缓存与碰撞算法 -> 识别真实碰撞
→
3
执行反馈:PWM 驱动振动马达 -> 骑手体感告警
→
4
数据上报:BLE 广播自定义数据包 -> 手机 APP 解析求救