Gold & Silver Price Tracker
Gold & Silver Price Tracker (internally titled "MetalsTracker") is a real-time precious metals price display device built for the LilyGO ESP32-S3 h...
Gold & Silver Price Tracker
Category: Embedded Systems / IoT / Financial Data Display
Platform: LilyGO T-Display-S3 / LilyGO T-Deck Plus / LilyGO T-Dongle S3 (ESP32-S3)
Framework: Arduino via PlatformIO | C++
Status: Active — Production Ready (v2)
Project Overview
Gold & Silver Price Tracker (internally titled "MetalsTracker") is a real-time precious metals price display device built for the LilyGO ESP32-S3 hardware family. It fetches live gold (XAU) and silver (XAG) spot prices denominated in Australian Dollars (AUD) from the MetalPriceAPI, and renders them on a purpose-built graphical dashboard with gradient panels, animated rainbow dividers, and custom metallic icons.
The device is engineered for reliability and efficiency — it only wakes the WiFi radio every 12 hours to refresh prices, then immediately disconnects and renders the updated data locally. A hardware button provides on-demand manual refresh at any time. The result is a beautifully styled, always-visible precious metals ticker that runs virtually indefinitely on a battery.
Core Features
Live Price Data
- Fetches gold (XAU) and silver (XAG) spot prices via HTTPS from MetalPriceAPI
- Prices returned as exchange rates relative to AUD (XAU/AUD, XAG/AUD) and inverted to produce the AUD price per troy ounce
- Data displayed as formatted price strings: e.g.,
$4,523.81 AUD - Currency formatting uses the AsciiFont8x16 glyph set which correctly renders
$(unlike TFT_eSPI's Font4 which maps$to£)
Smart WiFi Power Management
- 12-hour auto-refresh cycle — WiFi is activated, data fetched, NTP synced, and WiFi disconnected — all within a single fetch cycle
- Between refreshes, the device runs fully offline — no background radio activity
- WiFiManager handles first-time setup via a captive portal (AP name: MetalsTracker-Setup)
- Saved WiFi credentials are cached in memory and reused for each 12-hour reconnect
On-Demand Manual Refresh
- BOOT button (GPIO 0) interrupt-driven at hardware level (IRAM_ATTR ISR)
- Hold BOOT for 500ms to trigger an immediate full refresh cycle
- Debounced via interrupt state tracking — prevents false triggers
Animated Loading Screen
- Custom "FETCHING NEW DATA..." loading screen displayed during each refresh
- Features a 12-frame rainbow spinner animation (8 HSV-coloured orbiting dots)
- Spinner runs for approximately 1.2 seconds before API call begins
Graphical Dashboard Layout
The dashboard is divided into five precisely calculated sections across a 320x170 landscape display:
| Section | Y Position | Height | Content |
|---|---|---|---|
| Header | 0 | 18px | Title, WiFi status icon, current time |
| Gold Panel | 18 | 62px | Gold bar icon, XAU label, price |
| Rainbow Divider | 80 | 8px | Full-width HSV colour sweep |
| Silver Panel | 88 | 62px | Silver coin icon, XAG label, price |
| Footer | 150 | 20px | Countdown to next refresh, button hint |
Premium Visual Design
- Gold Panel: Warm dark amber to near-black gradient background; 28x14px gold bar icon with sheen, shadow, and centre groove detail
- Silver Panel: Cool slate gradient background; silver coin icon with highlight and dimensional rendering
- Rainbow Divider: Full-width HSV sweep at full saturation — cycles through the complete visible spectrum
- WiFi Status Icon: 4-bar signal strength icon (green when connected, red when offline)
- Header: Dark navy background with metallic accent text and cyan timestamp
- Footer: Countdown timer (Xh YYm) updating every 5 seconds; button hint text
First-Run WiFi Setup Screen
- Custom on-device setup instructions displayed while WiFiManager captive portal is active
- Styled instruction box with step-by-step numbered guide
- AP name highlighted in cyan, browser URL in green
- Rainbow bar at bottom for visual flair
NTP Time Synchronisation
- Syncs to pool.ntp.org on every 12-hour refresh cycle
- AEST/AEDT timezone (Australian Eastern Time with DST support)
- Time displayed in 12-hour format (H:MM AM/PM) in the dashboard header
- Header time refreshes every 60 seconds independently of the data refresh
Multi-Board Support
The project supports three LilyGO hardware variants with separate build environments:
| Board | Environment | Display Interface | Notes |
|---|---|---|---|
| T-Display S3 | lilygo-t-display-s3 | 8-bit parallel i8080 | 320x170 ST7789 |
| T-Deck Plus | tdeck-plus | SPI ST7789 | 320x240 with keyboard |
| T-Dongle S3 | tdongle-s3 | Custom | Compact dongle form factor |
Each board has its own source file and build filter in platformio.ini:
main.cpp— T-Display S3main_tdeck.cpp— T-Deck Plusmain_tdongle.cpp— T-Dongle S3
Technical Architecture
| Component | Detail |
|---|---|
| MCU | ESP32-S3 @ 240 MHz |
| Display | ST7789 1.9" IPS — 320x170 (i8080 8-bit parallel) |
| Graphics Library | LovyanGFX v1.2 — native i8080 bus driver |
| WiFi | WiFiManager v2.0 — captive portal + credentials cache |
| HTTPS | WiFiClientSecure (setInsecure — no cert pinning) |
| JSON | ArduinoJson v7.0 — streaming deserialization |
| RTOS | FreeRTOS (vTaskDelay for non-blocking sleep) |
| Time | configTzTime — POSIX timezone string (AEST-10AEDT) |
| Button ISR | GPIO 0 CHANGE interrupt with IRAM_ATTR handler |
API Integration
| Service | Purpose | Endpoint |
|---|---|---|
| MetalPriceAPI | Live XAU/XAG spot prices in AUD | api.metalpriceapi.com/v1/latest |
API returns base=AUD with currencies=XAU,XAG. The device computes:
- Gold AUD = 1.0 / XAU_rate
- Silver AUD = 1.0 / XAG_rate
Colour System
All colours are initialised after display setup using tft.color565():
| Token | Use Case | RGB Approximate |
|---|---|---|
| C_GOLD | Gold text and primary gold elements | #FFD200 |
| C_GOLD_DIM | Gold icon shadows and borders | #5A4100 |
| C_GOLD_BRIGHT | Gold icon sheen highlights | #FFF88C |
| C_SILVER | Silver text and primary silver elements | #C3CAD7 |
| C_SILV_DIM | Silver icon shadows | #4B505F |
| C_SILV_BRIGHT | Silver coin highlight | #EBF2FF |
| C_HDR_BG | Header background | #0C0C1C |
| C_WIFI_OK | WiFi connected indicator | #00D74B |
| C_WIFI_ERR | WiFi error indicator | #F03232 |
Deployment
- Open project in PlatformIO
- Select environment matching your hardware (lilygo-t-display-s3, tdeck-plus, or tdongle-s3)
- Build and flash to device
- On first boot: connect phone to MetalsTracker-Setup WiFi hotspot
- Open browser at 192.168.4.1 and enter home WiFi credentials
- Device connects, syncs NTP, fetches first prices, and renders the dashboard
- Hold BOOT button (500ms) at any time to force an immediate price refresh