文章目录
前言
一、硬件准备
所需组件
连接方式:
二、软件实现
1.所需库
2.代码实现
效果演示
三、上传Qt端
前言
在物联网和环境监测应用中,传感器是获取环境数据的关键组件。本文将详细介绍如何使用ESP32微控制器同时驱动BMP280大气压力传感器和MQ4甲烷气体传感器
一、硬件准备
所需组件
- ESP32开发板(如NodeMCU-32S、WROOM等)
- BMP280温度气压传感器模块
- MQ4甲烷气体传感器模块
- 面包板和连接线
- USB数据线
BMP280大气压力传感器
MQ4甲烷气体传感器
连接方式:
BMP280连接:
- VCC → ESP32 3.3V
- GND → ESP32 GND
- SCL → ESP32 GPIO 22 (I2C时钟线)
- SDA → ESP32 GPIO 21 (I2C数据线)
MQ4连接:
- VCC → ESP32 3.3V或5V(根据传感器型号)
- GND → ESP32 GND
- AO → ESP32 GPIO 34 (模拟输入)
- DO → ESP32 GPIO 35 (数字输入,可选)
二、软件实现
1.所需库
在Arduino IDE中,需要安装以下库:
- Adafruit BMP280 Library
- Adafruit Unified Sensor Library
可以通过Arduino IDE的库管理器直接安装即可。
2.代码实现
/*
*BMP280 + MQ4 多传感器实时数据采集系统
* 功能:同时读取 BMP280 的温度、气压、海拔数据和 MQ4 的甲烷浓度数据,并通过串口输出
* 连接方式:
* BMP280 VCC -> ESP32 3.3V
* BMP280 GND -> ESP32 GND
* BMP280 SCL -> ESP32 GPIO 22 (SCL)
* BMP280 SDA -> ESP32 GPIO 21 (SDA)
*
* MQ4 VCC -> ESP32 3.3V 或 5V (根据传感器型号)
* MQ4 GND -> ESP32 GND
* MQ4 AO -> ESP32 GPIO 34 (模拟输入)
* MQ4 DO -> ESP32 GPIO 35 (数字输入,可选)
*/
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <driver/adc.h>
#include <math.h>
// 定义引脚
#define I2C_SDA 21
#define I2C_SCL 22
#define MQ4_ANALOG_PIN 34 // 模拟输入引脚
#define MQ4_DIGITAL_PIN 35 // 数字输入引脚
#define LED_PIN 2 // 内置LED,用于警报指示
// 甲烷浓度阈值
#define METHANE_THRESHOLD 1000
// 采样参数
const unsigned long SAMPLE_INTERVAL = 950; // 采样间隔(毫秒)
unsigned long lastSampleTime = 0;
// 创建BMP280对象
Adafruit_BMP280 bmp;
// MQ4传感器校准参数
const float R0 = 10.0; // 传感器在洁净空气中的电阻值
const float RL = 10.0; // 负载电阻值10k
// 移动平均滤波
const int FILTER_SAMPLES = 10;
int filterIndex = 0;
int filterValues[FILTER_SAMPLES];
int filterSum = 0;
// bmp280的状态标志位
bool bmpSensorOK = false;
float temperature = 0.0;
float pressure = 0.0;
float altitude = 0.0;
float ppm = 0.0;
void setup() {
// 初始化串口,波特率115200
Serial.begin(115200);
while(!Serial) delay(10);
// 初始化I2C
Wire.begin(I2C_SDA, I2C_SCL);
// 初始化BMP280传感器
if (!bmp.begin(0x76)) { // bmp280地址:0x76地址
Serial.println("无法连接BMP280");
bmpSensorOK = false;
} else {
// 配置BMP280
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, // 工作模式
Adafruit_BMP280::SAMPLING_X2, // 温度过采样
Adafruit_BMP280::SAMPLING_X16, // 压力过采样
Adafruit_BMP280::FILTER_X16, // 滤波器
Adafruit_BMP280::STANDBY_MS_500); // 待机时间
Serial.println("BMP280初始化成功");
bmpSensorOK = true;
}
// 初始化MQ4引脚
pinMode(MQ4_ANALOG_PIN, INPUT);
pinMode(MQ4_DIGITAL_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
// 初始化滤波器数组
for (int i = 0; i < FILTER_SAMPLES; i++) {
filterValues[i] = 0;
}
// 预热提示
Serial.println("MQ4传感器预热中...");
delay(3000); //设置预热时间
}
void loop() {
unsigned long currentTime = millis();
// 每隔1s采样一次
if (currentTime - lastSampleTime >= SAMPLE_INTERVAL) {
lastSampleTime = currentTime;
String status = "正常";
// 读取BMP280传感器数据
if (bmpSensorOK) {
temperature = bmp.readTemperature();
pressure = bmp.readPressure() / 100.0F; // 转换为hPa
altitude = bmp.readAltitude(1013.25); // 使用标准大气压
}
// 读取MQ4传感器数据
int rawValue = analogRead(MQ4_ANALOG_PIN);
bool digitalValue = digitalRead(MQ4_DIGITAL_PIN);
// 应用移动平均滤波
filterSum = filterSum - filterValues[filterIndex] + rawValue;
filterValues[filterIndex] = rawValue;
filterIndex = (filterIndex + 1) % FILTER_SAMPLES;
int filteredValue = filterSum / FILTER_SAMPLES;
// 计算电压值
float voltage = filteredValue * (3.3 / 4095.0);
// 计算传感器电阻比
float rs = ((3.3 - voltage) / voltage) * RL;
float ratio = rs / R0;
// 计算甲烷浓度
ppm = 1000 * pow(ratio, -2.95);
// 检查是否超过阈值
if (ppm > METHANE_THRESHOLD) {
status = "警报";
digitalWrite(LED_PIN, HIGH); // 点亮LED作为警报
} else {
digitalWrite(LED_PIN, LOW); // 关闭LED
}
Serial.print("温度:");
if (bmpSensorOK) {
Serial.print(temperature, 1);
Serial.print("°C ");
} else {
Serial.print("未连接 ");
}
Serial.print("气压:");
if (bmpSensorOK) {
Serial.print(pressure, 1);
Serial.print("hPa ");
} else {
Serial.print("未连接 ");
}
Serial.print("海拔:");
if (bmpSensorOK) {
Serial.print(altitude, 1);
Serial.print("m ");
} else {
Serial.print("未连接 ");
}
Serial.print("甲烷:");
Serial.print(ppm, 1);
Serial.print("ppm ");
Serial.print("状态:");
Serial.println(status);
}
}
在MQ4获取的数据中,我使用移动平均滤波来时数据更平滑,窗口大小为10,大家如果只是想要数据的话可以不用滤波。
效果演示
如下运行后的效果图:
三、上传Qt端
在esp32获取到数据时,通过udp数据打包发送到同一子网下的Qt服务端程序接收并显示,效果如下: