Skip to the content
PCBKitNew board
2 layers226.3 × 90.5 mmClockclock main, the printed circuit board in 3D

Clockclock main

TiboDevC/clockclock3

Personal project of a kinetic clock inspired by Humans Since 1982, using 48 stepper motors to display time in an artistic and dynamic way.

Size
226.3 × 90.5 mm
Copper layers
2
Thickness
1.6 mm
Parts
132
Nets
330
Pads
930
Tracks, vias
1,445, 189
Pours
1
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
3 Aug 2024
Updated
2 Jan 2026

Overview

Clockclock main is an open-source printed circuit board by TiboDevC, from the TiboDevC/clockclock repository on GitHub, published under the GPL-3.0 licence. It is a 2-layer board of 226.3 × 90.5 mm with 132 parts on 330 nets, routed with 1,445 tracks and 189 vias.

It is built around the ESP32-C3-DEVKITM-1, 74HCT595D and TXB0102DCT(LX), with the ECA1HM471B among its other parts. Its parts include 63 capacitors, 26 ICs, 4 connectors, 2 resistors and 2 switches. It belongs with the ESP32 and RISC-V boards of this library.

Main components

4

README

README.md

ClockClock - 48 Stepper Motors Kinetic Clock

Personal project of a kinetic clock inspired by Humans Since 1982, using 48 stepper motors to display time in an artistic and dynamic way.

Clock front

Table of Contents


Project Overview

Goals

This project aims to create a kinetic clock with the following constraints:

  1. Simplicity: Use a single microcontroller (ESP32-C3) to control all 48 motors, unlike similar projects that use multiple MCUs
  2. Time Accuracy: Always accurate clock without permanent internet connection thanks to DCF77 receiver
  3. Compact Size: Target dimensions around 100 cm length
  4. Cost-Effective: Reasonable budget using BKA30D-R5 motors at ~4€/piece

Specifications

  • 48 stepper motors individually controlled
  • Display: 4 digits (HH:MM) with 12 motors per digit
  • Angular Resolution: 4320 steps/revolution (12 steps/degree)
  • Power Consumption: ~960 mA @ 5V (20mA/motor)
  • Time Synchronization: DCF77 (European long-range radio signal)

Technical Architecture

Overview

The ClockClock architecture is built around a highly efficient, centralized control system that manages all 48 stepper motors from a single ESP32-C3 microcontroller. This approach contrasts with typical multi-motor projects that require multiple microcontrollers or complex distributed systems.

Control Chain
text
ESP32-C3 → TPIC6C595 Shift Registers (×12) → VID6606 Motor Drivers (×12) → BKA30D-R5 Motors (×48)
   ↓                    ↓                              ↓                           ↓
 3 GPIO              96 bits                    2 signals per motor         2 bits per motor
  pins            (SPI @ 10MHz)                  (STEP + DIR)              (individual control)
Key Design Principles
  1. Minimal GPIO Usage: The entire system uses only 3 GPIO pins (MOSI, SCK, SS) thanks to the shift register cascade. This leaves the ESP32-C3's remaining pins available for other peripherals (I2C for RTC, buttons, encoder, etc.).

  2. Serial-to-Parallel Conversion: The 12 cascaded TPIC6C595 shift registers convert the serial SPI data stream into 96 parallel outputs. Each motor requires 2 control bits (STEP and DIR), allowing precise control of all 48 motors simultaneously.

  3. Hierarchical Organization:

    • 1 ESP32-C3: Single point of control and decision-making
    • 12 Shift Registers: Each controlling 4 motors (8 bits per register)
    • 12 VID6606 Drivers: Each driving 4 motors independently
    • 48 Motors: Organized in 4 groups of 12 (one per digit displayed)
  4. Data Flow Pipeline:

    text
    Time/Animation Logic → Motor Position Calculation → SPI Data Preparation → 
    Hardware SPI Transfer (10µs) → Parallel Latch → Simultaneous Motor Update

