# 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) 1. BMP180 reports **absolute** pressure → convert to **mean sea-level (MSL)** pressure using the configured altitude (barometric formula). 2. Store MSL pressure samples in the history buffer. 3. Compute the **3-hour pressure trend** → rising / steady / falling (threshold ≈ ±1.6 hPa over 3 h). 4. 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 (↑ / → / ↓). 5. 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: 1. **Live** — current time, MSL pressure + trend, temperature, forecast. 2. **History** — 24 h pressure + temperature chart. 3. **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): 1. **Sensors** — Serial print of BMP180 pressure/temp; sanity-check values. 2. **RTC** — set time, power-cycle, verify time held by battery; verify NTP sync updates DS3231. 3. **MSL conversion** — verify computed sea-level pressure is plausible for 150 m (abs ≈ MSL − ~18 hPa). 4. **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. 5. **Display** — verify layout, no overflow, correct icons/arrows. 6. **Web** — load page over LAN, confirm live values, chart renders, settings save and persist across reboot. 7. **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).