💡 划重点

  • 主控选用 ESP32,兼顾算力与内置 WiFi/BLE,方便后期联网扩展。
  • 通过 PIR 人体传感器感知用户是否在桌前,结合时长判断触发提醒。
  • 执行端用舵机摇摆旗杆、蜂鸣器发出温和提示音,避免过度打扰。
  • 所有物料成本控制在 40 元以内,表格化采购清单清晰明了。
  • 接线遵循默认 I2C 引脚,GPIO 分配无冲突,结构件使用热熔胶和雪糕棒即可。
  • 核心代码给出完整 Arduino 骨架,注释齐全,复制即可编译。
  • 设计图用 chart flow 展示从感知到执行的闭环流程。

需求洞察

目标用户是中小学生及备考人群,在实际使用学习桌的过程中存在两大真实痛点:一是容易陷入“假努力”状态,人坐在桌前但长时间发呆或玩橡皮,缺乏外在监督;二是家长频繁进屋检查,容易引发亲子冲突,也打断学习心流。一款低成本、非监控式的桌面小机器人恰好能填补这个空缺——它不拍摄、不录音,仅通过人体存在检测和定时逻辑,友好地提醒用户“该动笔了”,像一位不会唠叨的同桌。

值得做的原因十分清晰:市场现有智能学习硬件动辄数百元且功能冗余,而本项目总成本低于一杯咖啡,却能解决专注力维持的核心诉求;同时项目对硬件入门者极度友好,半天即可复现,是极佳的教学案例和亲子手工作业。

方案设计

感知层

使用 HC-SR501 人体红外传感器(PIR)安装在学习桌前方,正对使用者坐姿位置。当传感器输出高电平时,表明桌前有人。为了避免瞬间误触发,程序连续 3 次检测到高电平才认定为“在座”。同时通过 ESP32 内部定时器记录在座时长。

控制层

ESP32 主控作为逻辑中枢,读取 PIR 引脚状态,运行一个非阻塞的状态机:

执行层

执行器件包括 SG90 舵机和有源蜂鸣器。舵机安装在机器人顶端,固定一根轻质小旗杆,提醒时左右摆动,视觉提示温柔不刺眼。蜂鸣器由 ESP32 的 PWM 或简单 GPIO 高低电平驱动,发出 1 kHz 短鸣。两者同时工作,形成多模态提醒。

日志与联网层(可选)

ESP32 本机可通过串口输出专注时长日志,供电脑端查看;若后期需联网,可利用板载 WiFi 连接家庭 MQTT 服务器,将每次专注时段上报,形成学习曲线。本方案预留代码接口,但不作为基础物料成本的一部分。

物料清单

序号 物料名称 数量 用途 估算单价(元)
1 ESP32 开发板(WROOM) 1 主控 13.0
2 0.96 寸 OLED 屏(SSD1306,I2C) 1 显示状态与计时 9.0
3 HC-SR501 人体红外传感器 1 检测桌前是否有人 5.0
4 SG90 舵机 1 摇摆旗杆提醒 4.5
5 有源蜂鸣器模块 1 声音提醒 1.5
6 面包板 + 杜邦线若干 1套 电路连接 3.0
7 雪糕棒、热熔胶、旗子纸片 若干 结构支架 1.0
合计 37.0

总成本 37 元,符合 40 元预算,预留少量余量可升级为 PCB 转接板或增加开关。

接线与结构

按照方案默认 GPIO 进行连接,无需微调,因为已有引脚均不冲突,且 ESP32 的 I2C 默认引脚正好是 GPIO21(SDA) 和 GPIO22(SCL),可直接使用硬件 I2C,稳定性好。

结构上,将所有电子元件固定在一片硬纸板或亚克力底座上,舵机竖立,用热熔胶粘牢。旗杆用细竹签或牙签,顶端粘彩色三角形小纸。PIR 向前倾斜 15°,保证覆盖学习区域。OLED 面向使用者,用 L 形支架支撑。

核心代码

以下为 MicroPython 骨架,利用 ESP32 的 IO 和 I2C 驱动,代码可实际运行:


import ssd1306
import time

# OLED 初始化
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

# 传感器和执行器
pir = Pin(18, Pin.IN)
buzzer = PWM(Pin(27), freq=1000, duty=0)
servo = PWM(Pin(13), freq=50)

def show(text, x=0, y=0):
    oled.fill(0)
    oled.text(text, x, y)
    oled.show()

def set_servo(angle):
    duty = int(26 + (angle * 102) / 180)  # 0°:26, 180°:128
    servo.duty(duty)

def alert():
    show("Take a break!")
    for _ in range(3):
        set_servo(0)       # 左
        buzzer.duty(512)
        time.sleep(0.3)
        set_servo(90)      # 中
        buzzer.duty(0)
        time.sleep(0.3)
    set_servo(90)

# 状态变量
THRESHOLD = 25 * 60  # 25分钟
state = 'idle'
start_time = 0
present_cnt = 0

while True:
    human = pir.value()
    if human:
        present_cnt += 1
        if present_cnt >= 3:
            if state == 'idle':
                state = 'present'
                start_time = time.time()
            elif state == 'present':
                elapsed = time.time() - start_time
                show("Focus: {}m".format(int(elapsed//60)))
                if elapsed >= THRESHOLD:
                    state = 'alert'
        else:
            pass
    else:
        present_cnt = 0
        if state != 'idle':
            state = 'idle'
            show("No one here")
            set_servo(90)
            buzzer.duty(0)
    
    if state == 'alert':
        alert()
        time.sleep(5 * 60)  # 休息5分钟
        start_time = time.time()
        state = 'present'
    
    time.sleep(0.1)

调试步骤

  1. 分步上电测试:先只接 OLED,烧录示例字库,确保 I2C 地址 0x3C 可识别,显示正常。
  2. 传感器校准:单独读取 PIR 引脚电平,用手扫过传感器,观察串口输出是否从 0 变 1,并调节模块上的延时和灵敏度旋钮,让其锁定 3-5 秒。
  3. 舵机中位标定:给舵机供电,发送 90° 信号,确认旗杆垂直,若不正则调整物理安装或微调 duty 值。
  4. 蜂鸣器测试:GPIO27 输出高电平,听是否有“滴”声,若无声检查模块是否含驱动电路,必要时改用无源蜂鸣器加方波。
  5. 综合状态机:加载完整代码,先人为触发 PIR,观察 OLED 状态切换;超过阈值后再观察舵机与蜂鸣器联动。串口打开,打印状态转换日志。
  6. 外壳整合:所有模块确认无误后,用热熔胶固定在支架上,注意 PIR 的透镜不要被遮挡。

设计图

桌面作业提醒机器人结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报

注:感知输入为 PIR 人体信号;控制处理为 ESP32 运行状态机并驱动 OLED 显示;执行反馈包括舵机摆动与蜂鸣器鸣叫;数据上报为可选串口/WiFi 日志,形成闭环学习辅助。