Skip to content

Sidereal (LST) and apparent-solar time-row modes#8

Draft
peterlewis wants to merge 4 commits into
mitxela:masterfrom
peterlewis:sidereal-modes
Draft

Sidereal (LST) and apparent-solar time-row modes#8
peterlewis wants to merge 4 commits into
mitxela:masterfrom
peterlewis:sidereal-modes

Conversation

@peterlewis

Copy link
Copy Markdown

Draft — two new opt-in time-row modes that turn the big HH:MM:SS digits into a live ticking clock in an alternate timebase:

  • MODE_LST — Local Sidereal Time (a GPS-disciplined sidereal clock, for the astronomers).
  • MODE_SUNDIAL — local apparent solar time; reads exactly 12:00:00 at your meridian transit.

Stacking note (please read first)

This builds on #6 (astro pack) — it reuses astro.c's solar routines. Until #6 lands, this PR's diff includes #6's commits too; the sidereal-specific change is the single top commit, 29acd18 (that's the one to review). Once #6 merges I'll rebase and this collapses to just that commit. Happy to reorder or split further if you'd prefer.

How it stays honest and leaves civil timekeeping untouched

It clones the existing MODE_COUNTDOWN takeover (new COUNT_ALT, four SysTick_Alt_Px clones). The GMST/EoT double maths runs once per second in the main loop; the SysTick handlers latch pre-rendered digits at the true PPS boundary via the untouched PPS() path. So civil currentTime, PPS discipline, calibrateRTC/write_rtc and the date row are byte-identical to stock; the setPrecision P3→P0 sub-second digit-hiding applies to sidereal unchanged; and no double-precision maths ever runs in an ISR.

The display is quantised to civil second boundaries and reseeded each second, so sidereal's 1.00273791× rate makes the seconds display double-step about once every 6 minutes — deliberately visible, the honest signature of a GPS-disciplined sidereal clock rather than a rate-warped one. A dedicated colon animation (alt_colon_mode, default alt_sawtooth, kept distinct from the civil colon) marks the mode so it can't be mistaken for civil time; with no position the row shows dashes rather than GMST-as-LST.

Maths

astro.c regains local_sidereal_time() / local_solar_time() with the GMST series factored into one gmst_hours() helper (+T² term for sub-ms accuracy for decades). Native suite 53/53, including the IAU GMST(J2000.0) anchor and Meeus example 12.b. DUT1 (±0.9 s) is the documented accuracy floor.

Default-off: without the config keys, no alt handler is installed and behaviour is identical to stock. Builds clean (-O3, no new warnings); passed an adversarial review pass. Hardware validation still pending — hence draft.

peterlewis and others added 2 commits June 30, 2026 18:33
Five GPS-derived astronomy read-outs, each opt-in via a MODE_* config key and
shown on the 10-char date row while the live clock keeps running on the time
row (SATVIEW-style, COUNT_NORMAL):

  MODE_SUN       sunrise / sunset / solar noon (local), auto-paged
  MODE_SUN_AZEL  sun azimuth & elevation, now
  MODE_MOON      moon phase index (0-7) + illuminated %
  MODE_GRID      Maidenhead grid locator
  MODE_LATLON    latitude / longitude, auto-paged

The astronomy maths is a self-contained Core/Src/astro.c (+ astro.h): low-
precision NOAA/Meeus sun alt-az and event times, moon phase, equation of time,
and Maidenhead. It has no firmware dependencies, so it unit-tests natively
(test/test_astro.c, 45 reference vectors) and was validated to ~1e-5 before
touching the firmware.

The L4 has only a single-precision FPU, so the double maths would be slow soft-
float. It is therefore computed in the main loop (astro_update(), gated on the
active mode exactly as measure_vbat() is for MODE_VBAT) and swapped into a cache
under a brief __disable_irq() mask; the sendDate() cases that run inside the
SysTick ISR only format the cached scalars -- no trig in the interrupt.

Modes are disabled by default; with no GPS fix they use fake_latitude/longitude
if set, else show "----". config.txt documents the keys and the moon-phase
index legend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"LAT 51.48" vs "LAT-51.48" let the minus swallow the separator. Add a sign
slot after the label space — "LAT  51.48" / "LAT -51.48" — so the digits
start in the same column either way, matching the RISE/SET layout. A 3-digit
longitude can't fit both the separator and the slot in 10 characters, so the
separator alone is dropped there ("LON-179.99").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
peterlewis and others added 2 commits July 5, 2026 12:42
The paged modes (SUN, LATLON) previously flipped sub-screen every 2 s hard-coded.
Make the dwell a config key (page_ms, ms; unset -> 5500, floored at 250 so a tiny
value can't flood the date-board UART), driven off uwTick, and repaint the moment a
page flips rather than waiting for the 1 Hz date-row refresh (guarded by decisec!=9
to avoid racing the SysTick sendDate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MODE_LST and MODE_SOLAR turn the big HH:MM:SS digits into a live ticking
Local Sidereal Time or apparent-solar clock. Both reuse the MODE_COUNTDOWN
takeover pattern: the heavy GMST/EoT double maths runs once per second in the
main loop, staging pre-rendered digits that the SysTick handlers latch at the
true GPS PPS boundary -- so accuracy and the P3..P0 sub-second digit-hiding are
inherited from the disciplined civil second, and civil timekeeping (currentTime,
PPS, the date row) is untouched.

The display is quantised to civil second boundaries and reseeded every second,
so sidereal's 1.00273791x rate makes the seconds double-step once every ~6 min
-- the honest signature of a GPS-disciplined sidereal clock. A dedicated colon
animation (alt_colon_mode, default alt_sawtooth, kept distinct from the civil
colon) marks the mode so it can never be mistaken for civil time; apparent solar
especially can sit within minutes of it. With no position the row shows dashes
-- never GMST-as-LST.

astro.c regains local_sidereal_time()/local_solar_time() with the GMST series
factored into one helper (gmst_hours, +T^2 term); native suite 53/53 incl. the
IAU J2000 anchor and Meeus example 12.b. All default-off: stock behaviour
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
peterlewis added a commit to peterlewis/clock4 that referenced this pull request Jul 6, 2026
The exact residue between the pure union of the five draft PRs (mitxela#5 $PMTXTS,
mitxela#6 astro pack, mitxela#7 hardening, mitxela#8 sidereal/solar, mitxela#9 tempcomp + significance-fade
+ tc_seed — mitxela#5 and mitxela#6 arrive as ancestors of mitxela#9 and mitxela#8) and the rollup tree that
has been emulator-verified and hardware-run:

- astro.c/astro.h/test_astro.c: rollup astro refinements not yet folded back into
  the refreshed PR mitxela#6/mitxela#8 heads (candidates for a future PR update)
- version.c: rollup version string
- qspi/output/*.bin: rollup's built firmware images
- .settings IDE noise

After this commit the megapack tree is BYTE-IDENTICAL to the previously validated
rollup (feaf970) while the merge ancestry proves containment of all five PR heads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant