Releases: GDKeller/JPL-MiniPulse
Release list
v1.1.5
v1.1.4
v1.1.3
OTA Firmware Update Fix
Fixed a critical issue where over-the-air firmware updates would fail with "connection refused" errors during download.
Root cause: The ESP32 Arduino WiFiClientSecure library has a bug where TLS session state isn't properly cleaned up between HTTP redirect hops when using HTTPClient::setURL(). GitHub's firmware download URL redirects through multiple hops (GitHub → versioned URL → CDN), and the stale TLS context caused the connection to fail on the second redirect.
Fix: OTA updates now manually resolve the full redirect chain using a fresh TLS context per hop before downloading, bypassing the bug entirely.
Additional improvements
- getData task is now paused during OTA to free heap for the download
- Web portal guards against triggering duplicate concurrent OTA updates
- HTTP response is sent to the client before OTA begins (successful updates reboot the device, so the response would never arrive otherwise)
- otaUpdateTriggered flag marked volatile for correct cross-core visibility between the web server (Core 1) and data fetching task (Core 0)
v1.1.2
New
- Simplified mDNS hostname — Device is now reachable at minipulse.local by default, making first-time setup easier. Multi-device users can enable "Unique hostname (MAC suffix)" in the portal to use minipulse-{mac}.local instead.
Fixed
- Dummy data mode reliability — Fixed fallback XML failing to parse after the first cycle due to a stale shared buffer. The fallback data is now reloaded from flash each cycle.
- Parse accuracy — Dummy data mode now stops after the first valid craft, matching the behavior of live data parsing.
- Memory cleanup — Moved fallback XML to PROGMEM, trimmed whitespace, and removed dead retry logic.
v1.1.1
v1.1.0
What's New
OTA Firmware Updates via GitHub Releases
MiniPulse now checks for firmware updates directly from GitHub Releases over HTTPS. The captive portal shows your current version, checks for available updates, and can flash new firmware over-the-air — no USB cable needed.
Spacecraft Filtering
A curated list of 44 high-priority missions (Voyager, JWST, Perseverance, Europa Clipper, etc.) is now the default display mode. Non-priority spacecraft are still recognized but filtered out to keep the display focused on active deep space missions. This can be toggled via the useApprovedOnly config flag.
Portal Improvements
- New Spacecraft page listing all recognized craft (non-priority missions shown dimmed)
- NASA JPL logo in the portal header
- Firmware version check is now cached to prevent device crashes from repeated page loads
- Manual "Check for Updates" button for on-demand version checks
- Improved button layout and menu ordering
Bug Fixes
- 10 critical and short-term stability fixes — queue initialization order, semaphore flag assignment, pointer-to-pointer queue send, pool allocator rewrite, WiFi connection check, uninitialized variables, dangling pointers, null-termination, display timer reset, and inverted startup logic
- Binary up signal detection — simplified from unreliable rate-based heuristic to binary presence detection
- Semver parsing — handles
vprefix from GitHub tags and correctly compares pre-release vs stable versions - Null root element guard in XML parser prevents crash on malformed DSN data
- Portal input validation — hardened checkbox parsing, brightness mapping, and division-by-zero guard
Performance
- 30 FPS frame limiter with render time and heap diagnostics
- Eliminated LittleFS round-trip in data fetch pipeline — spacecraft data served from memory
- Replaced
std::mapwithstrcmpchain intermColor()for lower overhead - Reduced semaphore hold time from seconds to microseconds
- Optimized boot sequence — skip flash writes when firmware version unchanged
Security & Reliability
- All library dependency versions pinned for reproducible builds
- Serial output gated behind
showSerialconfig flag (off by default) - Added
.catch()handlers to all portal fetch calls - 43-spacecraft fallback dataset from real DSN observations replaces dummy XML
Full Changelog: v1.0.4...v1.1.0