Arduino、ESP32驱动BMV080 PM2.5空气质量传感器(气体传感器篇)
BMV080 PM2.5空气质量传感器基于博世(Bosch)研发的全球最小颗粒物传感器BMV080打造一款集成了无风扇静音设计、±10μg/m³专业级精度、2420mm超微型体积、6μA超低功耗以及长达10年使用寿命的革命性产品。采用激光散射原理,直接测量自由扩散的颗粒物,彻底解决了传统带风扇传感器存在的体积庞大、运行噪音显著、易积灰堵塞及寿命短暂(约1-2年)等核心痛点。其宽广的量程(0-1000μg/m³)可覆盖从日常环境到重度污染的各种场景,并同步输出PM1.0、PM2.5及PM10质量浓度数据,为桌面空气伴侣、高端静音空气净化器、智能新风系统、便携式检测设备等对空间与可靠性要求严苛的应用提供了理想的一体化解决方案。

1、传感器特性
BMV080 PM2.5空气质量传感器与依赖风扇强制通风的传统传感器不同,BMV080传感器通过创新的光学计数原理进行测量,空气通过自由扩散的方式进入传感区域。这种根本性的设计变革,完全消除了运动部件,从而实现了运行期间的绝对静音,并从根本上避免了因风扇积灰导致的性能衰减或故障,使得产品故障率极低,使用寿命显著延长至10年。

得益于内置的博世BMV080传感器芯片,该产品具备卓越的测量性能。在0-100μg/m³浓度范围内,精度高达±10μg/m³;在101-1000μg/m³的高浓度范围内,精度也能保持在±10%。其激光散射技术稳定可靠,最小可检测0.5μm的颗粒物,启动时间仅需1.2秒,能在10秒内输出稳定数据,确保监测数据的准确性和响应及时性。
传感器技术指标如下:
- 专业级精度:±10μg/m³高精度,数据准确可靠
- 宽广量程:0-1000μg/m³,覆盖日常至重度污染
- 激光原理:基于激光散射技术,测量稳定可靠
- 多参数测量:同步测量PM1/PM2.5/PM10质量浓度
- 超低功耗:工作电流低至6μA,极省电
- 静音免维护:无风扇设计,终身静音,故障率低
2、硬件原理图
传感器原理图如下所示:

3、控制器和传感器连线图
I2C模式下控制器和传感器连线图如下所示:

按图示连接 BMV080 传感器与 ESP32-E,核心对应关系:
- 传感器引脚 “3V3” → ESP32-E 3.3V
- 传感器引脚 “GND” → ESP32-E GND
- 传感器 I2C 引脚 “SCL” → ESP32-E SCL(默认 GPIO22)
- 传感器 I2C 引脚 “SDA” → ESP32-E SDA(默认 GPIO21)
SPI模式下控制器和传感器连线图如下所示:

按图示连接 BMV080 传感器与 ESP32-E,核心对应关系:
- 传感器引脚 “3V3” → ESP32-E 3.3V
- 传感器引脚 “GND” → ESP32-E GND
- 传感器 SPI 引脚 “SCK” → ESP32-E SCK(默认 GPIO18)
- 传感器 SPI 引脚 “MOSI” → ESP32-E MOSI(默认 GPIO23)
- 传感器 SPI 引脚 “MISO” → ESP32-E MISO(默认 GPIO19)
- 传感器 SPI 引脚 “CSB” → ESP32-E GPIO13
4、驱动程序
4.1、I2C模式下连续读取传感器数值
通过 ESP32-E 的 I2C 接口与 BMV080 通信,连续读取 PM2.5 测量数值。
#include "DFRobot_BMV080.h"
// 设置循环任务的栈大小为60KB
SET_LOOP_TASK_STACK_SIZE(60 * 1024);
// I2C地址选择表:
/*
* --------------------------------------
* | CSB引脚 | MISO引脚 | 地址 |
* --------------------------------------
* | 0 | 0 | 0x54 |
* --------------------------------------
* | 0 | 1 | 0x55 |
* --------------------------------------
* | 1 | 0 | 0x56 |
* --------------------------------------
* | 1 | 1 | 0x57 |
* --------------------------------------
*/
// 创建I2C传感器实例,地址为0x57(可根据实际接线修改)
DFRobot_BMV080_I2C sensor(&Wire, 0x57);
float pm1, pm2_5, pm10;
void setup() {
char id[13]; // 用于存储BMV080传感器的芯片ID
Serial.begin(115200);
while (!Serial)
delay(100);
Serial.println("连续读取模式启动");
while (sensor.begin() != 0) {
Serial.println("传感器初始化失败!请检查传感器连接是否正确");
delay(1000);
}
Serial.println("传感器初始化成功");
while (sensor.openBmv080()) {
Serial.println("传感器打开失败");
delay(1000);
}
Serial.println("传感器打开成功");
// 获取并打印芯片ID
sensor.getBmv080ID(id);
Serial.println("芯片ID:" + String(id));
// 启用遮挡检测(有遮挡时会提示数据可能无效)
sensor.setObstructionDetection(true);
// 设置测量模式为连续模式
if (0 == sensor.setBmv080Mode(CONTINUOUS_MODE)) {
Serial.println("测量模式设置成功(连续模式)");
} else {
Serial.println("测量模式设置失败");
}
}
void loop() {
if (sensor.getBmv080Data(&pm1, &pm2_5, &pm10)) {
// 打印PM1、PM2.5、PM10数值
Serial.print("PM1:" + String(pm1) + " ug/m³ ");
Serial.print("PM2.5:" + String(pm2_5) + " ug/m³ ");
Serial.print("PM10:" + String(pm10) + " ug/m³");
// 检测是否有遮挡
if (sensor.ifObstructed()) {
Serial.print(" 注意:传感器被遮挡,数据可能无效");
}
Serial.println();
}
delay(100);
}
运行效果如下所示:

4.2、SPI模式下连续读取传感器数值
通过 ESP32-E 的 SPI 接口与 BMV080 通信,连续读取 PM2.5 测量数值。
#include "DFRobot_BMV080.h"
// 设置循环任务栈大小(ESP32运行传感器需足够内存,避免崩溃)
SET_LOOP_TASK_STACK_SIZE(60 * 1024);
// SPI关键配置:定义片选(CS)引脚,需根据ESP32-E实际接线修改(示例为13引脚)
#define SPI_CS_PIN 13
DFRobot_BMV080_SPI sensor(&SPI, SPI_CS_PIN);
float pm1, pm2_5, pm10;
void setup() {
char id[13];
Serial.begin(115200);
while (!Serial) delay(100);
Serial.println("启动SPI模式读取PM值");
while (sensor.begin() != 0) {
Serial.println("传感器初始化失败,请检查接线!");
delay(1000);
}
Serial.println("传感器初始化成功");
while (sensor.openBmv080()) {
Serial.println("传感器打开失败");
delay(1000);
}
Serial.println("传感器打开成功");
// 读取并打印芯片ID(用于确认硬件识别正常)
sensor.getBmv080ID(id);
Serial.print("芯片ID:");
Serial.println(id);
// 设为连续测量模式(读取PM值的基础模式)
if (0 == sensor.setBmv080Mode(CONTINUOUS_MODE)) {
Serial.println("已开启连续测量模式");
} else {
Serial.println("模式设置失败");
}
}
void loop() {
if (sensor.getBmv080Data(&pm1, &pm2_5, &pm10)) {
Serial.print("PM1:" + String(pm1) + " ug/m³ ");
Serial.print("PM2.5:" + String(pm2_5) + " ug/m³ ");
Serial.print("PM10:" + String(pm10) + " ug/m³");
// 检测是否有遮挡
if (sensor.ifObstructed()) {
Serial.print(" 注意:传感器被遮挡,数据可能无效");
}
Serial.println();
}
delay(100);
}
运行效果如下所示:




