💡 划重点
- 主控采用 RP2040,搭配 SPI OLED、震动电机与实体按键,在办公桌上提供无侵入的番茄钟与久坐提醒。
- 方案聚焦“低成本、高可靠、易复刻”,全部物料含开发板在 55 元以内。
- 双按键交互配合 OLED 图形化界面,避免频繁看手机,保持心流状态。
- 通过震动电机直接提醒站立,比声音提醒更友好,避免干扰同事。
- 代码骨架基于 MicroPython,可快速修改工歇时长与震动模式。
需求洞察
目标用户
长期在电脑前工作的程序员、设计师、文字工作者,以及注重精力和脊椎健康的远程办公者。
真实痛点
- 番茄钟依赖手机 App,但手机本身就是干扰源,通知一来容易分心。
- 多数桌面提醒器只有屏幕闪烁或蜂鸣声,蜂鸣在开放工位会打扰同事,只闪屏又容易被忽略。
- 久坐对腰椎、颈椎的损害已被大量医学研究证实,但工作投入时很难自觉起身活动。
为什么值得做
办公桌场景天然适合放置一个小型硬件终端。物理按键提供确定感,振动反馈不依赖视觉或听觉,能在不打断同事的前提下完成提醒。将番茄钟与站姿提醒合并,用极低的成本形成“专注+健康”双闭环,既有个人效率价值,也有健康管理价值,适合长期使用。
方案设计
本项目以 RP2040 为中心,从四层结构出发构建:
感知层
- 两枚轻触按键,分别用于番茄钟的启动/暂停与重置/模式切换。
- 内部 RTC 定时器作为时间基准,无需外部时钟芯片。
- 可选扩展:通过 I2C 接入红外人体传感器检测是否离座,用于数据辅助,但当前成本控制在基础版本。
控制层
- RP2040 运行 MicroPython,实现番茄钟状态机:待机 → 工作(25 分钟)→ 短休息(5 分钟)→ 长休息(15 分钟,每 4 个番茄)。
- 久坐逻辑:从坐下开始计时,满 45 分钟触发站立提醒,可与番茄钟结束信号叠加。
- 按键消抖与长按、短按识别,避免误触。
执行层
- 0.96 寸 SPI OLED 显示番茄倒计时、当前阶段图标和久坐进度条。
- 震动电机在番茄结束或久坐超时产生短震两次,提醒站立;工作时震动极短一次提示开始。
- 所有提醒均为触觉,不使用蜂鸣器,兼顾安静办公环境。
日志/联网层(基础+预留扩展)
- 当前通过 USB 串口输出每次番茄完成、站立次数、总专注时长等数据,可配合电脑端脚本记录。
- 预留 UART 接口可接蓝牙透传模块,未来低成本升级到手机数据同步。
- ESP-AT 指令 Wi-Fi 模块也可后期叠加,但基础版不包含以控制成本。
物料清单
| 物料名称 | 数量 | 用途 | 单价(元) | 小计(元) |
|---|---|---|---|---|
| WeAct RP2040 核心板 | 1 | 主控 | 19.9 | 19.9 |
| 0.96寸 OLED 模块 (SPI, SSD1306) | 1 | 显示界面 | 13.5 | 13.5 |
| 微型震动电机模块 | 1 | 站立提醒 | 3.8 | 3.8 |
| 6x6 轻触按键 | 2 | 交互控制 | 0.3 | 0.6 |
| 10KΩ 电阻(按键上拉备用) | 2 | 稳定电平 | 0.1 | 0.2 |
| 面包板 + 杜邦线 | 1套 | 电路搭建 | 8.0 | 8.0 |
| 迷你 USB 数据线 | 1 | 供电与编程 | 3.0 | 3.0 |
| 合计 | 49.0 |
合计 49 元,预留 6 元缓冲,完全满足 55 元内目标。若已有面包板和线材,实际成本可进一步压低至 41 元。
接线与结构
使用给定 GPIO 并微调:OLED 采用 SPI 接口,CS 接 GP13,DC 接 GP14,SCLK 接 GP10,MOSI 接 GP11;震动电机接 GP15;按键使用内部弱上拉,接 GP6(启动/暂停)和 GP7(重置)。
微调理由:原给定 OLED 接线中未指定 SCLK 和 MOSI,这里选用 RP2040 的硬件 SPI0,稳定且刷新快。两个按键直接占用 GP6、GP7,不冲突任何已分配 SPI 引脚,软件中启用内部上拉可省略外部上拉电阻(物料清单仍保留以防抖动,实际焊接可取舍)。
结构:所有模块固定在面包板上,OLED 置于顶部倾斜面朝使用者,按键在右侧便于惯用手操作,震动电机粘贴于面包板背面,通过桌面传递振动。使用 3D 打印外壳可固定形态,但并非必需。
核心代码
以下为 MicroPython 骨架,实现番茄钟启动/暂停、倒计时显示与站立震动提醒。
import ssd1306
import time
# OLED 初始化
spi = SPI(0, baudrate=4000000, polarity=0, phase=0, sck=Pin(10), mosi=Pin(11))
cs = Pin(13, Pin.OUT)
dc = Pin(14, Pin.OUT)
rst = Pin(12, Pin.OUT) # 若 OLED 有 RST
oled = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
# 电机与按键
motor = Pin(15, Pin.OUT)
btn_start = Pin(6, Pin.IN, Pin.PULL_UP)
btn_reset = Pin(7, Pin.IN, Pin.PULL_UP)
WORK_MIN = 25
SHORT_BREAK = 5
LONG_BREAK = 15
SIT_LIMIT = 45 # 久坐提醒阈值(分钟)
# 状态变量
running = False
paused = False
current_timer = WORK_MIN * 60
phase = 'work' # work, short_break, long_break
sit_counter = 0
pomodoro_count = 0
def vibrate(pattern):
for _ in range(pattern):
motor.on()
time.sleep_ms(150)
motor.off()
time.sleep_ms(100)
oled.fill(0)
mins, secs = divmod(remaining_sec, 60)
oled.text(f"{phase} {mins:02d}:{secs:02d}", 0, 0)
sit_bar = int((sit_counter / (SIT_LIMIT*60)) * 60)
oled.text(f"Pomo:{pomodoro_count}", 0, 30)
oled.show()
def tick(timer):
if not running or paused:
return
sit_counter += 1
current_timer -= 1
if current_timer <= 0:
vibrate(2) # 结束提醒
running = False
if phase == 'work':
pomodoro_count += 1
if pomodoro_count % 4 == 0:
phase = 'long_break'
current_timer = LONG_BREAK * 60
else:
phase = 'short_break'
current_timer = SHORT_BREAK * 60
else:
phase = 'work'
current_timer = WORK_MIN * 60
# 久坐提醒(仅工作阶段且未暂停)
if phase == 'work' and sit_counter >= SIT_LIMIT * 60:
vibrate(2)
sit_counter = 0
update_display(current_timer)
timer = Timer()
timer.init(period=1000, mode=Timer.PERIODIC, callback=tick)
def check_buttons():
if not btn_start.value():
time.sleep_ms(50)
if not btn_start.value():
if not running:
running = True
paused = False
current_timer = WORK_MIN * 60 if phase == 'work' else current_timer
sit_counter = 0
vibrate(1)
else:
paused = not paused
while not btn_start.value():
pass
if not btn_reset.value():
time.sleep_ms(50)
if not btn_reset.value():
global phase, pomodoro_count
running = False
paused = False
phase = 'work'
current_timer = WORK_MIN * 60
pomodoro_count = 0
sit_counter = 0
update_display(current_timer)
while not btn_reset.value():
pass
# 主循环
while True:
check_buttons()
time.sleep_ms(100)
代码需配合 ssd1306.py 库使用,可通过 Thonny 或 rshell 上传至 RP2040。定时器每秒更新一次,按键检测置于主循环,实现基本的番茄钟逻辑与久坐站立震动提醒。
调试步骤
- 硬件上电检查:USB 连接电脑,RP2040 板载 LED 闪烁,OLED 亮起并显示初始界面。
- 固件烧录:按住 BOOTSEL 插入 USB,将 MicroPython 固件拖入 RPI-RP2 磁盘。
- 上传依赖:将
ssd1306.py及主程序上传至设备。 - 功能验证:短按 GP6,OLED 开始 25 分钟倒计时,电机短震一次;计时归零时震动两次并自动进入休息阶段。长按或点按 GP7 重置所有状态。
- 久坐联调:为测试可将
SIT_LIMIT临时改为 1 分钟,验证站立震动提醒。 - 串口日志观察:可在主循环中添加
print()输出当前阶段与时间戳,通过串口监视器查看数据。 - 整体集成:确认无误后,将模块用热熔胶或壳体固定,即可放置于工位长期使用。