桌面作业提醒机器人:硬件编程项目方案

💡 划重点

  • 主控芯片:ESP32,支持Wi-Fi与蓝牙,成本低且性能充足。
  • 核心功能:通过人体传感器感知入座,利用OLED屏与蜂鸣器提醒作业计划,用舵机做出“点头”或“摇头”等趣味反馈。
  • 目标成本:40 元以内,所有物料均为常见模块,兼容性强。
  • 关键接线:OLED使用I2C接口(SDA=21,SCL=22),PIR人体传感器接GPIO18,舵机接GPIO13,蜂鸣器接GPIO27。
  • 开发方式:采用Arduino框架编写,代码结构清晰,适合初学者和进阶用户二次开发。

需求洞察

目标用户:主要面向中小学生、考研自习者以及在书桌前长时间进行脑力劳动的人群。他们的学习桌通常在卧室或书房,环境较为安静,但缺乏外部学习监督,容易被手机、杂念等干扰。

真实痛点:学生坐下后往往忘记时间,要么一坐就是数小时导致颈椎疲劳,要么刚坐下几分钟就起身玩手机。传统的番茄钟需要手动操作,而家长提醒又容易引发亲子矛盾。这个项目解决的问题是“坐在书桌前却没有按照计划学习”这一高频且真实的场景。

为什么值得做:首先,硬件成本低,一套不超过40元,具有很高的可复制性。其次,ESP32是其学习平台;通过这一项目可综合练习传感器输入、执行器输出、无线通信和外壳装配等多项技能。最后,这个项目具有实用价值,能真正改变用户的学习习惯,不是“吃灰玩具”。

方案设计

感知层

感知层由PIR人体红外传感器构成,安置于桌面朝向用户的支架上,用于检测用户是否坐在书桌前。当用户入座后,传感器输出高电平信号至ESP32的GPIO18。为了降低误报,可在代码中设置连续高电平超过3秒才判定为“有效入座”。

控制层

控制层以ESP32为核心,负责信号采集、状态管理和任务调度。系统维护一个简单的时间状态机,分为“未入座”、“已入座未开始任务”、“任务进行中”、“超时提醒”四种状态。使用定时器记录在座时长,并与设定的学习时段(例如50分钟)进行对比。此外,ESP32可获取本地时间(通过NTP),在预设的学习时段内若检测到人,则自动启动提醒流程。

执行层

执行层包括OLED显示屏、舵机和蜂鸣器。

日志/联网层

ESP32通过Wi-Fi连接到本地网络,使用NTP获取时间。为保证日志不依赖外部服务,使用SD卡或闪存记录每日入座与离开的时间戳。若未来需要实现远程监控,可通过MQTT将日志发送至家中服务器或手机APP,但该功能初始版本不强制开启。

物料清单

序号 物料名称 数量 用途 估算单价(元)
1 ESP32开发板 1 主控芯片 18
2 0.96寸OLED显示屏(I2C) 1 状态显示 8
3 PIR人体传感器 1 感知用户是否入座 3
4 SG90舵机 1 制作机械提醒动作 4
5 有源蜂鸣器 1 声音提醒 2
6 面包板与跳线若干 1套 电路搭建 3
7 纸板或亚克力外壳 1 固定传感器与舵机 1
8 杜邦线、扎带、胶枪 若干 组装 1
合计 40元以内(按实际采购冗余,总价约39元)

接线与结构

接线明确如下:

微调说明:原定GPIO没有变动。若使用SSD1306的OLED,地址通常为0x3C;若为其他地址,可在代码中修改。舵机电源建议从5V引脚接入,避免ESP32板载稳压器过载。

核心代码

以下为Arduino骨架,可直接在PlatformIO或Arduino IDE中编译。不依赖复杂库,仅使用Wire、Adafruit_SSD1306和ESP32Servo。


#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <ESP32Servo.h>

#define OLED_SDA 21
#define OLED_SCL 22
#define PIR_PIN 18
#define SERVO_PIN 13
#define BUZZER_PIN 27

Adafruit_SSD1306 display(128, 64, &Wire;, -1);
Servo reminderServo;

const int STUDY_MINUTES = 50;
unsigned long sitStartTime = 0;
bool isSitting = false;
bool isReminded = false;

void setup() {
  pinMode(PIR_PIN, INPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  display.clearDisplay();
  display.setTextSize(1);
  reminderServo.write(90);
  Serial.begin(115200);
}

void loop() {
  int pirState = digitalRead(PIR_PIN);
  if (pirState == HIGH && !isSitting) {
    isSitting = true;
    sitStartTime = millis();
    isReminded = false;
    playTone(200, 100);
    nodHead(2);
    displayMessage("Welcome!");
  }
  if (isSitting && !isReminded && (millis() - sitStartTime > STUDY_MINUTES * 60000UL)) {
    isReminded = true;
    playTone(800, 200);
    playTone(400, 200);
    playTone(800, 200);
    shakeHead(3);
    displayMessage("Break Time!");
  }
  if (pirState == LOW && isSitting) {
    isSitting = false;
    isReminded = false;
    reminderServo.write(90);
  }
  delay(100);
}

void nodHead(int times) {
  for (int i = 0; i < times; i++) {
    reminderServo.write(60);
    delay(200);
    reminderServo.write(120);
    delay(200);
  }
  reminderServo.write(90);
}

void shakeHead(int times) {
  for (int i = 0; i < times; i++) {
    reminderServo.write(30);
    delay(200);
    reminderServo.write(150);
    delay(200);
  }
  reminderServo.write(90);
}

void playTone(int freq, int ms) {
  tone(BUZZER_PIN, freq, ms);
  delay(ms + 20);
  noTone(BUZZER_PIN);
}

void displayMessage(String msg) {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println(msg);
  display.display();
}

此代码编译时需安装Adafruit_SSD1306库与ESP32Servo库。若蜂鸣器为无源蜂鸣器,建议在信号线上串联一个1kΩ电阻。

调试步骤

  1. 硬件自检:先单独测试OLED,烧写简单I2C扫描代码确认地址。再分别测试PIR,用手遮挡传感器触发蜂鸣器。
  2. 舵机校正:上电时舵机应处于90度位置。若上电后抖动,检查电源和接地。
  3. 状态机验证:将STUDY_MINUTES临时改为0.2分钟,快速模拟超时,观察舵机点头与蜂鸣器提醒是否正常。
  4. NTP时间校准:若后续加入联网功能,需在setup()中添加Wi-Fi连接,并调用configTime。注意蜂窝或校园网可能屏蔽NTP端口。
  5. 整体联动测试:放置在桌面,正常入座30秒,判断是否误触发;离开后是否重置状态。

设计图

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

本设计图展示系统的信息流向:感知输入(PIR与时钟)→控制处理(ESP32状态机)→执行反馈(OLED、舵机、蜂鸣器)→数据上报(Wi-Fi日志,可选)。整体模块化程度高,各环节解耦,便于后期升级。用户可在调试过程中将舵机与小熊猫模型固定于OLED上方,形成完整的桌面陪伴式提醒机器人。