💡 划重点

  • 本项目以 ESP32-C3 为主控,围绕书桌学习场景,设计一盏能实时感知室内二氧化碳浓度的专注监测台灯。当学习空间空气变得浑浊、二氧化碳浓度升高时,台灯通过 WS2812 灯环的颜色与亮灯数量给出直观提醒,并通过蓝牙将数据发送到手机,帮助用户及时开窗通风。整机目标成本控制在 120 元以内,重点突出环境感知、视觉反馈与低成本可落地三大特点。

需求洞察

目标用户是长时间在家或宿舍书桌前学习、办公的学生与知识工作者。很多人都有类似体验:学习一两个小时后开始犯困、注意力下降,但往往误以为是疲劳,其实可能是房间门窗紧闭导致二氧化碳浓度过高。真实痛点在于,人很难主动察觉空气逐渐变差,等到明显不适时才想起通风,学习效率已经受到影响。

这个项目值得做,是因为它把抽象的空气质量指标转化为书桌上最直观的灯光语言。台灯本身就是学习时一定会放在面前的设备,不需要额外占用桌面,也不会像手机弹窗那样打断专注。它用低成本的传感器和灯环,解决一个高频、真实但常被忽略的问题,非常适合作为硬件编程入门与智能家居原型项目。

方案设计

整体分为四层。

感知层使用 SCD41 二氧化碳传感器,通过 I2C 接口与 ESP32-C3 通信,连续采集二氧化碳浓度、温度与湿度。SCD41 体积小、精度足够,适合桌面设备。

控制层由 ESP32-C3 负责。ESP32-C3 具备低功耗、蓝牙和丰富外设,能够完成传感器数据读取、阈值判断、灯环控制与蓝牙数据上报。按键用于切换自动监测模式与手动呼吸灯模式。

执行层使用 WS2812 灯环。灯环安装在台灯底座或灯罩边缘,根据二氧化碳浓度显示不同颜色和亮灯数量。绿色表示空气良好,黄色表示浓度升高,红色表示需要立即通风。灯光同时兼顾台灯照明和状态指示。

日志与联网层通过 ESP32-C3 的蓝牙功能,将浓度数据周期发送到手机端。手机端可以用通用蓝牙调试工具查看历史趋势,也可以后续扩展为微信小程序或自建应用。

物料清单

物料 数量 用途 估算单价(元) 小计(元)
ESP32-C3 开发板 1 主控与蓝牙通信 18 18
SCD41 二氧化碳传感器模块 1 采集二氧化碳、温湿度 48 48
WS2812 灯环 8 灯 1 状态指示与辅助照明 12 12
轻触按键 1 模式切换 1 1
5V 电源适配器或充电宝 1 整机供电 15 15
电阻、导线、洞洞板、外壳 若干 连接与结构固定 15 15
合计 109

总成本约 109 元,低于 120 元目标。若使用二手或批量采购,成本可进一步压到 90 元以内。

接线与结构

保持给定接线方案:SCD41 的 I2C 数据线 SDA 接 GPIO8,时钟线 SCL 接 GPIO9;WS2812 灯环数据输入接 GPIO10;按键一端接 GPIO3,另一端接 GND,启用内部上拉。SCD41 供电 3.3V,WS2812 灯环供电 5V,ESP32-C3 与传感器共地。

关于按键使用 GPIO3 的说明:该引脚在 ESP32-C3 上电时可能影响启动模式,因此按键串联一个 1 千欧电阻,并保持默认内部上拉,按下时拉低。这样正常上电时引脚为高电平,不会干扰启动。若实际测试发现启动异常,可将按键改接 GPIO2,但本方案优先保持给定 GPIO。

结构上,SCD41 传感器应放置在灯座侧面开孔处,避免被灯罩完全遮挡,保证空气流通。WS2812 灯环安装在灯罩内圈,光线透过亚克力或磨砂片散出。主控和电源板固定在底座内部,按键从底座侧壁露出。

核心代码

以下为 Arduino 骨架,使用 PlatformIO 或 Arduino IDE 均可编译。需要安装 Adafruit NeoPixelSensirion I2C SCD4x 库。


#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <SensirionI2cScd4x.h>

#define PIN_LED 10
#define PIN_KEY 3
#define LED_COUNT 8

Adafruit_NeoPixel ring(LED_COUNT, PIN_LED, NEO_GRB + NEO_KHZ800);
SensirionI2cScd4x scd41;

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9);
  ring.begin();
  ring.setBrightness(40);
  ring.clear();
  ring.show();

}

void loop() {
  bool keyPressed = digitalRead(PIN_KEY) == LOW;
  static bool lastKey = HIGH;

  if (keyPressed && lastKey == HIGH) {
    delay(50);
    if (digitalRead(PIN_KEY) == LOW) {
      breathMode();
    }
  }
  lastKey = keyPressed;

  uint16_t co2 = 0;
  float temp = 0, hum = 0;

  if (co2 < 800) {
    showLevel(2, 0, 255, 0);
  } else if (co2 < 1200) {
    showLevel(5, 255, 180, 0);
  } else {
    showLevel(8, 255, 0, 0);
  }

  Serial.printf("CO2:%d ppm T:%.1f C H:%.1f %%\n", co2, temp, hum);
  delay(2000);
}

void showLevel(int count, int r, int g, int b) {
  ring.clear();
  for (int i = 0; i < count; i++) {
  }
  ring.show();
}

void breathMode() {
  for (int i = 0; i < 120; i++) {
    int brightness = 40 + 40 * sin(i * 0.05);
    for (int j = 0; j < LED_COUNT; j++) {
    }
    ring.show();
    delay(30);
  }
  ring.setBrightness(40);
  ring.clear();
  ring.show();
}

调试步骤

第一步,单独测试电源。确认 ESP32-C3 上电后指示灯正常,3.3V 与 5V 输出稳定。第二步,扫描 I2C 设备。下载 I2C 扫描程序,确认地址 0x62 出现。第三步,读取原始二氧化碳数据。将 SCD41 靠近口鼻呼气,观察串口数值是否明显上升。第四步,测试灯环。手动设置不同颜色和亮灯数量,确认 WS2812 方向正确。第五步,测试按键。按下按键观察串口是否输出模式切换信息。第六步,整体联调。将台灯置于小房间内,关闭门窗,等待 10 到 20 分钟,观察灯环是否从绿变黄再到红。第七步,测试蓝牙。使用手机端通用蓝牙调试工具扫描并连接设备,确认能收到浓度字符串。

设计图

CO₂ 学习专注监测台灯结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报