Absurdly Accurate Clock project visualization showing the VFD and prototype electronics on a workbench.
AI-assisted project visualization based on the working prototype.

At a glance

MCU
Raspberry Pi Pico 2 / RP2350, C++ firmware
Time source
u-blox NEO-7-class GPS: RMC over UART0, PPS on GP2
Display
Posiflex PD-2200 VFD, 2 × 20, RS-232 via MAX3232
Network export
SPI Protocol v1 (40 bytes, CRC-32) + TIME_SYNC to an ESP32
Recovery
4 s RP2350 hardware watchdog

Why it exists

Why “Absurdly Accurate”?

Notes from the bench — Rob

Even though it looks like I kept bolting crap onto a clock until NTP fell out, there was a little more engineering behind it than that.

The project started with an eight-digit seven-segment display that cost less than $2 from AliExpress. I thought it would make a fun clock. Soon afterward, a serial VFD customer display I'd recently found in the basement was sitting under my workbench, and it became a much more interesting display for the project.

What surprised me was how much could be done with very inexpensive hardware. A roughly $4 Raspberry Pi Pico 2, paired with GPS and a hardware PPS signal, could form the basis of a genuinely useful authoritative time source. As the project developed, I added PPS qualification, fault handling, an authoritative UTC timebase independent of the display, and defined interfaces for other devices to consume that time.

That eventually led to AAC Time Bridge: a roughly $6–7 ESP32 that takes qualified UTC from the clock and distributes it wirelessly to the local network using NTP, while providing its own WebUI for monitoring and management.

The “absurd” part isn't simply the accuracy. It's the mismatch between the cost and origins of the hardware and what the system became: inexpensive commodity microcontrollers, a GPS receiver, and repurposed point-of-sale hardware forming a deliberately structured timing system with defined authority, qualification, failure behavior, diagnostics, physical display, and network time distribution.

It started with a sub-$2 display and the idea of making a clock. I quickly realized it could become a reliable time appliance.

Architecture

Time authority, separated from its consumers

Absurdly Accurate Clock is an embedded timing system built around the Raspberry Pi Pico 2 and its RP2350 controller. The C++ firmware receives GPS serial data and a separate pulse-per-second (PPS) signal, qualifies their relationship, and maintains an authoritative UTC state. A Posiflex PD-2200 vacuum-fluorescent display presents that state; a separate interface exports it to an ESP32 network-time appliance.

The central decision is to separate time authority from its consumers. The Pico owns the accepted UTC second and its validity. The display derives a local-time presentation from a copy of that state, while the network interface publishes a read-only snapshot. Neither can set the clock. The Pico runs without an ESP32 or USB host, and the hardware-specific display layer can be adapted without replacing the timekeeping core.

“Authoritative” describes ownership within this system, not an independent realization of UTC. The clock still depends on the receiver’s UTC labels and pulse configuration. Its engineering focus is deciding when that information is usable, associating it with a boundary, and withdrawing validity when the association cannot be trusted.

The diagram follows the clock’s timing and presentation boundaries. GPS supplies UTC labels and PPS timing; the Pico 2/RP2350 qualifies those inputs and maintains authoritative time; the display subsystem drives the Posiflex VFD; and the ESP32 exports qualified time to the network.

GPS SOURCE / QUALIFICATIONAUTHORITATIVE TIMING CORENETWORK EXPORTACTIVE GPS ANTENNASMA · magnetic baseu-blox NEO-7-class GPSUART: RMC UTC / date labelPPS: precise 1 s boundaryNMEA arrival does not advance the system clock.Pico associates the label with the PPS epoch.VERIFIED PHYSICAL HARDWARERMC / PPS qualificationRMC completesPPS nPPS n+1Bench observation: completion ≈ +140 ms after preceding PPS.Qualification window: start ≥20 ms · complete ≤900 msno boundary crossing.UART0 · RMCPPS → GP2Raspberry Pi Pico 2 / RP2350Central timing authorityRMC parserUTC + date labelPPS captureminimal ISRLabel / PPS qualificationsequence · cadence · validitypolicy in normalfirmware contextAUTHORITATIVE UTCPPS-driven second stateGPS VALID · PPS PRESENTPPS LOCKED · UTC VALIDRP2350 watchdog4 s hardware watchdogreacquire validityafter resetDISPLAY PRESENTATIONPRESENTATION / HARDWARE DRIVERPresentation stateUTC / US timezonerolling secondsDisplay rendererdisplay-agnosticboundaryPD-2200 driverNoritake command modeUART1 TX · TTL UARTMAX3232TTL→RS-232Alternate display driverfuture / alternateimplementationPosiflex PD-2200 VFD2 × 20 character · RS-232 · Noritake mode12:34:56GPS+ PPS+ SAT 08~50% brightness · PPS-synchronized presentationRS-232ESP32 / ESP-WROOM-32Companion network time appliancePico remains authoritySPI Protocol v1MODE 1 · 100 kHz · 40 bytes“ACT1” · CRC-32Qualified TIME_SYNCPico → ESP32 · accepted PPS boundarysoftware delayed ≤5 msESP32 controllerPico peripheralSPITIME_SYNCLAN / NTPnetwork time exportCS asserted → immutable packet snapshot→ TX FIFO preload (SSE disabled) → enable SSESPI recovery/reset while deselectedTX alignment hardware verified12 V power input / distribution12 V → VFDregulated low-voltage rail →Pico / GPS / interface electronicsRegulator topology intentionally shown generically.12 VHARDWARE VERIFIEDGPS/PPS lock · PPS-driven UTC · serial VFD · watchdog recovery · 40-byte SPI transport · CRC-valid ACT1 · TIME_SYNC phase association · ESP32 Pico-authority qualification
Primary system boundary shows built/tested/documented functionality. Dashed elements indicate replaceable or future presentation-layer work; no OCXO is shown as installed.Open full-size diagram ↗

Timing

UTC acquisition and qualification

The serial message names the second; PPS marks its boundary. Setting time when an NMEA sentence finishes would attach UTC to message delivery and serial transmission delay. Instead, a short interrupt timestamps each rising PPS edge and increments a capture sequence. The main loop takes a coherent copy and performs parsing, calendar conversion, and qualification outside the interrupt.

The receiver contract assumes a 1 Hz navigation solution with a UTC-aligned rising pulse and a GPRMC sentence for that same second arriving afterward. The firmware sends no receiver configuration commands. Association requires a checksum-valid, active RMC with valid date/time and no nonzero fractional seconds. Consecutive pulses must be 900–1100 ms apart; sentence consumption must begin at least 20 ms after the associated pulse and finish within 900 ms, without crossing another capture.

Two labels on consecutive captures must advance by exactly one UTC second. The following qualifying edge commits the second label plus one. After lock, qualifying PPS edges advance the epoch while fresh labels continue checking it. An RMC arrival never advances or rewrites the authoritative second. A conflicting label clears lock, and a correction requires reacquisition before it is committed at another edge.

The stored epoch is a signed 64-bit Unix-second value. It is not a continuously interpolated fractional UTC clock. The acquisition windows are rejection policies, not accuracy specifications; even consistent labels cannot expose a receiver stream that is always one whole second late. The documented approximately 140 ms RMC completion offset supports the association window, but does not independently verify absolute UTC alignment.

Display

Display and local-time presentation

The reference build drives a separately powered Posiflex PD-2200 in Noritake mode over 9600-baud, 8N1 UART through a MAX3232 RS-232 interface. A debounced button selects UTC, Eastern, Central, Mountain, or Pacific time. Contemporary U.S. daylight-saving rules are applied only during rendering; the authoritative state and exported timestamps remain UTC. Selection resets to UTC at boot.

The upper row shows the selected zone and time; the lower row reports GPS validity, PPS presence, and a supplemental satellites-used count. The digit after the decimal point is a PPS-synchronized visual indicator, not tenths of UTC. It holds zero for the first half-second, then progresses toward nine before the next pulse. Display transmission and device response are separate from the timing boundary.

Output is bounded to one UART byte per service call and updates changed fields rather than queuing animation frames. This unit’s reported space-to-zero behavior led to a startup clear followed by positioned writes that leave blank cells unwritten. Reported incorrect hour glyphs led to contiguous two-character hour writes instead of directly addressing the ones cell. That accommodation is implemented, but its physical effectiveness and the underlying fault are not established. The output cache records UART acceptance, not display readback.

Network interface

A read-only network-time boundary

The ESP32 companion’s architectural role is network-time/NTP service. It controls SPI transactions, while the Pico remains the time source. Native SPI1 operates as the peripheral in mode 1 at the documented, hardware-qualified 100 kHz rate. Incoming MOSI bytes are discarded: there is no command path for network observations to set or discipline Pico UTC.

Protocol v1 explicitly serializes a 40-byte packet containing the UTC epoch, quality flags, publication and boundary sequences, synchronization information, satellite status, and CRC-32. The publisher prepares a complete buffer; chip-select assertion copies it into an immutable transaction snapshot. A read therefore cannot combine fields from different publications, and repeated reads do not represent new seconds. CRC detects corruption, not authentication.

A separate TIME_SYNC output announces a newly processed, qualified boundary only when UTC is valid, PPS is present and locked, and processing is no more than 5 ms late. Late edges are suppressed. The packet reports the delay from the PPS capture timestamp to a timer read immediately before the GPIO transition, allowing the consumer to subtract that interval from its captured TIME_SYNC time. This is a software-delivered reference, not a zero-latency copy of GPS PPS or a calibrated precision output.

The consumer must wait for publication, validate the packet and quality flags, and match its captured edge to the synchronization and boundary sequences. Missing edges, reboot, invalid data, or ambiguous reads break that association. The repository records hardware validation of ESP32 packet acceptance and phase association; this establishes the source interface, not an end-to-end NTP accuracy result.

Failure handling

Validity, bounded work, and recovery

GPS validity, PPS presence, association lock, and UTC validity are separate state concepts. Missing PPS invalidates time after 1.5 seconds; three seconds without valid RMC or a usable association also clears lock. Skipped captures and invalid cadence are rejected. The last epoch remains stored after invalidation, but it is no longer authoritative: the display shows unavailable time, the packet clears UTC validity, and no new qualified TIME_SYNC edge is emitted.

The cooperative loop bounds GPS parsing, diagnostic drainage, and display output. If GPS servicing is delayed by more than 20 ms, parsers and association are reset and buffered input is drained, preventing known backlog from acquiring misleading fresh reception timestamps. USB diagnostics use a bounded queue that drops whole messages rather than waiting for an absent host. These limits reduce interference; they are not a measured worst-case execution-time guarantee.

A 4,000 ms RP2350 hardware watchdog is armed early in startup and fed only after all recurring loop services finish. Interrupts and timers do not feed it. Ordinary reference loss, invalid UTC, display backpressure, or an absent ESP32 do not intentionally trigger a reset. Recovery follows normal startup and reacquires time quality; no validity is preserved across reboot. USB reset markers and a faster heartbeat identify a watchdog boot. The README supplies a physical watchdog test procedure, rather than a recorded bench acceptance result.

Current state

Engineering evidence and remaining limits

Hardware records distinguish successful transport from inferred causes. The VFD bring-up verified the Pico UART output on an oscilloscope and displayed test characters through the MAX3232. It also established misleading TTL-header labels and a required DB9 transmit-to-receive crossover for the tested module/display combination; those findings are specific to that hardware.

SPI investigation separated a chip-select/reset feedback storm from a later first-byte alignment fault. The production lifecycle resets the peripheral only while deselected, keeps controller-owned signals input-only, and primes the transmit FIFO before enabling it. Final acceptance records correctly aligned, CRC-valid packets and successful ESP32 phase association. Startup short-transfer and chip-select fault counts remained in the cumulative totals, while the recorded steady-state intervals added full transactions without further transport-error increments. The exact analog reset transient and prior internal shifter state were not directly captured.

Recorded on hardware

  • Pico UART output to the VFD verified on an oscilloscope; test characters displayed through the MAX3232.
  • Correctly aligned, CRC-valid SPI Protocol v1 packets (final acceptance).
  • ESP32 packet acceptance and TIME_SYNC phase association.

Host-tested

  • Timebase policy and presentation.
  • Serializer retries, independent packet vectors, and corruption rejection.
  • Transport ordering against a register model.

Host tests complement the bench records; they cannot establish electrical timing, optical display behavior, or absolute accuracy.

Not established / out of scope

  • No characterized absolute timing-error budget or measured end-to-end NTP accuracy.
  • Physical effectiveness of the VFD hour-glyph accommodation.
  • A recorded watchdog bench acceptance (the README supplies the procedure).
  • OCXO holdover remains future work; leap-second insertion/deletion is unsupported.
  • The current RMC parser accepts years 2000–2099 and rejects second 60.

Contact

Complete the security check to send your message.