High Level Schematic All motor blocks are linked together

Electronic Architecture A motor block

Motor Control

BKA30D-R5 Stepper Motors

Features:

  • Type: Bipolar stepper motor
  • Current: 20 mA per motor
  • Resolution: 360° continuous rotation
  • Torque: Suitable for lightweight hands (acrylic)

Motor Motor

The motor itself with its PCB to connect to the motor driver

VID6606 Drivers

Each VID6606 driver (or equivalent AX1201728SG/STI6606z) can control 4 motors with only 2 signals per motor:

  • STEP: Step signal (rising edge = one step)
  • DIR: Direction (HIGH/LOW)

Motor

The AX1201728SG driver is connected to 4 motors (the two connectors on its right and left). On top, the shift register

TPIC6C595 Shift Registers
  • Quantity: 12 x 8-bit registers in cascade
  • Total: 96 bits of control for 48 motors (2 bits/motor)
  • Communication: Hardware SPI interface from ESP32-C3
  • Clock Speed: 10 MHz
  • Data Transfer: 12 bytes (96 bits) in approximately 10 µs
  • Signals:
    • MOSI (Data Out): Serial data to first register
    • SCK (Shift Clock): Shift clock at 10 MHz
    • SS (Latch Clock): Synchronous output latch

Key Advantages:

  1. Hardware SPI Optimization: Using the ESP32-C3's hardware SPI peripheral instead of bit-banging provides significant performance improvement. The 10 MHz clock allows extremely fast data transfer of all 12 bytes in approximately 10 microseconds.
  2. Perfect Synchronization: The latch mechanism ensures all 48 motors receive their new commands simultaneously in a single atomic operation. There is no timing skew between motors - they all update at exactly the same moment when the latch signal is triggered.
  3. Monolithic Control: This architecture provides a single point of control with zero concurrency issues. All motor states are managed centrally by the ESP32-C3, eliminating the complexity and synchronization challenges found in distributed control systems using multiple microcontrollers.
  4. Deterministic Timing: The fast SPI transfer combined with the synchronous latch ensures predictable, jitter-free motor updates, critical for smooth visual animations.

Time Synchronization

DS3231 RTC Module
  • Accuracy: ±2 ppm (±1 minute/year)
  • Interface: I2C
  • Battery: CR2032 backup for timekeeping
DCF77 Receiver
  • Module: CANADUINO DCF77 Radio Clock Receiver Kit V2
  • Frequency: 77.5 kHz (transmitter in Mainflingen, Germany)
  • Range: ~2000 km in optimal conditions
  • Accuracy: Atomic clock synchronization
  • Function: Automatic DS3231 recalibration
DST (Daylight Saving Time) Management

The firmware implements European rules:

  • Summer Time Start: Last Sunday of March at 2:00 → 3:00 (UTC+2)
  • Winter Time Start: Last Sunday of October at 3:00 → 2:00 (UTC+1)
  • Automatic Calculation: Zeller's algorithm to determine Sundays

Hardware

Main Board

Files: elec/clockclock_main/ → PDF Schematic

Main board Main board

Main board fully wired

Clock starts

Clock starts

Main Components
ComponentReferenceQuantityFunction
MicrocontrollerESP32-C3-DevKitM-11Central control (RISC-V)
Shift RegistersTPIC6C59512Output expansion
Motor DriversVID6606 / AX1201728SG124 motors per driver
RTCDS32311Real-time clock
Radio ReceiverDCF77 CANADUINO1Atomic sync
User Interface

Buttons:

  • PIN 0: Rotary encoder button
  • PIN 1: Mode (short = config, long = calibration)
  • PIN 10: Shutdown (long press)

Rotary Encoder:

  • PIN 2: Encoder A (interrupt)
  • PIN 3: Encoder B (interrupt)

Back of the clock Only one button is connected (the orange button here), and it is used to enter the "shutdown" mode

Motor Boards

Files: elec/clokclock_stepper/ → PDF Schematic

