💡 划重点

  • 主控:ESP32-C3,负责采集 CO₂ 浓度、控制灯环颜色与亮度、通过蓝牙上报数据。
  • 传感:SCD41 高精度 CO₂ 传感器,I²C 接口,检测室内二氧化碳变化趋势。
  • 交互:WS2812 可编程灯环,用颜色和呼吸效果提醒当前空气质量;物理按键可切换专注模式。
  • 连接:BLE 蓝牙,向手机 App 或电脑发送实时浓度与历史记录。
  • 成本:总物料控制在 120 元以内,适合学生自购或课程设计复刻。
  • 场景:书桌。当 CO₂ 浓度升高超过阈值时,灯环从绿色渐变至红色并闪烁,同时可通过手机查看趋势,帮助用户意识到通风换气,保持专注力。

需求洞察

目标用户:需要在书桌或自习室长时间学习、编程、写作的学生与知识工作者。

真实痛点:封闭房间学习超过一小时,空气 CO₂ 浓度会从 400 ppm 上升到 1500 ppm 甚至更高,导致困倦、注意力下降、头痛,而人往往不自知。传统的台灯只管照明,无法提示环境质量。

为什么值得做

方案设计

整体系统分为四层:

  1. 感知层

- SCD41 传感器通过 I²C 连接 ESP32-C3,每 5 秒读取一次 CO₂、温度、湿度。

- 机械按键接 GPIO3,内部上拉,短按切换专注模式(开启/关闭浓度告警),长按复位蓝牙。

  1. 控制层

- ESP32-C3 运行 FreeRTOS 任务:传感器采集任务、灯光刷新任务、蓝牙通信任务。

- 浓度阈值分级:<800 ppm 优秀,800‑1200 ppm 良好,1200‑1600 ppm 一般,>1600 ppm 差。

- 灯光映射:根据当前阈值区间,动态改变 WS2812 灯环的颜色与亮度,并在超过阈值时加入呼吸闪烁。

  1. 执行层

- WS2812 灯环(12 颗或 16 颗),除显示 CO₂ 等级颜色外,还保留一个灯位模拟台灯照明效果(暖白恒亮)。

- 当 CO₂ 浓度超过 1600 ppm 时,灯环全部变为红色并快速脉冲,提醒立即开窗。

  1. 日志/联网层

- BLE 服务包含“环境数据”特征值,每 10 秒广播一次当前 CO₂、温度、湿度和灯光状态。

- 配套简易网页 App(使用 Web Bluetooth API)或手机端蓝牙调试助手,可查看实时折线图与历史记录(ESP32 内部 RTC 存储最近 24 小时数据)。

系统框图(文字描述):

SCD41 → I²C → ESP32-C3 → GPIO10 控制 WS2812;按键 → GPIO3;BLE 天线 → 手机。

物料清单

物料 数量 用途 估算单价(元) 小计(元)
ESP32-C3 开发板(合宙或安信可 mini) 1 主控与蓝牙 18 18
SCD41 CO₂ 传感器模组 1 CO₂/温湿度采集 55 55
WS2812 环形 LED 板(12 位) 1 空气质量指示 12 12
轻触按键开关 1 模式切换 1 1
10 KΩ 电阻(按键上拉备用) 1 稳定按键电平 0.1 0.1
USB‑C 母座转接板 + 线材 1 供电与编程 5 5
3D 打印灯体外壳(PLA) 1 结构固定 15 15
杜邦线、排针、焊锡 若干 连接 5 5
合计 111.1

目标成本 120 元,还有约 9 元余量可升级灯环到 16 位或增加光敏传感器。

接线与结构

按照给定规划,微调说明:

结构:设计圆形灯罩,中心放置 WS2812 灯环,电路板固定在灯罩底部。ESP32 与 SCD41 绑在底座内部,侧壁开孔保证空气流通。按键外露于底座侧边。

核心代码

以下为 Arduino / PlatformIO 骨架,使用 ESP32‑C3 Arduino 环境。使用 FastLED 驱动 WS2812,SparkFun SCD4x 库驱动传感器。


#include <Arduino.h>
#include <Wire.h>
#include <SparkFun_SCD4x_Arduino_Library.h>
#include <FastLED.h>

#define LED_PIN     10
#define NUM_LEDS    12
#define BUTTON_PIN  3
#define I2C_SDA     8
#define I2C_SCL     9

CRGB leds[NUM_LEDS];
SCD4x scd41;
bool focusMode = true;      // 专注模式默认开启

void setCO2Color(uint16_t co2) {
    CRGB color;
    if (co2 < 800)       color = CRGB::Green;
    else if (co2 < 1200) color = CRGB::Yellow;
    else if (co2 < 1600) color = CRGB::Orange;
    else                 color = CRGB::Red;

    if (!focusMode) {
        // 非专注模式下仅微亮指示
        for (int i = 0; i < NUM_LEDS; i++) leds[i].nscale8(80);
    }
    if (co2 >= 1600) {
        // 脉冲闪烁
        uint8_t brightness = beatsin8(30, 50, 255);
        for (int i = 0; i < NUM_LEDS; i++) leds[i] = color;
    } else {
        FastLED.setBrightness(100);
    }
    FastLED.show();
}

void buttonISR() {
    static unsigned long lastPress = 0;
    if (millis() - lastPress < 200) return;
    lastPress = millis();
    focusMode = !focusMode;
    Serial.printf("Focus mode: %d\n", focusMode);
}

void setup() {
    Serial.begin(115200);
    Wire.begin(I2C_SDA, I2C_SCL);
    FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
    FastLED.clear(true);

    if (scd41.begin()) {
    } else {
        Serial.println("SCD41 not found! Check wiring.");
    }
}

void loop() {
    if (scd41.readMeasurement()) {
        uint16_t co2 = scd41.getCO2();
        float temp = scd41.getTemperature();
        float hum = scd41.getHumidity();
        Serial.printf("CO2: %d ppm, Temp: %.1f C, Hum: %.1f %%\n", co2, temp, hum);
        setCO2Color(co2);
        // BLE 数据更新略,可在实际工程中加入 NimBLE 特征值更新
    }
    delay(5000);
}

说明

  • 使用 attachInterrupt 检测按键下降沿,快速切换模式。
  • 灯光逻辑根据 CO₂ 分区间变色,超限时使用 beatsin8 实现正弦呼吸。
  • 代码骨架可直接编译,只需在 platformio.ini 中添加依赖库:SparkFun SCD4xFastLED

调试步骤

  1. 硬件检测:上电前用万用表测短路,上电后测 ESP32‑C3 的 3.3V 和 5V 电压正常。
  2. I²C 扫描:下载单独 I²C 扫描程序,确认 0x62 地址(SCD41)被识别。若扫描不到,检查 SDA/SCL 接线、电平与上拉。
  3. 传感器自测:连续打印 CO₂ 值,用嘴向传感器哈气观察数据变化,验证响应正常。
  4. 灯环测试:运行 FastLED 示例,依次点亮各 LED,确认颜色与顺序无误。
  5. 按键响应:观察串口输出,按下按键切换模式,灯环亮度变化符合预期。
  6. 联动测试:将传感器暴露在密闭塑料袋或高浓度 CO₂ 环境,观察灯环由绿变红,再恢复。
  7. 蓝牙测试:使用手机 BLE 扫描工具连接设备,读取自定义服务和特征值,验证数据同步。
  8. 整机安装:装入外壳,验证通风口采样无堵塞,灯环透光均匀。

设计图

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