Files
Arduino/README.md
T
2026-07-18 11:52:33 +07:00

5.2 KiB
Raw Blame History

Weather Predictor

An autonomous barometric weather station built on a Wemos D1 mini (ESP8266). It reads atmospheric pressure and temperature, keeps accurate battery-backed time, and predicts near-term local weather entirely on-device using the Zambretti algorithm — no internet forecast service required. Readings and the forecast are shown on a small TFT and on a self-hosted web interface styled as a barometer instrument.

Features

  • Local Zambretti forecast from the 3-hour sea-level pressure trend (rising / steady / falling), adjusted for season.
  • On-device TFT screen (160×80): time, date, pressure with trend arrow, temperature, a scaled weather icon, and the station's Wi-Fi/IP.
  • Web interface served from the device (no external CDNs, works offline):
    • live barometer dial with a needle and a "set hand" ghost at the pressure 3 h ago;
    • barograph of pressure & temperature with labelled axes;
    • forecast change log;
    • settings with city presets and a UTC-offset time-zone picker.
  • Persistence in LittleFS: settings, pressure history, and the forecast log all survive reboots.
  • Wi-Fi provisioning via WiFiManager (captive portal — no credentials in code) and NTP time sync to the DS3231.

Hardware

Component Part Bus / notes
MCU Wemos D1 mini (ESP8266, 4 MB flash)
Pressure & temperature BMP180 (GY-68) I²C, addr 0x77
Real-time clock DS3231 (HW-022, battery-backed) I²C, addr 0x68
Display 0.96" 80×160 TFT, ST7735S 4-wire SPI, run landscape 160×80

Wiring

The display uses hardware SPI; the two I²C modules share one bus.

Signal Wemos pin GPIO
TFT CS D8 15
TFT DC D3 0
TFT RST D4 2
TFT SDA (MOSI) D7 13
TFT SCL (SCK) D5 14
TFT BLK (backlight) D2 4
I²C SDA (BMP180 + DS3231) D6 12
I²C SCL (BMP180 + DS3231) D1 5

All modules run on 3.3 V / GND. I²C is started with Wire.begin(D6 /*SDA*/, D1 /*SCL*/).

Build & flash (Arduino IDE)

  1. Install the ESP8266 board package; select board "LOLIN(WEMOS) D1 R2 & mini".
  2. Set Tools → Flash Size to a layout with a filesystem, e.g. 4MB (FS:2MB).
  3. Install libraries via Library Manager: Adafruit GFX, Adafruit ST7735 and ST7789, Adafruit BMP085, RTClib, ArduinoJson (v7.x), WiFiManager (by tzapu). ESP8266WiFi, ESP8266WebServer, LittleFS, Wire, SPI, time ship with the core.
  4. Open Arduino/WeatherPredictor/WeatherPredictor.ino and upload.

First run

  1. On first boot the device opens a Wi-Fi access point WeatherPredictor-Setup. Join it from a phone and pick your network in the captive portal.
  2. After connecting, the device syncs time over NTP and writes it to the DS3231.
  3. The screen and Serial (115200) print the station's IP — open http://<ip>/.
  4. The forecast shows "Collecting data…" until ~3 h of pressure history exists; that is expected — the Zambretti method needs a trend before its first call.

Set your altitude in the web settings (or pick a city preset): sea-level pressure — and therefore the forecast — depends on it (~0.12 hPa per metre).

REST API

Endpoint Method Returns
/ GET Web UI
/api/current GET time, pressure (abs + sea level), temperature, trend, forecast
/api/history GET recent pressure/temperature samples
/api/forecasts GET forecast change log (newest first)
/api/settings GET / POST altitude, time-zone offset, coordinates

Project structure

Arduino/WeatherPredictor/
  WeatherPredictor.ino   scheduler; wires the modules together
  config.h               pins, addresses, intervals, defaults
  state.h                shared current-readings struct
  sensors.*              BMP180 read + sea-level conversion
  rtc_time.*             DS3231 read/set + NTP sync
  display_ui.*           ST7735 rendering + weather icons
  forecast.*             Zambretti forecast + trend classification
  history.*              pressure ring buffer + LittleFS persistence
  flog.*                 forecast change log
  app_settings.*         settings struct + LittleFS JSON
  net.*                  WiFiManager connection
  web_server.*           HTTP server + REST API
  web_page.h             web UI (HTML/CSS/JS) in PROGMEM
  docs/superpowers/      design spec and implementation plan

Notes & gotchas

  • BGR panel: this 0.96" ST7735S has red/blue swapped, so colours are built R/B-exchanged in display_ui.cpp. If your panel looks wrong, adjust there (and the invertDisplay / setRotation in displayBegin()).
  • Restrictive networks: on some LANs the router does not resolve external hostnames, so NTP uses hard-coded Cloudflare/Google anycast IPs instead of names. Such networks may also block SSH.
  • Flash wear: history is flushed every 15 min and the forecast log only on change, so LittleFS wear leveling keeps flash life at years/decades.

Credits

Zambretti forecast constants and lookup tables adapted from G6EJD's ESP Zambretti forecaster.