ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Arduino环境感知入门:MQ-135气体传感器原理、接线与空气质量监测实战

Arduino环境感知入门:MQ-135气体传感器原理、接线与空气质量监测实战 做 Arduino 实验做到第 15 个你会逐渐摸到一条规律凡是要做“环境感知”的小项目传感器基本绕不开温度、湿度、气体这几个方向。MQ-135 就是气体检测这条线上非常典型的一个模块它便宜、耐造、接线简单接上 Arduino Uno 之后可以快速测出环境空气质量的变化。这篇文章会用一整篇的篇幅把这个模块讲透从工作原理、硬件连线、代码实现到校准思路和排查经验全部基于我实际调试中的记录整理。基础是刚学完数字 IO 和模拟输入、想往传感方向走一步的 Arduino 玩家看完可以直接在面包板上复现。你可能会问市面上气体传感器那么多为什么偏偏选 MQ-135原因是我觉得它最适合当“第一块气体传感器”来玩它输出的是模拟信号天然适合练习analogRead和 ADC 采样它测量对象覆盖氨气、硫化物、苯系蒸汽、烟雾等常见空气污染物最关键的是它模块化程度高板上自带比较器电路和电位器既有模拟输出也有数字输出能做的实验深度足够。下面我就从这个思路开始展开。1. 项目背景与整体思路1.1 MQ-135 到底是什么东西MQ-135 本质上是一个基于二氧化锡SnO2半导体材料的气敏电阻传感器。结构上分两部分一部分是绕在陶瓷管外面的加热丝一部分是涂了 SnO2 敏感材料的测量电极。工作时加热丝持续通电把敏感材料加热到几百摄氏度的最佳工作温度此时空气中的氧气会吸附在 SnO2 表面夺取电子形成氧负离子让材料的表面势垒升高、电导率下降。当环境中出现还原性气体比如乙醇蒸汽、氨气、烟雾中的有机物分子时这些气体会与吸附态的氧发生反应把电子释放回材料表面导致 SnO2 电导率升高、电阻下降最终反映在输出电压上。打个不严谨但容易理解的比方传感器就像一个化学反应里的天平干净空气里天平保持一个“稳定位”一旦有污染气体分子过来它就会往另一边偏输出端的电压跟着变化。我们读取的正是这个电压变化量而不是直接读一个“浓度值”。这也是 MQ-135 这类半导体传感器的特点它能告诉你“气味有没有变浓”但很难告诉你“具体有多少 ppm 的某种气体”。原因在于它的交叉敏感特性——对很多种还原性气体都有响应而且电阻与浓度的关系是非线性的通常会做成对数关系。所以做项目时我更倾向于把它当作一个“空气质量趋势指示器”来用而不是用来做精确的化学计量。1.2 本次实验目标与方案选型实验目标定得很具体让 Arduino Uno 读取 MQ-135 模块的模拟输出把读到的 ADC 数值换算成电压在串口监视器里持续打印同时做一次简单的“基线校准”用当前读数与基线读数的比值去判断空气质量是否变差必要时点亮板载 LED 做提醒。这样既覆盖了传感器读数的完整链路也能看出一个最简单的空气质量判断逻辑是怎么搭起来的。方案上我没有直接用第三方库而是坚持手写analogRead加换算的流程。原因不是库不好而是就这个实验而言库把太多细节隐藏掉了ADC 怎么量化、电压怎么换算、基线怎么取这些东西只有自己写一遍才能体会到。而且 MQ-135 本身受加热温度、湿度、漂移影响很大不把底层逻辑搞清楚后面数据波动起来了你都不知道从哪下手排查。先把裸代码跑通再去考虑封装是我一贯的调试节奏。2. 硬件准备与接线2.1 器件清单这次需要的器件很少都是玩 Arduino 的常规库存。我列一个清单出来你对照着准备就行。序号器件名称数量备注1Arduino Uno 开发板1块也可以兼容板建议用原厂或质量稳定的板子2MQ-135 气体传感器模块1块常见蓝色PCB版本引脚间隔2.54mm3面包板1块建议830孔方便后续扩展4杜邦线若干公对公至少4根5USB 数据线1条用于供电和程序下载6可选LED模块或电阻LED1组用来做报警输出指示也可以直接用板载LEDMQ-135 的裸传感器有两种形态一种是带底座的插针式另一种是集成好的模块。我建议新手直接买模块因为模块上已经集成了必要的负载电阻和比较器电路接线和调试都省事很多。裸传感器虽然更便宜但需要自己搭负载电阻和稳压电路反而不适合入门。2.2 MQ-135 引脚说明与接线步骤MQ-135 模块通常有 4 个引脚个别版本会有第 5 个引脚AOUT 旁的额外电源或空脚所以接线前先看模块上的丝印别插反。常见引脚定义如下VCC电源正极接 Arduino 的 5VGND电源地接 Arduino 的 GNDAO模拟输出接 Arduino 的 A0 引脚DO数字输出接 Arduino 的 D2 引脚可选接线表整理如下我建议严格按照这个顺序操作每接一根就对照一次能避免大部分低级错误MQ-135 模块引脚连接目标VCCArduino Uno 5VGNDArduino Uno GNDAOArduino Uno A0DOArduino Uno D2可选默认也可不接接好后再检查一遍电源正负极有没有接反确认无误后再插 USB 线。第一次上电会摸到传感器顶部有点发热这是加热丝在工作属于正常现象不用慌。如果模块上的电源 LED 不亮优先检查 5V 线和 GND 线是不是真的导通了。需要特别提醒的是这个模块一定要用 5V 供电不能用 3.3V。原因是模块内部加热丝需要足够功率才能达到工作温度3.3V 下加热不足SnO2 敏感层温度偏低测试结果会严重漂移有时甚至读不出有效数据。我之前偷懒省功耗接过一次 3.3V模拟输出读数就像抽风一样来回跳浪费了大半天排查最后换回 5V 立刻正常。2.3 上电前检查接线完成到上电之间花两分钟做一遍目视检查可以省掉很多麻烦。第一看面包板正负极排是否和 Arduino 完全对应5V 排别接成 GND第二检查 AO 是否真的插在 A0 引脚上A0 附近有数字引脚插错一格很常见第三确认 DO 悬空时不会碰到相邻引脚如果没接 DO最好把杜邦线撤走避免裸露的排针误触。还有一个细节上电后不要立刻拿传感器去测任何气体。MQ-135 的敏感层需要预热才能稳定首次上电或长时间未通电后的前几分钟读数会有一个明显的漂移过程。这时直接采数据只能得到“加热曲线”不能代表真实的空气质量。先把模块通电让它空烧几分钟再做下面的实验这个习惯要养成。3. Arduino 端程序实现3.1 先别急着装库MQ-135 在 GitHub 上有第三方库封装了读取浓度、校准、温湿度补偿这些功能看起来很省事。但我强烈建议这个实验先手写至少把读取和换算两件事写明白。理由是这样的气体传感器和温湿度传感器最大的区别是它没有固定的“读数-物理量”对应公式你必须自己定义基线、自己算偏移比例这个逻辑不亲手实现一遍就很难理解最终显示的数据到底怎么来的。换个角度说你把analogRead返回的 0 到 1023 理解得越透彻后面接触其他模拟传感器就越轻松。这就像学骑自行车刚开始宁可慢一点也要自己把握平衡等熟练之后再用辅助轮反而没必要了。3.2 基础读取代码先把最基础的读取代码放出来。功能很纯粹每秒钟读一次 A0 的模拟值换算成电压打印到串口监视器。/* * Arduino Uno 实验15MQ-135 气体传感器 - 基础读取 * 接线VCC - 5VGND - GNDAO - A0DO可选- D2 */ int mq135Pin A0; // 模拟输入引脚 int ledPin 13; // 板载LED可选 void setup() { Serial.begin(9600); // 打开串口 pinMode(mq135Pin, INPUT); pinMode(ledPin, OUTPUT); Serial.println(MQ-135 init...); Serial.println(请将传感器置于新鲜空气中预热后再观察数据); } void loop() { int rawValue analogRead(mq135Pin); // 读取ADC原始值范围0~1023 float voltage rawValue * 5.0 / 1023.0; // 换算成电压 // 打印原始ADC值和电压值 Serial.print(ADC:); Serial.print(rawValue); Serial.print( Voltage:); Serial.print(voltage, 3); Serial.println( V); delay(1000); // 每秒刷新一次 }下载的时候记得先把串口监视器关掉不然会占用串口导致下载失败。下载成功后打开串口监视器波特率调到 9600你会看到类似下面的输出MQ-135 init... 请将传感器置于新鲜空气中预热后再观察数据 ADC:182 Voltage:0.889 V ADC:186 Voltage:0.909 V ADC:188 Voltage:0.919 V可以看到读数不是稳定不变的会有小幅波动。这个波动来自两个方面一是传感器本身对空气流动、温湿度的敏感性二是 ADC 采样本身存在量化噪声。只要你所在的环境没有突然出现污染源波动范围通常不会太大。如果波动幅度大到几十甚至上百就要检查接线有没有虚接或者供电是否稳定了。3.3 核心代码逐段拆解看代码时不要光想着“复制粘贴跑起来”把每一行干了什么弄清楚后面拓展才有底。我挑几个关键点展开讲一下。analogRead(mq135Pin)拿到的是 ADC 量化结果。Arduino Uno 用的是 ATmega328P 芯片自带的 10 位 ADC所以输出范围是 0 到 1023一共 1024 个量化档位。默认参考电压是 5V所以当输入电压为 0V 时读数是 0输入电压为 5V 时读数是 1023中间每变化约 4.88mV读数增加 1。电压换算这里我用了rawValue * 5.0 / 1023.0。严格按 ADC 离散特性来算应该是rawValue * 5.0 / 1024.0因为 1024 才是总档位数。Arduino 官方在很多例程里习惯把 1023 当分母实践中两者差异极小没必要纠结。但从原理角度我提示一下如果做高精度采集用 1024.0 更贴近 ADC 的参考电压划分逻辑如果只是做趋势监测两个都行。你想深究就按 1024 算不想深究就保持一致即可。delay(1000)控制采样周期。对于空气质量的缓慢变化来说1 秒一次已经足够甚至 5 秒一次都可以。如果采集频率太高不仅刷屏还会放大噪声反而不利于观察趋势。3.4 扩展空气质量分级与报警基础读取跑通后我们来加一个简单判断逻辑先在上电时采集多次数据求平均值作为基线然后每次循环计算当前读数与基线的比值比值超过阈值就认为空气质量变差点亮板载 LED。/* * Arduino Uno 实验15MQ-135 气体传感器 - 空气质量分级 * 接线VCC - 5VGND - GNDAO - A0板载LED可不接 */ int mq135Pin A0; int ledPin 13; int baseline 0; // 基线值 float warnRatio 1.2; // 触发报警的比值阈值 void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); // 预热后校准基线取20次读数的平均值降低抖动影响 Serial.println(Calibrating baseline...); float sum 0.0; int count 20; for (int i 0; i count; i) { sum analogRead(mq135Pin); delay(50); } baseline sum / count; Serial.print(Baseline: ); Serial.println(baseline); } void loop() { int rawValue analogRead(mq135Pin); float voltage rawValue * 5.0 / 1023.0; float ratio (float)rawValue / baseline; Serial.print(Raw:); Serial.print(rawValue); Serial.print( Voltage:); Serial.print(voltage, 3); Serial.print( Ratio:); Serial.println(ratio, 3); if (ratio warnRatio) { digitalWrite(ledPin, HIGH); // 空气质量变差点亮LED } else { digitalWrite(ledPin, LOW); } delay(1000); }这里校准时机有个小讲究代码里的基线校准放在setup里执行但 MQ-135 刚上电时读数还没稳定立即校准可能得到一个偏高的基线。实际使用时我建议让模块先通电预热 3 到 5 分钟再手动重启程序触发校准或者把校准逻辑放到串口指令里收到特定字符后再重新标定。下面这段思路可以留作进阶版本去实现在loop里判断Serial.available()收到字符C时重新走一遍平均采样逻辑更新基线。判断条件里我用了“当前值除以基线值大于 1.2”作为报警阈值。之所以用比值而不是绝对值是因为不同环境下基线差异很大你窗边测的基线可能是 100室内角落可能是 250直接用绝对值很难设置一个通用阈值。用比值之后只要相对于当前环境出现 20% 以上的偏移就可以报警这个思路在实测中很有用。至于 1.2 这个数怎么来的来源于我几次测试的折中平时波动大概在 5% 以内拿着酒精棉靠近时会飙升到 1.5 以上所以 1.2 作为报警线不会太灵敏也不会太迟钝。你可以根据现场情况上下调。4. 串口监控与数据校准4.1 串口数据怎么读最直观基础程序跑起来后串口监视器里是一行一行的文本数据适合记录但不适合看趋势。Arduino IDE 从 1.6.6 版本开始内置了一个“串口绘图器”Serial Plotter在“工具”菜单里可以打开。它会自动解析串口输出的数值并实时绘制波形比干巴巴看数字直观得多。用串口绘图器有个小经验它会把串口监视器顶掉两者不能同时打开。所以你要么用监视器看数值要么用绘图器看曲线。另外串口绘图器对数据格式有一定要求最简单的用法就是每行只打印一个数值它会自动画出一条曲线。如果想同时显示多组数据用逗号或制表符分隔第一行用label1:数值 label2:数值这样的格式即可。我最推荐的做法是预热期间开串口绘图器观察ADC值曲线你会看到曲线从初始值逐渐爬升或回落后趋于平缓。这个过程就是加热丝和敏感层达到热平衡的过程通常需要两三分钟。等曲线基本平了再进行基线校准和后续测试这样数据才有意义。4.2 校准基准值的三个要点关于 MQ-135 的校准我实际操作中总结出三个关键点直接决定数据可信度。第一校准环境必须选在“当前你要监测的环境里空气质量相对正常的时段”。比如你要在室内做监测就别在刚喷完空气清新剂或者炒完菜的厨房里校准否则基线本身就偏高后面真正出现污染时可能也触发不了报警。理想情况是开窗通风一段时间后在稳定环境里校准。第二校准要用多次采样取平均不要用单次读数。原因前面提过ADC 单次采样有随机波动而 MQ-135 对微气流也很敏感单次读数可能偏高或偏低。我在代码里取了 20 次平均值你也可以根据环境稳定性调整次数环境越乱取的次数越多。第三基线不是永远不变的。随着时间推移传感器的敏感材料会慢慢老化吸附污染物的程度也会变化基线会漂移。长期运行的项目建议定时重新校准或者记录下发现在“空气质量正常”时基线已经在缓慢上升说明该重新标定了。不要迷信一劳永逸的基线这是气体传感器项目的通用教训。4.3 数值关系与 ADC 精度把 ADC 数值和电压的关系彻底搞清楚对排查问题很有帮助。Arduino Uno 的 ADC 是 10 位我们做一个最简单的映射表ADC 读数对应电压V说明00.00理论上模块输出最低值2561.25约四分之一量程5122.50约二分之一量程7683.75约四分之三量程10235.00理论上模块输出最高值MQ-135 模块的模拟输出范围在实际中很少会到 0V 或 5V 的极端值多数环境条件下读数落在 0.5V 到 3.5V 之间。如果你发现读数一直粘在 1023 附近多半是传感器附近有很强的污染源如果读数一直是 0则可能 AO 引脚接错、模块电源没供上或者传感器受损。关于“精度”10 位 ADC 的固有分辨率约 4.88mV换算成 ADC 档位就是 1。对于 MQ-135 这种本身就存在较大噪声的传感器来说这个分辨率绰绰有余。真正限制精度的反而不是 ADC而是传感器的漂移和温湿度交叉敏感。所以这个实验里我们追求的是“稳定可重复的相对变化”不是绝对精度。5. 常见问题与排查技巧5.1 现象与解决方案速查表玩 MQ-135 的坑我基本都踩过一遍。把典型问题和排查方法整理成了一张表先收藏再看能帮你快速定位问题。现象可能原因排查与解决方案读数始终为 0AO 没接到 A0或模块没供电先量模块 VCC 和 GND 之间电压再查 AO 是否在正确引脚读数始终为 1023传感器附近有强污染源或模块损坏换到通风处看是否下降若不变检查 AO 输出电压读数上下乱跳幅度很大接线虚接、供电不稳、模块未预热重新拔插杜邦线确认 5V 供电预热后再测读数缓慢持续上升很久不平正常预热过程或温湿度变化大耐心等 5 分钟观察曲线是否走平DO 不输出任何变化板上电位器阈值调得不合适用螺丝刀微调电位器控制比较器的触发阈值串口监视器乱码波特率不匹配确认代码Serial.begin和监视器右下角都设为 9600数值正常但每次开机差异很大基线校准时机太早先预热再校准或改进程序支持手动触发校准排序下来你会发现大多数“读数异常”问题到最后都归结为三类接线问题、供电问题、预热问题。把这三关过了MQ-135 其实非常稳。5.2 排查过程中的三个小经验这里分享三个不太会写在教科书里的经验都是我实际摸爬滚打出来的。第一个经验先量电压再怀疑传感器。排查问题时我喜欢先拿万用表量一下模块 VCC 和 GND 之间的电压。如果这里不是稳定的 5V后面一切分析都是白费。很多时候“读数抽风”的原因其实是面包板电源轨接触不良或者劣质杜邦线内部断了。确认供电没问题之后再谈传感器本身。这个顺序能帮你省掉大量无效排查时间。第二个经验千万别用手直接摸传感器裸露的引脚。SnO2 敏感层表面状态很微妙手上的汗液和油脂会影响局部导电性导致读数异常。我刚开始实验时为了确认接线牢固习惯捏一下模块结果数值猛跳一阵子才恢复还以为传感器坏了。现在我会拿镊子或戴静电手套操作避免直接接触。轻触一下也可能造成瞬时读数波动所以测试时尽量让传感器悬空固定不要频繁触碰。第三个经验测气体响应时不要凑太近猛喷。很多同学测试传感器直接把酒精棉球怼到传感器脸上结果读数瞬间爆表然后又迅速回落。这样测试不是不行但它容易让传感器“中毒”——高浓度气体会在敏感层表面留下残留吸附物导致之后一段时间的数值都偏高、回不到原来的基线。更稳妥的测试方式是让气体源离传感器大约 10 到 20 厘米慢慢靠近观察数据变化趋势。5.3 进阶排查如何判断传感器是否老化如果按上面的方法排查了一圈读数还是怪怪的那就要考虑传感器本身的老化问题。MQ-135 属于消耗性器件它的敏感层会随着使用时间增长而性能衰退。判断方法很简单在充分预热后记录它在清洁空气中的基线电压然后和之前的数据对比。如果基线电压明显上升或者对同样浓度的测试气体响应幅度明显变小那大概率是传感器寿命快到了。还有一个容易被忽略的因素是灰尘。长期暴露在空气中的 MQ-135敏感层表面会积附灰尘影响气体分子与敏感层的接触效率。这种情况下可以尝试用一个干净的软刷子轻轻扫一下传感器表面的防爆网罩不要用液体清洗。如果清理后数据恢复说明只是表面污染如果没有变化才考虑换新传感器。毕竟 MQ-135 价格不高真老化到不能用换一个远比折腾划算。收尾这次实验做完我个人最有收获的一点不是“我让一块传感器出数了”而是弄清楚了“读到的数到底是怎么一步步变成有意义的判断结果的”。ADC 采样、电压换算、基线归一化、阈值报警这套链路放之四海而皆准以后你接任何模拟输出的传感器思路都是相通的。至于 MQ-135 本身我最后建议你做一件事把它固定在一个通风但不会受阳光直射的位置通电跑一整天用串口绘图器记录数据你会发现读数会随着你开关门窗、做饭、甚至房间人数多少而产生微妙变化。这种把传感器放进真实生活环境的体验比在实验台上做一百次测试都更能让你理解“环境感知”这四个字的分量。
返回列表