Close
0%
0%

Clock 24

A fully custom 24-quadrant clock inspired by Humans since 1982 ClockClock 24

Similar projects worth following
Inspired by the "Humans since 1982" installations, I built Clock²⁴, my own fully custom kinetic clock. This from-scratch project uses 24 quadrants and 48 3D-printed hands to "draw" the time in a 2x2 layout. Every aspect is custom-made: from the wooden frame, based on my own sectional design, to the custom PCBs I engineered to manage the motors. The system's brain is a master/slave architecture, using an ESP32 master handling WiFi and time sync, which commands two Arduino Mega slaves that orchestrate the movement of the hands.

0. Introduction

Clock 24 is my first comprehensive project that combines woodworking, electronics design, and coding into one build.

Since this is still a work in progress, the build details, wiring, and code are far from final and are subject to change as I refine the design.

I would be happy to hear any feedback, advice, or suggestions you might have to help me improve it.

1. The Build: Frame & Display

I wanted a simple and modern look

  • The Frame: I designed a custom multi-level profile to house the mechanism, glass, and backing. The profile was milled from wood and assembled by a professional framer with 45° cuts. The external dimensions are 53.3 cm x 73.3 cm.
  • The Face: The front panel is a simple sheet of plexiglass, cut to size and drilled manually to accommodate the 24 motor shafts. It is painted with a matte anthracite spray to minimize reflections and maximize contrast with the white hands.
  • The Hands: I custom designed and printed the 48 hands.

2. The Mechanics: Motors & "Parking"

  • Actuators: The clock uses 24 BKA30D-R5C dual stepper motors (clones of the VID28-05). These are crucial as they allow for continuous 360° rotation.
  • Visual Logic: As the original ClockClock 24 does, when a quadrant is not needed to form a digit (e.g., the empty space next to a "1"), the hands move to a "parking position" (diagonal 45°).

3. Electronics: Custom PCBs & Modular Architecture

To controlling the 48 stepper motors I designed two types of custom PCBs:

  • Driver Boards (x12): Each board manages two dual-motors (4 hands) using the AX1201728SG stepper driver chip.
  • Distribution/Slave Boards (x2): These act as "motherboards" for each side of the clock. Each one hosts an Arduino Mega 2560 and connects to 6 Driver Boards via IDC cables.

4. The "Open-Loop" Challenge & Power Backup

