💡 划重点

  • 本项目基于 XIAO ESP32-S3 主控芯片,结合 MPU6050 六轴姿态传感器与振动反馈单元,打造一款可贴合于背部或肩颈区域的“矫正坐姿背带贴片”。系统通过实时检测人体躯干倾角与弯腰幅度,在识别到不良坐姿(如低头、驼背、侧倾)时触发振动马达,形成即时触觉提醒,引导使用者主动恢复正确坐姿。设备采用锂电池供电,整体硬件成本控制在 75 元以内,面向学生与

需求洞察

目标用户:长时间伏案学习的中学生、大学生,以及每日面对电脑工作超过六小时的办公室白领。

真实痛点:绝大多数人意识到“坐直”的重要性,但在专注状态下(写作业、写代码、处理文档)会无意识前倾或塌腰。传统矫正带属于物理束缚,佩戴不适且限制活动;智能坐垫仅能检测臀部压力,无法感知上半身姿态;手机摄像头监测则存在隐私与部署成本问题。真正需要的不是“强制纠正”,而是在错误姿势刚发生且可逆时,给予一个轻微的、不打断注意力的信号

为什么值得做:颈椎病与腰椎间盘突出正呈现低龄化趋势,预防成本远低于治疗成本。一个不足 75 元的可穿戴小装置,能够在不打扰他人、不束缚动作的前提下,通过触觉神经通路建立“姿势-提醒”的条件反射循环,长期使用即可改善肌肉记忆。该方案体积小、功耗低、成本可控,具备 DIY 量产的可能性,也适合作为硬件编程教学的综合实践项目。

方案设计

系统整体分为四个逻辑层面:

  1. 感知层:采用 MPU6050 六轴传感器(三轴加速度 + 三轴陀螺仪),贴附于肩胛骨之间或背部脊柱位置。通过算法融合加速度与角速度数据,计算俯仰角(Pitch)与横滚角(Roll)。当 Pitch 角大于设定阈值(如 25-30°)且持续超过 2 秒,判定为“低头驼背”姿态;当 Roll 角偏移过大,判定为“侧斜”姿态。
  1. 控制层:XIAO ESP32-S3 内置 Xtensa LX7 双核处理器,主频 240MHz,足以运行姿态解算逻辑。软件设定防抖时间窗口(如 2 秒),避免打哈欠、伸懒腰等短暂动作引发误报。同时设置冷却时间(如 5 秒),防止连续震动造成麻木感。
  1. 执行层:采用扁平微型振动马达(直径 10mm,厚度 3mm),通过 GPIO 输出 PWM 信号驱动三极管(如 S8050)进行功率放大。根据姿态严重程度分级反馈:轻度前倾->单次短震(200ms);中度歪斜->双次中震(300ms 间隔 150ms);长时间塌腰->连续长震(500ms 停顿 200ms 循环三次)。
  1. 日志/联网层:XIAO ESP32-S3 具备 Wi-Fi 与 BLE 能力。预留蓝牙低功耗通道,可将每日不良坐姿次数、累计时长等统计数据发送至手机微信小程序或手机 APP。若无手机连接,则在板载 Flash 中存储最近七天的行为摘要,通过 USB 导出。

物料清单

