💡 划重点
- 不到一杯奶茶的成本,用XIAO ESP32-S3+MPU6050+震动马达做成可缝入背带的可穿戴贴片,驼背超过15°立即高频提醒,学生、白领戴上即用,75元内养成挺拔坐姿。
需求洞察
目标用户是长时间伏案的学生和办公室白领。根据《中国国民健康大数据报告》,成年人颈椎、腰椎问题发病率已超70%,青少年脊柱侧弯检出率逐年上升。真实痛点在于:久坐时会不自觉地弓背、前倾,身体感知疲劳后才发觉,属于“无意识”体态塌陷。市面上提醒器多为独立背带,笨重、不贴身,售价过百;手机APP提醒仅依赖摄像头或定时器,无法实时感知肩背角度。为什么值得做:将六轴传感器直接固定在背部衣物内侧,通过振动而非声音提醒,不打扰他人;成本控制在75元以下,材料即插即用,学生和职场人都能自己组装,相当于每天花2分钱守护脊柱。
方案设计
感知层:使用MPU6050六轴模块(含三轴加速度计和三轴陀螺仪),I2C接口输出原始数据,经数字运动处理器(DMP)解算欧拉角,重点提取躯干相对竖直方向的俯仰角(Pitch)。采样率设定50Hz,兼顾实时性与功耗。
控制层:XIAO ESP32-S3主控。内核为双核LX7,运行FreeRTOS。一个核专门读取MPU6050并执行互补滤波融合,平滑后得到稳定倾角;另一个核处理逻辑:当连续3秒俯仰角超过设定阈值(前倾15°或后倾-5°),置位提醒标志。利用ESP32-S3低功耗模式,定时唤醒检查,延长电池寿命。
执行层:GPIO7驱动微型扁平振动马达。采用非对称提醒:初次姿态异常先短振100ms,若用户在1秒内未复位,振动升级为连续脉冲,直到恢复标准坐姿。不使用蜂鸣器,完全静默干预,适合图书馆、办公室。
日志/联网层:XIAO ESP32-S3自带Wi-Fi和BLE,可以低功耗蓝牙(BLE)连接手机,通过自定义Service上传每5分钟统计的不良坐姿次数、累积时长。手机端用简单Web蓝牙应用记录每日曲线,并给出改善建议。离线模式下也可将日志存入内部闪存,待连接后批量同步。
物料清单
| 物料名称 | 数量 | 用途 | 估算单价(元) |
|---|---|---|---|
| XIAO ESP32-S3 开发板 | 1 | 主控与无线连接 | 30 |
| MPU6050 六轴模块 | 1 | 姿态检测 | 7 |
| 微型扁平振动马达 | 1 | 触觉反馈 | 3 |
| 3.7V 500mAh 软包锂电池 | 1 | 供电 | 12 |
| TP4056 USB-C 充电模块 | 1 | 锂电池充放电管理 | 3 |
| 自锁开关(微型侧按) | 1 | 整机电源开关 | 1 |
| 轻薄编织线、背带魔术贴 | 若干 | 电气连接与固定 | 4 |
| ABS 小外壳(3D打印或开模) | 1 | 保护电路,便于缝制固定 | 5 |
| 合计 | 65 |
总成本65元,预留10元波动空间,完全符合75元以内目标。
接线与结构
依据建议接线,MPU6050 I2C 数据线:SCL接GPIO6,SDA接GPIO5,与XIAO ESP32-S3硬件I2C通道一致,提升通信稳定性。模块VCC取3.3V,GND接开发板GND。振动马达正极接GPIO7,负极接地;马达并联一颗1N4148续流二极管防止反向电压。锂电池输出经自锁开关,接入TP4056模块的BAT端,TP4056的OUT端再接入XIAO的5V引脚;USB-C口用于充电。所有组件装入扁平外壳,外壳背面缝有魔术贴勾面,可粘贴在书包背带、内衣肩带或座椅靠垫上。MPU6050需尽量平行于脊柱方向,安装时用水平仪初校准。
核心代码
基于Arduino环境,使用Adafruit_MPU6050和其内部DMP获取倾角。以下骨架可直接编译并上传至XIAO ESP32-S3。
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
const int MOTOR_PIN = 7; // 震动马达
const float PITCH_THRESHOLD = 15.0; // 前倾阈值(度)
const unsigned long ALERT_DELAY = 3000; // 持续异常3秒触发
unsigned long bad_posture_start = 0;
bool is_alerting = false;
void setup() {
Serial.begin(115200);
pinMode(MOTOR_PIN, OUTPUT);
digitalWrite(MOTOR_PIN, LOW);
Wire.begin(5, 6); // SDA=5, SCL=6
if (!mpu.begin()) {
while (1) delay(10);
}
}
float getPitch() {
sensors_event_t a, g, temp;
mpu.getEvent(&a;, &g;, &temp;);
// 加速度计角度近似(假设Y轴朝前,Z轴朝上)
float pitch = atan2(-a.acceleration.x, a.acceleration.z) * 180.0 / PI;
return pitch;
}
void loop() {
float pitch = getPitch();
// 判断是否不良坐姿:前倾角度大于阈值
bool bad_posture = (pitch > PITCH_THRESHOLD);
if (bad_posture) {
if (bad_posture_start == 0) {
bad_posture_start = millis();
} else if (millis() - bad_posture_start > ALERT_DELAY && !is_alerting) {
is_alerting = true;
digitalWrite(MOTOR_PIN, HIGH); // 开始震动
}
} else {
bad_posture_start = 0;
if (is_alerting) {
digitalWrite(MOTOR_PIN, LOW);
is_alerting = false;
}
}
delay(20);
}
代码中若坐姿恢复,立即停止震动。可根据需要加入蓝牙广播不良次数,核心逻辑仅20行。
调试步骤
- 串口监视:使用Arduino IDE串口绘图器,将串口输出改为
Serial.println(pitch),观察实时俯仰角。 - 零点校准:佩戴者保持标准坐姿(耳、肩、髋在一条直线),记录此时读出的Pitch值,在代码中作为偏移量减去。
- 阈值确定:故意前倾,观察角度变化,找出个人舒适但又不塌腰的临界值,通常在12°~18°。推荐从15°开始,再微调宏
PITCH_THRESHOLD。 - 马达测试:在标准坐姿下用手倾斜模块超过阈值并保持3秒,马达应振动;恢复坐姿立即停止。
- 结构检查:贴在背带上后,重新执行2、4步,确保贴合稳定不晃动。