ESP32驱动BMP280和MQ4传感器
文章目录
前言
一、硬件准备
所需组件
连接方式:
二、软件实现
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() {// 初始化串口,波特率115200Serial.begin(115200);while(!Serial) delay(10);// 初始化I2CWire.begin(I2C_SDA, I2C_SCL);// 初始化BMP280传感器if (!bmp.begin(0x76)) { // bmp280地址:0x76地址Serial.println("无法连接BMP280");bmpSensorOK = false;} else {// 配置BMP280bmp.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; // 转换为hPaaltitude = 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服务端程序接收并显示,效果如下: