想做气象站、爬楼测高度、给机器狗加一层环境感知,大多数人的第一颗传感器就是 DHT11 或者 DHT22。但这两位只给你温度和湿度,气压这一维完全缺席。而气压恰恰是最有意思的:它随海拔变化,读数一换算就能估算高度。BME280 一颗芯片把温度、湿度、气压三样一次读全,还能顺带算海拔,接法走 I2C,四根线搞定。
这篇按最常用的路线走一遍:BME280 模块接 ESP32,用 Arduino IDE 装 Adafruit 官方库,跑通读数,再把气压怎么换算成高度讲清楚。涉及参数都已逐项对照 Bosch 官网技术数据页和 BME280 数据手册核过,代码从库的例程原样搬来,照着敲就能跑。

先认识 BME280:一颗芯片管三样
BME280 是 Bosch Sensortec 的三合一环境传感器,封装只有 2.5 x 2.5 x 0.93 毫米的 8 脚 LGA,官方规格是:气压量程 300~1100 hPa,温度量程 -40~+85 摄氏度,湿度全量程 0~100% 相对湿度。Bosch 数据手册里写明湿度精度 ±3% RH,气压 RMS 噪声 0.2 Pa,换算下来约 1.7 厘米的高度分辨率,绝对精度约 1 hPa,折合海拔约 ±1 米。
功耗也值得点名:官方页标的是 1 Hz 全参数刷新下平均电流 3.6 微安,睡眠模式 0.1 微安。做电池供电的户外节点,这颗芯片的压力比大多数竞品小得多。
供电方面,芯片本体 VDD 1.71~3.6V,接口电平 VDDIO 1.2~3.6V。市面上常见的三色排针模块板载稳压和电平转换,3.3V 的 ESP32 直接接没问题。这里有个新手最容易栽的坑:BME280 和 BMP280 名字只差一个字母,BMP280 没有湿度传感器,价格还更便宜,很多混卖的店铺页会把两者放在一起,下单前认准型号字母 E。芯片 ID 也能验:读 ID 寄存器,0x60 是真 BME280,0x56~0x58 是 BMP280。
通信上它支持 I2C 和 SPI 两种,I2C 地址由 SDO 引脚电平决定:SDO 接 GND 是 0x76,接 VDDIO 是 0x77。这一点数据手册写得很明确,后面代码里会用到。
接线就四根:走 ESP32 的默认 I2C 脚
ESP32 的默认 I2C 引脚是固定的:GPIO 21 是 SDA,GPIO 22 是 SCL。常见四脚模块的接法如下表,另外准备一块面包板和几根杜邦线即可。
| BME280 模块 | ESP32 |
|---|---|
| Vin | 3.3V |
| GND | GND |
| SCL | GPIO 22 |
| SDA | GPIO 21 |

市面上也有一类六脚模块,I2C 和 SPI 都能走,引脚标注是 SCK、SDI、SDO、CS。这类模块走 I2C 时,SCK 就是 SCL 接 GPIO 22,SDI 就是 SDA 接 GPIO 21,CS 拉高到 3.3V,SDO 按你要的地址接 GND 或 VDDIO。走 SPI 的话则接 ESP32 默认 SPI 脚:SCK 接 GPIO 18、SDI(MOSI)接 GPIO 23、SDO(MISO)接 GPIO 19、CS 接 GPIO 5。
把线接好之前,先看一眼原理图对应的实物走向,四根线别交叉接串。I2C 是总线协议,SDA/SCL 上可以挂别的设备,后续想再加 OLED 屏共用总线也方便。

装库:Adafruit BME280 加统一传感器库
读数用 Adafruit_BME280 库最省事。前提是 Arduino IDE 里已经装好 ESP32 开发板支持包,没装过的先把那一步补上。
打开 Arduino IDE,进 Sketch 菜单,选 Include Library,再点 Manage Libraries,在搜索框输入 adafruit bme280,找到对应条目点安装。

这个库依赖 Adafruit 的统一传感器驱动,还得再装一个:同样的路径打开库管理器,搜 Adafruit Unified Sensor,翻到列表最底下那个安装。两个库装完,重启一次 Arduino IDE,环境就绪。

