Weather ESP32

By Paul , 15 September 2025

ESP32 Weather Station Project

Overview

This project creates a complete weather station using an ESP32 microcontroller that reads temperature, humidity, and pressure data from sensors and displays the information on an OLED screen.

Components Required

Hardware

  • ESP32 Development Board (ESP32-WROOM-32 or similar)
  • BME280 Sensor Module (Temperature, Humidity, Pressure)
  • 0.96" I2C OLED Display (SSD1306, 128x64 pixels)
  • Breadboard or PCB
  • Jumper Wires
  • Micro USB Cable
  • Optional: 3D printed enclosure

Software Libraries

  • Adafruit BME280 Library
  • Adafruit SSD1306 Library
  • Adafruit GFX Library
  • Wire Library (built-in)

Wiring Diagram

BME280 Connections

BME280    →    ESP32
VCC       →    3.3V
GND       →    GND
SCL       →    GPIO 22 (SCL)
SDA       →    GPIO 21 (SDA)

OLED Display Connections

OLED      →    ESP32
VCC       →    3.3V
GND       →    GND
SCL       →    GPIO 22 (SCL)
SDA       →    GPIO 21 (SDA)

Note: Both devices share the same I2C bus (SDA/SCL pins)

Arduino Code

#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED Display Settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C

// Create objects
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_BME280 bme;

// WiFi credentials (optional - for future web features)
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// Sensor variables
float temperature;
float humidity;
float pressure;
float altitude;

// Display update interval
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 2000; // Update every 2 seconds

void setup() {
  Serial.begin(115200);
  
  // Initialize I2C
  Wire.begin();
  
  // Initialize OLED Display
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  
  // Initialize BME280
  if (!bme.begin(0x76)) { // Try address 0x76 first
    if (!bme.begin(0x77)) { // If that fails, try 0x77
      Serial.println("Could not find a valid BME280 sensor, check wiring!");
      while (1);
    }
  }
  
  // Configure BME280 settings
  bme.setSampling(Adafruit_BME280::MODE_NORMAL,
                  Adafruit_BME280::SAMPLING_X2,  // temperature
                  Adafruit_BME280::SAMPLING_X2,  // pressure
                  Adafruit_BME280::SAMPLING_X2,  // humidity
                  Adafruit_BME280::FILTER_X16,
                  Adafruit_BME280::STANDBY_MS_500);
  
  // Clear display
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Weather Station");
  display.println("Initializing...");
  display.display();
  
  // Optional: Initialize WiFi
  initWiFi();
  
  delay(2000);
  
  Serial.println("Weather Station Ready!");
}

void loop() {
  if (millis() - lastUpdate >= updateInterval) {
    readSensors();
    updateDisplay();
    printToSerial();
    lastUpdate = millis();
  }
  
  // Add small delay to prevent watchdog timer issues
  delay(10);
}

void readSensors() {
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F; // Convert Pa to hPa
  altitude = bme.readAltitude(1013.25); // Sea level pressure in hPa
}

void updateDisplay() {
  display.clearDisplay();
  
  // Title
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(25, 0);
  display.println("WEATHER STATION");
  
  // Draw separator line
  display.drawLine(0, 12, 128, 12, SSD1306_WHITE);
  
  // Temperature
  display.setCursor(0, 16);
  display.print("Temp: ");
  display.print(temperature, 1);
  display.print(" C");
  
  // Humidity
  display.setCursor(0, 28);
  display.print("Humid: ");
  display.print(humidity, 1);
  display.print(" %");
  
  // Pressure
  display.setCursor(0, 40);
  display.print("Press: ");
  display.print(pressure, 1);
  display.print(" hPa");
  
  // Altitude (optional)
  display.setCursor(0, 52);
  display.print("Alt: ");
  display.print(altitude, 0);
  display.print(" m");
  
  display.display();
}

void printToSerial() {
  Serial.println("=== Weather Station Reading ===");
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" °C");
  
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");
  
  Serial.print("Pressure: ");
  Serial.print(pressure);
  Serial.println(" hPa");
  
  Serial.print("Altitude: ");
  Serial.print(altitude);
  Serial.println(" m");
  
  Serial.println("==============================");
}

void initWiFi() {
  // Uncomment and configure if you want WiFi connectivity
  /*
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
  */
}

// Function to handle sensor errors
void handleSensorError() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("SENSOR ERROR!");
  display.println("Check connections");
  display.display();
  
  Serial.println("Sensor reading error!");
  delay(1000);
}

Setup Instructions

1. Hardware Assembly

  1. Connect the BME280 and OLED display to the ESP32 using the wiring diagram above
  2. Both devices use I2C communication and share the same SDA/SCL pins
  3. Ensure all connections are secure and use the correct voltage (3.3V)

2. Software Setup

  1. Install the Arduino IDE
  2. Add ESP32 board support:
    • Go to File → Preferences
    • Add https://dl.espressif.com/dl/package_esp32_index.json to Additional Board Manager URLs
    • Go to Tools → Board → Boards Manager and install "esp32"
  3. Install required libraries:
    • Go to Sketch → Include Library → Manage Libraries
    • Install: "Adafruit BME280 Library", "Adafruit SSD1306", "Adafruit GFX Library"
  4. Upload the code:
    • Select your ESP32 board (Tools → Board → ESP32 Dev Module)
    • Select the correct COM port
    • Upload the sketch

3. Testing

  1. Open the Serial Monitor (115200 baud rate)
  2. You should see sensor readings every 2 seconds
  3. The OLED display should show current weather data

Features

Current Features

  • Real-time sensor readings every 2 seconds
  • OLED display showing temperature, humidity, pressure, and altitude
  • Serial monitor output for debugging
  • Error handling for sensor connectivity issues

Possible Enhancements

  • WiFi connectivity for web-based monitoring
  • Data logging to SD card or cloud
  • Weather forecasting based on pressure trends
  • Alerts for extreme weather conditions
  • Battery power with sleep modes for portable use
  • Web server to view data remotely
  • Historical data graphs
  • Multiple sensor locations (indoor/outdoor)

Troubleshooting

Common Issues

  1. OLED not displaying: Check I2C address (try 0x3C or 0x3D)
  2. BME280 not found: Check I2C address (try 0x76 or 0x77)
  3. Jumbled display: Check power supply and connections
  4. No sensor readings: Verify wiring and library installations

Verification Steps

  1. Use I2C scanner code to detect device addresses
  2. Check all solder joints and connections
  3. Verify power supply voltage (should be 3.3V)
  4. Test each component individually

Power Consumption

  • ESP32: ~80mA (active), ~5µA (deep sleep)
  • BMP180: ~5µA (standby), ~1000µA (measuring)
  • DHT11: ~0.5mA (standby), ~1.5mA (measuring)
  • OLED: ~20mA (on), ~0µA (off)

For battery operation, implement deep sleep between readings to extend battery life significantly. Note that DHT11 requires longer wake times due to its slower response.

Enclosure Ideas

  • 3D printed weather-resistant case
  • Clear acrylic case for indoor use
  • Ventilated enclosure for accurate readings
  • Wall-mounted or desktop versions

This weather station provides a solid foundation for environmental monitoring and can be easily expanded with additional features!

Tags

Comments