基于Arduino/ESP32的PM2.5与CO2空气质量检测仪DIY全攻略
2026/7/29 3:42:54 网站建设 项目流程

1. 项目概述:为什么我们需要一个自制的空气质量检测仪?

最近几年,大家对室内空气质量的关注度明显提高了。无论是新装修的房子、长时间密闭的办公室,还是秋冬季节为了保暖很少开窗的卧室,空气里看不见的“隐形杀手”其实不少。PM2.5大家比较熟悉,指的是空气中直径小于等于2.5微米的颗粒物,它能深入肺部甚至进入血液循环。而二氧化碳(CO2)浓度则常常被忽视,它虽然本身无毒,但却是衡量室内通风状况和人员密集度的关键指标。CO2浓度过高会直接导致人感到憋闷、头晕、注意力不集中,长期处于高浓度环境下对健康和学习工作效率都有负面影响。

市面上的空气质量检测仪选择很多,从几十块的“玩具”到几千块的专业设备都有。但作为一个喜欢动手的创客或电子爱好者,我总觉得买来的成品少了点“灵魂”——你不知道它的传感器准不准、算法有没有优化、数据是不是真实。更重要的是,你无法根据自己的需求去定制功能,比如设定一个阈值自动打开空气净化器,或者将数据长期记录并可视化。

这就是为什么我决定自己动手,用Arduino搭建一个PM2.5和CO2的室内空气质量检测仪。这个项目的核心价值在于透明、可定制和可学习。你清楚地知道每一个部件的工作原理,可以自由选择不同精度和价位的传感器,还能通过编程实现任何你想要的联动功能。整个过程不仅让你获得一个实用的工具,更能深入理解传感器技术、数据采集和嵌入式系统开发。接下来,我就把从选型、接线、编程到调试的完整过程,以及我踩过的那些坑,毫无保留地分享给你。

2. 核心硬件选型与设计思路

自己动手做项目,第一步也是最关键的一步就是硬件选型。选对了,事半功倍;选错了,可能连数据都读不出来。我的设计思路是:在保证基本精度和稳定性的前提下,尽量选择性价比高、资料丰富、易于Arduino驱动的传感器,同时整个系统要简洁、低功耗,适合长期运行。

2.1 传感器选型:PM2.5与CO2的探测原理

PM2.5传感器:激光散射式是主流测量PM2.5主要有两种原理:红外LED式和激光散射式。红外式成本极低,但精度很差,基本只能判断“有灰尘”和“没灰尘”,数值参考意义不大。对于室内空气质量监测,我强烈推荐使用激光散射式传感器。它的原理是让激光照射通过采样气流,颗粒物会使激光发生散射,通过检测散射光的强度来反推颗粒物的浓度。这类传感器输出的是经过内部算法计算后的数字信号(通常是UART串口或PWM脉冲),Arduino直接读取即可。

市面上常见的型号有:

  • 攀藤(Plantower)PMS5003/PMS7003系列:这是开源项目和DIY圈里的“明星产品”,性价比极高。它通过UART输出PM1.0、PM2.5、PM10的浓度值(单位:μg/m³),数据相对可靠。我这次项目用的就是PMS5003,它的蓝色塑料外壳很有辨识度。
  • 夏普(Sharp)GP2Y1010AU0F:这是一个比较老的型号,输出的是模拟电压值,需要Arduino的模拟引脚读取,再通过公式换算。它的缺点是容易受干扰,需要外接电路(电阻电容),且没有PM1.0/PM10的分级数据,现在已不推荐作为首选。
  • 更专业的传感器:如Sensirion的SPS30,精度更高,还具有颗粒物数量浓度输出,但价格也贵不少。

注意:激光传感器内部有风扇进行主动吸气,因此会有轻微噪音和功耗。在选购时,务必确认其工作电压(通常是5V)和通信接口是否与你的主控板匹配。