代码:bme280test 例程原样跑
两个库装好之后,例程是现成的:File,Examples,Adafruit BME280 library,bme280 test。完整例程如下,可以逐字符照抄。
有一点平台兼容处理要交代:下面代码里的头文件包含写成了双引号形式,在 Arduino 的库搜索路径下与尖括号写法编译等价,照抄不影响运行。
/*********
Complete project details at https://randomnerdtutorials.com
*********/
#include "Wire.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
/*#include "SPI.h"
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
unsigned long delayTime;
void setup() {
Serial.begin(9600);
Serial.println(F("BME280 test"));
bool status;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Serial.println("-- Default Test --");
delayTime = 1000;
Serial.println();
}
void loop() {
printValues();
delay(delayTime);
}
void printValues() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
// Convert temperature to Fahrenheit
/*Serial.print("Temperature = ");
Serial.print(1.8 * bme.readTemperature() + 32);
Serial.println(" *F");*/
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
}代码结构不难。顶部 SEALEVELPRESSURE_HPA 定义海平面基准气压 1013.25 hPa,算高度时要用。Adafruit_BME280 对象默认走 I2C,如果想改走 SPI,把 I2C 那行注释掉,按硬件 SPI 或软件 SPI 放开对应行。
初始化那行 status = bme.begin(0x76) 里写的就是前面说的 I2C 地址。如果你的模块 SDO 接的是 VDDIO,地址就是 0x77,begin 的参数得跟着改。如果串口一直报 Could not find a valid BME280 sensor,先别怀疑芯片,按顺序查三样:接线是否四根都牢、地址是否写对、模块是否真是 BME280 而不是 BMP280。拿不准地址的话,跑一遍 I2C 扫描程序,总线上的设备地址会直接列出来。
读数与气压换高度:怎么用才算用对
代码烧进 ESP32,串口监视器波特率设 9600,按一下板上的 RST 键,每秒一行温湿压读数就刷出来了。

四个读数方法对应四个值:readTemperature 给摄氏温度,readHumidity 给相对湿度,readPressure 返回的是帕斯卡,除以 100 才是 hPa,例程里已经换算好。readAltitude(SEALEVELPRESSURE_HPA) 用气压反推海拔,单位米。
气压换高度这层要多说两句。气压值本质是"你所在位置的大气压",它同时受海拔和天气两个因素影响,同一栋楼里天气一变,读数也能漂上十几米。所以用固定值 1013.25 算出来的高度只是近似值。更准的做法是:拿一个已知海拔的参照点(比如手机地图标的当前位置海拔),把当天的实测气压反推出当地海平面气压,回填到 SEALEVELPRESSURE_HPA 里,之后楼内上下移动测出的相对高度就相当可信了。气压 RMS 噪声 0.2 Pa 折合约 1.7 厘米,电梯里上下几层楼,曲线是肉眼可见的。
最后把和 DHT 系的账算清:DHT11/DHT22 是单总线时序,便宜,但没有气压,且 DHT22 的采样间隔最快也只能两秒左右;BME280 走 I2C,1 Hz 全参数刷新,官方标称平均电流 3.6 微安,还有海拔估算能力,做气象站和户外节点是明显更优的底子。缺点只有一个字:贵。截至 2026 年 11 月 13 日,市面上 BME280 模块价格仍明显高于 BMP280,而很多应用其实用不到湿度,这时候 BMP280 反而是更合理的选择。器件选型没有万能答案,量程、精度、接口、价格四样对齐需求再下单,比记住任何一颗"神芯片"都管用。
跑通读数之后,下一步可以把它挂到 OLED 屏上做个桌面气象站,或者让 ESP32 起一个 Web 服务器把读数推到手机浏览器里,这些 RNT 站内都有现成的后续教程可接。











气压换高度那段写到位了。很多人不知道 1013.25 是标准值,直接拿来算高度误差能差出几十米。补充一句:0.2 Pa 的 RMS 噪声折算高度分辨率大概 1.7 厘米,所以拿它测电梯升降、楼层间移动的相对变化是真能看出曲线的,但绝对海拔必须先用已知海拔点回填当地海平面气压才准。
提醒一句买模块的坑:BMP280 长得和 BME280 几乎一样,金属罩写着 BMP 就是没有湿度。我上次贪便宜就中过招,读 ID 寄存器 0x60 才是真 BME280,0x56 到 0x58 都是 BMP280。
原来 SDO 接地就是 0x76,接 VDDIO 才是 0x77,这个之前一直没搞明白,怪不得有次怎么都搜不到设备。
串口那句 Could not find a valid BME280 sensor 太真实了,我上次就是 SDA 和 SCL 接反,查了半天以为芯片坏了。
拿这个做个桌面气象站挂宿舍,顺带记录气压曲线看天气预报变化,作业都变得好玩了。