第2课 智能教室空气质量监测系统#
让我们用 ENS160 空气质量传感器模块和SK6812 RGB灯模块,打造一个智能教室空气质量监测系统,当空气质量不佳时,RGB灯会发出警报,为师生创造一个健康舒适的学习环境!
2.1 SK6812 RGB灯模块#
我们这款 SK6812 RGB灯模块集成了四个可编程RGB灯,支持多种颜色和动态效果,可通过简单的信号控制实现丰富的灯光效果。

2.1.1 参数#
工作电压:DC 3.3 ~ 5V
最大功率:1W
IC型号:4颗/SK6812
灰度等级:25
发光角度:180°
发光颜色:可以通过控制器调为白,红,黄,蓝,绿等
工作温度:-10°C ~ +50°C
尺寸:32mm x 23mm x 8mm
定位孔大小:直径为 4.8 mm
接口:间距2.54 mm,3pin防反接口
2.1.2 原理#
SK6812 RGB灯模块采用单线串行通信协议,每个灯珠内置驱动IC,通过数据线逐级传输信号,可独立控制每颗灯珠的亮度和颜色,形成动态光效。
每个灯珠包含红(R)、绿(G)、蓝(B)三个颜色的 LED,可以通过调节三原色的亮度混合出任意颜色。
灯珠序号:

2.1.3 实验代码#
#include <Adafruit_NeoPixel.h>
#define LED_PIN 4 // 控制信号引脚
#define LED_COUNT 4 // LED 灯珠数量
// 创建 NeoPixel 对象
Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
leds.begin(); // 初始化 LED 灯带
leds.show(); // 关闭所有灯珠
leds.setBrightness(100); // 设置亮度(0~255)
}
void loop() {
// 设置第一个灯珠为红色
leds.setPixelColor(0, 255, 0, 0);
// 设置第二个灯珠为绿色
leds.setPixelColor(1, 0, 255, 0);
// 设置第三个灯珠为蓝色
leds.setPixelColor(2, 0, 0, 255);
// 设置第四个灯珠为白色
leds.setPixelColor(3, 255, 255, 255);
// 更新显示
leds.show();
delay(1000);
// 关闭所有灯珠
leds.clear();
leds.show();
delay(1000);
}
2.1.4 代码说明#
1. 硬件与库配置
#include <Adafruit_NeoPixel.h>
引入 Adafruit_NeoPixel 库,该库用于控制 SK6812 可编程 RGB LED 灯带。
#define LED_PIN 4
定义控制信号引脚为主板的 IO4 引脚。
#define LED_COUNT 4
定义 LED 灯珠的数量为 4 个。
Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
创建一个 NeoPixel 对象,命名为
leds。参数说明:
LED_COUNT:灯珠数量(4 个)。LED_PIN:控制信号引脚(IO4)。NEO_GRB + NEO_KHZ800:指定 LED 灯珠的颜色顺序(红-绿-蓝)和通信频率(800kHz)。
2. 初始化设置(setup函数)
leds.begin();
初始化 LED 灯带,设置引脚模式和通信协议。
leds.show();
更新 LED 灯带的显示状态。由于此时没有设置颜色,所有灯珠会关闭。
leds.setBrightness(100);
设置 LED 灯珠的亮度,范围为 0(最暗)到 255(最亮)。
3. 主循环(loop函数)
leds.setPixelColor(index, red, green, blue);
设置指定序号的灯珠颜色。
参数说明:
index:灯珠的序号(从 0 开始)red:红色分量(0 ~ 255)green:绿色分量(0 ~ 255)blue:蓝色分量(0 ~ 255)
leds.show();
更新 LED 灯带的显示状态,使设置的颜色生效。
delay(1000);
延时 1 秒,保持当前灯珠状态。
leds.clear();
关闭所有灯珠。
leds.show();
更新显示状态,关闭所有灯珠。
delay(1000);
延时 1 秒,保持灯珠关闭状态。
2.1.5 实验结果#
外接电源,选择好正确的开发板板型(ESP32 Dev Module)和 适当的串口端口(COMxx),然后单击
按钮上传代码。代码上传成功后,你能看到循环过程:
4 个 LED 灯珠会依次点亮为红色、绿色、蓝色和白色,持续 1 秒,由于速度过快你可能看不到依次点亮的这个过程。
然后所有灯珠关闭,持续 1 秒。