CO2传感器:NDIR原理才是真靠谱测量CO2的方法更多,但适合民用的主要是NDIR(非分散性红外)原理。因为CO2对特定波长的红外光有强烈的吸收特性,传感器通过测量红外光穿过气室后的衰减程度,就能精确计算出CO2浓度。其他如半导体式(MQ系列)的“CO2传感器”其实对酒精、香烟等多种气体都有交叉敏感性,测CO2极不准确,千万别买错。

常见的NDIR CO2传感器有:

  • MH-Z19B/MH-Z19C:国产传感器中的佼佼者,价格亲民(百元级别),通过UART或PWM输出,量程可达5000ppm,自带温度补偿,精度在±(50ppm+5%读数)左右,完全满足室内监测需求。我用的就是MH-Z19B。
  • SenseAir S8:瑞典品牌,性能更稳定,精度更高,但价格也几乎是MH-Z19B的两倍以上,适合要求更高的项目。
  • SCD30/SCD40:Sensirion的传感器,除了CO2,还能测量温度和湿度,且体积小巧,采用I2C通信,但价格昂贵,属于“发烧级”选择。

我的搭配方案是攀藤PMS5003(PM2.5) + 炜盛MH-Z19B(CO2),两者都使用5V供电,UART(TX/RX)通信,总成本可控,性能和可靠性经过了大量项目验证。

2.2 主控板与外围设备选择

主控板:Arduino Uno的经典与ESP32的智能

  • Arduino Uno R3:经典之选。引脚丰富,5V逻辑电平,与上述传感器完美兼容。如果你只想本地读取数据并在串口监视器上查看,或者驱动一个LCD屏显示,Uno完全够用。它的缺点是只有一组硬件串口(Serial),而我们的两个传感器都是UART的,这就需要用到SoftwareSerial库来创建软串口,可能会在高速或复杂通信时有点不稳定。
  • ESP32 DevKit:我更加推荐的选择。它是一块功能强大的物联网开发板,自带Wi-Fi和蓝牙。除了能完成Uno的所有工作,其最大优势是可以轻松地将数据上传到物联网平台(如Blynk、ThingsBoard)、本地服务器(如Home Assistant)或者直接显示在网页上。ESP32有多个硬件串口,可以更稳定地同时连接两个传感器。本项目后续的联网功能就是基于ESP32实现的。

显示与交互设备:

  • OLED显示屏(SSD1306, 0.96寸):I2C接口,功耗低,显示清晰,非常适合显示实时数据。比传统的LCD1602液晶屏好看得多。
  • 按键或旋转编码器:用于切换显示页面、设置报警阈值等。
  • LED指示灯与蜂鸣器:用于超标报警,提供声光提示。

电源:建议使用可靠的5V/2A以上的USB电源适配器供电。如果使用ESP32并开启Wi-Fi,功耗会有所增加,劣质电源可能导致传感器工作不稳定或重启。

3. 电路连接与硬件搭建详解

硬件连接是项目的实体骨架,务必仔细。我的接线原则是:先供电,再信号;先主控,再外设;布局清晰,避免飞线。

3.1 基于Arduino Uno的接线方案(基础版)

如果你使用Arduino Uno,由于只有一个硬件串口(Pin 0 RX, Pin 1 TX,通常用于上传程序和电脑通信),我们需要为两个传感器分配软串口。

所需材料清单:

  • Arduino Uno R3 x1
  • PMS5003 PM2.5传感器 x1
  • MH-Z19B CO2传感器 x1
  • 0.96寸 I2C OLED显示屏 x1
  • 面包板、杜邦线(公对公、公对母)若干
  • 5V/2A USB电源 x1

