DOC. RMPW-TC-HIST REV. 14.0 CLASS. BUILD LOG ORIGIN: ROCHDALE, UK STATUS: IN SERVICE
___________________________ __|___________________________|__ / ============================= \ / . RED . ORANGE . GREEN . \ /___________________________________\ | [== =] [ = = = = ] [ = = = = ] == | | [DEST ] [ PRESENT ] [LAST DEP ] | \ ====================================/ \__________________________________/ || || [##] [##] == 88.0 mph ============
Time Circuits Project
THE BUILD LOG
From a Tangle of Wires to v14.0 · March 2025 → Now
"From a tangle of wires with hardcoded numbers, to a custom PCB with OTA firmware, a wireless keypad, and an epic time-travel sequence. One year. One pair of hands. Great Scott."
CHAOS ERA→ v1.0→ +RTC→ v6.x→ v9.1→ v9.8→ v10.2→ v10.6→ v10.10→ v11→ v14.0 ★
~12Months Building
2PCB Revisions
15+Firmware Versions
11KBv1.0 Size
85KBv14.0 Size
2ESP32 Units
Chaos Era — The Beginning
V0
The Very First Build~MAR 2025
A Tangle of Wires and a Dream
No version number. No settings page. No buttons. Just an ESP32 on a breadboard, a cluster of TM1637 displays wired together, and hardcoded numbers that showed up on the segments. If you wanted to change what time was displayed, you edited the code and reflashed.

Everything was direct-wired — display modules, power, data lines — in a configuration that worked, mostly, as long as you didn't breathe on it too hard. There was no WiFi setup, no NTP sync, no RTC. The time was whatever was in the code. The whole thing lived on a breadboard surrounded by a nest of DuPont leads.

But the displays lit up red, orange, and green. And it looked like Back to the Future. That was enough.
BreadboardHardcoded Everything No ButtonsNo SettingsWire Chaos
Learning to Code — Adding WiFi
~v4
Pre-v1.0 DevelopmentSPRING–SUMMER 2025
Learning to Code, One Feature at a Time
Over the months that followed, Rob learned to code properly — not from scratch, but from reading, experimenting, and working at each problem until it gave. Each problem became a lesson.

WiFi arrived first — using WiFiManager so the clock could connect to a home network. Then NTP for time sync. Then a basic setup page where you could at least change what date was showing without reflashing. Then a dimming schedule so the clock didn't glow at 3am.

The early attempts had real problems. Without an RTC, unplugging the clock reset everything. WiFi down on boot meant the clock didn't start at all — the "zombie boot" problem. The displays flickered sometimes. Every fix revealed the next thing to fix.
Learning PhaseWiFiManager Added Basic Setup PageNTP SyncFirst Dimming
First Stable Firmware
1.0
Version 1.0 — First Stable Commit1 OCT 2025
v1.0 Stable — The First Commit Worth Keeping
The first firmware good enough to be called stable and saved. Clocks_v1.0_Stable.ino — 11.5KB of working ESP32 code.

WiFi via WiFiManager. NTP via pool.ntp.org. Nine TM1637 displays, all three rows working with shared CLK architecture. NVS storage keeping settings across power cycles. A basic dimming schedule (22:00–07:00). Hardcoded film defaults: Red = Oct 26 1985, Orange = Nov 12 1955. The button could trigger a factory reset with a 3-second hold.

What it didn't have yet: any kind of RTC, no web UI, no settings you could change without reflashing. But it ran, it stayed running, and it kept the right time as long as WiFi was available.
📄 11,506 bytes
First Stable CommitWiFiManagerNTP Sync NVS StorageBasic DimmingFilm Defaults
RTC
RTC Added6 OCT 2025
The Clock Gains a Memory
Five days after v1.0: the DS3231 RTC arrived. Battery-backed timekeeping meant unplugging the clock no longer reset it to zero. The time survived power cuts, router outages, and travel. Wire.h and RTClib.h appeared in the includes. The firmware jumped from 11.5KB to 20KB overnight — half the size again just to handle one chip, but worth every byte.

This was the first of what would become a pattern: one new piece of hardware → significantly more firmware complexity → significantly better behaviour.
📄 20,254 bytes+8.7KB from v1.0
DS3231 RTCBattery BackedSurvives Power Cuts
PCB Era — From Wires to Silicon
PCB1
First Custom PCB DesignedNOV 2025
The First PCB — And It Blew the Clocks
The wire nest was never going to scale. A custom PCB was designed in KiCad — BTTF_Time_Circuit_Clock_PCB, targeting a 40mm × 200mm footprint with the ESP32 mounted vertically. Three KiCad backup snapshots exist from the evening of 9 November 2025, which suggests the design was iterated hard that night.

The PCB was ordered. It arrived. It was soldered up.

It kept blowing the display modules.

The power path wasn't properly protected. Without a polyfuse, TVS diode, and proper input conditioning, voltage spikes or reverse polarity events could reach the displays directly. Several TM1637 modules were casualties. The board was a lesson in why power integrity matters on custom hardware — a lesson learned the expensive way.
⚠ PCB v1 — Cause of Failure
No input protection on the 5V rail. No polyfuse. No TVS diode. Voltage spikes propagated directly to display VCC pins. Result: dead TM1637 modules.
KiCad Design40×200mm TargetVertical ESP32 Mount ⚡ Failed — Blew Displays
v6.x
200µs Fix — The Ghosting Problem29 NOV 2025
v6.1 / v6.2 — The 200µs Fix That Saved the Displays
Even before the PCB power problem was fully resolved, the firmware was already fighting a different battle. The display modules were showing random symbols — ghosting digits, scrambled segments, characters that weren't supposed to be there.

Root cause: the TM1637 bit-bang communication was running too fast. On a breadboard with short wires, fast data was fine. On a PCB with longer traces, the signal integrity degraded enough to confuse the display controllers.

Fix: TM1637Display red1(red_CLK, red1_DIO, 200); — a 200 microsecond software delay injected into the TM1637 driver constructor. It slowed the communication to a speed the hardware could reliably receive. The comment in the commit says it all: "TIMING FIX: Added 200us delay to display constructors to fix 'random symbols'".

This 200µs delay has been in every version since. It's part of the DNA of the clock.
📄 26,166 bytes+6KB from RTC version
200µs Bit-Bang DelayGhosting Fixed PCB Layout VerifiedGREEN3 = Pin 32 Confirmed
PCB2
PCB Ver 2.1 — Designed in EasyEDANOV–DEC 2025
PCB Ver 2.1 — The Stable Board That Ships
After the first PCB failure, the design moved from KiCad to EasyEDA Pro — and the whole power path was rethought. The Ver 2.1 board added a polyfuse, TVS diode, and SS34 protection diodes on the 5V input. JST-PH connectors replaced direct solder pads for the display cables. An MP1584 buck converter module provided clean regulated power. A proper 5V auxiliary screw terminal for accessories.

The EasyEDA project went through at least 16 revision saves (v55 through v71 and beyond in the backup files) — evidence of careful, iterative refinement before the Gerbers were sent to JLCPCB.

It worked. The clocks stayed alive. This board has shipped with every unit since.
✓ PCB Ver 2.1 — What's On It
ESP32 DevKit V1 (vertical) · 9× TM1637 via JST-PH · DS3231 RTC · MP1584 buck module · Polyfuse + TVS + SS34 input protection · AM/PM LEDs with 330Ω resistors · PCF8574T GPIO expander footprint · 5V screw terminals
EasyEDA ProPolyfuse + TVS ProtectionJST-PH Connectors MP1584 Buck Converter✓ Shipping Board
v9 Era — The Firmware Gets Serious
9.1
v9.1 Stable — First Major Milestone16 DEC 2025
v9.1 — The First Milestone Worth Naming
After months of incremental builds, v9.1 was the first version that felt like a proper product milestone. The folder name says it: CLocks_v9.1STABLE_USE_THIS. Fast boot logic: the RTC updates the displays instantly on power-up, before WiFi even attempts to connect. If WiFi was saved, it tried for 3 seconds then fell back to RTC. If factory reset, it froze on 1985 until setup was complete. OTA update capability arrived — firmware could now be updated wirelessly, without opening the case or touching a cable.

The 1985 defaults were baked in as a deliberate fail-safe: factory reset gives you Oct 26, 1985 on the red display — the day Marty arrived in the future.
📄 29,955 bytes
Fast Boot (RTC First)OTA Updates 1985 Fail-SafeWiFi Timeout + Fallback
9.1+
Non-Blocking Rewrite30 DEC 2025
The Firmware Gets a Proper Architecture
The end of December brought a serious push, and the results were immediate and visible in the file sizes: two new builds (29.7KB and 34.2KB) produced in the same day.

Non-blocking loop timing replaced the old delay-based approach — the clock could now handle button presses, WiFi events, and display updates simultaneously without missing anything. The fast boot logic was refined. RTC as a reliable backup became more robust. The architecture started to look like production code rather than a prototype.
📄 29–34KBNon-blocking rewrite
Non-Blocking LoopRTC Fallback HardenedProduction-Grade Code
9.8
v9.8 — The Web Portal Arrives5 JAN 2026
v9.8 — The Firmware More Than Doubles in Size
Claude_clocksV3webserver.ino — 60.8KB. Previously the largest file was 34KB. The web configuration portal arrived all at once: a full-page dark UI with sliders for brightness, fields for destination time and last departed time, dimming schedule controls, timezone and DST settings. Everything saved to NVS instantly. The comment in the file header: "STATUS: PRODUCTION READY".

The library count in the includes jumped too: WebServer.h and ESPmDNS.h joined the list. The clock was now a web server as well as a display unit. You could reach it at http://bttf.local — or its IP address — and configure everything from your phone.

Film defaults locked in code: Red = Oct 26, 1985 · Orange = Nov 5, 1955. Exactly as on screen.
📄 60,828 bytes+26KB in one session
Full Web PortalBrightness SlidersDimming Schedule Timezone + DSTmDNS (bttf.local)Film Defaults Locked
v10 Era — Production Polish
10.2
v10.2 — The UI Gets the DeLorean Treatment23 JAN 2026
v10.2 — Dark. Amber. BTTF.
The web portal looked like a settings page. Now it looked like part of the prop. Dark backgrounds, amber accents, styled to match the hardware it was controlling. Single click = time travel (the sequence at this point was a scramble-and-return). Double click = show IP address on the displays for 10 seconds. Hold 3 seconds = factory reset. Brightness spoofing implemented: the red and orange TM1637 modules max out at brightness level 5, but the UI shows it as 10 — multiplied to match the green row's 1–7 scale, so all three appear equally bright to the user at the same setting.
📄 47,903 bytes
Dark Amber UISingle/Double/Hold Buttons Brightness Spoofing12/24hr Format
10.4
v10.4 — The Epic SequenceJAN 2026
v10.4 — Six Phases. Twenty-Five Seconds. Great Scott.
The time travel button had been triggering a scramble-and-return. That was fine. This was different. A six-phase choreographed sequence built to match the film: scanner sweep racing across all nine displays · 1.21 gigawatts flashing in lightning across all three rows · the speed counter building from 0 to 88 · then fireworks — random date explosions going off simultaneously on every display · finally a cascade reveal, one display at a time, back to your saved times. Twenty-five seconds. Nothing on the market did this.

This is the version that made people stop and stare.
6-Phase SequenceScanner Sweep1.21G Flash 0→88 CounterFireworksCascade Reveal~25 Seconds
10.5
v10.5 — Standalone ModeJAN 2026
v10.5 — No WiFi? No Problem.
Not everyone wants to connect their Back to the Future prop to their home router. Standalone mode: on first boot, choose Standalone instead of WiFi Mode. Set the time once. The RTC keeps it running indefinitely — no internet, no network, no IP address to remember. Perfect for convention displays, showcase builds, or anywhere that just needs a prop that works and stays working.
Standalone ModeRTC Only No WiFi RequiredConvention Ready
10.6
v10.6 — WiFi Setup Fix26 JAN 2026
v10.6 — 70KB and Fixing the WiFi Setup Flow
The firmware crossed 70KB. A WiFi setup portal bug was fixed — a race condition in the first-boot flow meant that after selecting "Setup WiFi", the portal would sometimes not actually start. Fixed with a pendingWifiSetup flag and a deliberate restart into startConfigPortal() mode. The disconnect call was also changed to properly clear the ESP32's stored WiFi config when needed.
📄 69,903 bytes
WiFi Setup Portal FixpendingWifiSetup FlagRestart-Into-Portal Logic
Shipping Era — Real Customers
10.8
v10.8 — Web OTA + Customer Fixes26 JAN 2026
v10.8 — 85KB, No More USB Cable Ever
The firmware hit 84.8KB — nearly eight times the size of v1.0. The biggest addition: a web-based firmware update screen built directly into the first-boot setup portal. Customers could now update their firmware by connecting to BTTF_CLOCK, navigating to the Update option, selecting a .bin file from their phone or computer, and watching it install over WiFi. No USB. No Arduino IDE. No opening the case.

This was the version that started shipping to real customers. Real clocks. Real homes. Real edge cases that a test bench never surfaces.
📄 84,840 bytes7.4× larger than v1.0
Web OTA UpdatesCustomer BugfixesFirst Units Shipped
10.9
v10.9 — David's BuildFEB 2026
v10.9 — A Bespoke Build for a Full-Scale DeLorean
Customer David is building a full-scale DeLorean prop. His build had its own trigger system and needed the time travel sequence to be simpler — a quick two-phase scramble-and-return rather than the full 25-second epic. v10.9 was built specifically for him, with Epic mode swapped out for a streamlined sequence that fitted his integration. The first sign that the firmware was flexible enough to be customised per customer.
Bespoke BuildSimple 2-Phase ModeFull-Scale DeLorean Prop
★
v10.10 — The Production Standard★ Ships in Every BoxFEB 2026
v10.10 — The One That Goes in Every Box
A critical bug caught and fixed: saved brightness settings were being silently overwritten on every boot. The display test sequence ran after settings loaded — because it came later in setup() — and it reset brightness to the hardcoded default, overwriting the values NVS had just loaded. Fix: enforce the correct boot order. displaySegmentTest() must run before initializeDisplays().

Live preview endpoint also added: adjust brightness in the web portal and the clock responds in real time before you save. No more guessing what brightness 4 looks like.

This became the production standard. Every unit ships with v10.10.
Brightness Persistence FixBoot Order Corrected Live Preview Endpoint★ Production Firmware
Expanding the Hardware — Keypad Prototype
v11
v11.0 — Keypad Prototype Working17 MAR 2026
v11.0 — A Second ESP32 Enters the Build
A dedicated keypad controller — a second ESP32 with five backlit buttons: RED for time travel, GREEN for brightness cycling, YELLOW for last departed time, WHITE for destination time, CLEAR to reset input. 12-digit input (MMDDYYYYHHMM then press action) replicates how the DeLorean's keypad worked in the film.

The two units communicate entirely over WiFi. The clock broadcasts its IP every 5 seconds via UDP on port 4210. The keypad listens for the broadcast, discovers the clock automatically, and fires HTTP API calls to trigger sequences and set times. No physical wires between them. No pairing ceremony. It just finds the clock and works.

A DFPlayer Mini for authentic sound effects is also in the circuit, waiting for the right microSD card. Seven MP3 tracks planned: startup chime, destination set, time travel sequence, present set, last departed set, error/clear, keypress beep.
Second ESP325 Backlit ButtonsUDP Broadcast Discovery Wireless HTTP API12-Digit InputDFPlayer SoundNo Physical Cables
Today — v14.0
NOW
v14.0 — The Most Capable Build Yet★ Latest18 MAR 2026
v14.0 — Three WiFi Bugs, a Glowing Frame, and 0→88
Three separate WiFi stability bugs found and squashed. The worst one: WiFi.disconnect(false, true) — a single boolean parameter that told the ESP32 to wipe its saved WiFi credentials every 30 seconds. The clock was silently nuking its own settings on every reconnect attempt, then wondering why it couldn't reconnect. Fixed. Escalating reconnect logic added: 30 seconds → WiFi.reconnect(), 5 minutes → hard WiFi reset, 10 minutes → full restart.

The speedometer rebuilt from scratch. The previous version jumped directly to a calculated speed — skip to 15, skip to 23, skip to 40. No sense of acceleration. The new version increments by exactly 1 per step through five speed zones: 500ms below 10 · 160ms to 20 · 50ms to 30 · 25ms to 50 · 18ms to 88. Every number appears. It genuinely feels like a car flooring it.

A glowing picture-frame border now lights up all eight perimeter displays during the 88mph phase. Static, instant, no animation — the discovery that the 8-display gap animation was eating 112ms per update and making all speed zones above 20mph appear identical. Removing it entirely was the fix.

Dimming now fades in both directions — down at night, back up in the morning. Static IP option added for customers whose routers keep reassigning addresses.
3 WiFi Bugs FixedEraseAP Bug (Single Boolean)Escalating Reconnect Static IP OptionPicture-Frame Border5 Speed Zones Every Number 1→88Fade Up + Fade Down
⚡ The Complete Feature List — v14.0
9 seven-segment displays — red, orange, green rows
Internet NTP time sync, automatic Daylight Saving
Full web control panel from any device
Epic TT: scanner → 1.21G → 0–88 → fireworks → reveal
Glowing picture-frame border during 88mph phase
Epic or Simple mode — switchable in portal
Smooth dimming — fades down at night, up at dawn
Fixed IP option — never loses its address
Automatic WiFi recovery — retries and self-restarts
Standalone mode — RTC only, no WiFi needed
OTA firmware updates — no cables, just a browser
Wireless keypad prototype — 2nd ESP32, 5 buttons
◈ What's Coming Next
PCB Ver 2.1 with PCF8574T expansion — AM/PM LEDs, expansion slots, no LED switches on the back panel
DFPlayer Mini sound effects — 7 MP3 tracks including time-travel sequence audio
Keypad production build — current prototype confirmed working
World clock mode — red/orange as live secondary time zones (customer request)
"If you put your mind to it, you can accomplish anything."
— Marty McFly · and the entire philosophy behind this project