dylanzickus.com / Overengineered RTC Clock

Overengineered RTC Clock

Arduino Mega + DS3231 RTC in a custom 3D-printed purple enclosure. Brute-force calendar math including DST. Featured a scrapped side-scrolling game ("Spike and Dude").

Overview

A standalone, feature-rich digital clock built from the ground up using an Arduino Mega and a DS3231 Real-Time Clock (RTC) module. The system was designed to display current time, calculate the exact time elapsed since a specific past date, and count down to future recurring anniversaries.

What makes it worth documenting is the evolution. The project started as a software exercise in brute-forcing complex calendar math without external libraries, morphed into a battle against strict hardware memory limits, and ended as a hands-on lesson in 3D fabrication and physical assembly.


Hardware


Iteration History

Stage 1 — Brute-Force Calendar Math (rtcTest.ino / rtcTimeSince.ino)

The initial firmware was developed before taking any formal C programming classes. Instead of relying on standard Unix epoch libraries, all time-delta calculations were written from scratch. The system had to manually account for varying month lengths, leap years, and Daylight Saving Time (DST) every single second.

bool isStartDST (DateTime dt) {
  return !dst &&                                 // dst didn't start yet
          dt.dayOfTheWeek() == 0 &&              // it is a sunday
          dt.day() >= 8 && dt.day() <= 14 &&     // second sunday of the month
          dt.month() == 3 &&                     // it is march
          dt.hour() == 2 &&                      // 2 am
          dt.minute() == 0 && dt.second() == 0;  // on the dot
}

This brute-force approach was highly educational but computationally repetitive. To ensure the time didn't drift despite the heavy math, the DS3231 RTC was integrated to anchor the logic.


Stage 2 — Feature Creep & The Memory Wall (rtcDiffScreens.ino)

With the math working, the project expanded to include randomized, highly personalized greetings combining arrays of prefixes and nicknames.

Two realities of embedded hardware surfaced immediately:

SRAM Fragmentation. On an 8-bit AVR microcontroller, large arrays of string literals rapidly devour dynamic memory. The system quickly hit 60% memory capacity, risking heap fragmentation and silent crashes.

Custom Array Sizing. To squeeze the messaging system in without crashing, standard library functions were abandoned. The fix was writing custom indexing loops to manually calculate array lengths on the fly:

int calc_prefixes_len (char last[5]) {
  int i = 0;
  for (; prefixes[i] != last; i++) {}
  return i + 1;
}

Stage 3 — The Ambition of "Spike and Dude" (spike_and_dude.ino)

Wanting to push the 20x4 LCD to its limits, a Chrome-dinosaur-style side-scrolling obstacle game was developed as an alternative clock mode. It featured real-time jump physics, custom byte-array character sprites, tick-rate acceleration, and EEPROM-backed high scores.

// Custom byte-array character sprites
uint8_t spike_bits[] = {0x00, 0x00, 0x04, 0x04, 0x04, 0x0e, 0x0e, 0x1f};
uint8_t dude_bits[]  = {0x0e, 0x0e, 0x04, 0x0e, 0x15, 0x04, 0x0a, 0x11};

The Reality Check: While the game was successfully built and tested as a standalone script, the memory footprint of the brute-force calendar math and the personalized string arrays left absolutely no room for the game loop. "Spike and Dude" had to be cut from the final firmware to ensure the clock remained stable.


Stage 4 — Physical Fabrication (The Purple Enclosure)

The final stage was moving from a breadboard to a permanent physical artifact. This was a first attempt at 3D CAD design. Translating digital dimensions to a physical purple trapezoidal enclosure required accounting for tolerances, mounting points, and wire routing.

It took multiple expensive, time-consuming print iterations just to align the bottom screw holes correctly — a harsh initiation into designing for assembly. Internally, the lack of a custom PCB meant relying on a soldered, superglued rat's nest of wires, permanently sealing the project in its final state.


Architecture Diagram

┌─────────────────────────────────┐
│          Arduino Mega           │
│  - Brute-force calendar logic   │
│  - Custom array memory management│
└────────────┬────────────┬───────┘
             │ I2C        │ GPIO / Analog
             ▼            ▼
┌──────────────────┐  ┌──────────────────┐
│  DS3231 RTC Mod  │  │  Physical UI     │
│  (Timekeeping)   │  │  - Push Buttons  │
└──────────────────┘  │  - Photoresistor │
                      └──────────────────┘
             │ I2C
             ▼
┌─────────────────────────────────┐
│      20x4 Character LCD         │
│      (Adaptive Backlight)       │
└─────────────────────────────────┘

Status & Next Steps


Tech Stack

Layer Technology
Microcontroller Arduino Mega
Firmware C++ (Arduino Framework) — Wire.h, LiquidCrystal_I2C.h, RTClib.h
Hardware DS3231 RTC, 20x4 I2C LCD, Push Buttons, LDR
Fabrication Custom CAD, 3D Printed (Purple PLA/PETG)