接线步骤:

  1. 供电统一:将面包板的正极(+)负极(-)排孔分别连接到Arduino的5VGND。所有模块的VCC和GND都分别连接到面包板的+和-排孔上。
  2. 连接PMS5003
    • PMS5003的VCC-> 面包板+5V
    • PMS5003的GND-> 面包板GND
    • PMS5003的RX-> ArduinoPin 2(我们将把Pin2定义为软串口的TX,去连接传感器的RX)
    • PMS5003的TX-> ArduinoPin 3(我们将把Pin3定义为软串口的RX,去连接传感器的TX)
    • PMS5003的SET引脚悬空即可(用于切换模式,普通使用不需连接)。
  3. 连接MH-Z19B
    • MH-Z19B的Vin-> 面包板+5V
    • MH-Z19B的GND-> 面包板GND
    • MH-Z19B的RX-> ArduinoPin 4(软串口TX)
    • MH-Z19B的TX-> ArduinoPin 5(软串口RX)
  4. 连接OLED显示屏
    • OLED的VCC-> 面包板+5V
    • OLED的GND-> 面包板GND
    • OLED的SCL-> ArduinoA5(在Uno上,A4是SDA,A5是SCL)
    • OLED的SDA-> ArduinoA4

重要提示:UART通信是交叉连接,即主控的TX接传感器的RX,主控的RX接传感器的TX。很多新手会接反导致无法通信。另外,MH-Z19B上可能还有一个PWM输出引脚,我们不用,忽略即可。

3.2 基于ESP32的接线方案(进阶联网版)

ESP32的接线更为简洁,因为它有多个硬件串口。

所需材料清单:

  • ESP32 DevKit V1(或类似型号) x1
  • PMS5003 PM2.5传感器 x1
  • MH-Z19B CO2传感器 x1
  • 0.96寸 I2C OLED显示屏 x1
  • 面包板、杜邦线若干
  • 5V/2A USB电源 x1

接线步骤:

  1. 供电注意:ESP32的引脚工作电压是3.3V,但它的VIN引脚可以接受5V输入,板载稳压器会将其降到3.3V。PMS5003和MH-Z19B需要5V供电,OLED可以工作在3.3V。最佳实践是使用一个5V电源适配器,正极同时接到ESP32的VIN引脚和面包板的+5V排孔,负极共地。这样ESP32和传感器都获得了合适的电压。
  2. 连接PMS5003:使用ESP32的硬件串口2(UART2)。
    • PMS5003VCC-> 面包板+5V
    • PMS5003GND-> 公共GND
    • PMS5003TX-> ESP32GPIO16(RX2)
    • PMS5003RX-> ESP32GPIO17(TX2)
  3. 连接MH-Z19B:使用ESP32的硬件串口1(UART1)。注意UART1的默认TX引脚(GPIO10)有些板子可能未引出,我们可以自定义引脚。
    • MH-Z19BVin-> 面包板+5V
    • MH-Z19BGND-> 公共GND
    • MH-Z19BTX-> ESP32GPIO18(自定义为RX)
    • MH-Z19BRX-> ESP32GPIO19(自定义为TX)
  4. 连接OLED显示屏
    • OLEDVCC-> ESP323.3V引脚
    • OLEDGND-> 公共GND
    • OLEDSCL-> ESP32GPIO22
    • OLEDSDA-> ESP32GPIO21

硬件搭建心得:

  • 上电顺序:建议先给主控板上电,待程序启动完成后再连接传感器电源。特别是MH-Z19B,有用户反馈热启动时(主控不断电,传感器重新上电)可能通信异常。最稳妥的方法是所有设备同时上电。
  • 线缆整理:使用不同颜色的杜邦线区分电源(红色+5V,黑色GND)和信号线(黄色TX,绿色RX等),后期调试会轻松很多。
  • 防静电与保护:传感器激光头和红外气室都是精密光学部件,避免用手触摸,组装时注意防尘。

4. 软件编程与核心代码解析

硬件搭好只是成功了一半,让它们“活”起来的代码才是灵魂。我将分模块讲解代码,并提供完整的示例。这里以功能更强大的ESP32版本为例,Uno版本逻辑类似,主要区别在于串口初始化。

4.1 开发环境与库文件准备

  1. 安装Arduino IDE:从Arduino官网下载并安装最新版IDE。对于ESP32,你需要添加开发板支持。
  2. 添加ESP32开发板:在IDE的“文件”->“首选项”的“附加开发板管理器网址”中,添加https://espressif.github.io/arduino-esp32/package_esp32_index.json。然后在“工具”->“开发板”->“开发板管理器”中搜索“esp32”并安装。
  3. 安装必要的库
    • U8g2库:用于驱动OLED显示屏,功能强大,支持多种字体和图形。在“项目”->“加载库”->“管理库”中搜索“U8g2”安装。
    • SoftwareSerial库(仅Uno需要):Arduino IDE自带。
    • PMS库:用于解析PMS5003数据。在库管理器中搜索“PMS”或“Plantower”找到并安装。
    • MH-Z19库:用于驱动MH-Z19B传感器。搜索“MH-Z19”安装。

4.2 核心代码模块拆解

我们将代码分为几个部分:传感器初始化、数据读取、数据显示、数据上传(可选)。

第一部分:全局定义与库引入

#include <U8g2lib.h> // OLED驱动库 #include <PMS.h> // PMS传感器库 #include <MHZ19.h> // MH-Z19传感器库 #include <HardwareSerial.h> // ESP32硬件串口 // 定义OLED对象(根据你的OLED型号修改构造函数,常见的是SSD1306 128x64 I2C) U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // 定义PMS传感器对象,使用硬件串口2 PMS pms(Serial2); // ESP32: Serial2的默认引脚是GPIO16(RX), GPIO17(TX) PMS::DATA data; // 定义MH-Z19传感器对象,使用自定义引脚的硬件串口1 HardwareSerial mySerial(1); // 创建串口1实例 MHZ19 myMHZ19; // 创建MH-Z19实例 // 传感器数据变量 int pm25, pm10; int co2ppm; float temperature; // MH-Z19B也能读取板载温度 // 定时器相关,用于控制读取频率 unsigned long previousMillis = 0; const long interval = 5000; // 每5秒读取一次传感器(PMS需要稳定气流,不宜过快)

第二部分:初始化设置setup()

