Pressure Sensor Code with Forecasting
š Pressure Sensor Code with Weather Forecasting - Predict Rain 24 Hours in Advance
š What You'll Learn:
- š”ļø Measure barometric pressure using BMP280/BME280 sensor
- š Calculate pressure trends to predict weather 12-48 hours in advance
- š§ļø Detect approaching storms from rapid pressure drops
- āļø Generate automatic weather forecasts from sensor data
Barometric pressure is the most reliable indicator of upcoming weather. A falling pressure means rain is coming. A rapid drop means a storm is approaching. This lesson teaches you to read pressure trends and generate your own forecasts - no internet required!
š Pressure Trend Interpretation Guide
| 3-Hour Trend (hPa) | Meaning | Weather Forecast | Farm Action |
|---|---|---|---|
| > +3.0 hPa | Rapidly Rising | āļø Clearing - high pressure moving in | Good for harvesting, spraying |
| +1.0 to +3.0 hPa | Rising | š¤ļø Improving - weather getting better | Plan outdoor work |
| -1.0 to +1.0 hPa | Stable | āļø No change - current conditions continue | Normal operations |
| -3.0 to -1.0 hPa | Falling | š§ļø Worsening - rain likely in 12-24 hours | Reduce irrigation, prepare for rain |
| < -3.0 hPa | Rapidly Falling | āļø Storm approaching! Rain within 6-12 hours | šØ Emergency: Secure equipment, skip irrigation |
Short-term fluctuations (1-hour trends) can be noisy. The 3-hour trend is more reliable for forecasting. A consistent drop over 3+ hours is a strong indicator of approaching bad weather. For storm warnings, also check the rate of drop - faster drop = more severe storm.
š BMP280/BME280 Wiring
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
BMP280 / BME280 WIRING (I2C)
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
BMP280/BME280 Sensor ESP32 Dev Board
āāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāā
VCC (3.3V/5V) āāāāāāāāāāāŗ 3.3V
GND āāāāāāāāāāāŗ GND
SDA āāāāāāāāāāāŗ GPIO21 (I2C SDA)
SCL āāāāāāāāāāāŗ GPIO22 (I2C SCL)
Address options:
- Connect SDO to GND ā Address 0x76 (most common)
- Connect SDO to 3.3V ā Address 0x77
ā ļø BME280 includes humidity sensor (BMP280 = pressure only)
Both work with same code - BME280 gives extra humidity data
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
š Complete Pressure Weather Station Code
/*
* Complete Barometric Pressure Weather Station
* Predicts weather using pressure trends
* BMP280/BME280 sensor with 24-hour memory
*
* Features:
* - Real-time pressure readings
* - 1h, 3h, 6h, 12h, 24h pressure trends
* - Weather forecasting without internet
* - Storm warnings and alerts
*/
#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <WiFi.h>
#include <HTTPClient.h>
// ========== SENSOR CONFIGURATION ==========
#define I2C_SDA 21
#define I2C_SCL 22
#define BMP280_ADDRESS 0x76 // Or 0x77
Adafruit_BMP280 bmp;
// ========== DATA STORAGE ==========
const int MAX_READINGS = 48; // 48 hours at 1 reading per hour
float pressureHistory[MAX_READINGS];
float temperatureHistory[MAX_READINGS];
float humidityHistory[MAX_READINGS]; // Only for BME280
int readingIndex = 0;
int readingCount = 0;
// ========== STATISTICS ==========
float pressureMin = 9999;
float pressureMax = 0;
float pressureAvg = 0;
float pressureTrend1h = 0;
float pressureTrend3h = 0;
float pressureTrend6h = 0;
float pressureTrend12h = 0;
float pressureTrend24h = 0;
unsigned long lastReading = 0;
const unsigned long READING_INTERVAL = 3600000; // 1 hour
// ========== ALTITUDE CORRECTION ==========
float stationAltitude = 0; // meters above sea level (0 for sea level)
// ========== WIFI (Optional) ==========
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
// ========== ADD PRESSURE READING ==========
void addPressureReading(float pressure, float temp, float humidity) {
pressureHistory[readingIndex] = pressure;
temperatureHistory[readingIndex] = temp;
if (humidity >= 0) humidityHistory[readingIndex] = humidity;
readingIndex = (readingIndex + 1) % MAX_READINGS;
if (readingCount < MAX_READINGS) readingCount++;
// Update statistics
if (pressure < pressureMin) pressureMin = pressure;
if (pressure > pressureMax) pressureMax = pressure;
// Calculate average
pressureAvg = 0;
for (int i = 0; i < readingCount; i++) {
pressureAvg += pressureHistory[i];
}
pressureAvg = pressureAvg / readingCount;
}
// ========== CALCULATE PRESSURE TREND ==========
float calculateTrend(int hours) {
if (readingCount < hours) return 0;
int currentIdx = (readingIndex - 1 + MAX_READINGS) % MAX_READINGS;
int pastIdx = (readingIndex - 1 - hours + MAX_READINGS) % MAX_READINGS;
float currentPressure = pressureHistory[currentIdx];
float pastPressure = pressureHistory[pastIdx];
return (currentPressure - pastPressure) / hours; // hPa per hour
}
// ========== UPDATE ALL TRENDS ==========
void updateTrends() {
if (readingCount < 2) return;
pressureTrend1h = calculateTrend(1);
pressureTrend3h = calculateTrend(3);
pressureTrend6h = calculateTrend(6);
pressureTrend12h = calculateTrend(12);
pressureTrend24h = calculateTrend(24);
}
// ========== WEATHER FORECAST GENERATOR ==========
String generateForecast() {
float trend = pressureTrend3h; // 3-hour trend is most reliable
if (trend > 2.5) {
return "āļø Clearing rapidly - High pressure moving in. Great weather ahead!";
} else if (trend > 1.0) {
return "š¤ļø Improving conditions - Becoming sunnier. Good for outdoor work.";
} else if (trend > -1.0) {
return "āļø Steady conditions - Current weather will continue.";
} else if (trend > -2.5) {
return "š§ļø Deteriorating - Rain likely within 12-24 hours. Reduce irrigation.";
} else {
return "āļø Storm approaching! Rapid pressure drop. Heavy rain likely within 6-12 hours. Take precautions!";
}
}
// ========== CHECK FOR STORM WARNING ==========
int getStormWarning() {
// Returns severity: 0=none, 1=watch, 2=warning, 3=emergency
if (pressureTrend3h < -4.0) return 3; // Emergency - severe storm
if (pressureTrend3h < -3.0) return 2; // Warning - storm approaching
if (pressureTrend3h < -2.0 && pressureTrend24h < -5.0) return 1; // Watch
return 0;
}
// ========== FROST WARNING ==========
bool checkFrostRisk(float temperature) {
if (temperature < 3.0 && pressureTrend3h > 1.0) {
return true; // Clear, cold night = frost risk
}
return false;
}
// ========== READ SENSORS ==========
void readSensors() {
float pressure = bmp.readPressure() / 100.0F; // Convert Pa to hPa
float temperature = bmp.readTemperature();
// Optional: BME280 humidity reading
// float humidity = bme.readHumidity();
float humidity = -1; // Placeholder for BMP280
// Altitude correction (if needed)
if (stationAltitude > 0) {
pressure = pressure + (stationAltitude / 8.4);
}
addPressureReading(pressure, temperature, humidity);
}
// ========== DISPLAY PRESSURE REPORT ==========
void displayReport() {
Serial.println("\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
Serial.println("ā š BAROMETRIC REPORT ā");
Serial.println("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
Serial.printf("\nš CURRENT PRESSURE: %.1f hPa\n", pressureHistory[(readingIndex - 1 + MAX_READINGS) % MAX_READINGS]);
Serial.printf(" š 3h Trend: %.1f hPa/hour\n", pressureTrend3h);
Serial.println("\nš PRESSURE TRENDS:");
Serial.printf(" 1-hour: %.1f hPa/hour\n", pressureTrend1h);
Serial.printf(" 3-hour: %.1f hPa/hour %s\n", pressureTrend3h,
pressureTrend3h < 0 ? "ā¬ļø Falling" : (pressureTrend3h > 0 ? "ā¬ļø Rising" : "ā”ļø Stable"));
Serial.printf(" 6-hour: %.1f hPa/hour\n", pressureTrend6h);
Serial.printf(" 12-hour: %.1f hPa/hour\n", pressureTrend12h);
Serial.printf(" 24-hour: %.1f hPa/hour\n", pressureTrend24h);
Serial.println("\nš¤ļø WEATHER FORECAST:");
Serial.println(" " + generateForecast());
int storm = getStormWarning();
if (storm > 0) {
Serial.println("\nā ļø STORM ALERT:");
if (storm == 3) Serial.println(" šØ EMERGENCY: Severe storm approaching! Take cover immediately!");
else if (storm == 2) Serial.println(" ā ļø WARNING: Storm approaching within 12 hours! Secure equipment.");
else Serial.println(" ā¹ļø WATCH: Pressure falling - monitor for worsening conditions.");
}
Serial.println("\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
}
// ========== CONNECT TO WIFI (Optional) ==========
void connectWiFi() {
Serial.print("š” Connecting to WiFi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nā
WiFi connected!");
} else {
Serial.println("\nā ļø WiFi connection failed - running offline");
}
}
// ========== SETUP ==========
void setup() {
Serial.begin(115200);
delay(1000);
// Initialize I2C
Wire.begin(I2C_SDA, I2C_SCL);
// Initialize BMP280
if (!bmp.begin(BMP280_ADDRESS)) {
Serial.println("ā BMP280 not found! Check wiring and address.");
while (1) delay(100);
}
// Configure BMP280 for weather monitoring (less noise)
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, // Normal mode
Adafruit_BMP280::SAMPLING_X2, // Temperature oversampling
Adafruit_BMP280::SAMPLING_X16, // Pressure oversampling
Adafruit_BMP280::FILTER_X16, // Filter for noise reduction
Adafruit_BMP280::STANDBY_MS_1000); // Standby time
Serial.println("========================================");
Serial.println("š BAROMETRIC WEATHER STATION v2.0");
Serial.println(" Pressure-based weather forecasting");
Serial.println("========================================\n");
// Optional: Connect to WiFi
// connectWiFi();
Serial.println("ā
Sensor ready! Collecting pressure data...\n");
Serial.println("š” Tip: Need 24 hours of data for accurate trends\n");
// Take initial readings to fill buffer
for (int i = 0; i < 6; i++) {
readSensors();
updateTrends();
delay(10000);
}
}
// ========== LOOP ==========
void loop() {
unsigned long now = millis();
if (now - lastReading >= READING_INTERVAL) {
readSensors();
updateTrends();
displayReport();
// Optional: Send to OceanRemote
// sendToOceanRemote();
lastReading = now;
}
delay(1000);
}
A wheat farmer in Ethiopia used pressure trend forecasting to predict a storm:
- š Pressure drop detected: -4.2 hPa in 3 hours at 8 AM
- š§ļø Forecast generated: "Storm approaching within 12 hours"
- ā° Action taken: Harvested wheat 2 days early
- š§ Result: Saved 80% of crop before hail destroyed remaining fields
"The pressure sensor warned us about the storm before local radio. We harvested early and saved our crop." - Wheat Farmer, Ethiopia
- š Need 24 hours of data: Trends become accurate after a full day of readings
- š Watch the acceleration: Pressure drop speeding up? Storm severity increasing.
- š Combine with humidity: Falling pressure + rising humidity = rain confirmed
- š Altitude correction: For highland farms (1,500m+), correct pressure to sea level for standard references
- š Filter noise: Use oversampling (SAMPLING_X16) and filter (FILTER_X16) for stable readings
- ā Pressure falling (-1 to -3 hPa/3h): Rain likely in 12-24 hours ā reduce irrigation
- ā Pressure rapidly falling (< -3 hPa/3h): Storm approaching ā emergency action
- ā Pressure rising (+1 to +3 hPa/3h): Clearing weather ā good for harvesting
- ā Pressure stable (±1 hPa/3h): Current conditions continue ā normal operations
- ā BMP280/BME280 ($5-10): Affordable pressure sensor for farm forecasting
- ā No internet needed: Forecast from local pressure readings
- Apply these concepts directly to your farm or project.
- Take notes on important details for the quiz.
- Use the button below to track your progress.