基于Arduino DIY智能空气净化器:从传感器原理到PWM调速实战

Arduino空气净化器DIY
于 2026-05-31 13:10:00 修改
·本内容遵循CC 4.0 BY-SA版权协议

1. 项目概述与核心思路

几年前的一个凌晨四点,我盯着天花板毫无睡意,脑子里突然蹦出一个念头:为什么不自己动手做一个空气净化器呢?市面上那些动辄上千元的品牌产品,内部结构真的有那么神秘吗?这个想法一旦生根,就再也挥之不去。于是,我决定用最“创客”的方式——基于Arduino开源平台,从零开始打造一台属于自己的智能空气净化器。最终,这台设备的总成本被我控制在了2500卢比(约合人民币200多元,按当时汇率),核心功能却一点不差:实时监测PM2.5浓度,自动调节净化风速,甚至还有一个“静音模式”。最关键的是,滤网采用了与小米空气净化器2代兼容的HEPA滤芯,更换起来就像换灯泡一样简单,后期维护成本极低。

这个项目非常适合有一定动手能力的电子爱好者、创客,或者单纯想深入了解空气净化器工作原理的朋友。你不需要是机械或电子工程科班出身,只要愿意花点时间,跟着步骤一步步来,就能收获一台完全由自己掌控、数据透明的净化设备。它解决的不仅仅是“有没有”的问题,更是“为什么”和“怎么样”的问题——你能清楚地知道房间里的空气质量究竟如何,净化器是否在努力工作,以及每一分钱花在了哪里。

2. 核心组件选型与原理剖析

自己动手做东西,最难也最有趣的一步就是“选型”。每个零件的选择背后,都是一次成本、性能和可行性的权衡。

2.1 控制大脑:为什么是Arduino Nano?

主控板的选择上,我毫不犹豫地选了Arduino Nano。对于这类监测+控制型的项目,它几乎是“黄金标准”。首先,它体积小巧,非常适合嵌入到自制设备中,不会占用过多内部空间。其次,它基于ATmega328P芯片,性能对于读取传感器数据、进行简单逻辑判断、输出PWM信号控制风扇转速来说绰绰有余。最重要的是,它的生态极其丰富,任何你遇到的问题,几乎都能在网上找到现成的库函数和解决方案,极大降低了开发门槛。相比于更强大的ESP32或树莓派Pico,Nano在简单可靠和成本控制上取得了最佳平衡。

2.2 感知核心:GP2Y1010AU0F光学粉尘传感器

空气净化器的“眼睛”就是PM2.5传感器。我选用的是夏普的GP2Y1010AU0F。这是一款非常经典的、采用光学散射原理的粉尘传感器。它的工作原理很有趣:内部有一个红外LED和一个光电晶体管。LED发出红外光,如果空气中存在粉尘颗粒,光线就会被散射,部分散射光会被光电晶体管接收到。空气中的颗粒物浓度越高,散射的光就越强,传感器输出的模拟电压也就越高。

注意:这类光学传感器对灰尘,尤其是大颗粒物(如毛发、絮状物)比较敏感,且需要定期清洁光学窗口,否则读数会严重漂移。但它对于PM2.5这类细小颗粒物的趋势监测是完全足够的,而且成本远低于激光传感器(如攀藤PMS5003系列)。对于DIY项目,性价比是第一考量。

2.3 动力与净化核心:12V CPU风扇与HEPA滤网

风扇是净化器的“肺”。我直接拆了一个旧的电脑机箱12V CPU风扇。选择它的理由很充分:第一,成本极低甚至为零;第二,12V供电非常普遍,容易匹配电源;第三,CPU风扇本身就是为了在狭小空间内高效推动空气而设计的,风压和风量特性符合我们的需求。通过Arduino的PWM引脚控制其转速,就能实现无极调速。

滤网是净化器的“肾”,直接决定净化效果。我选择了第三方生产的“小米空气净化器2代兼容HEPA滤网”。这里有个关键点:HEPA(高效颗粒空气)滤网是有等级之分的,比如H11、H12、H13。等级越高,对0.3微米颗粒的单次过滤效率越高(H13可达99.95%以上),但风阻也越大。小米原装滤网通常等效于H12-H13级别。第三方兼容滤网成本能低30%-50%,但在选购时一定要确认其标称的过滤等级和效率,不能只看价格。我用的这款标称对PM0.3的过滤效率在99%以上,对于DIY使用已经足够。

2.4 结构材料:千色板(Millboard)的妙用

最初我想用硬纸板卷个圆筒,但立刻意识到这玩意儿强度太差,且不防潮。在学建筑的朋友指点下,我找到了“千色板”(Millboard,一种高密度纤维板)。它质地坚硬,又有一定的韧性和厚度(我用的约3mm),可以通过切割部分厚度后弯曲成型。用美工刀在板子一面间隔地划出深度约2/3厚度的平行切口,它就能沿着切口优雅地弯成圆弧,再粘合起来就是一个非常坚固的圆筒结构。这比用PVC管或者亚克力板加工要简单、便宜得多。

3. 机械结构制作详解

结构是项目的骨架,做结实了,后续的电子部分才能安稳。

3.1 制作净化器主体圆筒

  1. 下料与划线:根据你选用的HEPA滤网高度和直径,确定圆筒的尺寸。我的滤网直径约20cm,高约30cm。因此,需要裁切一块长方形的千色板,长度等于滤网周长(约63cm),宽度略高于滤网高度(我留了32cm,预留上下盖板位置)。
  2. 开槽以利弯曲:这是最关键的一步。在千色板未来将成为“内壁”的那一面,用直尺和美工刀,划出多条平行的切口。切口间距约1-1.5cm,深度控制在板厚的2/3。切得太浅弯不动,切穿了强度就没了。这个过程需要耐心,保持切口深度均匀。
  3. 弯曲与定型:沿着切口,慢慢将板材弯成一个圆筒。你会发现有了这些切口,弯曲变得非常容易且弧度均匀。将两端对接,使用“神器743”强力胶(或其他环氧树脂胶)在接缝内外都进行粘合固定。
  4. 内部加强:为了防止圆筒在受力后变形,我将剩余的“神器743”胶水灌入那些切开的缝隙里。胶水固化后,这些缝隙变成了加强筋,整个圆筒的刚性大大提升,甚至可以用手用力按压而不变形。

3.2 制作顶盖与安装风扇

  1. 顶盖制作:用圆规在另一块千色板上画一个与圆筒外径相同的圆,并仔细切割下来。这就是顶盖。
  2. 开风扇孔:将12V CPU风扇放在顶盖中央,描出外框。然后,在框内画出风扇的进风栅格区域(通常是中间一个圆或方框)。用笔刀或线锯将这个栅格区域挖空。这是出风口。
  3. 固定风扇:将风扇有标签的一面(吸风面)朝下,覆盖在刚挖好的孔洞上,确保风扇的四个螺丝孔位在顶盖实体部分上。用螺丝或直接用“神器743”胶水将风扇牢牢粘在顶盖内侧。确保风扇四周密封良好,防止空气从缝隙短路循环。

3.3 总装与气密性处理

将HEPA滤网放入做好的圆筒中。滤网本身是圆柱形,与圆筒内壁应该是紧密配合的。如果有点松,可以在滤网外侧贴一圈泡沫胶带。然后将装有风扇的顶盖盖在圆筒上,同样用胶水粘牢。至此,空气的路径就确定了:室内空气从圆筒底部和侧面的缝隙被风扇吸入,强制通过HEPA滤网,洁净空气从顶盖的风扇处吹出

实操心得:气密性至关重要!所有非预期的缝隙都会导致“漏风”,未经过滤的空气直接跑出去,净化效率大打折扣。在粘合每一个接缝时,都要确保胶水涂抹均匀、充分。完成后再检查一遍,可以用点燃的线香在设备周围缓缓移动,观察烟雾的流向,测试漏风点。

4. 电路设计与连接

电路是项目的神经网络,连接正确是成功的一半。

4.1 系统接线图与原理

整个系统的供电逻辑是:一个12V/2A的直流电源适配器作为总电源。它同时给两个设备供电:

  1. 12V CPU风扇:直接接12V正负极。
  2. Arduino Nano:通过其Vin引脚输入12V,Nano板载稳压器会将其降至5V为芯片供电。

控制逻辑是:Arduino读取传感器的模拟值,转换为PM2.5浓度,然后根据浓度值(或手动模式)输出一个PWM信号到风扇的调速线(通常是黄色线),从而控制风扇转速。

我额外增加了一个TTP223触摸开关模块,用于切换模式(如自动/手动/静音)。你也可以用普通的自锁开关代替,代码逻辑是通用的。

4.2 关键传感器接线(GP2Y1010AU0F)

这个传感器的接线需要特别小心,它需要一个小电容和电阻组成RC电路来驱动其内部的LED。具体接线如下:

Arduino Nano 引脚 GP2Y1010AU0F 引脚 说明 额外组件
5V VCC (Pin 3) 传感器供电
GND GND (Pin 4) 地线
A0 Vo (Pin 5) 模拟信号输出
D2 LED-GND (Pin 2) 控制内部LED开关 串联一个150Ω电阻
GND LED-GND (Pin 2) 另一端 LED电流回路 并联一个220μF电解电容(正极接D2方向)

踩坑记录:我买的传感器不带预焊的排针和RC组件。自己焊接那几条比头发丝粗不了多少的引脚线,简直是眼睛和耐心的双重折磨。务必准备好尖头烙铁、助焊剂和放大镜。焊接后,用万用表通断档仔细检查每一个连接点,避免虚焊。我在代码里特意加了一个“LED指示灯”功能,如果上电后传感器连接正常,板载LED会闪烁两次,否则不亮,这能帮你快速判断硬件连接是否成功。

4.3 风扇调速接线

普通三线CPU风扇(红/黑/黄):

  • 红线:接12V电源正极。
  • 黑线:接12V电源负极(同时也是Arduino的GND,共地)。
  • 黄线:调速线,接Arduino的某个PWM引脚(我用的D9)。

通过Arduino的 analogWrite(pin, value) 函数,给value赋值0-255,就能实现0-100%的转速控制。

5. 代码逻辑与功能实现

代码是项目的大脑,让硬件按照我们的想法智能运行。

5.1 核心逻辑与库依赖

程序的核心逻辑是一个状态机,主要包含以下几个部分:

  1. 初始化:设置引脚模式,启动串口通信,初始化中断定时器。
  2. 传感器数据读取与处理:周期性触发传感器LED,并读取A0引脚的模拟值。根据传感器数据手册提供的公式,将电压值转换为粉尘浓度(μg/m³)。这个公式通常不是线性的,需要参考传感器手册中的电压-浓度曲线图进行拟合或分段计算。
  3. 控制决策:根据当前模式(自动/手动/静音)和传感器读数,决定目标风扇转速。
    • 自动模式:设定几个PM2.5浓度阈值。例如,浓度<35为优,风扇低速;35-75为良,中速;>75为差,高速。
    • 手动模式:固定在一个预设转速。
    • 静音模式(Shh Mode):将风扇转速设定在一个很低的值,仅维持微弱空气循环,噪音极小。
  4. 平滑调速:为了避免风扇转速突变产生噪音,使用一个渐变函数,让当前转速平滑地过渡到目标转速。这里我使用了TimerOne库来产生一个稳定的中断,在中断服务程序里逐步调整PWM占空比,实现风扇的“淡入淡出”效果。
  5. 模式切换与指示:检测触摸开关的输入,循环切换模式,并通过板载LED或外接LED用不同的闪烁 pattern 来指示当前模式。

必须安装的库:在Arduino IDE的“库管理器”中搜索并安装 TimerOne。这个库让我们能够轻松使用硬件定时器中断,是实现平滑调速和精准定时读取传感器的关键。

5.2 代码关键片段解析

这里摘录部分核心代码并加以解释:

CPP
# include <TimerOne.h> // 引入定时器库
 
// 引脚定义
const int dustSensorLedPin = 2;
const int dustSensorVoPin = A0;
const int fanPwmPin = 9;
const int touchPin = 3; // 触摸开关引脚
 
// 变量定义
int currentFanSpeed = 0;
int targetFanSpeed = 0;
int operationMode = 0; // 0:自动,1:手动,2:静音
unsigned long lastSensorReadTime = 0;
const long sensorInterval = 1000; // 每秒读一次传感器
 
void setup() {
pinMode(dustSensorLedPin, OUTPUT);
pinMode(fanPwmPin, OUTPUT);
pinMode(touchPin, INPUT);
Serial.begin(9600);
 
// 初始化传感器LED检查
digitalWrite(dustSensorLedPin, HIGH);
delay(100);
digitalWrite(dustSensorLedPin, LOW);
delay(100);
digitalWrite(dustSensorLedPin, HIGH);
delay(100);
digitalWrite(dustSensorLedPin, LOW); // 闪烁两次表示硬件正常
 
// 设置定时器中断,每10ms执行一次smoothFan函数
Timer1.initialize(10000); // 单位:微秒
Timer1.attachInterrupt(smoothFan);
}
 
void loop() {
// 1. 模式切换检测
if (digitalRead(touchPin) == HIGH) {
delay(50); // 简单防抖
if (digitalRead(touchPin) == HIGH) {
operationMode = (operationMode + 1) % 3; // 在0,1,2间循环
indicateMode(operationMode); // 用LED指示模式
while(digitalRead(touchPin) == HIGH); // 等待松手
}
}
 
// 2. 定时读取传感器(仅自动模式需要)
if (operationMode == 0 && millis() - lastSensorReadTime >= sensorInterval) {
lastSensorReadTime = millis();
float dustDensity = readDustSensor(); // 自定义函数,读取并计算浓度
Serial.print("PM2.5: ");
Serial.print(dustDensity);
Serial.println(" ug/m3");
 
// 3. 根据浓度设定目标转速
if (dustDensity < 35) targetFanSpeed = 80; // 低速
else if (dustDensity < 75) targetFanSpeed = 150; // 中速
else targetFanSpeed = 255; // 高速
} else if (operationMode == 1) {
targetFanSpeed = 180; // 手动模式固定转速
} else if (operationMode == 2) {
targetFanSpeed = 60; // 静音模式极低转速
}
 
// 其他任务...
}
 
// 定时器中断服务函数:实现风扇转速平滑过渡
void smoothFan() {
if (currentFanSpeed < targetFanSpeed) {
currentFanSpeed++;
} else if (currentFanSpeed > targetFanSpeed) {
currentFanSpeed--;
}
analogWrite(fanPwmPin, currentFanSpeed); // 更新PWM输出
}

代码风格说明:你可能注意到,在模式判断部分,我用了多个独立的if语句,而不是if-else if链。这确实不够优雅,但在当时那种凌晨四点脑力枯竭的状态下,这是最直白、不容易出错的方式。编程有时就是为了解决问题,在确保功能正确的前提下,代码的“美观度”可以稍后重构。

6. 调试、优化与常见问题排查

硬件组装和代码烧录只是开始,让整个系统稳定可靠地运行,才是真正的挑战。

6.1 上电调试步骤

  1. 先供电,后连接:先将12V电源适配器接通市电,再用杜邦线连接Arduino和风扇、传感器。避免带电插拔。
  2. 观察指示灯:给Arduino上电后,观察板载LED(通常连接在D13)是否快速闪烁两次。如果没有,首先检查传感器部分的接线,尤其是LED驱动引脚(D2)上的150Ω电阻和220μF电容是否正确连接。
  3. 打开串口监视器:将Arduino连接到电脑,打开IDE的串口监视器,设置波特率为9600。你应该能看到每秒打印一次的PM2.5浓度数据。用手在传感器进气口处扇风或制造一些灰尘,观察数值是否变化。
  4. 测试风扇控制:在代码中暂时将targetFanSpeed固定为某个值(如128),重新上传。听风扇声音是否响起,并且转速是否随你修改的值而变化。
  5. 测试模式切换:触摸TTP223模块或拨动开关,观察板载LED的指示是否按预期变化(例如,快闪、慢闪、常亮代表不同模式),同时风扇转速也应相应改变。

6.2 性能校准与优化

  • 传感器读数校准:GP2Y1010AU0F的输出值容易受环境温湿度和元器件个体差异影响。最基础的校准方法是进行“零点校准”。在一个你认为空气非常洁净的环境(比如刚开启高效净化器的房间内运行半小时后),读取稳定的传感器模拟值,将这个值作为“零点”存储在代码中,后续读数减去这个零点。更精确的做法是使用专业的校准仪器进行对比,但对于DIY项目,零点校准已能大幅提升相对准确性。
  • 风扇转速与噪音平衡:在“静音模式”下,你需要找到一个最低的可用转速。这个转速要能保证风扇能持续启动转动,而不是停转或抖动,同时噪音几乎不可闻。可以通过反复试验targetFanSpeed的值(比如从30开始试)来确定。
  • 滤网风阻监测:HEPA滤网会随着使用逐渐堵塞,风阻增大。你可以通过一个简单的现象来判断:在相同的PWM值下,新滤网的风速(用手感测出风口风量)明显大于旧滤网。将这一点记录为“更换滤网”的直观依据。

6.3 常见问题速查表

