chore: make repo an Arduino collection with WeatherPredictor project
Flatten so the repo root is the Arduino sketchbook; the project lives in WeatherPredictor/. Add a collection index README at the root and move the detailed project README into WeatherPredictor/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
fc72f9b0bd
commit
11f57a244d
26 files changed
+120
-111
No files matched your search
@@ -1,114 +1,9 @@
|
|||||||
# Weather Predictor
|
# Arduino
|
||||||
|
|
||||||
An autonomous **barometric weather station** built on a Wemos D1 mini (ESP8266).
|
A collection of Arduino / ESP microcontroller projects.
|
||||||
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
|
## Projects
|
||||||
|
|
||||||
- **Local Zambretti forecast** from the 3-hour sea-level pressure trend (rising / steady / falling), adjusted for season.
|
- **[WeatherPredictor](WeatherPredictor/)** — autonomous barometric weather
|
||||||
- **On-device TFT screen** (160×80): time, date, pressure with trend arrow, temperature, a scaled weather icon, and the station's Wi-Fi/IP.
|
station on a Wemos D1 mini (ESP8266): local Zambretti forecast, TFT display
|
||||||
- **Web interface** served from the device (no external CDNs, works offline):
|
and a self-hosted web interface. See its [README](WeatherPredictor/README.md).
|
||||||
- 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](https://github.com/G6EJD/ESP32_Weather_Forecaster_TN061).
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
# 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 `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
|
||||||
|
|
||||||
|
```
|
||||||
|
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](https://github.com/G6EJD/ESP32_Weather_Forecaster_TN061).
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user