2.2 ENS160空气质量传感器#
ENS160 是一款高精度数字空气质量传感器,能够实时检测空气中的挥发性有机化合物(VOCs)、二氧化碳(CO₂)和空气质量指数(AQI)。该传感器专为室内空气质量检测而设计,能直接输出多种IAQ(TVOC、eCO2、AQI)数据。广泛应用于环境监测、智能家居和健康设备中。

2.2.1 参数#
工作电压:DC 3.3 ~ 5V
工作电流:29 mA
预热时间:< 3 分钟
通讯接口:I2C
I2C地址:默认为0x53,可修改为0x52
工作温度:-10°C ~ +50°C
工作湿度:5 %RH ~ 95 %RH
eCO₂测量范围:400 ppm ~ 65000 ppm
TVOC测量范围:0 ppb ~ 65000 ppb
尺寸:32mm x 23mm x 8mm
定位孔大小:直径为 3.2 mm
接口:间距2.54 mm,4pin防反接口
2.2.2 原理#
ENS160 的工作原理
ENS160 通过内置的金属氧化物半导体传感器检测空气中的气体成分,具体原理如下:
VOCs 检测:
检测原理
传感器表面的金属氧化物与空气中的 VOCs 发生化学反应,导致电阻变化,通过测量电阻变化来检测 VOCs 浓度。
不过,它无法区分具体是哪种 VOCs,而是将所有可检测的 VOCs 混合信号 折算为总挥发性有机物(TVOC)浓度(单位ppb)输出。
因此,ENS160 直接提供的是 TVOC 数据,而非单一 VOCs 成分,适合快速评估空气整体污染水平,但无法精确分析具体气体种类。
TVOC检测范围
输出单位:ppb(parts per billion,十亿分之一)
检测范围:0 ~ 65,000 ppb(注:实际有效精度范围通常为0 ~ 10,000 ppb)
TVOC(总挥发性有机物浓度)等级参考
TVOC浓度 (ppb)
等级划分
健康影响与建议
0-250
优秀
空气质量极佳,对人体无影响,适合长时间停留
250-500
良好
空气质量良好,敏感人群可能出现轻微不适,建议适度通风
500-1000
轻度污染
空气质量可接受,长期暴露可能导致头痛、疲劳,需加强通风
1000-3000
中度污染
空气质量不佳,可能引发眼喉刺激、嗜睡,建议减少暴露并排查污染源
>3000
重度污染
严重污染,可能导致神经系统损伤、肝肾毒性,必须立即通风或撤离
CO₂ 估算:
估算原理
ENS160 无法直接测量 CO₂,而是通过检测空气中的 VOCs(挥发性有机物)浓度,结合内置算法估算出 eCO₂(等效二氧化碳)。eCO₂ 是一种间接的 CO₂ 近似值,适用于趋势监测,但精度不如专业 CO₂ 传感器。
eCO₂输出范围
单位:ppm(parts per million,百万分之一)
检测范围:400 ~ 65,000 ppm(注:实际有效精度范围通常为400 ~ 5,000 ppm)
eCO₂等级参考
eCO₂
等级
建议
400-600
优秀
空气质量极佳,通风良好,
适合长时间停留600-800
良好
空气质量可接受,建议适度通风
800-1000
轻度污染
空气质量下降,需加强通风
1000-1500
重度污染
明显闷浊感,
建议减少人员密度或强制换气>1500
危险
严重缺氧环境,必须立即通风或撤离
IAQ 计算
计算原理
根据 TVOC 和 eCO₂ 的浓度,结合内置算法计算出室内空气质量指数(AQI)。
AQI(空气质量指数)等级参考
AQI指数
AQI等级
健康影响
1
优秀
空气清新,无健康风险
2
良好
基本安全,敏感人群或轻微不适
3
中等
可察觉异味,可能引发头痛、疲劳
4
较差
明显刺激眼喉,长期暴露有害健康
5
极差
强烈不适,急性健康风险高
ENS160 的控制原理
ENS160 的控制原理基于 I²C 通信协议,通过发送和接收特定的命令和数据来控制传感器并读取测量结果。
I²C 通信地址
默认 I²C 通信地址为 0x53。
如需更改为 0x52,可在模块的 0X52 空焊盘处焊接一个 0603 封装的 0Ω 电阻,同时修改代码中的设备地址。

2.2.3 实验代码#
#include <DFRobot_ENS160.h>
#include <Wire.h>
// 使用I2C通信,地址默认为0x53
DFRobot_ENS160_I2C ENS160(&Wire, 0x53);
void setup(void){
Serial.begin(9600);
// 初始化传感器
while(NO_ERR != ENS160.begin()) {
Serial.println("与设备的通信失败,请检查连接情况.");
delay(3000);
}
Serial.println("开始好的!");
// 设置电源模式为标准气体感应模式
ENS160.setPWRMode(ENS160_STANDARD_MODE);
// 设置环境温度和湿度用于校准(示例值:25°C,50%RH)
ENS160.setTempAndHum(25.0, 50.0);
}
void loop(){
// 获取传感器工作状态
uint8_t Status = ENS160.getENS160Status();
Serial.print("传感器运行状态: ");
Serial.println(Status);
// 获取空气质量指数(1-5)
uint8_t AQI = ENS160.getAQI();
Serial.print("空气质量指数: ");
Serial.println(AQI);
// 获取TVOC浓度(0-65000 ppb)
uint16_t TVOC = ENS160.getTVOC();
Serial.print("TVOC浓度: ");
Serial.print(TVOC);
Serial.println(" ppb");
// 获取等效CO2浓度(400-65000 ppm)
uint16_t ECO2 = ENS160.getECO2();
Serial.print("等效CO2浓度: ");
Serial.print(ECO2);
Serial.println(" ppm");
Serial.println();
delay(1000);
}
2.2.4 代码说明#
1. 头文件引入和初始化库配置
#include <DFRobot_ENS160.h>
#include <Wire.h>
DFRobot_ENS160_I2C ENS160(&Wire, 0x53);
DFRobot_ENS160_I2C ENS160(&Wire, 0x53):创建 ENS160 传感器对象使用 I2C 通信(&Wire)
传感器地址为 0x53(默认地址)
2. 初始化设置(setup函数)
void setup(void){
Serial.begin(9600);
// 初始化传感器
while(NO_ERR != ENS160.begin()) {
Serial.println("与设备的通信失败,请检查连接情况.");
delay(3000);
}
Serial.println("开始好的!");
// 设置电源模式为标准气体感应模式
ENS160.setPWRMode(ENS160_STANDARD_MODE);
// 设置环境温度和湿度用于校准(示例值:25°C,50%RH)
ENS160.setTempAndHum(25.0, 50.0);
}
传感器初始化:
ENS160.begin():尝试初始化传感器使用 while 循环持续尝试,直到初始化成功
每次失败后等待 3 秒(delay(3000))
工作模式设置:
setPWRMode(ENS160_STANDARD_MODE):设置传感器为标准工作模式
环境参数设置:
setTempAndHum(25.0, 50.0):提供环境温度和湿度,用于传感器校准和补偿
3. 主循环(loop函数)
void loop(){
// 获取传感器工作状态
uint8_t Status = ENS160.getENS160Status();
Serial.print("传感器运行状态: ");
Serial.println(Status);
// 获取空气质量指数(1-5)
uint8_t AQI = ENS160.getAQI();
Serial.print("空气质量指数: ");
Serial.println(AQI);
// 获取TVOC浓度(0-65000 ppb)
uint16_t TVOC = ENS160.getTVOC();
Serial.print("TVOC浓度: ");
Serial.print(TVOC);
Serial.println(" ppb");
// 获取等效CO2浓度(400-65000 ppm)
uint16_t ECO2 = ENS160.getECO2();
Serial.print("等效CO2浓度: ");
Serial.print(ECO2);
Serial.println(" ppm");
Serial.println();
delay(1000);
}
首先,通过
getENS160Status()获取传感器工作状态,确保设备正常运行。然后依次读取三种关键参数:
getAQI()获取1-5级的综合空气质量指数getTVOC()检测总挥发性有机物浓度getECO2()测量等效二氧化碳值最后,所有数据通过串口输出显示,并以
delay(1000)控制每秒采集一次的频率,形成完整的空气质量监测循环。
2.2.5 实验结果#
外接电源,选择好正确的开发板板型(ESP32 Dev Module)和 适当的串口端口(COMxx),然后单击
按钮上传代码。代码上传成功后,单击Arduino IDE右上角的
,打开串口监视器,设置波特率为 9600。
传感器首次上电需预热3-5分钟达到稳定,稳定后可以对着ENS160空气质量传感器哈气(吹气),可以看到打印数据,

⚠️ 特别提醒:如果串口监视器打印数据都是0,请按一下ESP32主控板上的复位键,等待几秒钟。

2.2.6 常见问题解决#
代码上传成功后串口监视器无任何信息打印?
确保模块已接线且正确接线,然后按下主板的复位键:

2.3 智能教室空气质量监测系统#
在前面的课程中,我们已经掌握了 SK6812 RGB灯模块 的色彩控制原理和 ENS160空气质量传感器 的数据采集方法。现在,让我们将这些技术结合起来,动手制作一个智能教室空气质量监测系统!
通过这个项目,我们将实现一个能够实时监测教室内的 eCO₂浓度(等效二氧化碳浓度)的智能装置。当空气质量下降(eCO₂浓度过高)时,系统会自动触发 SK6812 RGB灯红色警报,提醒师生及时通风换气,保障健康的学习环境。
让我们一起打造这个既实用又富有科技感的智能监测系统吧!
2.3.1 流程图#

2.3.2 实验代码#
#include <DFRobot_ENS160.h>
#include <Adafruit_NeoPixel.h>
// 硬件配置
#define LED_PIN 4 // RGB灯控制引脚
#define LED_COUNT 4 // LED灯珠数量
#define I2C_ADDR 0x53 // ENS160默认I2C地址
// eCO2浓度等级阈值 (ppm)
#define ECO2_EXCELLENT 400
#define ECO2_GOOD 800
#define ECO2_MODERATE 1000
#define ECO2_POOR 1500
// 创建对象
DFRobot_ENS160_I2C ENS160(&Wire, I2C_ADDR);
Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
// 初始化ENS160
while (NO_ERR != ENS160.begin()) {
Serial.println("与设备的通信失败,请检查连接情况.");
delay(3000);
}
Serial.println("开始可以了!");
// 设置传感器模式
ENS160.setPWRMode(ENS160_STANDARD_MODE);
ENS160.setTempAndHum(25.0, 50.0); // 设置校准温湿度
// 初始化RGB灯带
leds.begin();
leds.show(); // 初始清空灯带
leds.setBrightness(100); // 中等亮度
}
void loop() {
// 获取eCO2浓度
uint16_t eco2 = ENS160.getECO2();
Serial.print("eCO2 浓度: ");
Serial.print(eco2);
Serial.println(" ppm");
// 根据空气质量控制LED
updateAirQualityLED(eco2);
delay(2000); // 每2秒更新一次
}
// 空气质量可视化函数
void updateAirQualityLED(uint16_t eco2) {
if (eco2 <= ECO2_GOOD) {
// 优/良(绿色常亮)
setAllLEDs(0, 255, 0);
}
else if (eco2 <= ECO2_MODERATE) {
// 一般(蓝色常亮)
setAllLEDs(0, 0, 255);
}
else if (eco2 <= ECO2_POOR) {
// 差(黄色常亮)
setAllLEDs(255, 255, 0);
}
else {
// 严重污染(红色常亮)
setAllLEDs(255, 0, 0);
}
}
// 设置所有LED颜色
void setAllLEDs(uint8_t r, uint8_t g, uint8_t b) {
for (int i = 0; i < LED_COUNT; i++) {
leds.setPixelColor(i, leds.Color(r, g, b));
}
leds.show();
}
2.3.3 代码说明#
1. 硬件配置与对象初始化
硬件与参数配置
// 硬件配置
#define LED_PIN 4 // RGB灯控制引脚
#define LED_COUNT 4 // LED灯珠数量
#define I2C_ADDR 0x53 // ENS160默认I2C地址
// eCO2浓度等级阈值 (ppm)
#define ECO2_EXCELLENT 400
#define ECO2_GOOD 800
#define ECO2_MODERATE 1000
#define ECO2_POOR 1500
定义了硬件连接方式和关键参数
设置了4个eCO2浓度阈值等级
对象初始化
DFRobot_ENS160_I2C ENS160(&Wire, I2C_ADDR);
Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
创建ENS160传感器对象,初始化NeoPixel LED灯带
2. 初始化设置(setup函数)
void setup() {
Serial.begin(9600);
// 初始化ENS160
while (NO_ERR != ENS160.begin()) {
Serial.println("与设备的通信失败,请检查连接情况.");
delay(3000);
}
Serial.println("开始可以了!");
// 设置传感器模式
ENS160.setPWRMode(ENS160_STANDARD_MODE);
ENS160.setTempAndHum(25.0, 50.0); // 设置校准温湿度
// 初始化RGB灯带
leds.begin();
leds.show(); // 初始清空灯带
leds.setBrightness(100); // 中等亮度
}
完成所有硬件初始化
设置传感器工作模式和校准参数
配置 SK6812 RGB灯模块
3. 主循环(loop函数)
eCO₂浓度读取
uint16_t eco2 = ENS160.getECO2();
从ENS160传感器读取 eCO₂ 浓度值
串口输出监测数据
Serial.print("eCO2 浓度: ");
Serial.print(eco2);
Serial.println(" ppm");
通过串口输出浓度值
LED可视化控制
updateAirQualityLED(eco2);
调用LED显示函数更新状态,根据eCO₂浓度值控制LED显示状态
循环延迟控制
delay(2000); // 每2秒更新一次
避免传感器频繁读取导致数据不稳定、使LED效果有足够时间显示
4. 核心功能函数
LED可视化函数
void updateAirQualityLED(uint16_t eco2) {
if (eco2 <= ECO2_GOOD) {
// 优/良(绿色常亮)
setAllLEDs(0, 255, 0);
}
else if (eco2 <= ECO2_MODERATE) {
// 一般(蓝色常亮)
setAllLEDs(0, 0, 255);
}
else if (eco2 <= ECO2_POOR) {
// 差(黄色常亮)
setAllLEDs(255, 255, 0);
}
else {
// 严重污染(红色常亮)
setAllLEDs(255, 0, 0);
}
}
根据eCO₂浓度选择不同的显示效果,4种显示模式对应4个空气质量等级:
优/良状态:绿色常亮
一般状态:蓝色常亮
差状态:黄色常亮
严重污染状态:红色常亮
设置所有LED颜色函数
void setAllLEDs(uint8_t r, uint8_t g, uint8_t b) {
for (int i = 0; i < LED_COUNT; i++) {
leds.setPixelColor(i, leds.Color(r, g, b));
}
leds.show();
}
2.3.4 实验结果#
外接电源,选择好正确的开发板板型(ESP32 Dev Module)和 适当的串口端口(COMxx),然后单击
按钮上传代码。代码上传成功后,代码上传成功后,单击Arduino IDE右上角的
,打开串口监视器,设置波特率为 9600,对着ENS160空气质量传感器哈气(吹气),ENS160传感器每2秒读取一次eCO₂浓度值。
⚠️ 特别提醒:如果串口监视器打印数据都是0,请按一下ESP32主控板上的复位键,等待几秒钟。

根据eCO₂浓度值分为4个等级,并通过 SK6812 RGB LED 灯直观显示当前空气质量等级:
优/良(≤800ppm):绿灯常亮
一般(≤1000ppm):蓝灯常亮
差(≤1500ppm):黄灯常亮
严重污染(>1500ppm):红灯常亮

您可以通过深吸气后向ENS160传感器缓慢呼气来模拟空气质量变化,此时eCO₂浓度值将上升,同时可观察到SK6812 RGB LED灯的颜色和动态效果随之改变。对着模块呼气并不能将eCO2浓度值达到严重污染的级别。
2.3.5 常见问题解决#
代码上传成功后SK6812 RGB灯不亮?
确保ENS160传感器和SK6812 RGB灯已接线且正确接线,然后按下ESP32主板的复位键:
