基于Arduino与SDS011传感器的便携式PM2.5/PM10检测仪DIY全攻略
1. 项目概述与核心价值
几年前,我还在为家里的空气质量发愁。新装修的房子、窗外的马路、甚至炒菜的油烟,都让我对看不见的“灰尘”格外敏感。市面上专业的检测仪动辄上千,数据虽准但不够亲民;而几十块的廉价传感器,读数又经常飘得离谱,让人心里没底。于是,一个念头冒了出来:能不能自己动手,做一个既靠谱又实惠,还能揣着走的空气质量监测仪?这就是今天要和大家详细分享的——基于Arduino和SDS011传感器的便携式PM2.5/PM10检测仪DIY全记录。
这个项目的核心目标非常明确:制作一个能准确、实时测量空气中PM2.5和PM10颗粒物浓度,且便于携带的个性化设备。它解决的不仅仅是“有没有数据”的问题,更是“数据是否可靠、查看是否方便、使用是否灵活”的问题。SDS011传感器采用激光散射原理,其测量精度和稳定性在百元级传感器中口碑不错,是业余爱好者和创客项目中的常客。搭配上Arduino Nano Every这款小巧但性能足够的主控,以及一块省电的彩色屏幕,整个系统的骨架就清晰了。
它适合谁呢?首先当然是电子DIY爱好者、创客和学生,你可以通过它深入学习传感器原理、单片机编程和硬件集成。其次,是关注健康和生活品质的朋友,无论是想监测新房甲醛治理后的粉尘残留,还是评估办公室、卧室的空气质量,这个小设备都能给你提供直观的数据支持。最后,它也是一个绝佳的教育演示工具,能生动地向孩子或公众展示“看不见的污染”究竟是怎么回事。
整个制作过程,我会从原理、选型、电路、编程到组装调试,一步步拆开揉碎了讲。我会重点分享那些教程里通常不会写出来的“坑”和“技巧”,比如如何让传感器读数更稳、如何优化程序以节省每一毫安的电、以及组装时那些影响精度的小细节。目标就是让你看完之后,不仅能成功复现,更能理解背后的每一个“为什么”,甚至能举一反三,把它改造成更适合你自己需求的形态。
2. 核心器件选型与原理深度解析
工欲善其事,必先利其器。一个DIY项目的成败,很大程度上取决于核心器件的选型是否合理。这里的选择,每一个都经过了权衡和实测。
2.1 传感核心:SDS011激光颗粒物传感器
这是整个项目的“眼睛”,其重要性不言而喻。为什么选择SDS011,而不是更便宜的GP2Y1010AU0F(红外LED式)或更贵的攀藤PMS系列?
工作原理剖析:SDS011采用的是激光散射法。其内部有一个恒流驱动的激光二极管,发射出波长约650nm的稳定激光束。当空气中的颗粒物随气流被吸入传感器检测腔时,会穿过这片激光区域。颗粒物会使激光发生米氏散射,散射光的方向和强度与颗粒物的粒径、形状、折射率有关。在激光束的垂直方向,安装了一个高灵敏度的光电探测器(通常是光电二极管),专门用于收集这些散射光信号。
光电探测器将光信号转换为微弱的电流信号,经过内部的前置放大器和滤波电路处理后,送入一颗专用的MCU进行算法分析。这颗MCU内嵌了工厂校准的算法模型,能够根据散射光的强度脉冲信号,反算出不同粒径区间(主要是0.3-10微米)内颗粒物的数量,再通过标定的质量浓度转换公式,最终输出我们需要的PM2.5和PM10的质量浓度值(单位:微克/立方米,μg/m³)。
注意:这里说的“标定”非常关键。传感器出厂前,会在标准粉尘浓度仓内,用标准仪器(如β射线法或震荡天平法监测仪)进行对比校准,建立散射光信号与质量浓度之间的函数关系。这也是SDS011比单纯计数型传感器(只输出颗粒数)更实用、数据更接近环保部门监测值的原因。
选型理由与避坑指南:
- 精度与可靠性:激光散射法对细小颗粒(尤其是PM2.5)的灵敏度远高于红外法。红外传感器易受环境光、水蒸气干扰,对小于1微米的颗粒几乎无响应,而激光可以检测到0.3微米的颗粒。
- 直接输出质量浓度:SDS011直接通过串口输出处理好的PM2.5和PM10浓度值,省去了我们自行从颗粒数换算质量浓度的复杂且不准确的步骤。
- 性价比:在激光类传感器中,SDS011的价格相对平易近人,且市场存量足,资料丰富。
- 重要避坑点——风扇与休眠:SDS011内部有一个微型风扇,用于吸入空气。这是它精度高的保证,但也带来了两个问题:功耗和噪音。持续工作电流约70mA,对于电池供电设备是个负担。因此,我们的程序必须利用其休眠指令,在非采样时段关闭风扇和激光,将电流降至约4mA。另一个坑是,风扇长期运转会吸入灰尘污染激光器和光学镜片,导致读数逐渐漂移。虽然传感器有自清洁设计,但建议在进气口加装一片轻薄的防尘海绵(不能太密,影响气流),并定期用棉签蘸无水酒精清洁进气口。
2.2 控制大脑:Arduino Nano Every
主控选择了Arduino Nano Every,而不是更常见的Uno或普通的Nano。
选型理由:
- 尺寸与接口:其引脚布局与经典Nano完全兼容,体积小巧,非常适合嵌入便携设备。
- 性能与功耗:它采用ATMega4809芯片,性能比328P的Uno强不少,且有更多的内存(48KB Flash,6KB RAM)。更关键的是,它支持更灵活的低功耗模式。虽然我们主要靠传感器休眠节电,但主控本身的低功耗特性为未来功能扩展(如增加蓝牙模块实现数据上报)留有余地。
- 成本与易用性:价格与Nano相当,在Arduino IDE中易于编程,生态丰富。
替代方案思考:如果你追求极致低功耗,可以考虑使用ESP32(自带Wi-Fi/蓝牙,深度睡眠模式电流仅10μA左右),但编程复杂度稍高,且静态功耗可能比ATMega4809的掉电模式略高。对于这个以本地显示为核心的项目,Nano Every是平衡之选。
2.3 人机界面:ST7735 1.8英寸TFT彩屏
选择彩色屏幕而非单色OLED或LCD,主要是为了数据可视化。
优势与实现:ST7735驱动芯片的这块屏幕分辨率是128x160,足够显示两条曲线、数值和状态信息。其SPI接口通信速度快,刷新图表流畅。我们将用它实现一个“滑动窗口图表”:屏幕横向代表时间轴,每2分钟一个新的数据点从右侧加入,旧的数据点向左平移,形成动态变化的PM2.5和PM10浓度曲线。这种视觉呈现方式,比单纯的数字跳动直观得多,一眼就能看出污染趋势是上升、下降还是平稳。
功耗考量:彩屏是全设备中仅次于传感器风扇的耗电大户。为了省电,我们将在程序中进行优化:仅在数据更新时刷新屏幕的相关区域(局部刷新),而不是全屏清空重绘。同时,可以设置屏幕背光亮度为可调,在光线充足的环境下调低亮度以节省电力。
2.4 供电系统:9V电池与电压监测
采用一块普通的9V层叠电池(如6F22),容量通常在500-600mAh。选择它是因为其电压标准、易于获取和安装。
电压分压电路详解:Arduino Nano Every的模拟输入引脚(ADC)测量电压范围是0-5V(其工作电压为5V)。而9V电池满电时约9.6V,直接接入会烧毁ADC。因此必须使用电压分压电路。
电路很简单:两个阻值相同的电阻(R1和R2)串联在电池正极与地之间。从两个电阻的连接点引出电压到Arduino的模拟引��A6。根据分压公式,A6测得的电压 V_measure = V_battery * [R2 / (R1 + R2)]。当R1=R2=10kΩ时,V_measure = V_battery / 2。
这样,9V电池电压就被“压缩”到了0-4.8V的安全测量范围。在程序中,我们读取A6的模拟值(0-1023对应0-5V),然后反向计算出电池实际电压:V_battery = (analogRead(A6) / 1023.0 * 5.0) * 2。
实操心得:电阻选型的讲究原文中提到使用10kΩ电阻,但图片中误标为100kΩ。这里必须使用10kΩ,原因有二:一是阻抗匹配,ADC引脚内部有采样电容,需要在一定时间内充电到稳定电压。如果上拉电阻过大(如100kΩ),采样时间会变长,在高阻抗下更容易引入噪声,导致电压读数跳动。二是功耗,虽然100kΩ电阻的静态电流更小(约0.09mA),但对于整个系统几十毫安的总电流来说,这点节省微乎其微。而10kΩ电阻能提供更稳定、快速的电压采样,是更优选择。同时,建议选用1%精度的金属膜电阻,以保证分压比的准确性。
续航估算: 传感器工作电流70mA,休眠后4mA;屏幕背光中等亮度约20mA;Arduino主板约20mA。假设每2分钟传感器工作30秒进行采样(实际SDS011稳定读数需要约30秒),则平均电流大致为: 工作期:(70+20+20)mA * 30s = 3300 mA·s 休眠期:(4+20+20)mA * 90s = 3960 mA·s 平均每秒:(3300+3960)/120 ≈ 60.5 mA·s = 0.0168 mA·h 那么一块550mAh的电池,理论续航约为 550 / 0.0168 ≈ 32700 小时?这显然不对,因为我忽略了屏幕和Arduino的持续电流。实际上,屏幕和MCU是持续工作的(约40mA),这才是耗电主力。因此更合理的估算为:平均电流 ≈ 传感器平均电流(70*(30/120)=17.5mA) + 屏幕&MCU持续电流(40mA) ≈ 57.5mA。550mAh / 57.5mA ≈ 9.6小时。考虑到电池放电特性、电路效率等因素,原文提到的6小时是比较保守和实际的估算。若想延长续航,可进一步优化:降低屏幕亮度、让Arduino在休眠期间也进入空闲模式、缩短传感器每次的工作时间(经测试,SDS011在15-20秒后读数也能稳定)。
3. 电路设计与硬件组装实战
有了清晰的器件认知,接下来就是把它们可靠地连接起来。电路是项目的骨架,组装则决定了其稳定性和耐用性。
3.1 电路原理图与接线详解
整个系统的电路连接可以分为电源、传感器、屏幕和电压检测四个部分。
1. 电源部分:
- 9V电池正极接开关一端,开关另一端接Arduino Nano Every的
VIN引脚。这是给整个板子供电的入口。 - Arduino的
5V引脚输出稳定的5V电压,为SDS011传感器和ST7735屏幕供电。 - 所有器件(Arduino、传感器、屏幕)的
GND引脚最终都需要连接到电池的负极,形成共地。
2. SDS011传感器连接:SDS011通常有4根或5根线(红色-5V,黑色-GND,黄色-TX,绿色-RX,蓝色-设置引脚可选)。我们使用其串口通信。
- 红线 -> Arduino
5V - 黑线 -> Arduino
GND - 黄线(TX) -> Arduino 的
D2(我们将把它配置为软件串口的RX端) - 绿线(RX) -> Arduino 的
D3(配置为软件串口的TX端)
为什么用软件串口?Arduino Nano Every的硬件串口(
D0/RX,D1/TX)通常预留给与电脑通信进行调试。使用SoftwareSerial库在D2和D3上虚拟一个串口,可以避免占用调试端口,方便我们随时通过USB监控数据。
3. ST7735屏幕连接:ST7735通常有7-8个引脚,采用SPI接口。
VCC-> Arduino5VGND-> ArduinoGNDSCL(时钟) -> ArduinoD13(SCK)SDA(数据) -> ArduinoD11(MOSI)RES(复位) -> ArduinoD8(可自定义)DC(数据/命令) -> ArduinoD9(可自定义)CS(片选) -> ArduinoD10(可自定义)BL(背光) -> 通过一个220Ω限流电阻接ArduinoD7,以便程序控制亮度或开关。
4. 电池电压检测电路:
- 取两个10kΩ电阻R1和R2。
- R1一端接电池正极(开关之后,Arduino
VIN之前),另一端接A6引脚和R2的一端。 - R2的另一端接电池负极(GND)。
- Arduino
A6引脚测量中间点的电压。
3.2 PCB设计与焊接要点
原文作者使用了环氧树脂PCB,这对于追求稳固和美观的朋友是个好选择。但对于大多数DIYer,使用万用板(洞洞板)进行焊接是完全可行的,成本更低,灵活性更高。
焊接顺序建议:
- 先电源,后信号:首先焊接电源走线(5V和GND),确保供电网络畅通。建议用较粗的导线或直接在万用板背面用焊锡走“电源总线”。
- 固定核心器件:先焊接Arduino Nano Every的排母(不要直接焊芯片,方便更换),然后焊接SDS011和屏幕的接插件或排针。
- 分模块焊接:将电路划分为传感器模块、屏幕模块、分压器模块,逐个完成连接和测试。每完成一个模块,就用万用表通断档检查是否有短路或虚焊。
- 电压分压电路:两个10kΩ电阻尽量靠近Arduino放置,连接A6的导线要短,以减少噪声干扰。可以在A6与地之间并联一个0.1uF的瓷片电容,起到滤波作用,使电压读数更稳定。
避坑指南:数字地与模拟地在这个项目中,虽然模拟部分(电压检测)很简单,但养成良好的习惯很重要。所有器件的GND都连接到同一个“地平面”上。在万用板布局时,尽量让Arduino的GND引脚作为“星型接地”的中心点,其他器件的GND线单独连接到这个中心点,而不是像串糖葫芦一样一个接一个地串起来,这样可以减少共地阻抗带来的噪声。
3.3 机械结构与外壳组装
便携设备的外壳不仅关乎美观,更影响测量准确性。
1. 传感器气路设计:这是最关键也最容易出错的一环。SDS011需要吸入外部空气进行测量。不能直接把传感器密封在盒子里!必须在外壳上开进气孔,并使用一段柔性导管(如硅胶管)将外部空气引导至传感器的进气口。同时,要在盒子上开一个出气孔,让风扇排出的空气顺利流出,形成气流循环。
- 进气口位置:应远离屏幕、电池等可能发热的部件,避免测量到设备内部的热空气。最好位于盒子侧面或底部。
- 防尘措施:在进气导管入口处加一小块透气防尘海绵。这能有效阻挡大颗粒灰尘和纤维进入传感器腔体,延长传感器寿命,且对气流阻力很小,不影响测量。海绵需定期更换或清洗。
- 导管长度:不宜过长,一般10-20厘米足够,避免气流阻力过大。
2. 内部布局与堆叠:如原文图片所示,采用“三明治”堆叠法可以有效利用空间:
- 底层:固定SDS011传感器的亚克力板或环氧板。用塑料柱和螺丝将其悬空固定在底壳上,确保传感器下方也有空气流通。
- 中层:焊接好所有元件的万用板(或定制PCB),包含Arduino、电阻等。
- 顶层:ST7735显示屏,通过排针插在中层板子上,屏幕正面朝向透明上盖。
- 每一层之间用足够长的塑料柱隔开,确保结构稳固且利于散热。
3. 外壳选择与密封:选择一个尺寸合适(如12x8x6cm)、带有透明前盖的塑料防水盒。透明盖方便查看屏幕。除了必要的进气孔和出气孔,其他缝隙(如开关按钮处、线缆出口)最好用热熔胶或硅橡胶进行密封,防止外部空气从非设计路径进入,干扰传感器采样气流的代表性。
4. 软件编程与逻辑实现
硬件是躯体,软件是灵魂。让这个设备智能工作的所有逻辑,都写在Arduino的代码里。
4.1 开发环境与库文件准备
首先确保安装了最新版的Arduino IDE。然后需要导入以下必要的库,这些库都可以通过IDE的“库管理器”搜索安装:
SoftwareSerial.h:用于在D2,D3引脚创建虚拟串口与SDS011通信。Adafruit_ST7735.h和Adafruit_GFX.h:这是驱动ST7735屏幕最常用的库,功能强大。- (可选)
TimerOne.h或arduino-timer-cpp:用于实现精确的2分钟定时采样,比依赖delay()更专业。
解决“monimagecouleur.h”库缺失问题原文评论区有人提到找不到这个库。这很可能是一个作者自定义的、用于在屏幕上显示Logo图片的头文件。对于我们的项目,完全可以省略这个Logo显示,以节省宝贵的程序存储空间。如果确实需要显示自定义图片,可以使用
Adafruit_GFX库自带的位图转换工具,将图片转换为数组直接嵌入代码,无需额外库。
4.2 程序主逻辑与状态机
整个程序应该围绕一个清晰的状态机来设计,避免使用阻塞式的delay(),以保证界面响应和后续可能的功能扩展。
// 伪代码逻辑框架 #include <SoftwareSerial.h> #include <Adafruit_ST7735.h> #include <Adafruit_GFX.h> // 定义引脚、初始化对象、全局变量... void setup() { // 初始化串口(用于调试) Serial.begin(9600); // 初始化与SDS011通信的软件串口 sdsSerial.begin(9600); // 初始化屏幕 tft.initR(INITR_BLACKTAB); tft.setRotation(3); // 根据屏幕安装方向调整 // 初始化电压检测引脚 pinMode(VOLTAGE_PIN, INPUT); // 绘制屏幕静态界面(坐标轴、标题等) drawStaticGUI(); // 让传感器先休眠 setSensorMode(SLEEP_MODE); } void loop() { unsigned long currentMillis = millis(); // 状态1:等待采样间隔(2分钟) if (当前状态 == 等待 && 时间间隔已到) { 唤醒传感器(); 当前状态 = 预热; 预热开始时间 = currentMillis; } // 状态2:传感器预热(约30秒) if (当前状态 == 预热 && 预热时间足够) { 当前状态 = 读数; } // 状态3:读取传感器数据 if (当前状态 == 读数) { if (从串口读取到完整有效数据包) { 解析PM2.5和PM10数值(); 存储数据到数组(); 更新屏幕图表和数值(); 读取电池电压并显示(); 当前状态 = 等待; 设置传感器进入休眠(); 重置下一次采样计时器(); } } // 实时更新屏幕上的倒计时(每秒更新一次) if (currentMillis - 上次更新时间 > 1000) { 更新倒计时显示(); 上次更新时间 = currentMillis; } }4.3 核心功能代码解析
1. 与SDS011传感器通信:SDS011使用标准的串口协议,数据帧长度为10字节。我们需要编写函数来发送指令和解析返回的数据。
// 发送休眠指令(0xAA 0xB4 0x06 0x01 0x00 0x00 0x00 0x00 0x00 0xAB) void setSensorSleep() { byte sleepCmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB}; sdsSerial.write(sleepCmd, 10); } // 发送唤醒/查询指令(0xAA 0xB4 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0xAB) void wakeAndReadSensor() { byte queryCmd[] = {0xAA, 0xB4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB}; sdsSerial.write(queryCmd, 10); } // 解析数据包函数 bool parseSDSData(byte *buffer, float *pm25, float *pm10) { // 检查帧头(0xAA 0xC0)和帧尾(0xAB) if (buffer[0] == 0xAA && buffer[1] == 0xC0 && buffer[9] == 0xAB) { // 校验和计算:字节2~8之和的低字节等于字节8? int checksum = 0; for (int i = 2; i <= 7; i++) { checksum += buffer[i]; } if ((checksum & 0xFF) == buffer[8]) { *pm25 = ((buffer[3] * 256) + buffer[2]) / 10.0; *pm10 = ((buffer[5] * 256) + buffer[4]) / 10.0; return true; // 解析成功 } } return false; // 数据无效 }2. 屏幕图表绘制优化:这是提升用户体验的关键。不要每次刷新都清空全屏(tft.fillScreen(ST77XX_BLACK)),这会导致屏幕闪烁且耗电。
- 初始化时:只绘制一次静态元素,如坐标轴、刻度、标题“PM2.5/PM10 (μg/m³)”。
- 更新数据时:
- 擦除旧的曲线:用背景色在旧数据点的位置画线。
- 平移所有数据点在数组中的索引(相当于在逻辑上左移)。
- 将新数据点加入数组末尾。
- 用新的颜色在新的位置绘制所有数据点连成的曲线。
- 在屏幕固定位置用大字体更新最新的PM2.5和PM10数值。
// 示例:更新PM2.5曲线 void updatePM25Chart(float newValue) { // 1. 擦除最旧的数据点(在x=0的位置) tft.drawPixel(GRAPH_X_OFFSET, oldY0, BACKGROUND_COLOR); // 2. 平移数组 for (int i = 0; i < DATA_POINTS - 1; i++) { pm25Data[i] = pm25Data[i + 1]; } pm25Data[DATA_POINTS - 1] = newValue; // 3. 绘制新曲线 for (int i = 0; i < DATA_POINTS - 1; i++) { int y0 = map(pm25Data[i], 0, 500, GRAPH_BOTTOM, GRAPH_TOP); // 映射到屏幕坐标 int y1 = map(pm25Data[i+1], 0, 500, GRAPH_BOTTOM, GRAPH_TOP); tft.drawLine(GRAPH_X_OFFSET + i, y0, GRAPH_X_OFFSET + i + 1, y1, ST77XX_GREEN); } }3. 电池电压读取与电量提示:
float readBatteryVoltage() { int sensorValue = analogRead(VOLTAGE_PIN); float voltageAtPin = (sensorValue / 1023.0) * 5.0; // 读取A6引脚电压 float batteryVoltage = voltageAtPin * 2; // 乘以分压比 // 可选:多次采样取平均,减少跳动 return batteryVoltage; }可以在屏幕上显示精确电压,或者将其映射为电量图标(如满格、半格、空电池)。注意,9V电池的放电曲线并非线性,当电压低于7V左右时,设备可能已无法正常工作,应提示充电或更换。
4.4 功耗优化进阶技巧
如果对6小时的续航还不满意,可以尝试以下深度优化:
- Arduino睡眠模式:在两次采样的漫长等待期间,让Arduino进入
Idle或Power-down睡眠模式。这需要配置定时器中断来唤醒MCU,会显著增加编程复杂度,但能将MCU自身的电流从约20mA降至几个mA甚至微安级别。 - 屏幕动态管理:增加一个震动传感器或按钮,只有检测到用户拿起设备或按下按钮时,才点亮屏幕背光,其余时间关闭背光。ST7735的背光LED是耗电主力,关闭后屏幕本身功耗极低。
- 调整采样策略:如果不是需要严格每2分钟记录,可以改为“按需采样”,即用户按键时才启动传感器测量一次。或者根据历史数据动态调整采样频率(如连续几次读数都很低且稳定,则延长采样间隔)。
5. 校准、测试与常见问题排查
设备组装编程完成后,并不意味着大功告成。校准和测试是确保数据可信度的最后一步,也是最容易遇到问题的一环。
5.1 传感器读数验证与交叉对比
SDS011出厂已校准,但不同个体间可能存在微小偏差。为了建立信心,最好进行交叉对比。
验证方法:
- 与官方数据对比:在天气晴朗、空气质量较好的日子,将设备放在室外通风处,运行一段时间后记录稳定的PM2.5/PM10值。同时,查询本地环保部门官方监测站发布的实时数据(通常通过手机App或网站可查)。对比两者读数。由于监测站是标准设备,且位置、高度与你的设备不同,允许存在一定差异(例如±10μg/m³以内),但趋势应该一致。
- 与另一台设备对比:如果你有另一台商业空气质量检测仪(哪怕不同原理),可以进行同地点、同时段的对比测试。
- 零值测试(不严谨但可参考):在一个相对洁净的密闭小空间(如刚用空气净化器净化过的房间),读数应该很低(PM2.5可能是个位数甚至接近0)。向空气中喷洒少量纯净水雾(注意不是灰尘!),由于水雾颗粒也会散射激光,读数会短暂飙升,然后回落。这可以验证传感器对颗粒物变化的响应灵敏度。
重要提示:激光传感器对水蒸气也有反应。因此,在非常潮湿的环境(如浴室、雨天户外)下,读数可能会偏高,这并不完全代表“污染”,需要结合湿度数据综合判断。这也是为什么高端监测仪会同时集成温湿度传感器进行数据补偿。
5.2 典型问题与解决方案速查表
在制作和使用过程中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 屏幕无显示 | 1. 电源未接通或电压不足。 2. 屏幕背光未开启或损坏。 3. SPI引脚接错。 4. 复位引脚未正确初始化。 | 1. 用万用表检查5V和GND是否到达屏幕引脚。 2. 检查背光控制引脚( BL)是否接好,程序是否将其设置为高电平。3. 仔细核对 SCL、SDA、DC、CS、RES引脚定义是否与代码中一致。4. 在 setup()中尝试添加pinMode(RESET_PIN, OUTPUT); digitalWrite(RESET_PIN, HIGH);。 |
| 屏幕显示乱码或花屏 | 1. SPI通信速率过快或不稳定。 2. 电源噪声干扰。 3. 屏幕初始化指令不正确。 | 1. 尝试在tft.initR()后添加一小段delay(500)。2. 在屏幕的 VCC和GND之间并联一个10-100uF的电解电容,滤除电源波动。3. 检查 Adafruit_ST7735库的初始化参数(INITR_BLACKTAB等)是否与你的屏幕型号匹配。 |
| SDS011无数据返回 | 1. 串口线接反(TX/RX交叉)。 2. 波特率不匹配。 3. 传感器未唤醒。 4. 电源电流不足。 | 1.确保SDS011的TX接Arduino的D2(RX),RX接D3(TX),这是最常见错误。 2. 确认代码中 sdsSerial.begin(9600);与传感器一致。3. 在读取前,确保已发送唤醒指令并等待足够时间(>30秒)。 4. SDS011工作瞬间电流可能较大,确保你的5V电源(如Arduino的LDO)能提供至少150mA电流。 |
| 读数持续为0或异常高/低 | 1. 数据包解析错误。 2. 传感器进气口被堵塞或遮挡。 3. 传感器内部激光器或风扇故障。 4. 受到强电磁干扰。 | 1. 通过Arduino的硬件串口(Serial)打印出从SDS011收到的原始字节,检查帧格式和校验和。2. 检查进气导管是否畅通,防尘海绵是否过脏。 3. 倾听传感器内部风扇是否在采样时转动,是否有激光器工作的轻微声音(需在暗处观察进气口有无微弱红光,切勿直视)。 4. 让设备远离大功率电机、变压器等干扰源。 |
| 电池电量显示不准 | 1. 分压电阻阻值误差大。 2. Arduino的基准电压不准。 3. 模拟引脚噪声。 | 1. 使用精度更高的1%电阻。 2. 用万用表实际测量电池电压和A6引脚电压,在代码中校准比例系数(不一定是2,可能是1.98或2.02)。 3. 对A6引脚进行多次采样(如100次)取平均值,并并联滤波电容。 |
| 设备运行时间远短于6小时 | 1. 电池容量虚标或老化。 2. 传感器休眠失败,持续工作。 3. 屏幕背光常开且亮度太高。 | 1. 测量设备在工作模式和休眠模式下的总电流(用万用表串联在电路中)。 2. 检查代码,确保在采样间隙成功发送了休眠指令,并可通过监听风扇是否停转来验证。 3. 尝试调低屏幕亮度,或增加背光自动关闭逻辑。 |
5.3 数据解读与健康参考
设备做出来了,读到的数字代表什么?这里提供一个简单的参考(基于中国空气质量标准,单位:μg/m³):
- PM2.5 24小时平均:
- 优:0-35
- 良:35-75
- 污染:>75
- PM10 24小时平均:
- 优:0-50
- 良:50-150
- 污染:>150
需要注意的是,我们DIY设备显示的是瞬时值或短时平均值,会存在波动。观察时应更关注其变化趋势和相对高低,而非纠结于某一时刻的绝对数值是否与官方完全一致。例如,在门窗紧闭的室内开启空气净化器后,PM2.5数值应呈现明显的下降趋势,这就能证明净化器有效。
这个项目最大的乐趣在于,从一堆散件开始,亲手搭建出一个能真实反映环境状况的工具。过程中遇到的每一个问题,从焊接虚接到数据包解析错误,从屏幕闪烁到续航焦虑,都是宝贵的经验。它不仅仅是一个监测仪,更是一个打通了硬件、软件、机械和实际应用的完整学习案例。你可以在此基础上无限扩展:加上温湿度传感器(如DHT22)、甲醛传感器(如SGP30)、甚至Wi-Fi模块将数据上传到云端,打造属于自己的家庭环境监测网络。