问题现象 可能原因 排查步骤
上电后无任何反应 1. 电源未接通或损坏
2. Arduino Nano损坏
3. 电源线虚焊
1. 用万用表测量12V适配器空载电压。
2. 检查Nano板载电源指示灯是否亮起。
3. 重新焊接电源线接头。
串口监视器无数据输出 1. 串口选择错误或波特率不匹配
2. 传感器接线错误或损坏
3. 代码未成功上传
1. 确认IDE中选择正确的COM口,波特率设为9600。
2. 检查传感器VCC、GND电压是否为5V。用示波器或逻辑分析仪检查D2引脚是否有脉冲输出。
3. 重新编译上传代码,观察IDE下方有无错误信息。
风扇不转或抖动 1. PWM引脚连接错误
2. 风扇调速线未接或损坏
3. PWM初始值过低无法启动风扇
1. 确认黄线接在了定义的PWM引脚(如D9)。
2. 将风扇红线黑线直接接12V电源,测试风扇本身好坏。
3. 尝试将代码中targetFanSpeed设高(如200),测试风扇能否正常启动。
PM2.5读数始终为0或异常高 1. 传感器光学窗口被遮挡或污染
2. RC电路(电阻电容)值错误或未接
3. 计算公式错误或参考电压不对
1. 用棉签蘸无水酒精轻轻擦拭传感器进气窗口。
2. 对照数据手册和图解,确认150Ω电阻和220μF电容连接无误。
3. 检查代码中模拟读数analogRead的范围(0-1023)与计算公式是否匹配。
模式切换不灵敏或无效 1. 触摸模块或开关接线错误
2. 代码中引脚模式设置错误(应为INPUT)
3. 防抖逻辑过于简单或复杂
1. 用万用表测量触摸模块输出引脚,触摸时电平是否变化。
2. 检查pinMode(touchPin, INPUT)语句。
3. 调整防抖延时时间,或引入更稳定的状态检测逻辑。
设备运行一段时间后死机 1. 电源功率不足(风扇启动电流大)
2. 代码中有内存泄漏或中断冲突
3. 散热不良导致Arduino过热
1. 确保12V电源适配器额定电流大于风扇最大电流(通常1A以上足够)。
2. 检查中断服务程序smoothFan是否过于耗时,避免在中断内进行复杂操作。
3. 确保设备放置在通风处,必要时可为Arduino加装小型散热片。

7. 项目总结与扩展思路

这台DIY空气净化器在我卧室里连续服役了超过一年,期间经历了南方的梅雨季节和北方的雾霾天,表现相当稳定。最大的成就感来自于每次在手机APP上看到商用净化器指数飙升,而我的自制设备通过加速运转,也能让房间内的空气质量迅速回到“优”的水平。它不仅仅是一个工具,更是一个持续运行的环境监测站,让我对室内空气的动态有了前所未有的了解。

成本是它最大的优势。除了HEPA滤网是耗材需要定期更换(大约半年到一年,视使用环境而定),其他电子部件几乎没有损耗。即使算上滤网,长期使用的成本也远低于品牌产品。

如果你也想动手做一个,这里有几个可以继续改进和扩展的方向:

  1. 增加显示与交互:加一块OLED屏幕,实时显示PM2.5数值、温度湿度、风扇转速和工作模式,交互会直观很多。
  2. 联网与智能控制:将主控换成ESP8266或ESP32,接入家庭Wi-Fi。你可以通过手机APP远程查看空气质量、控制开关和模式,甚至与天猫精灵、小爱同学等智能音箱联动。
  3. 多传感器融合:增加一个SGP30或CCS811传感器来检测TVOC(总挥发性有机物)和二氧化碳浓度,让净化器不仅能对付颗粒物,还能应对装修污染和人体代谢带来的空气问题。
  4. 外观美化:像我开头说的,喷成黑色只是基础。你可以用更好的木材、亚克力板来制作外壳,甚至设计一个仿古或科幻风格的外观,让它成为一件独特的家具。
  5. 功耗记录:增加一个电流传感器,统计设备的实时功耗和累计耗电量,对于评估运行成本很有参考价值。

动手制作的过程,就是不断遇到问题、搜索资料、尝试解决、最终豁然开朗的过程。这台看似简陋的空气净化器,凝结的不仅是过滤洁净的空气,更是解决问题的思路和亲手创造的乐趣。希望这份详细的指南,能帮你少走一些我走过的弯路,顺利点燃你自己的创造火花。