4、常用传感器详解(下):HC-SR04超声波测距模块、BMP280气压传感器、MQ系列气体传感器,实战接线与测试。
好,咱们接着聊传感器。上一节我们把温湿度、光照和红外给搞定了,这一节咱们来啃几个硬骨头——超声波测距、气压测量,还有气体检测。这几个传感器在实际项目中出镜率极高,我个人的经验是,搞懂它们,你的物联网项目基本就能覆盖80%的物理量采集场景了。
4.1 HC-SR04 超声波测距模块
先说说这个测距模块。HC-SR04,说白了就是个声呐。它发出超声波,碰到障碍物弹回来,通过计算时间差来算距离。原理不复杂,但坑不少。
核心原理: 发射端发出8个40kHz的脉冲,接收端等待回波。从发射到接收的时间差t,乘以声速340m/s,再除以2,就是距离。
公式:距离 = t × 340 / 2 (单位:米)
4.1.1 引脚与接线
这个模块有4个引脚,我列个表,你照着接就行,别搞反了。
| 引脚 | 功能 | 接ESP32/Arduino |
|---|---|---|
| VCC | 电源正极 | 5V |
| GND | 电源负极 | GND |
| Trig | 触发引脚 | GPIO 5(示例) |
| Echo | 回波引脚 | GPIO 18(示例) |
注意: Echo引脚输出的是5V电平!如果你用的是3.3V的ESP32或STM32,必须加一个分压电阻(比如1kΩ和2kΩ分压),否则会烧引脚。我曾经有一次偷懒没加分压,结果烧了一个ESP32的GPIO口,血的教训。
4.1.2 实战代码与测试
我习惯用NewPing库,它把时序处理封装好了,省心。下面这段代码,你直接烧录进去,打开串口监视器就能看到距离数据。
#include <NewPing.h>
#define TRIG_PIN 5
#define ECHO_PIN 18
#define MAX_DISTANCE 400 // 最大测量距离(厘米)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
void setup() {
Serial.begin(115200);
Serial.println("HC-SR04 超声波测距测试开始");
}
void loop() {
delay(500);
unsigned int distance = sonar.ping_cm(); // 获取距离,单位厘米
if (distance == 0) {
Serial.println("超出测量范围或未检测到物体");
} else {
Serial.print("距离: ");
Serial.print(distance);
Serial.println(" cm");
}
}
跑起来之后,你拿个纸板在传感器前面晃一晃,看看数值变化。嗯,这里要注意,如果距离小于2cm,数据会不准,这是模块的物理限制。
避坑指南: 我曾经在项目里用这个模块做液位检测,发现数据老是跳变。后来排查发现,超声波打到水面会产生漫反射,导致回波不稳定。解决办法是加一个导波管,让声波定向传播。你想想看,如果直接对着水面测,误差能到好几厘米。
4.2 BMP280 气压传感器
接下来是BMP280。这个传感器挺有意思,它能测气压和温度,精度还不错。我常用它来做海拔高度估算——气压越低,海拔越高。说白了,就是利用大气压随高度变化的规律。
4.2.1 通信方式与接线
BMP280支持I2C和SPI两种通信方式。我一般用I2C,因为接线简单,只需要两根线。默认I2C地址是0x76,如果你把SDO引脚接VCC,地址会变成0x77。
| 引脚 | 功能 | 接ESP32(I2C) |
|---|---|---|
| VCC | 电源正极 | 3.3V |
| GND | 电源负极 | GND |
| SDA | 数据线 | GPIO 21 |
| SCL | 时钟线 | GPIO 22 |
注意: BMP280的VCC只能接3.3V!接5V会直接烧掉。我见过有人把模块插到5V面包板上,瞬间冒烟。别问我怎么知道的。
4.2.2 实战代码与测试
用Adafruit的BMP280库,几行代码就能读出数据。我习惯先初始化,然后循环读取。
#include <Wire.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp; // 使用I2C接口
void setup() {
Serial.begin(115200);
if (!bmp.begin(0x76)) { // 检查设备地址
Serial.println("BMP280 未找到,请检查接线!");
while (1);
}
Serial.println("BMP280 初始化成功");
}
void loop() {
delay(1000);
float temperature = bmp.readTemperature();
float pressure = bmp.readPressure() / 100.0F; // 转换为hPa
float altitude = bmp.readAltitude(1013.25); // 海平面标准气压1013.25hPa
Serial.print("温度: ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("气压: ");
Serial.print(pressure);
Serial.println(" hPa");
Serial.print("估算海拔: ");
Serial.print(altitude);
Serial.println(" m");
}
跑起来后,你用手捏一下传感器(别太用力),气压值会微微变化。为什么会这样?因为手温加热了传感器内部空气,导致局部气压升高。嗯,这个细节在精密测量时要注意。
个人经验: 用BMP280估算海拔时,一定要校准海平面气压。不同地区、不同天气,海平面气压都不一样。我一般在项目里加一个GPS模块,用GPS获取真实海拔,然后反推出当前的海平面气压,这样后续测量才准。
4.3 MQ系列气体传感器
最后说说MQ系列。这个系列传感器种类很多,MQ-2测可燃气体,MQ-7测一氧化碳,MQ-135测空气质量。它们的原理都一样——气敏材料遇到特定气体,电阻值会变化。说白了,就是通过电阻变化来反推气体浓度。
4.3.1 模块类型与选型
我列个表,你根据需求选型。别买错了,MQ-2和MQ-7虽然长得一样,但检测对象完全不同。
| 型号 | 检测气体 | 典型应用 |
|---|---|---|
| MQ-2 | 液化气、丙烷、氢气 | 厨房燃气泄漏报警 |
| MQ-7 | 一氧化碳 | 车库、锅炉房CO检测 |
| MQ-135 | 氨气、苯、烟雾 | 空气质量监测 |
4.3.2 接线与注意事项
MQ模块通常有4个引脚:VCC、GND、DO(数字输出)、AO(模拟输出)。我建议你直接用AO引脚接ADC,这样能读到气体浓度的模拟量,数据更丰富。
| 引脚 | 功能 | 接ESP32 |
|---|---|---|
| VCC | 电源正极 | 5V(注意!) |
| GND | 电源负极 | GND |
| AO | 模拟输出 | GPIO 34(ADC) |
| DO | 数字输出 | 可接GPIO,用于阈值报警 |
重要警告: MQ模块的加热丝需要5V供电!如果接3.3V,传感器无法正常工作,读数会一直偏低。另外,新模块第一次通电需要预热24小时以上,这叫“老化”,目的是让气敏材料稳定。我当年第一次用MQ-2,没预热就直接测,数据飘得跟心电图似的。
4.3.3 实战代码与测试
下面这段代码,用MQ-135测空气质量。我读取模拟值,然后映射到0-100的百分比,方便理解。
#define MQ_PIN 34 // 模拟输入引脚
void setup() {
Serial.begin(115200);
Serial.println("MQ-135 空气质量传感器测试");
Serial.println("请预热5分钟后查看数据");
}
void loop() {
delay(2000);
int sensorValue = analogRead(MQ_PIN);
// 将ADC值(0-4095)映射到0-100
float percentage = map(sensorValue, 0, 4095, 0, 100);
Serial.print("ADC原始值: ");
Serial.print(sensorValue);
Serial.print(" 空气质量指数: ");
Serial.print(percentage);
Serial.println(" %");
if (percentage > 70) {
Serial.println("警告:空气质量较差!");
}
}
测试时,你对着传感器吹一口气,数值会立刻飙升。为什么会这样?因为呼出的二氧化碳和水分会影响气敏材料。嗯,这个特性可以用来做简易的呼吸检测,但精度就别指望了。
避坑指南: MQ系列传感器功耗很大,加热电流能到150mA以上。如果你用电池供电,记得加一个MOS管开关,只在需要测量时才给传感器供电。我曾经在野外监测项目里没注意功耗,结果电池半天就耗光了。
4.4 小结
这一节我们搞定了三个传感器:HC-SR04测距离、BMP280测气压、MQ系列测气体。每个传感器都有自己的脾气——超声波怕漫反射、BMP280怕5V、MQ系列怕冷启动。你只要记住这些坑,实际用起来就顺了。
下一节,咱们开始讲传感器数据怎么通过WiFi和MQTT协议上传到云端。到时候,这些传感器采集的数据就能真正“上网”了。
课后练习: 把这三个传感器同时接到一块ESP32上,每5秒采集一次数据,通过串口打印出来。试试看,能不能让超声波测距和气压数据联动——比如,当距离小于10cm时,记录当前的气压值。