Each board is very simple and connects a BKA30D-R5 motor to its VID6606 driver.

Total: 24 identical motor boards

Motors mounted Row of motors mounted on the main frame

Power Supply

  • Source: Standard USB-C charger
  • Voltage: 5V DC
  • Current: Minimum 1.5A recommended
  • Regulation: Integrated on ESP32-C3-DevKitM-1 (3.3V logic)

Hands

This is the part that took most of the design time! I tried many different materials and manufacturing methods before settling on laser-cut acrylic hands.

The challenge is to be able to manufacture hands that can be unmounted/remounted easily and that fit perfectly on the motor shaft.
In addition, the hands should be as close together as possible in order to maintain a good viewing angle when looking at the clock from the side.

Hand Hand

Mounted hands

Here is the final solution I adopted: Hands assembly Hands assembly

Both the top and bottom hands are in two acrylic parts glued together.
The top one as a 1mm acrylic part glued to a 3mm part that fits on the motor shaft.
The bottom one is a 3mm part glued to a 3mm part that fits on the motor shaft.


Firmware

Development Environment

  • Framework: Arduino (PlatformIO)
  • Platform: Espressif32
  • Language: C++20 (GNU++2a)
  • IDE: VSCode + PlatformIO recommended

Code Structure

text
firmware/
├── platformio.ini          # Project configuration
├── include/
│   └── cfg.hpp            # Global constants (motors count, pins, etc.)
└── src/
    ├── main.cpp           # Entry point
    ├── time_manager.*     # Time management and DST
    ├── ntp_sync.*         # Optional NTP sync (dev only)
    ├── animation/         # Animation system
    │   ├── animation_manager.*
    │   ├── wave_animation.*
    │   └── sync_rotation_animation.*
    ├── button/            # Button and encoder handling
    │   └── button.*
    ├── mode/              # Operating modes
    │   ├── mode.*
    │   ├── calibration.*
    │   └── cfg_time.*
    └── motor/             # Motor control
        ├── motor_motion.* # Mapping and sequences
        ├── motion.*       # Display logic
        ├── shift_register.* # SPI interface
        └── AccelStepper.* # Movement library

Operating Modes

The firmware implements several operation modes:

1. MODE_CLOCK_DISPLAY (default)
  • Display current time
  • Update every minute
  • Execute scheduled animations
  • Sync with RTC every 500ms
2. MODE_CLOCK_CONFIG
  • Manual time configuration
  • Navigation with rotary encoder
  • Button validation
  • 20s timeout → return to display
3. MODE_CALIB (calibration)
  • Access: long press MODE button
  • Function: Reset zero position of all motors
  • Sequence: rotation to reference position, manual validation, save new origin
4. MODE_SHUTDOWN
  • Access: long press SHUTDOWN button
  • All motors return to neutral position (0°)
  • Power saving mode

Animation System

The AnimationManager enables choreographed animations:

Available Animations:

  1. Wave Animation: Undulating wave across all motors
  2. Sync Rotation: Synchronized rotation of all motors
  3. Custom: Possibility to implement new animations

Triggering:

  • Scheduled: At specific times (e.g., every hour)
  • Manual: Via user interface
  • Transition: Between digit changes

Libraries

PlatformIO dependencies:

  • NorthernWidget/DS3231@1.1.2: RTC interface
  • arduino-libraries/NTPClient@^3.2.1: Optional NTP sync

Build and Flash

Prerequisites

bash
# Install PlatformIO CLI
pip install platformio

# Or via VSCode: Install "PlatformIO IDE" extension

Build

bash
cd firmware/
pio run

Upload to ESP32-C3

bash
# Via USB
pio run --target upload

# Serial monitor
pio device monitor

WiFi Configuration (Optional)

To enable NTP sync during development, enable NTP_WIFI_SYNC define in main.cpp and configure your WiFi credentials.

Note: In production, WiFi is not required thanks to the DCF77 module.


Configuration

Motor Parameters

Motor speed and acceleration can be adjusted in firmware/src/motor/motor_motion.cpp.

Timezone Configuration

The firmware is configured for Central European Time (CET/CEST) by default. To change timezone, modify the DST configuration in main.cpp.

Initial Calibration

  1. Power on the device
  2. Long press MODE button → Calibration mode
  3. Verify physical alignment of hands
  4. Validate with encoder button
  5. System saves new zero reference

Schematics and Documentation

Electronic Design Files

DocumentPathFormat
Main board schematicelec/clockclock_main/output/clockclock_main.pdfPDF
Main board PCBelec/clockclock_main/clockclock_main.kicad_pcbKiCad
Motor board schematicelec/clokclock_stepper/output/clokclock_stepper.pdfPDF
Motor board PCBelec/clokclock_stepper/clokclock_stepper.kicad_pcbKiCad
Driver test boardelec/test_board_motor_driver/KiCad

Datasheets

All datasheets are available in the datasheet/ folder:


Development Notes

Debug

The code includes conditional debug flags that can be enabled in respective source files:

  • DEBUG - General messages
  • DEBUG_MOTION - Motor control debug
  • DEBUG_TIME_MGMT - Time management debug
  • DEBUG_ANIMATION - Animation debug
  • DEBUG_MODE - Mode debug

Pre-commit Hooks

Git pre-commit configuration available: .pre-commit-config.yaml

bash
pip install -r requirements.txt
pre-commit install

License

This project is open-source. Free to use and modify.

Acknowledgments

Inspired by the artistic work of Humans Since 1982.

Parts

132
QtyValueFootprintReferences
38100nFCapacitor_SMD:C_0805_2012MetricC1, C2, C11, C12, C14, C16, C17, C19, C21, C22, C24, C26, C27, C29, C31, C32 +22
244.7µFCapacitor_SMD:C_0805_2012MetricC10, C13, C15, C18, C20, C23, C25, C28, C30, C33, C35, C38, C40, C43, C45, C48 +8
1274HCT595Package_SO:SOIC-16_3.9x9.9mm_P1.27mmU3, U5, U7, U9, U11, U13, U15, U17, U19, U21, U23, U25
12Conn motor 0Connector_JST:JST_PH_B8B-PH-K_1x08_P2.00mm_VerticalM1, M3, M5, M7, M9, M11, M13, M15, M17, M19, M21, M23
12Conn motor 1Connector_JST:JST_PH_B8B-PH-K_1x08_P2.00mm_VerticalM2, M4, M6, M8, M10, M12, M14, M16, M18, M20, M22, M24
12VID6606Package_SO:SOP-28_8.4x18.16mm_P1.27mmU4, U6, U8, U10, U12, U14, U16, U18, U20, U22, U24, U26
210kResistor_SMD:R_0805_2012MetricR1, R2
2rotary_encoderConnector_PinHeader_2.54mm:PinHeader_1x05_P2.54mm_VerticalJ1, J4
1AM_DATATestPoint:TestPoint_Pad_1.5x1.5mmTP5
1Button modeSamacsys:FSM4JHS2
1Button shutdownSamacsys:FSM4JHS1
1DATA_OUTTestPoint:TestPoint_Pad_D1.0mmTP8
1DCF77 boardConnector_PinSocket_2.54mm:PinSocket_1x08_P2.54mm_VerticalJ2
1ECA-1HM471Capacitor_THT:CP_Radial_D10.0mm_P5.00mmC3
1ESP32-C3-DEVKITM-1Snapeda:ESP32-C3-DEVKITM-1_XCVR_ESP32-C3-DEVKITM-1U1
1GNDTestPoint:TestPoint_THTPad_2.0x2.0mm_Drill1.0mmGND_DCDC1
1RTCConnector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_VerticalJ3
1TP_GNDTestPoint:TestPoint_Pad_1.5x1.5mmTP2
1TP_LATCH_CLKTestPoint:TestPoint_Pad_2.0x2.0mmTP4
1TP_LATCH_CLKTestPoint:TestPoint_Pad_D1.0mmTP6
1TP_SHIFT_CLKTestPoint:TestPoint_Pad_2.0x2.0mmTP3
1TP_SHIFT_CLKTestPoint:TestPoint_Pad_D1.0mmTP7
1TP_VCCTestPoint:TestPoint_Pad_1.5x1.5mmTP1
1TXB0102DCTPackage_SO:VSSOP-8_2.3x2mm_P0.5mmU2
1USB power to ESP32TestPoint:TestPoint_2Pads_Pitch2.54mm_Drill0.8mmJP1
1VCC 5VTestPoint:TestPoint_Keystone_5005-5009_CompactVCC_DCDC1

