6.8 KiB
Weather Predictor — Design Spec
Date: 2026-07-17 Status: Approved (design), pending implementation plan
Overview
An autonomous barometric weather-prediction station built on a Wemos D1 mini (ESP8266). It measures atmospheric pressure and temperature (BMP180), keeps accurate time (DS3231 RTC), predicts near-term weather locally using the Zambretti algorithm (pressure trend based, no internet required), and displays current readings + forecast on a small TFT. A built-in web interface (served from the device) shows live readings, a 24 h history chart, and editable settings.
All on-device and web text is in English.
Hardware
| Component | Model |
|---|---|
| MCU | Wemos D1 mini (ESP8266, ~4 MB flash) |
| Pressure/Temp sensor | BMP180 (GY-68), I2C addr 0x77 |
| RTC | DS3231 (HW-022, no EEPROM), I2C addr 0x68, battery-backed |
| Display | 0.96" 80×160 TFT, ST7735S, 4-wire SPI, driver INITR_MINI160x80 |
Wiring
Display uses hardware SPI; both I2C modules share one bus (D1/D6).
| Signal | Wemos pin | GPIO |
|---|---|---|
| TFT CS | D8 | 15 |
| TFT DC | D3 | 0 |
| TFT RES | D4 | 2 |
| TFT SDA (MOSI) | D7 | 13 |
| TFT SCL (SCK) | D5 | 14 |
| TFT BLK (backlight) | D2 | 4 |
| I2C SCL (BMP180 + DS3231) | D1 | 5 |
| I2C SDA (BMP180 + DS3231) | D6 | 12 |
Power: all modules on 3.3 V / GND. I2C init: Wire.begin(D6 /*SDA*/, D1 /*SCL*/).
Software Architecture
Arduino IDE project: main .ino sketch + per-module .h/.cpp tabs.
Each module has one clear responsibility and a small interface.
| Module | Responsibility | Key library |
|---|---|---|
config.h |
Pins, I2C addresses, timing constants, defaults | — |
sensors |
Read BMP180 pressure + temperature | Adafruit_BMP085 |
rtc |
Read/set DS3231 time; NTP sync when Wi-Fi up | RTClib |
display |
Render the status screen | Adafruit_GFX, Adafruit_ST7735 |
forecast |
Zambretti prediction (pure, host-testable) | — |
history |
Ring buffer of samples + LittleFS persistence | LittleFS |
settings |
Load/save settings JSON | ArduinoJson, LittleFS |
wifi |
Connect via WiFiManager captive portal | WiFiManager |
webserver |
HTTP server + REST API + static page | ESP8266WebServer |
Third-party libraries (Arduino Library Manager)
Adafruit_GFX, Adafruit_ST7735, Adafruit_BMP085 (works for BMP180), RTClib, ArduinoJson, WiFiManager (tzapu). Built-in: SPI, Wire, ESP8266WiFi, ESP8266WebServer, LittleFS, time.h (NTP/SNTP).
Forecast Logic (Zambretti)
- BMP180 reports absolute pressure → convert to mean sea-level (MSL) pressure using the configured altitude (barometric formula).
- Store MSL pressure samples in the history buffer.
- Compute the 3-hour pressure trend → rising / steady / falling (threshold ≈ ±1.6 hPa over 3 h).
- Zambretti lookup from (MSL pressure, trend, season-from-month) → one of
~26 forecast codes → mapped to a short English label
(e.g.
Sunny,Fine,Changeable,Rain likely,Stormy) + an icon + trend arrow (↑ / → / ↓). - Until ~3 h of data exist after boot, show
Collecting data….
Southern-hemisphere handling is not needed (fixed northern location); season derived from RTC month.
Display Layout (80×160, portrait)
Top→bottom: large time HH:MM; date; MSL pressure (hPa) with trend arrow;
temperature (°C); forecast label + icon. Backlight on D2 (dimming/night mode
is a possible later enhancement, not in initial scope).
Data Flow
BMP180 ──▶ sensors ──▶ MSL convert ──▶ history (RAM ring buffer)
DS3231 ──▶ rtc │
▼
forecast (Zambretti) ──┬──▶ display
└──▶ webserver /api
history ──(every ~15 min)──▶ LittleFS (restored on boot)
settings ◀──▶ LittleFS (edited via web)
- Sensor sampling: every ~1 min (display/current values).
- History granularity: one stored sample every ~5 min → ~24–48 h in RAM.
- Flash flush: every ~15 min (and buffer capped) to limit flash wear.
Web Interface
Single page served from the device; no external CDNs (works even if the client has no internet). Vanilla JS + a small self-written inline SVG chart.
Pages/sections:
- Live — current time, MSL pressure + trend, temperature, forecast.
- History — 24 h pressure + temperature chart.
- Settings — altitude (m, default 150), timezone/UTC offset, default coordinates (54.9870, 82.8730) shown; editable and persisted to LittleFS.
REST API:
GET /api/current→ time, pressure (abs + MSL), temperature, trend, forecast.GET /api/history→ array of recent samples for the chart.GET /api/settings/POST /api/settings→ read/update settings.
Storage (LittleFS)
/settings.json— altitude, timezone offset, coordinates./history.dat(or.json) — periodic snapshot of the sample ring buffer, reloaded on boot so the trend survives restarts.
Wi-Fi & Time
- WiFiManager: on first boot (or no known network) the device opens a captive-portal AP so Wi-Fi is configured from a phone — no reflashing.
- NTP: when Wi-Fi is connected, sync time and write it to the DS3231. DS3231 (battery-backed) keeps accurate time when offline.
- Default location for timezone context: 54.9870 N, 82.8730 E (Novosibirsk, UTC+7), altitude 150 m — all editable via web.
Defaults Summary
| Setting | Default | Editable in web |
|---|---|---|
| Altitude | 150 m | yes |
| Coordinates | 54.9870, 82.8730 | yes |
| Timezone | UTC+7 | yes |
| Sensor sample interval | ~60 s | no (constant) |
| History sample interval | ~5 min | no (constant) |
| Flash flush interval | ~15 min | no (constant) |
Testing
Manual (Arduino IDE, no automated harness):
- Sensors — Serial print of BMP180 pressure/temp; sanity-check values.
- RTC — set time, power-cycle, verify time held by battery; verify NTP sync updates DS3231.
- MSL conversion — verify computed sea-level pressure is plausible for 150 m (abs ≈ MSL − ~18 hPa).
- Trend/forecast — inject synthetic pressure series via Serial or by editing the buffer; confirm rising/steady/falling classification and Zambretti label mapping against known reference values.
- Display — verify layout, no overflow, correct icons/arrows.
- Web — load page over LAN, confirm live values, chart renders, settings save and persist across reboot.
- Persistence — reboot; confirm settings and history restored from flash.
Out of Scope (initial)
- Online forecast providers (variant B/C hybrid).
- Cyrillic display fonts (English only).
- Backlight night dimming, CSV/JSON export (possible later enhancements).