ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32驱动红外PM2.5传感器GP2Y1010从接线到浓度换算全解析

STM32驱动红外PM2.5传感器GP2Y1010从接线到浓度换算全解析 如果只看淘宝标题“STM32 连接红外 PM2.5 传感器”看起来是人人都能干的小事但把它真正跑稳定远不止调一个 ADC 那么简单。我之前给一台空气净化器做颗粒物检测第一版就采用了红外 PM2.5 传感器 GP2Y1010AU0F本以为套用网上现成 Arduino 代码就能收工结果是反复折腾了整整一个周末踩了一串网上教程不会告诉你的坑。这篇文章就把从硬件接线、时序控制、ADC 采样到浓度换算的完整过程写清楚适合正在做毕业设计、课设或者只想低成本实现“空气质量检测”功能的嵌入式开发者。如果你已经比较熟悉 STM32 的定时器和串口直接跳到第 3 章看核心代码如果你是纯新手最好从第 1 章原理部分开始看理解脉冲采样的逻辑比抄代码重要得多。1. 红外 PM2.5 传感器的光学原理和信号特征1.1 这里说的 PM2.5 传感器具体是哪一类市面上的 PM2.5 传感器主要分成两类一类是激光式比如 PMS5003、PMS7003内部有激光管、光电二极管、风扇甚至一颗独立 MCU输出是串口数字帧直接给你一个“ug/m³”的浓度值另一类是本文要聊的红外式典型代表是夏普 GP2Y1010AU0F 和 GP2Y1014AU0F它们内部只是一个红外 LED 加一个光电二极管输出模拟电压没有任何数字协议。红外式之所以还有市场核心原因是便宜。同样一个模块激光式价格可能是红外式的 5 到 10 倍。红外传感器适合的场景是“定性判断”和“分档判断”比如空气净化器判断现在该用低档还是高档教室环境监测给一个“正常/轻度污染/污染”提示或者普通家用设备做一个灰尘超标报警。它的缺点也很明显不能精确区分颗粒物粒径读数受湿度影响标定困难长期稳定性和激光式没法比。如果你要做一个专业级空气质量监测仪建议老老实实选激光式。1.2 Vo 引脚的电压到底是什么GP2Y1010AU0F 最重要的引脚是 Vo也就是模拟输出。它的电压和空气中的颗粒物浓度大致呈正比关系但并不是一个精确的线性对应更接近“分段线性”。它的输出特性有几个关键数字建议直接记下来参数典型值说明供电电压 Vcc5V部分模块支持 3.3V但不推荐LED 供电 V-LED5V需要串联 150Ω 限流电阻LED 脉冲宽度0.32ms不能长时间点亮LED 脉冲周期10ms手册典型值对应 100Hz无尘时 Vo约 0.9V这就是基准电压灵敏度约 0.5V / (0.1 mg/m³)每个传感器个体差异很大最大输出约 3.6V高浓度时接近饱和网上很多 Arduino 工程把这两个参数写死比如直接用(voltage - 0.6) * 0.2或者0.17 * voltage - 0.1但它们之所以能跑是因为大多用了特定模块参考基准和参考电路恰好匹配。你自己做的时候如果直接抄公式读数很可能偏得离谱。正确思路是先读懂原始电压再根据你自己的电路和手头传感器做标定后面第 4 章会专门讲。1.3 几个写代码前必须形成肌肉记忆的时序参数这是红外 PM2.5 传感器和普通模拟传感器最大的区别它不是一个 24 小时持续输出有效信号的传感器。它内部的红外 LED 需要由 MCU 给出脉冲LED 亮起来之后光电二极管接收散射光Vo 才会输出一个随浓度变化的电平。LED 不亮的时候Vo 虽然也有电压残留但那个值没有意义。所以核心时序只有三句话给 LED 引脚一个高电平持续 0.32ms然后拉低。在这个 0.32ms 的脉冲内等到从上升沿开始算起大约 0.28ms 的时刻用 ADC 读取 Vo。每 10ms 重复一次这个脉冲也就是采样频率 100Hz。为什么采样点要卡在 0.28ms因为 LED 刚亮起来那一小段时间内光电二极管的响应没有完全建立Vo 还没有稳定到最终值如果采样太早读数偏低。而如果超过 0.32msLED 已经灭了内部电容放电Vo 开始跌落读数还是偏低。所以有效的采样窗口大约就是 0.28ms 前后 0.05ms 这个区间。好在 STM32 的 ADC 转换速度非常快单次转换在几微秒级别只要启动采样时刻准确不需要担心来不及读完。2. 硬件接线与电压匹配动手前把风险点先排掉2.1 六脚传感器的引脚定义如果你买的是裸传感器 GP2Y1010AU0F而不是集成好的模块会发现它有 6 个引脚。第一次拿到的人很容易把 V-LED 和 Vcc 搞混两个都叫“电源”但用途完全不同。引脚号名称作用1V-LED红外 LED 的正极电源必须经过 150Ω 电阻再接 5V2LED-GNDLED 的接地端3LEDLED 控制引脚由 MCU 给脉冲信号4S-GND传感器内部光电电路的接地端5Vo模拟电压输出接 MCU 的 ADC6Vcc传感器内部运放等电路的电源接 5VV-LED 和 Vcc 如果接反或者共用一路 5V 不加限流电阻LED 的电流会偏大轻则读数异常重则烧掉发光管。我自己第一次就因为偷懒把 V-LED 直接接 5V 没串电阻结果传感器工作几分钟之后 Vo 电压开始漂移排查了很久才发现是 LED 过热。如果你买的是模块引脚一般被简化成 VCC、GND、AOUT、LED 之类但内部电路原理不变接法同样是 LED 引脚给脉冲、AOUT 接 ADC。2.2 一个可以直接抄的接线方案以 STM32F103 系列为例我推荐下面的接法GP2Y1010 的 V-LED 引脚串联一个 150Ω 电阻后接 5V。LED-GND 接 GND。LED 引脚接 STM32 的 PA0配置为推挽输出。S-GND 接 GND。Vo 引脚接 STM32 的 PA1配置为 ADC 输入。Vcc 接 5V。Vcc 与 GND 之间靠近传感器引脚放一个 4.7µF 陶瓷电容再并一个 100µF 电解电容。接线看似简单但有两个坑。第一个是传感器 Vcc 的电源和 STM32 的 5V 如果是同一个电源轨电机、继电器、PWM 负载产生的纹波会直接串进 Vo第二个是 Vo 到 ADC 之间的走线不要太长最好控制在 10 厘米以内否则示波器上会看到明显的高频毛刺。2.3 3.3V ADC 和 5V 传感器之间的电压匹配STM32F103 的 ADC 参考电压是 3.3V输入范围不能超过 VDDA。而 GP2Y1010 的 Vo 在浓度较高时可以达到 3.6V直接接进 ADC 会超出量程导致测量结果卡在 4095而且 3.3V 以上区域已经完全失真。处理办法有两种我推荐第一种在 Vo 和 ADC 之间加一个 2:1 电阻分压比如 10kΩ 和 10kΩ。这样最高 3.6V 变成 1.8VADC 始终工作在线性区。把传感器供电降到 3.3V让 Vo 最高值也降到 3.3V 以下。代价是 LED 亮度降低传感器整体灵敏度明显下降信噪比变差实测读数会比 5V 供电偏低所以不推荐。用了分压电阻之后代码里要记得把 ADC 读到的电压乘以 2 再参与浓度换算这个因子很容易漏掉。我见过不少朋友在串口上看到电压只有 0.8V 左右以为传感器坏了其实就是忘了乘分压系数。2.4 电容和电阻到底在起什么作用150Ω 电阻的作用是限制 LED 峰值电流。GP2Y1010 内部的红外 LED 在工作时电流比较大如果不限流发光强度不受控Vo 输出和浓度之间的对应关系就会乱。4.7µF 和 100µF 电容的作用是稳住电源。LED 每 10ms 才亮一次每次点亮都会拉走一个电流尖峰如果电源内阻大Vcc 电压会跟着一起波动ADC 读到的电压就会叠加一个 100Hz 的纹波。加了足够容量的电容之后这个尖峰被电容储存的电荷吸收Vo 能稳定很多。最后再强调一遍不要把 LED 引脚直接接高电平让它常亮。虽然这样也能读到电压但传感器会发热功耗上升Vo 也会随时间持续漂移。脉冲驱动本来就是这种传感器设计的一部分别绕过它。3. STM32 软件实现脉冲、采样和 ADC 读取3.1 方案 AGPIO 手动脉冲 微秒延时这是最简单也最适合学习和调试的方案。思路是用一个 GPIO 模拟 0.32ms 脉冲在脉冲期间用 ADC 读一次电压。整个时序完全由软件控制缺点是微秒延时期间 CPU 被占用不适合搞复杂多任务但对绝大多数课设和毕设足够。首先在 CubeMX 里做几件基本配置PA0 配置为 GPIO_Output初始电平 Low。PA1 配置为 ADC1_IN1采样时间尽量拉长选 239.5 Cycles。系统时钟保持 72MHz。串口 1 配置为 115200 8N1用于输出调试数据。微秒延时我建议用 DWT也就是内核调试单元。它比普通的空循环延时精确而且不依赖定时器资源。初始化代码很简单static void DWT_Delay_Init(void) { CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk; DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk; DWT-CYCCNT 0; } static void delay_us(uint32_t us) { DWT-CYCCNT 0; while (DWT-CYCCNT (uint32_t)(us * (SystemCoreClock / 1000000U))); }核心读取函数如下uint16_t read_pm25_raw(void) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); delay_us(280); HAL_ADC_Start(hadc1); HAL_ADC_PollForConversion(hadc1, 10); uint16_t adc HAL_ADC_GetValue(hadc1); delay_us(40); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); return adc; }主循环里每隔 10ms 调用一次while (1) { uint16_t raw read_pm25_raw(); float voltage raw * 3.3f / 4096.0f; if (voltage_divide_enable) { voltage voltage * 2.0f; } printf(adc:%u voltage:%.3f\r\n, raw, voltage); HAL_Delay(10); }这里的voltage_divide_enable是逻辑示意如果你接了分压电阻就必须乘 2否则后续算出来的浓度会低一半。实际操作中建议把这个判断直接写成固定逻辑不要留开关免得后面调试时忘记。有个容易被忽略的点HAL_Delay(10)会让实际周期变成 10.32ms 左右因为 read_pm25_raw 本身消耗了 0.32ms。这个误差对测量没有实质影响但如果你对 10ms 周期非常在意可以把 HAL_Delay 的时间改成 9.7ms。我一般不改因为传感器的脉冲周期本来就是一个工程近似值。3.2 方案 B定时器 PWM 输出 比较中断触发采样如果你希望长期稳定运行或者想释放 CPU那么方案 A 就不太合适了。更好的做法是让硬件定时器自动产生 0.32ms 的脉冲同时用定时器比较中断在 0.28ms 处触发 ADC 采样这样主循环只需要查询一个标志位或一个全局变量。以 TIM2 为例如果定时器时钟是 72MHz把预分频设为 71那么计数频率就是 1MHz一个 tick 就是一微秒。设置自动重装载值 ARR 为 9999就得到 10ms 周期。通道 1 输出 PWM比较值设为 320也就是 0.32ms 脉宽通道 2 用于产生比较中断比较值设为 280也就是 0.28ms 时刻。关键配置代码htim2.Instance TIM2; htim2.Init.Prescaler 71; htim2.Init.Period 9999; htim2.Init.CounterMode TIM_COUNTERMODE_UP; HAL_TIM_PWM_Init(htim2); HAL_TIM_OC_Init(htim2); TIM_OC_InitTypeDef sConfigOC {0}; sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 320; sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(htim2, sConfigOC, TIM_CHANNEL_1); sConfigOC.Pulse 280; HAL_TIM_OC_ConfigChannel(htim2, sConfigOC, TIM_CHANNEL_2); HAL_TIM_PWM_Start(htim2, TIM_CHANNEL_1); HAL_TIM_OC_Start_IT(htim2, TIM_CHANNEL_2);然后在定时器比较中断回调里启动 ADCvolatile uint16_t pm25_adc_value 0; void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM2) { HAL_ADC_Start(hadc1); if (HAL_ADC_PollForConversion(hadc1, 10) HAL_OK) { pm25_adc_value HAL_ADC_GetValue(hadc1); } } }通道 2 的比较值 280 是相对于计数器从 0 开始计算的而 PWM 通道 1 的上升沿也在计数器为 0 时产生所以相当于从脉冲上升沿开始等 280µs 再采样。要注意的是ADC 在中断里使用 PollForConversion 会占用几十微秒但只要在 0.32ms 脉宽结束前读完就没有问题。实测下来整段转换加读取大概在 10 到 20 微秒左右远小于余量。3.3 两种方案怎么选对比项GPIO 手动脉冲定时器 PWM 比较中断代码复杂度低容易理解中等需要懂定时器和回调时序准确性依赖 DWT基本准确硬件保证长期运行更稳CPU 占用每 10ms 有 0.32ms 忙等只有极短中断占用适合场景毕设、验证、起步调试产品原型、长期运行后期扩展不好扩展多传感器容易扩展 DMA 和多通道我自己的习惯是先搭方案 A 验证传感器和电路没问题再改成方案 B 做稳定性测试。如果你一上来就写方案 B纯靠串口数据判断接线问题会浪费很多时间在“到底是时序不对还是硬件不对”的排查上。另外提醒一句如果你用的是标准库而不是 HAL 库思路完全一样。标准库无非是把HAL_GPIO_WritePin换成GPIO_SetBits或GPIO_ResetBits把HAL_ADC_Start换成ADC_SoftwareStartConvCmd。真正影响测量结果的不是库而是 0.32ms 和 0.28ms 这两个时序。网上关于标准库和 HAL 库哪个好的讨论很多但在这个传感器项目里选哪个都不会成为瓶颈。4. 从 ADC 原始值到 PM2.5 浓度电压换算与标定4.1 原始值先换算成电压STM32F103 的 ADC 是 12 位读回来的值范围是 0 到 4095。如果参考电压是 3.3V那么每个 ADC 量化单位对应的电压是voltage (float)adc * 3.3f / 4096.0f;记住分母是 4096而不是 4095。虽然差 1 在实际使用中可以忽略但严谨一点更好。如果你加了 2:1 分压真正的传感器输出电压应该是real_voltage voltage * 2.0f;这一步不处理好后面所有计算都会翻车。我在给一个同学排查数据时发现他串口里显示的电压最高只有 1.65V后来一看就是忘了乘分压系数导致所有浓度都比真实值低一半。4.2 浓度计算的经验公式GP2Y1010 这类传感器没有一个全球统一的解析式工程上最常用的简化模型是concentration (real_voltage - v0) * k;其中v0是无尘环境下传感器的基准电压典型值约为 0.9V。k是电压到浓度的转换系数由传感器的灵敏度决定。如果传感器的灵敏度典型值是 0.5V/(0.1 mg/m³)也就是说电压每升高 0.5V浓度增加 0.1mg/m³那么转换系数就是k 0.1 / 0.5 0.2;所以一个常见公式就是pm25 (real_voltage - 0.9f) * 0.2f;我用这个公式在我的净化器项目里做过验证在室内门窗关闭的环境中测得电压大约在 1.0V 到 1.2V 之间对应浓度约 0.02 到 0.06mg/m³数值上比较符合一台普通净化器的常规经验值。但必须强调这不代表你的传感器也能直接用这个公式。每颗传感器的基准和灵敏度都有差异而且你买到的模块内部电路可能和夏普参考电路不完全一致所以一定要实测标定。4.3 标定不是玄学按这几步做第一步找一个相对干净的环境最好是无人的房间配合空气净化器运行一段时间记录长时间稳定后的电压把这个值作为v0。不要一上电就记录传感器需要预热一般至少等 5 分钟。第二步找一个中等污染的环境比如有人在室内活动、或者关闭门窗后在室内走动几分钟再用标准 PM2.5 仪器测量当前浓度。同时记录你的传感器输出电压计算经验系数k 浓度 / (电压 - v0)。第三步做至少两到三个标定点。只看一个点定出来的公式换一个环境很容易失效。我通常会在低污染、中污染、高污染三个区间各取一组数据。第四步不同温度和湿度下传感器响应会变化。湿度高的时候颗粒物吸水后散射特性改变相同质量浓度下输出电压可能偏高。如果希望产品可靠最好在不同天气条件下重复测量。顺便说一个坏消息红外 PM2.5 传感器在高浓度段会出现饱和。当电压超过 3.0V 之后继续增加浓度电压变化越来越小此时算出来的浓度已经完全失真。所以这种传感器更适合做“超标报警”而不是“精确测量”。4.4 滤波算法别把单次采样直接拿出去用红外传感器的单次采样值通常带有一点随机噪声如果你直接把 100Hz 的原始读数显示出来数字会跳得很厉害。常见处理手段有三种中值滤波、滑动平均、指数平均。中值滤波适合去除偶发毛刺但会引入一定延迟。比如对连续 5 次采样取中值能有效干掉单次异常值。滑动平均适合让曲线变平滑窗口大小一般取 5 到 20对应 0.5 到 2 秒的平滑时间。指数平均实现最简洁权重由系数决定越小的系数平滑效果越强但响应也越慢。下面这段是我比较常用的滑动平均代码窗口大小取 10#define PM_FILTER_N 10 float pm25_filtered 0.0f; void filter_update(float new_value) { static float buffer[PM_FILTER_N] {0}; static uint8_t index 0; static float sum 0.0f; sum - buffer[index]; buffer[index] new_value; sum buffer[index]; index (index 1) % PM_FILTER_N; pm25_filtered sum / PM_FILTER_N; }使用前要记得保证 buffer 已经被填满或在代码里区分“前 N 次平均值不准”的阶段。如果要求不高也可以忽略前几秒的数据。我的经验是滑动窗口选 10相当于用 1 秒平均输出一个值既能压住噪声响应速度也足够空气净化器做档位判断。4.5 实际应用逻辑空气净化器、新风系统这类应用通常不会直接用浓度值做连续控制而是做阈值迟滞。比如浓度低于 0.05mg/m³进入低档。浓度高于 0.08mg/m³升到中档。浓度高于 0.15mg/m³升到高档。低于 0.03mg/m³ 保持一段时间后才降回低档。注意这里的高档和低档切换阈值不要设成同一个值否则浓度在阈值附近波动时风机会疯狂切换档位。加入迟滞区间后整个系统会更稳定。5. 串口输出和调试经验5.1 打印格式怎么设计调试阶段最忌讳的是打开串口助手看到一堆无格式数字根本不知道哪个值对应哪一帧。我的建议是输出 CSV 格式文本一行一个采样点方便直接存成文件后拖进 Excel 或 MATLAB 分析。推荐格式printf(t:%lu adc:%u v:%.3f pm:%.2f\r\n, HAL_GetTick(), raw, voltage, pm25);其中的t是系统运行时间用毫秒表示方便看你采样的频率是否稳定。adc是原始值v是换算后的电压pm是滤波后的浓度值。在 Keil 里要正常使用 printf需要在工程选项里勾选 MicroLIB或者自己实现fputc重定向到串口。这个操作网上教程很多是一个通用问题就不展开写了。如果你用的是 STM32 USB 虚拟串口逻辑也一样只是底层发送函数不同但注意虚拟串口和调试串口使用同一个 USB 外设时不能同时把调试信息都堆在同一个接口里。5.2 上位机调试图怎么看用普通串口助手能看到数据在滚动但很难看出趋势。建议配合免费的虚拟示波器软件或者直接用串口工具里的曲线功能把电压、浓度两个变量单独建两条通道。这样你能直观看到脉冲是否作用正常、采样是否稳定。如果你手头有逻辑分析仪可以同时抓 LED 引脚和 Vo 引脚看 LED 信号是不是 10ms 周期 0.32ms 脉宽以及 Vo 是否在 LED 亮起后迅速上升。这是排查“为什么读数偏低”最快的手段。没有逻辑分析仪也没关系把 LED 引脚当作普通 GPIO 输出延到另一个空闲 ADC 通道也能看出脉冲波形的大致形状。5.3 室内测尘的几个操作技巧不要对着传感器呼吸或者用手指堵住进气口。汗液和气流会造成剧烈尖峰甚至会让你误以为传感器坏了。传感器最好放在空气能自然流通的位置不要紧贴墙壁或机箱角落。GP2Y1010 本身没有风扇靠扩散进气如果放在死角读数会明显偏低。离线分析时采样时间不要低于 30 秒。短期波动可能是人员走动或空调气流引起的随机事件。如果做对比测试把标准仪器和你的传感器放在同一个位置而不是一个放桌上一个放地上否则颗粒物浓度的空间差异会完全淹没你的测量误差。6. 踩坑记录与长期稳定性优化6.1 没加去耦电容ADC 读数乱跳我第一次搭电路时偷懒只在面包板上飞线传感器 Vcc 和 V-LED 没有就近加电容。结果串口输出在 0.5V 到 1.5V 之间随机跳完全看不出规律。当时还以为是 GPIO 脉冲宽度不对用逻辑分析仪查了半天最后发现是 LED 每次点亮瞬间把 5V 电源拉出一个大坑Vo 跟着一起抖。解决方法是把 100µF 电解电容放在传感器电源入口4.7µF 陶瓷电容放在靠近 Vcc 引脚的位置。加完电容之后数据立刻稳定了一个数量级。这不是玄学红外 LED 的脉冲电流峰值不小没有储能电容电源根本稳不住。6.2 采样时刻偏移读数忽高忽低还有一次我为了优化代码把方案 A 里的delay_us(280)改成了一个基于 HAL_GetTick 的延时逻辑结果采样点被系统其他任务打断从 280µs 变成了 350µs。由于 LED 在 320µs 后已经关闭Vo 在下降过程中被 ADC 采到浓度一会儿正常一会儿接近零。这说明一个道理采样时刻是这种传感器的生命线。用方案 A 的时候读电压之前的那几分钟内尽量避免开中断嵌套和耗时的临界区用方案 B 的时候要确认定时器比较中断的优先级不要让其他中断把它堵住太长时间。否则读到的信号不是“颗粒物浓度”而是“中断延迟时间”。6.3 上电后前几分钟数据不能用GP2Y1010 这类传感器上电后有一段时间的预热过程。一开始我直接开机就在串口界面上看数据发现浓度从很小的值慢慢爬升有时候能爬好几分钟才稳定下来。如果你把这段预热期的数据当成有效数据上报后端的阈值判断可能会误报警。处理办法很简单程序启动后做一个计数前 300 秒的数据只做内部计算不投入到显示和控制逻辑或者在上位机开始绘图前先跳过前 5 分钟。产品化的时候可以用一个“预热完成”标志位让设备在预热期间显示“请等待”而不是给出一个假的浓度值。6.4 用 DMA 把 ADC 转换从中断里搬出来方案 B 的定时器比较中断里仍然使用了HAL_ADC_PollForConversion这会在中断里形成一个短忙等。如果项目里同时有编码器、串口通信、PID 运算这种忙等会拉高 CPU 占用。更高级的做法是用 ADC 的 DMA 模式配置一个单通道 DMA每次定时器比较事件来了之后ADC 自动转换转换完自动把结果放到内存完全不需要 CPU 干预。配置思路很简单。在 CubeMX 里打开 ADC1 的 DMA 请求模式选择 Circular 或 Normal如果选 CircularDMA 会持续搬运 ADC 转换结果。然后定时器事件触发 ADC 启动CPU 只在 DMA 传输完成中断里做一个数据拷贝。这样整条链路的中断负载很低适合更复杂的产品架构。初次学习不建议直接用 DMA否则出了问题很难定位到底是 ADC 配置问题还是 DMA 配置问题。6.5 长期使用会漂移需要定期清洁红外 PM2.5 传感器用久了光路里会积灰LED 发光效率也会缓慢下降因此同一颗传感器稳定测量几天之后同样的环境浓度下Vo 可能比新的时候低。对于只有趋势判断需求的设备这个漂移可以接受对于计量用途这款传感器不建议考虑。如果设备运行环境灰尘很大可以在传感器进气口加一层可拆卸防尘棉。注意防尘棉不能完全堵死气流通道否则扩散式进气会被阻碍浓度反而偏低。我在净化器上做过对比加一层中等密度的防尘棉读数会有 10% 到 20% 的下降但长期稳定性明显更好。6.6 低功耗场景的最后一点建议如果这个项目需要电池供电比如便携式空气质量检测仪脉冲驱动的优点会体现出来。LED 每 10ms 只亮 0.32ms实际占空比只有 3.2%本身就省电。MCU 可以在两次采样之间进入 STOP 或 SLEEP 模式用定时器唤醒采完再睡。但要注意传感器 Vcc 不能随便断开Vcc 保持供电LED 引脚保持低电平就不会产生额外功耗。读一个数据点大约 0.32ms流程是从 STOP 唤醒配置 ADC拉高 LED 引脚 0.32ms读 ADC拉低然后立刻回到 STOP。实测可以做到平均电流远低于 10mA足够一节锂电池撑很久。最后说一个容易被忽略的细节GP2Y1010 这类红外传感器对气流极度敏感。你把传感器裸放在桌面和把它装进一个带有小风扇的风道里读数能差一倍。原因是空气流动快时单位时间内经过光路的颗粒物数量更多散射光更强。所以不要纠结“为什么我的传感器读数比别人低”先确认你们的安装方式和风道是否一致。我做这个项目最后的体会是红外 PM2.5 传感器适合做“趋势判断”和“档位判断”适不适合做“精确测量”心里要有数。如果你预算允许直接换激光式传感器会省掉很多标定和气流设计的麻烦。
返回列表