💡 划重点
- 本项目为办公桌场景打造一款成本 55 元以内的智能番茄钟工位站姿提醒设备。以 RP2040 为主控,结合 OLED 屏幕、震动电机与双按键,实现番茄工作法定时、久坐站姿提醒、按键交互与状态可视化,软硬件全部开源,适合个人 DIY 或小批量教学实践。核心指标:30 分钟工作 / 5 分钟休息循环、每 45 秒震动提示挺直脊柱、OLED 实时显示倒计时与姿态图标
需求洞察
目标用户
长期伏案办公的知识工作者、程序员、远程办公人群及大学生,他们普遍存在“久坐成疾”与“注意力碎片化”两大难题。
真实痛点
- 持续久坐超过 1 小时后,腰椎和颈肩压力剧增,身体不自觉前倾或驼背,却缺乏即时提醒。
- 番茄钟类手机 APP 容易分散注意力,通知频繁反而打断心流;纯软件方案无法感知真实坐姿。
- 市面智能升降桌或穿戴设备价格动辄数百元,个人工位改造门槛高。
为什么值得做
低成本硬件 + 确定性功能闭环,能把番茄钟的效率管理和站姿健康管理融为一体。震动电机直接贴附椅背或置于工位表面,形成物理级提醒,比屏幕弹窗更不易被忽略。RP2040 的 PIO 与双核对定时任务友好,方便后续扩展无线日志或桌面小仪表。55 元内完成所有物料,真正可实现“一人一机”。
方案设计
感知层
- 两个微动按键(GPIO6/7)分别负责“开始/暂停”与“重置/模式切换”。
- 按键采用内部上拉,中断 + 消抖获取短按、长按事件。
- 可选外接一个倾斜/震动开关(预留 GPIO 位置),进阶感知身体前倾,但本版控制在预算内不强制。
控制层
- 主控 RP2040(树莓派 Pico),双核 ARM Cortex‑M0+,主频 133 MHz。
- Core0 运行 1 毫秒定时器中断,驱动全局时基和番茄钟状态机:工作 30 分钟 → 休息 5 分钟 → 循环。
- Core0 同时处理按键中断、OLED 刷新队列与震动控制。
- 站姿提醒定时器独立于番茄钟,每 45 秒触发一次短震,每 10 分钟通过 OLED 显示“请挺直”图标。
执行层
- 0.96 寸 SPI OLED(128×64),CS=13, DC=14,显示倒计时、状态字符和简易图标。
- 震动电机模块接 GPIO15,NPN 管驱动,用 PWM 调节震动强度,提醒时震动 200ms。
- OLED 状态行切换:“工作中|休息中|暂停”。
日志 / 联网层
- USB‑CDC 虚拟串口实时输出 JSON 格式日志:
{"status":"work","remain":1500,"posture_remind":true}。 - 如果需要历史记录,可挂接一颗廉价的 SPI Flash(板载 2MB 足够),但默认可通过串口连接电脑或树莓派作数据采集,保持物料在预算内。
- 后续可通过更换主控板为 Pico W,零成本移植 WiFi 上报功能。
物料清单
| 名称 | 数量 | 用途 | 估算单价(元) | 小计(元) |
|---|---|---|---|---|
| 树莓派 Pico(RP2040) | 1 | 主控板 | 22.0 | 22.0 |
| 0.96 寸 OLED 128×64 SPI | 1 | 状态显示 | 12.0 | 12.0 |
| 震动电机模块(微型扁平) | 1 | 坐姿/站姿提醒 | 3.5 | 3.5 |
| 微动按键 | 2 | 启停、重置 | 0.5 | 1.0 |
| 直插电阻 10kΩ | 2 | 按键上拉备用 | 0.1 | 0.2 |
| NPN 三极管 S8050 | 1 | 震动电机驱动 | 0.3 | 0.3 |
| 1kΩ 电阻(基极限流) | 1 | 匹配三极管 | 0.1 | 0.1 |
| 面包板 + 杜邦线套装 | 1 | 连线与固定 | 8.0 | 8.0 |
| 热缩管 / 泡棉胶 | 少量 | 绝缘与固定电机 | 1.0 | 1.0 |
| USB‑micro 数据线 | 1 | 供电与日志 | 3.0 | 3.0 |
| 合计 | 51.1 |
接线与结构
严格遵循给定 GPIO 并微调 SPI 信号线。
OLED SPI:CS=13, DC=14, SCK=18, MOSI=19, RST=17(原计划未指定 SCLK/MOSI/RST,补充后可与大部分 SPI OLED 模块兼容)。选用 RP2040 的 SPI0 外设,SCK=18, MOSI=19 为默认映射,接线整洁且支持 DMA 刷新。
震动电机:控制脚 GPIO15,通过 S8050 驱动。
按键:KEY1=GPIO6(启停),KEY2=GPIO7(重置),内部上拉,短按触发。
结构上,Pico 固定于面包板一端,OLED 用杜邦线引出竖立在视野正前方;震动电机用泡棉胶粘在椅背或桌沿,导线从面包板走线。所有元器件不超过 100×80mm 面积,可装入 3D 打印外壳(外壳暂不计入 55 元成本,可后期自制)。
核心代码
基于 Arduino IDE + Earle Philhower 的 RP2040 核心 (Mbed OS 亦可),使用 Adafruit_SSD1306 库。下面给出可编译的骨架。
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_CS 13
#define OLED_DC 14
#define OLED_RST 17
Adafruit_SSD1306 display(128, 64, &SPI;, OLED_DC, OLED_RST, OLED_CS);
#define VIBE_PIN 15
#define KEY1_PIN 6
#define KEY2_PIN 7
enum State { IDLE, WORK, REST, PAUSE } state = IDLE;
uint32_t timerSec = 0;
uint32_t lastVibe = 0;
bool postureFlag = false;
char statusStr[20];
void setup() {
pinMode(VIBE_PIN, OUTPUT);
Serial.begin(115200);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
}
void loop() {
static uint32_t lastMs = millis();
if (millis() - lastMs >= 1000) {
lastMs = millis();
if (state == WORK || state == REST) {
timerSec++;
if (state == WORK && timerSec >= 1800) { // 30 分
state = REST; timerSec = 0;
} else if (state == REST && timerSec >= 300) { // 5 分
state = WORK; timerSec = 0;
}
}
if (state == WORK && (millis() - lastVibe >= 45000)) { // 45 秒提醒
digitalWrite(VIBE_PIN, LOW);
lastVibe = millis();
postureFlag = true;
}
// 显示更新
display.clearDisplay();
display.setCursor(0,0);
const char* stateText = (state==WORK)?"工作":(state==REST)?"休息":"暂停";
snprintf(statusStr, sizeof(statusStr), "%s %02d:%02d", stateText, timerSec/60, timerSec%60);
display.print(statusStr);
if (postureFlag) {
display.setCursor(0,40);
display.print("请挺直");
postureFlag = false;
}
display.display();
// 串口日志
Serial.print("{\"status\":\"");
Serial.print(stateText);
Serial.print("\",\"remain\":");
Serial.print((state==WORK?1800:300)-timerSec);
Serial.print(",\"posture\":");
Serial.print(postureFlag?"true":"false");
Serial.println("}");
}
// 按键扫描
if (!digitalRead(KEY1_PIN)) {
delay(50); if(!digitalRead(KEY1_PIN)) {
state = (state == WORK || state == REST) ? PAUSE : WORK;
while(!digitalRead(KEY1_PIN));
}
}
if (!digitalRead(KEY2_PIN)) {
delay(50); if(!digitalRead(KEY2_PIN)) {
state = IDLE; timerSec = 0;
while(!digitalRead(KEY2_PIN));
}
}
}
编译环境:安装 RP2040 板包和 Adafruit SSD1306 库,选择“Raspberry Pi Pico”即可。
调试步骤
- 接线检查:用万用表短接测试各 VCC/GND 通路,确保 OLED 和振动模块供电无短路。
- OLED 驱动:先烧录 SPI 扫描示例,确认 SCK、MOSI、CS、DC、RST 对应正确,屏幕能点亮并打印“Hello”。
- 按键测试:在 IDE 串口监视器打印按键状态,确认短按不抖动,长按识别正常。
- 震动测试:编写单独代码让 GPIO15 以 PWM 驱动电机,确认强度和续流二极管保护。
- 定时器联调:修改宏将工作周期临时改为 30 秒、休息 5 秒,观察状态切换与震动逻辑。
- 整机运行:黏贴振动电机至工位边缘,坐姿下实际体验 45 秒提醒是否明显,根据反馈调整震动时长。
- 串口日志:打开串口绘图器或 Python 脚本记录 json,验证数据连续性。
设计图
番茄钟工位站姿提醒结构flow
1
感知输入
→
2
控制处理
→
3
执行反馈
→
4
数据上报