序号 物料名称 规格/型号 数量 用途说明 估算单价(元) 小计(元)
1 主控开发板 XIAO ESP32-S3 1 核心控制、姿态解算、无线通信 35.00 35.00
2 姿态传感器 MPU6050 模块(GY-521) 1 检测倾角与角速度 6.50 6.50
3 振动马达 扁平纽扣式振动电机 10mm 1 触觉反馈输出 2.80 2.80
4 驱动三极管 S8050 + 1kΩ 基极电阻 1套 放大 GPIO 驱动电流 0.50 0.50
5 锂电池 3.7V 400mAh 聚合物电池(带保护板) 1 便携供电 9.00 9.00
6 充电管理 TP4056 模块(Type-C 母座) 1 USB-C 充电、过充保护 2.50 2.50
7 升压稳压 MT3608 升压模块(调至 5V) 1 为 ESP32-S3 提供稳定 5V 3.50 3.50
8 背带载体 弹性尼龙背带 + 魔术贴 1 贴合背部固定硬件 8.00 8.00
9 结构壳体 3D 打印 ABS 小盒(40x30x15mm) 1 固定 PCB 与电池 5.00 5.00
10 辅助材料 杜邦线、热缩管、焊锡丝、双面胶 若干 连接与固定 2.00 2.00
11 电源开关 SS12D00 滑动开关 1 总电源开关 0.60 0.60
合计 75.40

成本控制说明:上述合计 75.40 元,若在批量采购或使用国产替代传感器(如 QMI8658)时可微调至 75 元内。TP4056 模块自带 Type-C 母座,直接满足 USB-C 充电需求,无需额外焊接。

接线与结构

接线定义(按项目指定 GPIO)

模块 引脚 连接到 XIAO ESP32-S3 备注
MPU6050 VCC 3.3V 模块供电
MPU6050 GND GND 共地
MPU6050 SDA GPIO5 I2C 数据线,使用内部上拉
MPU6050 SCL GPIO6 I2C 时钟线
MPU6050 AD0 GND 地址 0x68
振动马达驱动 基极电阻 GPIO7 输出高电平触发震动
TP4056 OUT+ 锂电池正极 / 升压模块 IN+ 电池输出端
TP4056 OUT- 锂电池负极 / 系统 GND

微调说明:原方案默认 MPU6050 接 5/6 引脚,符合 ESP32-S3 任意 GPIO 均可配置为 I2C 的特性,故直接沿用。震动马达驱动电路需要 GPIO7 输出 3.3V 逻辑电平,经三极管放大后驱动马达(马达工作电压 3V,电流约 80mA),不可直接接 GPIO。

结构布局

核心代码

以下为适用于 XIAO ESP32-S3 的 Arduino 框架代码骨架,通过 PlatformIO 编译。代码实现了姿态读取、阈值判断与震动触发。


#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;
const int VIB_PIN = 7;        // 震动马达 GPIO7
const float PITCH_THRESHOLD = 25.0;  // 俯仰角阈值,低头超过25°
const float ROLL_THRESHOLD = 15.0;   // 横滚角阈值,侧倾超过15°
const unsigned long DURATION_MS = 2000; // 不良姿态持续2秒才触发
const unsigned long COOLDOWN_MS = 5000; // 两次提醒间隔5秒

unsigned long badPostureStart = 0;
unsigned long lastVibrateTime = 0;
bool badPostureActive = false;

void setup() {
  pinMode(VIB_PIN, OUTPUT);
  digitalWrite(VIB_PIN, LOW);
  Wire.begin(5, 6);   // GPIO5=SDA, GPIO6=SCL
  mpu.initialize();
  if (mpu.testConnection()) {
    // 可以加一点状态指示
  }
}

