ESP32 BME280 Weather Station with OLED Display (Temperature, Humidity, Pressure)

ESP32 BME280 Weather Station with OLED Display (Temperature, Humidity, Pressure)

A real weather station measures temperature, humidity and barometric pressure, and the tiny BME280 does all three on a single I2C bus. In this project the ESP32 reads the BME280 every two seconds and shows the three values on a 0.96″ OLED. Both devices share the same two I2C wires because they’ve different bus addresses (0x76 for the sensor, 0x3C for the display).

Pressure is the secret weapon of this build: a falling pressure trend predicts rain hours before the sky changes, something a temperature-only station can never tell you.

Components Required

  • ESP32 DevKit
  • BME280 sensor module (I2C version)
  • 0.96″ SSD1306 OLED display (I2C, 128×64)
  • Breadboard and jumper wires

Circuit Diagram and Wiring

ESP32 PinComponent PinWire Color (diagram)

3V3BME280 VCCRed

GNDBME280 GNDBlack

GPIO21BME280 SDAGreen

GPIO22BME280 SCLYellow

3V3OLED VCCRed

GNDOLED GNDBlack

GPIO21OLED SDAGreen

SCLYellow

GPIO22 OLED

The Code (Arduino IDE with ESP32 core)

/*
 * ESP32 BME280 + OLED Weather Station
 * Ogbugbu Technologies - ogbugbu-technologies.com.ng/
 * Libraries: "Adafruit BME280", "Adafruit SSD1306", "Adafruit Unified Sensor"
 */
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_BME280 bme;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);                 // ESP32 default I2C pins

  if (!bme.begin(0x76)) {             // try 0x77 if this fails
    Serial.println("BME280 not found!");
    while (1);
  }
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED not found!");
    while (1);
  }
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  float t = bme.readTemperature();
  float h = bme.readHumidity();
  float p = bme.readPressure() / 100.0F;   // Pa -> hPa

  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println(" Ogbugbu Weather");
  display.println(" --------------------");
  display.setTextSize(2);
  display.setCursor(0, 18);
  display.print(t, 1); display.println(" C");
  display.setCursor(0, 36);
  display.print(h, 1); display.println(" %");
  display.setCursor(0, 54);
  display.setTextSize(1);
  display.print("Pressure: "); display.print(p, 1); display.print(" hPa");
  display.display();

  Serial.printf("%.1f C, %.1f %%, %.1f hPa
", t, h, p);
  delay(2000);
}

How the Code Works

I2C is a shared bus: every device listens to the same SDA and SCL lines and answers only when its own address is called. That’s why the BME280 and the OLED connect to GPIO21 and GPIO22 in parallel, the Wiring column of the table literally repeats. Wire.begin(21, 22) makes those pins explicit on the ESP32, whose I2C pins aren’t fixed like an Arduino’s.

Pressure arrives in pascals and is divided by 100 to get the hPa (millibar) unit used in weather forecasts. Normal sea-level pressure is around 1013 hPa; a steady drop of 1–2 hPa per hour often means approaching rain. The display layout uses two text sizes, big numbers for temperature and humidity, small text for pressure, all drawn to an off-screen buffer and pushed with one display.display() call to avoid flicker.

Testing and Troubleshooting

If the OLED works but the sensor is “not found”, your BME280 is probably at address 0x77, change bme.begin(0x76) accordingly (run an I2C scanner to check). Some cheap boards labelled BME280 are actually BMP280 (no humidity), humidity will read 0 or NaN. If nothing works at all, confirm both modules are 3.3V-logic versions and that SDA/SCL aren’t swapped.

Conclusion

Your desk now has its own micro weather service. Next steps: compute a pressure-trend arrow from the last hour of readings, push the data to the web dashboard from this series, or add a battery and deep sleep for an outdoor station.

Found this tutorial helpful? Share it with a fellow maker and check out more builds on Ogbugbu Technologies!

Leave a Reply

Your email address will not be published. Required fields are marked *