void setup() { // 启动串口调试,用于在电脑端查看数据 Serial.begin(115200); Serial.println("Air Quality Monitor Starting..."); // 初始化OLED u8g2.begin(); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB08_tr); // 设置字体 u8g2.drawStr(0, 20, "Initializing..."); u8g2.sendBuffer(); delay(1000); // 初始化PMS传感器串口 Serial2.begin(9600, SERIAL_8N1, 16, 17); // RX=16, TX=17 pms.passiveMode(); // 设置为被动模式,由我们主动请求数据 // pms.activeMode(); // 主动模式,传感器会自动持续发送数据,但更耗电 // 初始化MH-Z19传感器串口 mySerial.begin(9600, SERIAL_8N1, 18, 19); // RX=18, TX=19 myMHZ19.begin(mySerial); // 将串口实例传递给MHZ19库 myMHZ19.autoCalibration(false); // 关闭自动基线校准(ABC)。对于室内长期固定使用的场景,建议关闭,否则它会将连续运行几天后的低值作为零点。 // 预热与首次读取 delay(2000); // 给传感器预热时间 readSensors(); // 首次读取 displayData(); // 首次显示 }

关键点解析

  1. PMS被动模式 vs 主动模式:被动模式下,MCU需要发送请求命令,传感器才返回一帧数据,更省电且可控。主动模式下,传感器会持续发送数据,可能造成串口缓冲区溢出。推荐使用被动模式。
  2. MH-Z19自动校准autoCalibration(false)非常重要。如果开启(默认是开启的),传感器会以连续运行一段时间(如7天)内的最低浓度值作为400ppm的基准点。这在室内场景很危险:如果房间一直通风不良,CO2浓度长期在1000ppm以上,传感器会误以为1000ppm是“新鲜空气”,导致读数严重偏低。对于室内监测,务必关闭。

第三部分:主循环loop()与数据读取函数

void loop() { unsigned long currentMillis = millis(); // 定时读取传感器 if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; readSensors(); displayData(); // 可以在这里添加数据上传函数,如 uploadToServer(); } } void readSensors() { // 读取PMS5003数据 pms.requestRead(); if (pms.readUntil(data)) { pm25 = data.PM_AE_UG_2_5; // 大气环境下PM2.5浓度 (μg/m³) pm10 = data.PM_AE_UG_10_0; // 你也可以读取 data.PM_AE_UG_1_0 (PM1.0) } else { Serial.println("PMS read failed."); pm25 = pm10 = -1; // 标记读取失败 } // 读取MH-Z19B数据 co2ppm = myMHZ19.getCO2(); // 获取CO2浓度 temperature = myMHZ19.getTemperature(); // 获取温度(可选) // 打印到串口监视器,用于调试 Serial.print("PM2.5: "); Serial.print(pm25); Serial.print(" μg/m³ | "); Serial.print("PM10: "); Serial.print(pm10); Serial.print(" μg/m³ | "); Serial.print("CO2: "); Serial.print(co2ppm); Serial.println(" ppm"); }

避坑指南

  1. PMS读取失败pms.readUntil(data)可能会超时失败。确保接线正确,波特率是9600,并且传感器已稳定工作(风扇在转)。失败时最好有错误处理,而不是使用旧数据。
  2. MH-Z19读数异常:如果返回-1或9999等异常值,检查接线(TX/RX是否接反)、供电是否充足(5V电压是否稳定)。尝试发送myMHZ19.getCO2(true)请求一个带校验的新读数。

第四部分:OLED显示函数

void displayData() { u8g2.clearBuffer(); // 绘制边框或标题 u8g2.drawFrame(0,0,128,64); // 显示PM2.5数据 u8g2.setFont(u8g2_font_helvB14_tf); u8g2.setCursor(10, 25); u8g2.print("PM2.5"); u8g2.setCursor(70, 25); if(pm25 >= 0) { u8g2.print(pm25); u8g2.setFont(u8g2_font_helvB08_tf); u8g2.print(" ug/m3"); } else { u8g2.print("Err"); } // 显示CO2数据 u8g2.setFont(u8g2_font_helvB14_tf); u8g2.setCursor(10, 50); u8g2.print("CO2"); u8g2.setCursor(70, 50); u8g2.print(co2ppm); u8g2.setFont(u8g2_font_helvB08_tf); u8g2.print(" ppm"); // 根据空气质量添加简单提示 u8g2.setFont(u8g2_font_6x10_tf); u8g2.setCursor(5, 62); if (pm25 > 75 || co2ppm > 1000) { u8g2.print("> Poor Air <"); } else if (pm25 > 35 || co2ppm > 800) { u8g2.print("> Moderate <"); } else { u8g2.print("> Good <"); } u8g2.sendBuffer(); // 将缓冲区内容发送到显示屏 }

这段代码实现了在OLED上分两行显示PM2.5和CO2的数值,并底部有一个简单的空气质量状态提示。你可以发挥创意,添加更多图形,比如用进度条表示浓度,或者显示历史趋势简图。

5. 功能扩展与数据可视化实践

基础数据显示完成了,但一个完整的空气质量监测系统,离不开数据记录和可视化。这里我分享两个最实用的扩展方向:本地数据记录和云端数据可视化。

5.1 本地SD卡数据记录

如果你想在不依赖网络的情况下长期记录数据,添加一个SD卡模块是最经济实惠的方案。

硬件添加:购买一个SPI接口的Micro SD卡模块(通常几块钱),连接到ESP32:

  • SD模块 VCC-> 5V
  • SD模块 GND-> GND
  • SD模块 MOSI-> GPIO23
  • SD模块 MISO-> GPIO19 (注意:如果和MH-Z19冲突,需调整引脚)
  • SD模块 SCK-> GPIO18
  • SD模块 CS-> GPIO5

代码修改:你需要包含SD.hSPI.h库。在setup()中初始化SD卡,在readSensors()函数后添加数据写入逻辑。

#include <SD.h> #include <SPI.h> File dataFile; void setup() { // ... 其他初始化代码 ... if (!SD.begin(5)) { // CS引脚接在GPIO5 Serial.println("SD Card initialization failed!"); return; } Serial.println("SD Card initialized."); } void logDataToSD() { dataFile = SD.open("/airlog.csv", FILE_APPEND); // 以追加模式打开文件 if (dataFile) { dataFile.print(millis()); // 时间戳 dataFile.print(","); dataFile.print(pm25); dataFile.print(","); dataFile.print(pm10); dataFile.print(","); dataFile.print(co2ppm); dataFile.print(","); dataFile.println(temperature); dataFile.close(); } else { Serial.println("Error opening airlog.csv"); } }

然后在loop()的定时任务中调用logDataToSD()。数据会以CSV格式保存,方便用Excel或Python进行后续分析。

5.2 基于ESP32的无线数据传输与云端可视化

这才是发挥ESP32真正威力的地方。将数据上传到云端,你可以在任何地方的手机或电脑上查看实时数据和历史曲线。

方案一:使用Blynk平台(快速入门)Blynk提供了一个非常简单的物联网平台,适合快速原型开发。

  1. 在手机应用商店下载Blynk App,创建一个新项目,选择ESP32设备,获取Auth Token。
  2. 在项目中添加两个Gauge(仪表)组件,分别绑定虚拟引脚V0和V1。
  3. 在Arduino代码中安装Blynk库,并添加以下代码:
#define BLYNK_PRINT Serial #include <WiFi.h> #include <BlynkSimpleEsp32.h> char auth[] = "YourAuthToken"; // 从App获取 char ssid[] = "YourWiFiSSID"; char pass[] = "YourWiFiPassword"; void setup() { // ... 其他初始化 ... Blynk.begin(auth, ssid, pass); } void loop() { Blynk.run(); // 维持Blynk连接 // ... 你的定时读取传感器代码 ... if (timeToSend) { Blynk.virtualWrite(V0, pm25); // 将PM2.5发送到虚拟引脚V0 Blynk.virtualWrite(V1, co2ppm); // 将CO2发送到虚拟引脚V1 } }

上传代码后,你就能在Blynk App的仪表盘上看到实时数据了。

方案二:使用MQTT协议 + 自建服务器(更灵活可控)对于想深度掌控数据的开发者,MQTT+Node-RED+InfluxDB+Grafana是一套强大的组合拳。

  1. MQTT:轻量级的物联网消息协议。ESP32使用PubSubClient库向MQTT代理(如Mosquitto)发布消息。
  2. Node-RED:图形化编程工具,可以订阅MQTT主题,对数据进行处理(如单位转换、过滤),然后写入数据库。
  3. InfluxDB:专门为时间序列数据优化的数据库,存储效率极高。
  4. Grafana:强大的数据可视化平台,从InfluxDB读取数据,绘制出精美的实时图表和历史曲线。

这套方案需要你在电脑(或树莓派等)上部署服务,有一定门槛,但数据完全私有,功能无限。你可以创建这样的面板:同时显示PM2.5和CO2的实时曲线,设置不同颜色的报警阈值线,还能计算一天内的平均值、超标时长等统计信息。

6. 校准、维护与常见问题排查

DIY设备不比商业产品,需要一些额外的调校和维护才能获得可靠数据。

6.1 传感器校准与准确性提升

  • PM2.5传感器(PMS5003):激光传感器一般出厂已校准,无法手动校准。其准确性受环境湿度影响较大(高湿度时,水蒸气会被误判为颗粒物)。可以通过在干燥天气与一个靠谱的商用检测仪对比,得出一个大概的修正系数(例如,乘以0.7或0.8)。更专业的做法是收集一段时间的数据,与参考仪器进行线性回归分析。
  • CO2传感器(MH-Z19B)
    • 手动校准零点:这是最重要的校准。你需要将传感器带到室外通风良好的地方(确保CO2浓度在400ppm左右),稳定运行20分钟后,通过发送特定指令进行零点校准。注意:务必在空气新鲜的环境下操作,否则会校准错误。
    // 在Arduino代码中,确保传感器已预热稳定在新鲜空气中 myMHZ19.calibrateZero(); // 发送零点校准命令
    • 关闭自动校准(ABC):如前所述,室内应用必须关闭。
    • 跨度校准:通常不需要。如果你有已知浓度的标准气体(如2000ppm),可以进行跨度校准以提升线性度。

6.2 长期运行维护要点

  1. 清洁:PM2.5传感器的进气口和激光头会积灰,建议每3-6个月用压缩气罐或软毛刷轻轻清理。切勿用嘴吹或湿布擦拭。
  2. 预热:传感器每次断电重启后,需要一段时间(PMS约30秒,MH-Z19B约3分钟)读数才能稳定。程序里应加入预热延迟或丢弃初期不稳定数据的逻辑。
  3. 供电稳定:使用质量好的5V电源。电压波动可能导致传感器重启或读数异常。
  4. 数据验证:偶尔将你的设备读数与已知准确的设备(如朋友家的品牌检测仪)进行对比,做到心中有数。

6.3 常见问题与解决方案速查表

问题现象可能原因排查步骤与解决方案
串口监视器无数据或乱码1. 波特率设置错误
2. TX/RX接反
3. 供电不足
4. 代码中串口引脚定义错误
1. 检查Serial.begin()Serial2.begin()的波特率是否与传感器一致(PMS:9600, MH-Z19B:9600)。
2. 交换TX和RX线再试。
3. 尝试单独给传感器外接5V电源,或换用电流更大的电源。
4. 核对代码中HardwareSerialSoftwareSerial的引脚定义。
PMS5003读数始终为01. 处于被动模式但未发送请求命令
2. 风扇未转(传感器损坏或供电问题)
1. 确认代码中调用了pms.requestRead()pms.readUntil(data)
2. 观察传感器侧面的小风扇是否在微微转动。不转则检查5V供电或传感器可能已损坏。
MH-Z19B读数始终为410ppm或固定值1. 通信失败,读取到的是上电默认值
2. 自动校准(ABC)开启,且处于低浓度环境
1. 检查接线和供电。尝试使用myMHZ19.getCO2(true)获取带校验的读数。
2. 确认已执行myMHZ19.autoCalibration(false)
CO2读数异常高(如持续>2000)1. 传感器暴露在人体呼吸区
2. 零点漂移严重
1. 将传感器放置在房间中央或高处,远离人嘴和通风口。
2. 执行一次正确的室外零点校准。
OLED屏幕不显示或花屏1. I2C地址不对
2. 供电不足(ESP32用3.3V)
3. 库不匹配
1. 使用I2C扫描程序确认OLED地址(通常是0x3C)。
2. 确保OLED的VCC接的是3.3V(ESP32)或5V(Uno)。
3. 尝试U8g2库提供的不同构造函数。
ESP32连接WiFi经常断开1. WiFi信号弱
2. 电源干扰
1. 让设备靠近路由器,或代码中加入WiFi重连逻辑。
2. 为ESP32的电源引脚并联一个100-470uF的电解电容,滤除因传感器风扇启停造成的电压波动。
数据上传到云端失败1. 网络问题
2. MQTT/Blynk参数错误
3. 代码逻辑问题
1. 检查ESP32能否ping通外网。
2. 核对服务器地址、端口、用户名、密码、Topic/Auth Token。
3. 在数据上传代码前后添加串口打印,确认数据已正确准备,并检查上传函数的返回值。

这个项目从简单的数据读取到复杂的物联网系统,有非常广阔的扩展空间。你可以增加温湿度传感器(如DHT22)、甲醛传感器,甚至联动家里的智能插座,在空气质量超标时自动打开新风或空气净化器。动手的过程就是学习的过程,当你看到自己亲手制作的设备忠实地记录着环境的每一次呼吸,那种成就感和对身边环境的全新认知,是购买任何成品都无法替代的。希望这份超详细的指南能帮你少走弯路,顺利打造出属于你自己的空气质量守护者。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询