Questions

How big is the Clockclock main PCB?

It measures 226.3 × 90.5 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Clockclock main use?

132 parts, built around the ESP32-C3-DEVKITM-1, 74HCT595D, TXB0102DCT(LX) and ECA1HM471B. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Clockclock main KiCad files?

From the TiboDevC/clockclock repository on GitHub, at the commit this page was made from: the board is elec/clockclock_main/clockclock_main.kicad_pcb and its schematic elec/clockclock_main/clockclock_main.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Clockclock main design in my own project?

Its repository publishes it under the GPL-3.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

More from TiboDevC/clockclock

2
  • 2 layers79 × 55 mmTest board motor driver, the printed circuit board in 3D

    Test board motor driver

    TiboDevC/clockclock

    Personal project of a kinetic clock inspired by Humans Since 1982, using 48 stepper motors to display time in an artistic and dynamic way.

    23 parts3GPL-3.0
  • 2 layers42 × 42.3 mmClokclock stepper, the printed circuit board in 3D

    Clokclock stepper

    TiboDevC/clockclock

    Personal project of a kinetic clock inspired by Humans Since 1982, using 48 stepper motors to display time in an artistic and dynamic way.

    3 parts3GPL-3.0

Similar boards

  • 4 layers100 × 100 mm4C, the printed circuit board in 3D

    4C

    ayaamghi/4C

    4 Channel motor controller board for high voltage high amperage solutions. Integrated PID.

    204 parts
  • 2 layers209.9 × 135.9 mmMerged, the printed circuit board in 3D

    Merged

    Samorales-03/The_Cart_Buddy

    Senior design project

    110 partsMIT
  • 2 layers75 × 60 mmDUTler V2, the printed circuit board in 3D

    DUTler V2

    TheYoctoJester/dutler

    A bench butler for your Device Under Test: turns a Raspberry Pi Pico into a USB-serial console bridge with power-relay and MOSFET strap/reset control for embedded-Linux bring-up and hardware-in-the-loop.

    54 parts23Apache-2.0
  • 6 layers180 × 74 mmHandHeld One, the printed circuit board in 3D

    HandHeld One

    phytec-labs/phytec-handheld-one

    PCB files for Handheld Ones Demo

    178 parts1
  • 4 layers60 × 35 mmSlug v1.0, the printed circuit board in 3D

    Slug v1.0

    rumbletech/Slug_v1.0

    Slug ( Slog/Serial Logger ) is an open source firmware and an open source hardware project , it implements logging of serial buses like USART,I2C,SPI to an SD Card.

    78 parts1MIT
  • 2 layers75 × 117.5 mmDucha, the printed circuit board in 3D

    Ducha

    luciaeletti/ProyectoFinal-Eletti-Palandri

    104 parts
  • 2 layers50 × 25 mmJsnsr04t, the printed circuit board in 3D

    Jsnsr04t

    Pollex/MFM-Module-JSN-SR04T

    16 partsMIT
  • 2 layers50 × 50 mmRoom hub, the printed circuit board in 3D

    Room hub

    lucanastasio/myHomeAutomation

    Home automation stuff

    125 parts1