Device Output.
Every one of the 1,476 frames in this loop was rendered by the device itself, pulled over a debug endpoint that draws any requested simulation time.
A desktop digital twin of Earth on a 1.75" round AMOLED: the real day/night line, NASA satellite clouds, city lights, the night sky above your location, tonight's actual Moon phase, and the ISS overhead.
Every one of the 1,476 frames in this loop was rendered by the device itself, pulled over a debug endpoint that draws any requested simulation time.
Planetaria is a standalone, internet-connected desk display built on an ESP32-S3 microcontroller. On its 1.75" round AMOLED it renders a live, sun-synchronous Earth: the true day/night terminator computed each frame, daily cloud cover composited from two NASA VIIRS satellites, and city lights that come on only where night has actually fallen. A settings-page tap switches it to any of eleven views: nine more worlds, the Moon with tonight's real phase, or a live planisphere of the stars and constellations above your location, with the ISS tracked across the globe.
It runs entirely on the device, and everything needed to set it up ships inside it. Setup is a built-in captive portal (including enterprise 802.1X school and work networks), configuration is a web dashboard, and a sealed case can always be returned to setup by switching the power off and on three times. Every data source is keyless and licensed for commercial use. It ships as a product through the CosNFX store.
Calculates the real-time position of the sun to accurately drape a soft twilight terminator (day/night line) across the globe.
Composites daily imagery from NASA's NOAA-20 and Suomi-NPP VIIRS satellites, destripes swath-edge artifacts, and gap-fills from the previous day's mosaic; storms are real, current, and continuous.
Renders NASA "Black Marble" city lights exclusively on the shadowed hemisphere of the Earth.
Earth, Mercury through Neptune, the Moon, the Sun, and a live Night Sky (switched live from the settings page while the globe keeps running), plus scheduled pop-up cards for time & weather and the tide. The Moon is tidally locked like the real one, and its terminator is tonight's actual phase.
The stars and constellations above your location right now (Yale Bright Star Catalogue + d3-celestial figures), the Moon drawn phase-correct at its true position, and the five naked-eye planets as colour-coded dots, from an on-device Keplerian ephemeris validated against JPL Horizons to 0.077ยฐ. The whole sky wheels with the clock, or with the time-lapse.
On a schedule you choose it pops up like the weather card: the nearest NOAA station's water level right now (rising, falling, or the turn of the tide), today's true curve drawn from hourly NOAA predictions, the next high and low, and the Moon that drives it all.
Recent USGS earthquakes (M4.5+, past day) pulse on the globe at their real epicentres, larger for stronger quakes, fading as they age. The Pacific Ring of Fire, visible from your desk.
A marker rides the globe at the ISS's real position, propagated on-device from CelesTrak orbital elements (two-body + J2). In time-lapse it visibly orbits, the ground track corkscrewing westward pass after pass.
On a user-defined schedule (every 30 minutes out of the box), the globe transitions to a full-screen card with local time, date, temperature, "feels like," humidity, and wind, then returns to orbit.
A local web dashboard adjusts motion (true 24-hour rotation to fast time-lapse), brightness with optional auto-dim after local sunset, tilt, rotation, and more, plus a one-tap two-minute demo tour through every view that restores your settings when it's done.
Each frame begins from the true subsolar point (NOAA solar position) for the current UTC. From there the globe composites NASA VIIRS daily cloud mosaics from two satellites and additively blends NASA Black Marble city lights on the night side.
A precomputed table maps every pixel on the round screen to a point on Earth's surface. Neighbouring map pixels are blended as it samples, so the globe stays smooth right down to the pixel; that smoothing is tucked into spare space in the table, so it adds no memory cost. A fine dither pattern hides the colour banding the display's 16-bit colour would otherwise show.
A background task fetches the daily two-satellite cloud image (2048ร1024) and shrinks it into a working texture (averaging four source pixels into each one, which cleans up noise), then removes the stripe artifacts at the satellites' swath edges, smooths the seam at the dateline, and swaps the new clouds in without interrupting the display.
The renderer has Python replicas on the desktop, and the firmware exposes a deterministic capture endpoint that renders any requested simulation time on demand. The product video is rendered frame-by-frame this way: marketing material that doubles as a frame-exact test rig.
A freshly-built daily mosaic has missing satellite swaths, so completeness is judged by no-data pixels in the mid-latitude band only (polar night is legitimately black). Incomplete days are rejected back up to 7 days, and remaining gaps are filled from the previous mosaic, colour-matched, so clouds continue across the seam.
Honest figures, read straight from the repository: a single-purpose firmware plus the host tooling that feeds and verifies it.
The entire device program in one file, firmware/src/main.cpp (C++ / Arduino), backed by a Python host-tooling suite in backend/.
Ten surface textures (one per world), NASA's Black Marble night-lights layer, a packed font/icon atlas, and a compiled-in star catalog of 1,010 stars and 743 constellation segments. All stored on the device.
Ten sun-shaded worlds, the live Night Sky planisphere (with the naked-eye planets), and a live NOAA tide dial, with the ISS and USGS earthquakes tracked over Earth; targeting the LilyGo T-Display-S3 AMOLED (ESP32-S3, 8 MB PSRAM) via PlatformIO.
The real story of embedded systems lies in the hardware edge cases. Here are four critical bugs (and one non-bug) resolved during field-testing:
Text rendered perfectly on the host replica but garbled randomly on the physical panel. Root cause: the CO5300 display driver passes raw x/y/w/h coordinates without rounding. Any partial SPI write with an odd dimension shifts and corrupts the hardware buffer. The fix: strict even-padding on every text blit.
During time-lapse animations, the globe would hold still for 30 frames then awkwardly lurch forward. The underlying NTP clock was bound to time(nullptr), which is whole-second granular. The fix derived a sub-second fractional offset using millis(), re-anchoring on every RTC tick, so the spin advances smoothly between clock ticks.
When the globe was moved to a new house, the captive portal refused to load on 192.168.4.1. The ESP32's SoftAP channel strictly follows the Station radio. The radio kept hunting for the old home network saved deep in the driver, dragging the hotspot off-channel. The fix: explicitly wipe the persistent driver credentials and serve the portal in pure WIFI_AP mode.
Two ISS lessons. First, a real bug: the time-lapse clock races ~30 days per real hour, and a staleness guard comparing it against the orbital-element epoch silently expired after 19 minutes; staleness checks must always use the real clock. Second, a non-bug that survived a frame-by-frame audit of 432 captured frames: in the sun-locked view the marker retraces the same screen arc every orbit. Correct physics: a sun-fixed camera is nearly inertial, so the orbit ring holds still and it's Earth that slides beneath it.