void loop() {
  // 读取六轴原始数据
  mpu.getMotion6(&ax;, &ay;, &az;, &gx;, &gy;, &gz;);

  // 将加速度归一化并计算 Pitch 与 Roll(单位:度)
  float accX = ax / 16384.0;
  float accY = ay / 16384.0;
  float accZ = az / 16384.0;

  float pitch = atan2(accX, sqrt(accY * accY + accZ * accZ)) * 180.0 / PI;
  float roll  = atan2(accY, sqrt(accX * accX + accZ * accZ)) * 180.0 / PI;

  // 姿态判断逻辑
  bool isBadPosture = (pitch > PITCH_THRESHOLD) || (roll > ROLL_THRESHOLD) || (roll < -ROLL_THRESHOLD);

  unsigned long now = millis();

  if (isBadPosture) {
    if (!badPostureActive) {
      badPostureStart = now;
      badPostureActive = true;
    }

    // 持续时间超过阈值且不在冷却期
    if ((now - badPostureStart >= DURATION_MS) && (now - lastVibrateTime >= COOLDOWN_MS)) {
      // 触发震动马达:连续两次 300ms 震动,间隔 150ms
      digitalWrite(VIB_PIN, HIGH);
      delay(300);
      digitalWrite(VIB_PIN, LOW);
      delay(150);
      digitalWrite(VIB_PIN, HIGH);
      delay(300);
      digitalWrite(VIB_PIN, LOW);

      lastVibrateTime = millis();
      // 可以在此处记录日志或通过 BLE 发送数据
    }
  } else {
    badPostureActive = false;
    badPostureStart = 0;
  }

  delay(50); // 20Hz 采样率,足够感知慢速姿态变化
}

代码要点说明

  • Wire.begin(5, 6) 显式指定 SDA 与 SCL 引脚。
  • 使用 atan2 直接计算倾角,无需额外库。
  • 阈值与时间窗口均为常量,可通过宏定义调整。
  • 若需上传数据,可在 lastVibrateTime 更新处调用 BLE 蓝牙库(如 BLEDevice)发送统计值。

调试步骤

  1. 基本通电测试:先不连接马达,仅给 XIAO 烧录空白程序,确认板载 LED 正常呼吸闪烁,TP4056 充电指示灯亮起,测量电池端输出电压约 3.7-4.2V。
  1. I2C 通信验证:使用 Arduino 的 I2C 扫描例程(Wire 库扫描 0x68 地址)确认 MPU6050 能被识别。若失败,检查 SDA/SCL 是否接反、上拉电阻是否缺失(GY-521 板载 10kΩ 上拉,通常无需外接)。
  1. 姿态数据可视化:连接串口监视器(波特率 115200),编写临时脚本每 100ms 打印一次 pitchroll 值。将板子平放读数应接近 0°,竖直立起读数约 90°,倾斜 30° 则读数应在 28-32° 之间(误差允许 2°)。
  1. 震动驱动确认:使用万用表二极管档测量 GPIO7 输出的高电平电压(应约 3.3V)。接好三极管电路后,短接 GPIO7 与 3.3V 引脚,马达应转动,若带偏心锤则有明显振动感。
  1. 阈值整定:将背带穿在身上,模拟正常坐姿(挺直)与伏案低头姿势,观察串口打印的 Pitch 值变化。若坐直时读数仍大于 10°,说明背带贴合位置或传感器方向有偏移,需微调安装角度,或者将目标阈值设为“坐直值 + 15°”作为动态基准。
  1. 整机佩戴测试:连续运行 30 分钟,记录是否出现误触发(如伸懒腰、扭头看旁边)。若误报频繁,增大 DURATION_MS 至 3000ms 或提高阈值 5°。若该提醒时不提醒,适当降低阈值。
  1. 充电与续航测试:充满电后,连续运行 8 小时,观察电池电压下降曲线。若不足 6 小时,考虑优化睡眠模式(未触发姿态变化时进入 modem 休眠)。
  1. 信号完整性检查:在震动马达启动瞬间,用示波器(或逻辑分析仪)观察 MPU6050 的 SDA/SCL 线上是否有毛刺干扰。若存在,可在马达两端并联 100nF 电容并靠近马达放置。

设计图

矫正坐姿背带贴片结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报

流程说明:感知输入由 MPU6050 完成,数据通过 I2C(GPIO5/6)送入 XIAO ESP32-S3 主控;进行姿态解算与阈值判断后,控制层输出 PWM 信号至 GPIO7,经三极管放大驱动振动马达,实现执行反馈。同时,控制层可将不良姿态统计数据打包,通过蓝牙 BLE 对外广播,供手机端接收上报。整个流程循环运行,无外部干预。