A modular, high-performance weather display system for the LILYGO T-Display S3, featuring real-time weather data from OpenWeatherMap API with smooth animations and professional UI.
Inspired from Volos Projects (YouTube): Let's make Cheap Internet Weather Station using LilyGo T-Display S3 and OpenWeatherMap.org
- Real-time Weather Data: Fetches current weather from OpenWeatherMap API every 3 minutes
- Weather Icons: Visual weather condition icons (18 different conditions) displayed on screen
- Smooth Animations: 40 FPS scrolling ticker with professional transitions
- Modular Architecture: Clean, maintainable code structure with separate classes
- Secure Credentials: API keys and WiFi credentials stored in
secrets.h - Performance Optimized: Font caching, message buffering, and memory management
- Brightness Control: Hardware button support for display brightness adjustment
- Time Synchronization: Automatic NTP sync every 30 minutes
- Error Recovery: Robust WiFi reconnection and API error handling
- LILYGO T-Display S3 board
- PlatformIO IDE or Arduino IDE
- OpenWeatherMap API key (free at openweathermap.org)
-
Clone the repository:
git clone <repository-url> cd weather-micro-station
-
Create secrets file:
cp include/secrets_template.h include/secrets.h
-
Configure your credentials in
include/secrets.h:#define OPENWEATHERMAP_API_KEY "your_api_key_here" #define WIFI_SSID "your_wifi_network" #define WIFI_PASSWORD "your_wifi_password" #define OPENWEATHERMAP_CITY "Your_City"
-
Build and upload:
pio run --target upload
weather-micro-station/
βββ src/
β βββ main.cpp # Main application entry point
β βββ config.h # Configuration (timing, units, timezone)
β βββ weather_data.h # Data structures and types
β βββ weather_display.h/cpp # Display management and UI rendering
β βββ weather_api.h/cpp # API client and network operations
βββ include/
β βββ secrets.h # Secure credentials (not in git)
β βββ secrets_template.h # Template for secure credentials
β βββ weather_icons.h # Weather condition icons (RGB565)
β βββ *.h # Font files
βββ docs/
β βββ execution_flow.md # Detailed execution flow documentation
β βββ images/ # Documentation images
βββ icons/ # Source PNG files for weather icons
βββ SECURITY_SETUP.md # Complete security configuration guide
βββ tools/
βββ generate_callgraph.py # Call graph generator
βββ trace_functions.h # Runtime function tracing
| Component | Purpose | Key Features |
|---|---|---|
| WeatherDisplay | UI rendering and animation | 40 FPS updates, font caching, scrolling ticker |
| WeatherAPI | Network and API operations | HTTP client, JSON parsing, error handling |
| WeatherData | Data structures | Weather info, display state, configuration |
| Main Loop | Orchestration | Timing control, state management |
View detail Weather Station Execution Flow Analysis
graph TD
A[Power On/Upload] --> B[Serial Init]
B --> C[Display Init]
C --> D[WiFi Connection]
D --> E[Time Sync]
E --> F[Show 'Fetching data...']
F --> G[Initial API Call]
G --> H[Update Display]
H --> I[Enter Main Loop]
graph TD
A[Loop Start] --> B{25ms passed?}
B -->|No| J[yield]
B -->|Yes| C[Update Animation]
C --> D{3 minutes passed?}
D -->|No| G[Draw Display]
D -->|Yes| E[API Fetch Sequence]
E --> F[Update Data]
F --> G
G --> H[Handle Buttons]
H --> J
J --> A
- Clear Animation β Reset scrolling position
- Show "Fetching data..." β 2-second display
- HTTP API Call β OpenWeatherMap request
- Parse JSON β Extract weather data
- Update Display β Fresh animation with new data
All configuration is centralized in src/config.h for easy customization.
// Set to true for metric (Β°C, km/h, km), false for imperial (Β°F, mph, mi)
#define USE_METRIC_UNITS true// Common examples:
// Eastern US: GMT_OFFSET = -5, TZ = "EST5EDT,M3.2.0/2,M11.1.0/2"
// Pacific US: GMT_OFFSET = -8, TZ = "PST8PDT,M3.2.0/2,M11.1.0/2"
// UK/London: GMT_OFFSET = 0, TZ = "GMT0BST,M3.5.0/1,M10.5.0/2"
// Europe: GMT_OFFSET = 1, TZ = "CET-1CEST,M3.5.0,M10.5.0/3"
// Japan: GMT_OFFSET = 9, TZ = "JST-9"
#define GMT_OFFSET_HOURS -5
#define DAYLIGHT_SAVING_ENABLED 1
#define TIMEZONE_STRING "EST5EDT,M3.2.0/2,M11.1.0/2"#define UPDATE_INTERVAL_MS 180000 // 3 minutes - API calls
#define SYNC_INTERVAL_UPDATES 10 // 30 minutes - time sync
#define ANIMATION_START_POSITION 100 // Scrolling start positionThe scrolling ticker displays (units adjust based on USE_METRIC_UNITS):
"... [description], visibility is [X] km, wind of [Y] km/h, last updated at [HH:MM:SS] ..."
- Left Panel: Time, date, temperature, "Micro Station" branding
- Right Panel: Weather icon (18 different conditions), humidity, pressure, wind, clouds, visibility
- Bottom Ticker: Scrolling weather summary with real-time updates
The app includes 18 weather condition icons (9 in reality, using same icon for day(d) and night(n)) that automatically display based on the current weather:
- Clear sky (01d/01n)
- Few clouds (02d/02n)
- Scattered clouds (03d/03n)
- Broken clouds (04d/04n)
- Shower rain (09d/09n)
- Rain (10d/10n)
- Thunderstorm (11d/11n)
- Snow (13d/13n)
- Mist (50d/50n)
Icons are 24x24 pixels, stored in RGB565 format, and automatically selected based on the OpenWeatherMap API response. Day and night variants are supported.
Add to your code for runtime analysis:
#include "tools/trace_functions.h"
void myFunction() {
TRACE_FUNCTION(); // Basic tracing
MONITOR_PERFORMANCE("myFunc"); // Performance monitoring
TRACK_CALL_STACK(); // Call stack depth
// ... your code
}Generate visual call graphs:
python3 generate_callgraph.py > callgraph.mdRun comprehensive code analysis:
pio check --verbose| Metric | Value | Notes |
|---|---|---|
| Display FPS | 40 Hz | Smooth animation |
| API Calls | Every 3 minutes | Rate limit compliant |
| Memory Usage | ~85% heap | Optimized buffers |
| WiFi Reconnect | 30 second timeout | Automatic recovery |
| Time Sync | Every 30 minutes | NTP synchronization |
Display not updating:
- Check WiFi connection (LED indicators)
- Verify API key in
secrets.h - Monitor serial output for errors
Scrolling message stuck:
- API call might be failing
- Check internet connectivity
- Verify OpenWeatherMap service status
Compilation errors:
- Ensure all font files are in
include/directory - Check
secrets.hexists and is properly formatted - Verify PlatformIO libraries are installed
Enable detailed logging by monitoring serial output at 115200 baud:
=== STARTUP: Making initial API call ===
Scrolling: ... Fetching data ...
=== API FETCH SUCCESS ===
API VALUES:
Temp: 22.1Β°C | Feels: 24.3Β°C | Humidity: 65% | Pressure: 1013 hPa
Wind: 11.1 km/h | Clouds: 75% | Visibility: 10.0 km | few clouds
Updated: 14:23:45
- Never commit
secrets.h- Add to.gitignore(seeSECURITY_SETUP.md) - API Key Protection - Use environment variables in production
- WiFi Security - Ensure WPA2/WPA3 network encryption
- HTTPS Only - All API calls use secure connections
This project is licensed under the MIT License - see the LICENSE file for details.
- OpenWeatherMap - Weather data API
- LILYGO - T-Display S3 hardware
- TFT_eSPI - Display library
- ArduinoJson - JSON parsing
- ESP32Time - Real-time clock management
- Issues: GitHub Issues