Device Output.
Not an animation: all 1,380 frames of this loop were rendered by the device itself, pulled over a debug endpoint that draws any requested simulation time.
A desktop digital twin of Earth — 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 — on a 1.75" round AMOLED.
Not an animation: all 1,380 frames of this loop were 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 operates entirely on the device — no companion app, no cloud account, no API keys. 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, no restart. 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), with the Moon drawn phase-correct at its true position. The whole sky wheels with the clock — or with the time-lapse.
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.
Most "Earth globe" gadgets use static textures spinning on a timer. This project calculates the true subsolar point (NOAA solar position) for the current UTC, composites NASA VIIRS daily cloud mosaics from two satellites, and additively blends NASA Black Marble city lights on the night side.
A precomputed lookup table maps every pixel on the round display to a geographic normal. True bilinear sampling rides in the LUT's padding byte — the quality feature costs zero extra memory bandwidth — with 8×8 Bayer dithering to prevent RGB565 banding.
A dedicated RTOS task fetches the daily dual-satellite VIIRS snapshot at 2048×1024 and decodes at half scale — 4:1 supersampling into the working texture — then destripes swath-edge haze, feathers the dateline seam, and publishes atomically via pointer swap.
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 1,080 frames pulled 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 instead of vanishing.
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 ~3,700 lines of Python host tooling in backend/.
12 LittleFS binaries — ten 1 MB RGB565 body textures, the Black Marble night-lights layer, and a packed font/icon atlas — plus an 11 KB compiled-in star catalog: 1,010 stars and 743 constellation segments.
Ten sun-shaded worlds plus the live Night Sky planisphere, with the ISS 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 involved 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.