Build a WiFi Weather Station with Arduino & BME280
Proto.supply Team15 min read
Monitor your local weather with a sensor that costs less than a cup of coffee. The BME280 measures temperature, humidity, and barometric pressure with impressive accuracy.
Bill of Materials
| Component | Qty | Price |
|---|---|---|
| ESP32 DevKit v1 | 1 | ₹450 |
| BME280 sensor module | 1 | ₹180 |
| 0.96" OLED display (SSD1306) | 1 | ₹220 |
| Breadboard + jumper wires | 1 set | ₹80 |
| USB-C cable | 1 | — |
| **Total** | **₹930** |
Wiring
Both the BME280 and OLED use I2C, so they share the same two data lines:
ESP32 GPIO21 (SDA) → BME280 SDA → OLED SDA
ESP32 GPIO22 (SCL) → BME280 SCL → OLED SCL
ESP32 3.3V → BME280 VCC → OLED VCC
ESP32 GND → BME280 GND → OLED GNDThe Code
Install these libraries via Arduino Library Manager:
- Adafruit BME280 (and Adafruit Unified Sensor)
- Adafruit SSD1306 (and Adafruit GFX)
- WiFi (built into ESP32 core)
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <WebServer.h>
Adafruit_BME280 bme;
Adafruit_SSD1306 display(128, 64, &Wire);
WebServer server(80);
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
void setup() {
Serial.begin(115200);
Wire.begin();
bme.begin(0x76);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
server.on("/", []() {
float temp = bme.readTemperature();
float hum = bme.readHumidity();
float pres = bme.readPressure() / 100.0;
String html = "<h1>Weather Station</h1>";
html += "<p>Temperature: " + String(temp, 1) + " C</p>";
html += "<p>Humidity: " + String(hum, 1) + " %</p>";
html += "<p>Pressure: " + String(pres, 1) + " hPa</p>";
server.send(200, "text/html", html);
});
server.begin();
Serial.println("Server at: http://" + WiFi.localIP().toString());
}
void loop() {
server.handleClient();
// Update OLED every 2 seconds
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate > 2000) {
lastUpdate = millis();
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.printf("Temp: %.1f C\n", bme.readTemperature());
display.printf("Hum: %.1f %%\n", bme.readHumidity());
display.printf("Pres: %.0f hPa\n", bme.readPressure() / 100.0);
display.printf("\nIP: %s", WiFi.localIP().toString().c_str());
display.display();
}
}Taking It Further
- Data logging: Push readings to InfluxDB + Grafana for beautiful time-series charts
- Alerts: Send a Telegram notification when pressure drops rapidly (storm incoming!)
- Solar power: Add a TP4056 charge controller and 18650 battery for off-grid operation
- Multi-sensor: Daisy-chain multiple BME280s at different I2C addresses for indoor/outdoor comparison