The BME280 gives temperature, humidity and barometric pressure from one tiny chip, which makes it the standard sensor for ESP32 weather stations.
The ESP32 runs it at 3.3 V on GPIO21/22. The sketch tries both I2C addresses, so it works whether your board’s SDO pin is tied low (0x76) or high (0x77), and reads once every five seconds in forced mode.
Wiring
| ESP32 DevKit V1 | BME280 breakout | Wire | Notes |
|---|---|---|---|
| 3V3 | VIN / VCC | red | The BME280 chip is 3.3 V-only; 3V3 is right for every board variant. |
| GND | GND | black | |
| D22 | SCL | yellow | |
| D21 | SDA | blue | |
| GND | SDO | black | 6-pin boards only: SDO to GND selects 0x76. Leave CSB alone — the board pulls it up for I2C. |
3.3 V (VIN boards with a regulator: 3.3–5 V) part, 3.3 V board. The chip itself is 3.3 V-only. Many purple 6-pin boards have no regulator — feed them 3.3 V only. Boards with a VIN pin and regulator accept 5 V, but keep SDA/SCL at the board's logic level.
Board quirks
- Mount the sensor on a short cable away from the ESP32 module — the Wi-Fi radio warms the board by a few degrees.
- Forced mode takes one measurement per
takeForcedMeasurement()and sleeps in between, so the chip doesn’t heat itself. - If humidity reads 0 % the board is a BMP280 sold as a BME280; the sketch prints the chip ID (0x60 = BME280, 0x58 = BMP280).
Code
// BME280 temperature, humidity and pressure on an ESP32 DevKit V1.
// VIN → 3V3, GND → GND, SDA → D21, SCL → D22. Address 0x76 (SDO → GND) or 0x77.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // SDA, SCL
bool ok = bme.begin(0x76, &Wire) || bme.begin(0x77, &Wire);
if (!ok) {
Serial.println("No BME280 at 0x76 or 0x77 — run the I2C scanner");
while (true) delay(1000);
}
// Weather-station settings: one forced measurement per reading, no self-heating.
bme.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, Adafruit_BME280::SAMPLING_X1, Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::FILTER_OFF);
Serial.printf("BME280 found (chip ID 0x%02X)\n", bme.sensorID());
}
void loop() {
bme.takeForcedMeasurement();
Serial.printf("Temp %.1f °C Humidity %.1f %% Pressure %.1f hPa\n",
bme.readTemperature(), bme.readHumidity(), bme.readPressure() / 100.0F);
delay(5000);
}// BME280 temperature, humidity and pressure on an ESP32 DevKit V1.
// VIN → 3V3, GND → GND, SDA → D21, SCL → D22. Address 0x76 (SDO → GND) or 0x77.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // SDA, SCL
bool ok = bme.begin(0x76, &Wire) || bme.begin(0x77, &Wire);
if (!ok) {
Serial.println("No BME280 at 0x76 or 0x77 — run the I2C scanner");
while (true) delay(1000);
}
// Weather-station settings: one forced measurement per reading, no self-heating.
bme.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, Adafruit_BME280::SAMPLING_X1, Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::FILTER_OFF);
Serial.printf("BME280 found (chip ID 0x%02X)\n", bme.sensorID());
}
void loop() {
bme.takeForcedMeasurement();
Serial.printf("Temp %.1f °C Humidity %.1f %% Pressure %.1f hPa\n",
bme.readTemperature(), bme.readHumidity(), bme.readPressure() / 100.0F);
delay(5000);
}Library: Adafruit BME280 Library (Adafruit (also install Adafruit Unified Sensor)) — compiled with Adafruit BME280 Library 2.3.0.
Expected serial output
BME280 found (chip ID 0x60)
Temp 27.3 °C Humidity 58.4 % Pressure 1008.6 hPa
Temp 27.3 °C Humidity 58.5 % Pressure 1008.6 hPaBME280 found (chip ID 0x60) Temp 27.3 °C Humidity 58.4 % Pressure 1008.6 hPa Temp 27.3 °C Humidity 58.5 % Pressure 1008.6 hPa
Common errors
“No BME280 at 0x76 or 0x77”
SDA/SCL swapped or the board unpowered. Run the I2C scanner; nothing at all means wiring.
Pressure correct but humidity 0 %
You have a BMP280. Use the Adafruit BMP280 library instead — it has no humidity sensor.