A NTP Server with LTC Input and Offsetting Options
Find a file
Chaos Rogers d63a019584 feat: add sync_logic and config modules to lib.rs
Co-authored-by: aider (openai/gpt-5) <aider@aider.chat>
2025-10-22 00:04:08 +01:00
.github actually you do effectively build them twice 2025-07-21 21:36:58 +01:00
docs docs: Update API docs with new endpoints and response details 2025-08-07 21:59:32 +01:00
firmware Add files via upload 2025-07-22 13:34:13 +01:00
scripts feat: enable mock serial port via HACI_SERIAL_PORT and update logs 2025-10-21 23:44:29 +01:00
src feat: add sync_logic and config modules to lib.rs 2025-10-22 00:04:08 +01:00
static updated some masthead and readme 2025-08-31 22:13:47 +01:00
.dockerignore feat: add Docker setup with Dockerfile and docker-compose 2025-10-21 22:51:25 +01:00
.gitattributes Add .gitattributes, .gitignore, and README.md. 2024-07-27 20:16:00 +01:00
.gitignore Merge branch 'master' into withmergeresolve 2025-07-21 14:25:00 +01:00
Cargo.toml feat: add audio LTC input path and config options (audio-input) 2025-10-21 23:58:56 +01:00
config.yml change default yaml to not have timeturning 2025-08-30 22:52:42 +01:00
docker-compose.yml feat: enable mock serial port via HACI_SERIAL_PORT and update logs 2025-10-21 23:44:29 +01:00
Dockerfile feat: add mock Teensy support with entrypoint and LTC generator 2025-10-21 23:40:14 +01:00
LICENSE Create LICENSE 2025-07-22 13:40:18 +01:00
README.md updated some masthead and readme 2025-08-31 22:13:47 +01:00
SECURITY.MD Create SECURITY.MD 2025-07-29 11:29:46 +01:00
setup.sh fixed error in naming of service 2025-08-31 21:54:18 +01:00
splash.png Rename wallpaper.png to splash.png 2025-06-24 22:29:29 +01:00
test_ltc_serial.py final test_ltc_serial.py 2025-07-07 20:23:28 +01:00
timeturner.py refactor: Use rational numbers for accurate frame rate calculations 2025-08-02 12:26:17 +01:00
timeturner.service fix: Ensure static web assets are installed and clarify service config 2025-08-12 16:02:25 +01:00
update.sh fixed error in naming of service 2025-08-31 21:54:18 +01:00

Fetch | Hachi (alpha)

An LTC-driven NTP server for Raspberry Pi, built with broadcast precision

Hachi synchronises timecode-locked systems by decoding incoming LTC (Linear Time Code) and broadcasting it as NTP/PTP — with the dedication our namesake would insist upon.

Created by Chris Frankland-Wright and Chaos Rogers


📦 Hardware Requirements


🛠️ Software Features

  • Reads SMPTE LTC from Audio Interface (3.5mm TRS but adaptable to BNC/XLR)
  • Converts LTC into NTP-synced time
  • Broadcasts time via local NTP server
  • Supports configurable time offsets (hours, minutes, seconds, frames or milliseconds)
  • Systemd service support for headless operation
  • Web-based UI for monitoring and control when running as a daemon

🖥️ Web Interface & API

When running as a background daemon, Hachi provides a web interface for monitoring and configuration.

  • Access: The web UI is available at http://<raspberry_pi_ip>:8080.
  • Functionality: You can view the real-time sync status, see logs, and change all configuration options directly from your browser.
  • API: A JSON API is also exposed for programmatic access. See docs/api.md for full details.

🛠️ Known Issues

  • Supported Frame Rates: 24/25fps
  • Non Supported Frame Rates: 23.98/30/59.94/60
  • Fractional framerates have drift or wrong wall clock sync issues

🚀 Installation

The setup.sh script compiles and installs the Hachi application. You can run it by cloning the repository with git or by using the curl command below for a git-free installation.

Prerequisites

  • Internet Connection: To download dependencies.
  • Curl and Unzip: The script requires curl to download files and unzip for the git-free method. The setup script will attempt to install these if they are missing.

This command downloads the latest version, unpacks it, and runs the setup script. Paste it into your Raspberry Pi terminal:

curl -L https://github.com/cjfranko/NTP-Timeturner/archive/refs/heads/main.zip -o NTP-Timeturner.zip && \
unzip NTP-Timeturner.zip && \
cd NTP-Timeturner-main && \
chmod +x setup.sh && \
./setup.sh

What the Script Does

The installation script automates the following steps:

  1. Installs Dependencies: Installs git, curl, unzip, and necessary build tools.
  2. Compiles the Binary: Runs cargo build --release to create an optimised executable.
  3. Creates Directories: Creates /opt/timeturner to store the application files.
  4. Installs Files:
    • The compiled binary is copied to /opt/timeturner/timeturner.
    • The web interface assets from the static/ directory are copied to /opt/timeturner/static.
    • A symbolic link is created from /usr/local/bin/timeturner to the binary, allowing it to be run from any location.
  5. Sets up Systemd Service:
    • Copies the timeturner.service file to /etc/systemd/system/.
    • Enables the service to start automatically on system boot.

After installation is complete, the script will provide instructions to start the service manually or to run the application in its interactive terminal mode.

The working directory is /opt/timeturner.
Default 'config.yml' installed to /opt/timeturner.

To start the service, run:
  sudo systemctl start timeturner.service

To view live logs, run:
  journalctl -u timeturner.service -f

To run the interactive TUI instead, simply run from the project directory:
  cargo run
Or from anywhere after installation:
  timeturner

🔄 Updating

If you installed Hachi by cloning the repository with git, you can use the update.sh script to easily update to the latest version.

Note: This script will not work if you used the curl one-line command for installation, as that method does not create a Git repository.

To run the update script, navigate to the NTP-Timeturner-main directory and run:

chmod +x update.sh && ./update.sh

The update script automates the following:

  1. Pulls the latest code from the main branch on GitHub.
  2. Rebuilds the application binary.
  3. Copies the new binary to /opt/timeturner/.
  4. Restarts the timeturner service to apply the changes.

🕰️ Chrony NTP

chronyc sources | Checks Source
chronyc tracking | NTP Tracking
sudo nano /etc/chrony/chrony.conf | Default Chrony Conf File

Add to top:
# Serve the system clock as a reference at stratum1
server 127.127.1.0
allow 127.0.0.0/8
local stratum 1

Add to bottom:
# Allow LAN clients
allow 0.0.0.0/0

# comment out:
pool 2.debian.pool.ntp.org iburst
sourcedir /run/chrony-dhcp