💡 划重点
- 本项目以 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 NeoPixel 和 Sensirion 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 分钟,观察灯环是否从绿变黄再到红。第七步,测试蓝牙。使用手机端通用蓝牙调试工具扫描并连接设备,确认能收到浓度字符串。