The system operates in open-loop: there are no Hall sensors or magnets to detect the absolute position of the hands. The software assumes the hands are where it told them to be.

  • Manual Homing: On the very first startup, all 48 hands must be manually positioned vertically (12 o'clock).
  • UPS Solution: To prevent the clock from losing calibration during a power outage, the two Arduino Mega Slaves are powered via Adafruit PowerBoost 500C modules acting as a UPS (battery backup). This ensures the Slaves never lose their memory of the hands' positions, even if the main wall power (powering the ESP32 Master) goes down.

5. Software Architecture

The code is split into a Master/Slave configuration:

  • Master (ESP32): Handles WiFi, NTP time syncing and runs a TCP/Telnet server for remote commands. It sends formatted time strings to the slaves via serial.
  • Slaves (Arduino Mega x2): The workload is split vertically.
    • Left Slave: Handles the first hour digit and first minute digit.
    • Right Slave: Handles the second hour digit and second minute digit.
    • They use a lookup table to translate digits (0-9) into specific target angles for the 12 hands composing that digit.

6. Maintenance App: "24Client"

I am currently developing a dedicated Android app named 24Client to serve as a remote control and maintenance tool. It connects to the Master via Telnet and will provide a UI to select specific quadrants and hands. Its primary purpose is fine-tuning:

  1. Disaster Recovery: If the batteries completely drain, the system loses its zero position. The app will allow for re-calibrating the hands remotely without disassembling the frame.
  2. Minor Adjustments: It allows for correcting small mechanical misalignments or "drift" that might occur over time, ensuring the display remains as sharp as possible.

PXL_20260115_081031239.MP.jpg

JPEG Image - 3.81 MB - 01/22/2026 at 10:35

Preview

PXL_20230122_141158845.jpg

Painting of plexiglass panel

JPEG Image - 3.15 MB - 11/02/2025 at 09:50

Preview

PXL_20230416_125508102.jpg

Early wiring and powering of the distribution and driver boards

JPEG Image - 2.94 MB - 11/02/2025 at 09:50

Preview

PXL_20230216_081404236.jpg

Hand-drawn sketch of the frame design

JPEG Image - 2.98 MB - 11/02/2025 at 09:50

Preview

PXL_20221203_093459125.jpg

Driver boards installed to the main panel

JPEG Image - 2.37 MB - 11/02/2025 at 09:50

Preview

View all 19 files

  • Structured communication protocol and redesigned 24Client app

    Francesco Comi03/22/2026 at 17:05 0 comments

    Firmware (Master + Slave)

    Major refactoring of the Telnet communication protocol between the ESP32 Master and the 24Client Android app.

    All responses now use structured prefixes, making it straightforward for the client to parse and distinguish between data, confirmations, and errors:

    • OK <command> — command executed successfully
    • ERR <command> <message> — command failed
    • LOG <text> — informational message
    • STATUS <key>=<value> — system status (from DEBUG)
    • POS <slaveId> <values> — hand position data

    Other changes:

    • Command parsing rewritten with exact matching instead of startsWith, preventing false matches.
    • Changed the FINETUNE command format from a cryptic positional encoding (010+5.00) to a readable FINETUNE=R,C,L,D (Row, Column, Lance, Degrees).
    • Removed unused commands (SETSPINSETCOUNTSETMINSETHOU) and associated variables (countModespinModehoursHandsActiveminutesHandsActive) from both Master and Slave.
    • Fixed an unsigned integer underflow bug in setTimeInSeconds() that could cause an ~8 hour time display error under certain conditions.
    • Improved time offset precision from seconds to milliseconds, eliminating a potential ~1s truncation error.
    • SETNTP now forces an immediate display update instead of waiting for the next minute change in the loop.

    Android App (24Client)

    Completely redesigned the UI, splitting it into two screens:

    Main screen:

    • Quick-access buttons for all common commands (SETNTP, SETHOME, SETZERO, GETPOS, LED ON/OFF, DEBUG, UPTIME) — one tap to send.
    • Free text input for manual/debug commands.
    • Terminal-style output area with dark background, green text, and auto-scroll.
    • FINETUNE button opens the dedicated calibration screen.

    FineTune screen:

    • 6×4 clock grid showing the actual hand positions (automatically requests GETPOS on open).
    • Tap a clock to select it, tap again to toggle between hour and minute hand.
    • Slider for -90° to +90° adjustment.
    • SET button sends the FINETUNE command.

    The TcpClient connection is shared between activities via an Application singleton, so the connection stays alive when switching screens.

  • Fixed erratic motor movement during OTA flash — 10kΩ pull-down on AX1201728SG RESET

    Francesco Comi03/22/2026 at 17:03 0 comments

    Problem

    During firmware flashing of the ATmega2560 Slaves, clock hands would move erratically and uncontrollably.

    Root Cause

    Each Arduino Mega Slave controls 6 driver boards, each carrying an AX1201728SG quad stepper driver. Pin 17 of the Mega is connected to the RESET pin of all 6 drivers in parallel — when HIGH, the drivers are active; when LOW, they are in reset (motors disabled, outputs high-impedance).

    The original PCB design included a pull-down resistor (R1) between RESET and GND on each board, intended to keep the drivers disabled during boot/flash. However, a 1kΩ resistor was mistakenly populated instead of the 10kΩ recommended by the AX1201728SG datasheet. Since the drivers didn't work at all with 1kΩ, R1 was removed entirely — which introduced the erratic movement problem.

    Solution

    Populate R1 with the correct 10kΩ value, as specified by the AX1201728SG datasheet.

    Mounting a single 10kΩ R1 on just one of the 6 boards per slave completely solved the problem — one resistor is sufficient because the RESET bus is shared. All 48 hands now stay perfectly still during OTA flash.

View all 2 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates