Raspberry Pi NTP Server

From Linux Wiki
Jump to navigation Jump to search

Configurarea Raspberry Pi ca server NTP folosint NEO-7M

Un server NTP asigura sincronizarea corecta a orei pentru toate dispozitivele dintr-o retea, prevenind erori în loguri, autentificari sau servicii care depind de timp precis. Folosind un modul GPS cu PPS, un Raspberry Pi poate deveni o sursa Stratum‑1 foarte stabila și independenta de internet. Acest proiect prezinta configurarea unui astfel de server NTP simplu și fiabil pentru uz local.

Componente folosite

Pentru realizarea acestui server NTP stratum 1 am folosit componente simple, accesibile si usor de integrat. Lista de mai jos include toate elementele hardware necesare pentru configuratie.

  • Raspberry Pi 1 Model B - 180 RON (pret din 2012)
  • Modul GPS u-blox NEO-7M - 49,07 RON
  • Antena GPS ~28 dB gain - 67 RON
  • Fire jumper female–female - 5,79 RON
  • Card SD 16 GB - aprox 30 RON

*preturi valabile in decembrie 2025

Configurare UART și activare PPS

Pe Raspberry Pi, consola seriala este activa implicit, ceea ce blocheaza utilizarea interfetei UART pentru modulul GPS. Pentru a putea folosi portul serial și semnalul PPS, este necesara dezactivarea consolei și activarea manuala a suportului UART și PPS.

Dezactivarea consolei seriale

Pentru dezactivarea consolei seriale editam fisierul /boot/firmware/cmdline.txt de unde stergem segmentul care contine consola, de obicei ceva de forma:

console=serial0,115200

Lasam restul liniei pe un singur rand, exact cum era.

Verificarea activarii UART

Editam fisierul /boot/firmware/config.txt unde ne asiguram ca exista:

[all] enable_uart=1

Activarea modulului PPST

Incarcam modulul PPS executand:

echo 'pps-gpio' >> /etc/modules

Pentru configurarea pinului PPS (GPIO 18) editam din nou fisierul /boot/firmware/config.txt iar in partea de jos adaugam:

dtoverlay=pps-gpio,gpiopin=18

Aceasta indica kernelului ca semnalul PPS este conectat la GPIO 18.

Dupa ce efectuam aceste modificari, oprim systemul in vederea conectarii modului de GPS.


Conectarea modului GPS

Dupa dezactivarea consolei seriale și activarea suportului PPS, interfața UART a Raspberry Pi devine libera pentru comunicarea cu modulul GPS. Conectarea se face direct pe pinii GPIO, folosind alimentarea de 5V, masa comuna și liniile de date RX/TX, plus semnalul PPS.

Schema de conectare

Schema conactare
Schema conactare
  • Conectam pinul de 5V al Raspberry Pi la pinul de alimentare al modulului GPS.
  • Conectam GND la masa modulului GPS.
  • Conectam TX0 de pe Raspberry Pi la RX al modulului GPS (Pi transmite → GPS primește).
  • Conectam RX0 de pe Raspberry Pi la TX al modulului GPS (GPS transmite → Pi primește).
  • Conectam GPIO 18 la pinul PPS al modulului GPS, conform configurarii din config.txt

Test pentru UART si PPS

Dupa conectarea modulului GPS si configurarea UART/PPS, putem verifica functionarea celor doua interfete direct din sistem.

Test UART (NMEA)

Pentru a verifica daca modulul GPS transmite date NMEA prin UART:

# cat /dev/serial0 $GNRMC,140221.00,A,4423.43286,N,02605.77991,E,0.096,,250226,,,A,V*14 $GNVTG,,T,,M,0.096,N,0.178,K,A*3C $GNGGA,140221.00,4423.43286,N,02605.77991,E,1,10,2.11,105.1,M,34.9,M,,*44 $GNGSA,A,3,10,23,15,29,16,26,27,18,,,,,3.30,2.11,2.54,1*00 $GNGSA,A,3,02,25,,,,,,,,,,,3.30,2.11,2.54,3*07 .............

Acest rezultat confirma faptul ca Pi-ul primeste date GPS de la modul Daca totul este configurat corect, ar trebui sa apara siruri NMEA. In cazul in care nu apare asemenator mai sus, verificati conexiunile RX/TX si setarile UART.

Instalare unelte PPS si testare

Pentru testarea semnalului PPS, instalati pachetul necesar:

  • apt install pps-tools

Dupa instalare, verificam semnalul PPS:

# ppstest /dev/pps0 trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1769914968.660167945, sequence: 330 - clear 0.000000000, sequence: 0 source 0 - assert 1769914969.660165119, sequence: 331 - clear 0.000000000, sequence: 0 source 0 - assert 1769914970.660164293, sequence: 332 - clear 0.000000000, sequence: 0

Un rezultat corect va afisa impulsuri detectate la fiecare secunda.

Configurare gpsd

Instalam pachetele necesare pentru gestionarea modulului GPS:

  • apt install gpsd gpsd-clients

Startup config pentru gpsd

Editam fisierul de configurare gpsd:

# nano /etc/default/gpsd START_DAEMON="true" DEVICES="/dev/serial0 /dev/pps" GPSD_OPTIONS="-n" USBAUTO="false" GPSD_SOCKET="/var/run/gpsd.sock"

  • START_DAEMON -> Porneste automat serviciul gpsd la boot. Daca este "false", gpsd nu se lanseaza singur.
  • DEVICES -> Aceasta linie indica gpsd sa deschida doua dispozitive simultan
    • /dev/serial0 → fluxul NMEA provenit de pe UART (datele GPS clasice: GGA, RMC, sateliti etc.)
    • /dev/pps → semnalul PPS hardware folosit pentru sincronizare precisa la nivel de secunda
  • GPSD_OPTIONS -> Porneste gpsd chiar daca nu exista clienti conectati. Fara "-n", gpsd asteapta un client inainte sa initializeze modulul GPS.
  • USBAUTO -> Dezactiveaza detectarea automata a dispozitivelor GPS USB; necesar cand folosim un modul pe UART.
  • GPSD_SOCKET -> Definește socket-ul UNIX prin care aplicatiile (cgps, chrony etc.) comunica cu gpsd.

Repornim serviciul executand:

  • service gpsd restart

Testare gpsd

Testam functionarea modulului GPS:

# cgps -s lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklqqqqqqqqqqqqqqqqSeen 21/Used 14qqk x Time 2026-02-25T14:06:01.000Z (18)xxGNSS S PRN Elev Azim SNR Usex x Latitude 44.43550340 N xxGP 10 10 28.0 182.0 43.0 Y x x Longitude 26.10252040 E xxGP 15 15 16.0 80.0 46.0 Y x x Alt (HAE, MSL) 128.736, 93.872 m xxGP 18 18 67.0 45.0 32.0 Y x x Speed 0.02 km/h xxGP 23 23 57.0 144.0 37.0 Y x x Track (true, var) 166.0, 5.8 deg xxGP 26 26 52.0 222.0 23.0 Y x x Climb 1.92 m/min xxGP 27 27 30.0 299.0 27.0 Y x x Status 3D DGPS FIX (9 secs) xxGP 29 29 22.0 105.0 38.0 Y x x Long Err (XDOP, EPX) 0.56, +/- 2.2 m xxSB127 40 31.0 142.0 35.0 Y x x Lat Err (YDOP, EPY) 0.64, +/- 2.4 m xxSB128 41 15.0 114.0 31.0 Y x x Alt Err (VDOP, EPV) 1.28, +/- 4.5 m xxGA 2 302 65.0 200.0 36.0 Y x x 2D Err (HDOP, CEP) 0.85, +/- 3.4 m xxGA 25 325 19.0 157.0 34.0 Y x x 3D Err (PDOP, SEP) 1.54, +/- 7.4 m xxGA 30 330 44.0 304.0 22.0 Y x x Time Err (TDOP) 0.90 xxGA 34 334 49.0 242.0 25.0 Y x x Geo Err (GDOP) 1.79 xxGA 36 336 74.0 38.0 29.0 Y x x Speed Err (EPS) +/- 17.5 km/h xxGP 5 5 5.0 34.0 0.0 N x x Track Err (EPD) n/a xxGP 16 16 55.0 285.0 0.0 N x x Time offset -2113301 s xxGP 20 20 9.0 57.0 25.0 uN x x Grid Square KN34bj13 xxSB123 36 39.0 184.0 40.0 N x x ECEF X, VX 4099907.290 m 0.020 m/sxxSB126 39 27.0 132.0 0.0 N x x ECEF Y, VY 2008197.370 m 0.010 m/sxxSB136 49 35.0 209.0 0.0 N x x ECEF Z, VZ 4439297.500 m 0.020 m/sxxGA 6 306 4.0 81.0 37.0 N x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqjmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

Din coloana situata in partea dreapta observam ca sistemul nostru se conecteaza la:

  • GP - GPS (Global Positioning System) este un sistem global de navigatie prin satelit dezvoltat de Statele Unite.
  • GA - Galileo este sistemul european de navigatie prin satelit (GNSS), dezvoltat de Uniunea Europeana.
  • SB - SBAS (Satellite-Based Augmentation System) este un sistem care imbunatateste precizia si fiabilitatea pozitionarii GNSS (GPS, Galileo etc.)

Alte sisteme de GNSS care nu sunt prezente in conexiunea nostra ar pute fi:

  • GL - GLONASS este sistemul de navigatie prin satelit al Federatiei Ruse
  • BD - BeiDou este sistemul de navigatie prin satelit al Chinei

Configurarea serverului NTP

Acest server foloseste un modul GPS cu suport PPS pentru a furniza timp de inalta precizie, transformand sistemul intr-o sursa NTP stratum 1. In pasii urmatori configuram Chrony astfel incat sa foloseasca exclusiv GPS si PPS ca referinte de timp.

Instalare Chrony

Inainte de instalare ne asiguram ca sistemul foloseste un singur serviciu NTP (Chrony va deveni sursa principala).

  • apt install chrony

Verificarea surselor NTP initiale

# chronyc sources MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* time.cloudflare.com 3 6 7 0 +3337us[ -12.3s] +/- 26ms ^+ 31.25.10.207 3 6 7 0 -3833us[ -12.3s] +/- 93ms ^- 92-180-26-89.orangero.net 3 6 7 1 -2427us[ -12.3s] +/- 98ms ^+ ntp0.chroot.ro 2 6 7 1 -2785us[ -12.3s] +/- 52ms # chronyc tracking Reference ID  : A29FC87B (time.cloudflare.com) Stratum  : 4 Ref time (UTC)  : Wed Feb 25 14:12:12 2026 System time  : 0.000358473 seconds fast of NTP time Last offset  : +0.000938197 seconds RMS offset  : 0.000938197 seconds Frequency  : 21.559 ppm fast Residual freq  : -96.777 ppm Skew  : 0.076 ppm Root delay  : 0.052518558 seconds Root dispersion : 0.001089336 seconds Update interval : 1.7 seconds Leap status  : Normal

chronyc sources afiseaza sursele NTP publice pe care sistemul le foloseste implicit, inainte de configurarea GPS‑ului. chronyc tracking arata ca sistemul functioneaza momentan ca stratum 3, fiind doar un client NTP obisnuit.

Editare configuratie Chrony

In aceasta etapa eliminam sursele NTP publice si configuram Chrony sa foloseasca exclusiv GPS (NMEA) si PPS ca referinte de timp. Ajustam parametrii de corectie initiala si stabilim PPS ca sursa principala, astfel incat serverul sa poata functiona ca stratum 1. Rezultatul final este un server NTP autonom, sincronizat direct din semnal GPS cu precizie sub‑microsecunda.

# nano /etc/chrony/chrony.conf #pool 2.debian.pool.ntp.org iburst makestep 0.1 -1 initstepslew 1.0 GPS # GPS serial time (NMEA) refclock SHM 0 delay 0.2 refid GPS poll 4 noselect # PPS precise time refclock PPS /dev/pps0 refid PPS lock GPS poll 4 prefer

  • 2.debian.pool.ntp.org este serverul NTP public folosit initial de catre chrony
  • makestep permite corectii mari de timp atunci cand diferenta este prea mare pentru slew. Modificam din initialul "makestep 1.0 3" pentru a permite corectii oricand, cu limita mai mica.
  • initstepslew corecteaza timpul la boot daca diferenta fata de GPS este mai mare de 1 secunda.
refclock SHM (NMEA)

NMEA este fluxul de timp citit din GPS prin gpsd și expus către Chrony printr-un segment SHM (shared memory). Acest semnal conține ora completă, dar are o întârziere naturală de aproximativ 200 ms și o precizie relativ slabă. Îl folosim cu noselect pentru că nu vrem ca NMEA să fie sursa principală de timp; rolul lui este doar să ofere context temporal pentru PPS, astfel încât impulsul PPS să poată fi „legat” corect de ora GPS.

refclock PPS

PPS este semnalul hardware de precizie foarte mare (sub‑microsecundă), generat o dată pe secundă de modulul GPS. Spre deosebire de NMEA, PPS nu conține ora, ci doar impulsul exact, motiv pentru care îl „blocăm” pe GPS (lock GPS) pentru a-i oferi contextul temporal. Îl marcăm ca prefer deoarece PPS trebuie să fie sursa principală de sincronizare, fiind cea mai precisă referință disponibilă.

Dupa salvarea noii configuratii restartam chrony

  • service chrony restart

Verificarea surselor NTP adaugate

# chronyc sources MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #? GPS 0 4 377 12 +289ms[ +289ms] +/- 129ms #* PPS 0 4 363 12 -13us[ -13us] +/- 57ms # chronyc tracking Reference ID  : 50505300 (PPS) Stratum  : 1 Ref time (UTC)  : Wed Feb 25 14:21:25 2026 System time  : 0.000000158 seconds slow of NTP time Last offset  : -0.000000000 seconds RMS offset  : 0.000000006 seconds Frequency  : 21.246 ppm fast Residual freq  : -0.000 ppm Skew  : 0.159 ppm Root delay  : 0.000000001 seconds Root dispersion : 0.000071716 seconds Update interval : 16.0 seconds Leap status  : Normal

Dupa aplicarea configuratiei, Chrony incepe sa renunte la sursele NTP publice si sa foloseasca exclusiv GPS si PPS. In primele secunde, chronyc sources poate arata doar GPS, iar PPS apare abia dupa ce semnalul devine stabil. Pe masura ce PPS este validat si blocat pe GPS, chronyc tracking trece automat de la stratum 3 la stratum 1, confirmand ca serverul functioneaza acum ca o sursa autonoma de timp de inalta precizie.

Configurarea serverului pentru acces LAN

După ce serverul NTP funcționează corect pe GPS + PPS și a devenit stratum 1, următorul pas este să îl facem disponibil în rețeaua locală. Practic, permitem dispozitivelor din LAN să folosească acest server ca sursă principală de timp. Chrony nu răspunde implicit către rețea, așa că trebuie să activăm explicit accesul pentru subnetul nostru.

# nano /etc/chrony/chrony.conf allow 192.168.1.0/24

După restart, Chrony ascultă pe toate interfețele pentru UDP 123, fiind gata să răspundă clienților din LAN.

# netstat -tulnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name .......... udp 0 0 0.0.0.0:123 0.0.0.0:* 848/chronyd ..........

Cu aceste setari, configurarea serverului NTP este completa. Sistemul functioneaza acum ca un server stratum 1 bazat pe GPS + PPS, stabil, autonom si gata sa ofere timp precis intregii retele. Practic, in acest punct serverul este complet operational si pregatit sa serveasca LAN‑ul

Configurarea clientului NTP Ubuntu

Clientul NTP din retea va folosi serverul nostru stratum 1 ca sursa principala de timp. Pe Ubuntu, Chrony este usor de configurat si poate inlocui rapid pool‑urile implicite cu serverul nostru local.

Instalare Chrony

Instalam Chrony pe client pentru a putea sincroniza timpul cu serverul NTP din LAN.

# apt install chrony

Verificare stare initiala

Inainte de modificari, clientul foloseste pool‑urile Ubuntu.

# chronyc sources MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^- alphyn.canonical.com 2 6 17 34 -4699us[-4699us] +/- 75ms ^+ prod-ntp-5.ntp4.ps5.cano> 2 6 17 35 -5344us[-3553us] +/- 25ms ^* prod-ntp-4.ntp4.ps5.cano> 2 6 17 34 -4327us[-2535us] +/- 22ms ^- prod-ntp-3.ntp4.ps5.cano> 2 6 35 32 -5388us[-5388us] +/- 23ms ^+ ntp7.kernfusion.at 2 6 17 34 +8539us[ +10ms] +/- 37ms ^+ time.cloudflare.com 3 6 17 35 +1563us[+3354us] +/- 27ms ^- time.cloudflare.com 3 6 17 34 +822us[ +822us] +/- 28ms ^+ ntp7.kernfusion.at 2 6 17 35 +6762us[+8554us] +/- 38ms # chronyc tracking Reference ID  : B97DBE39 (prod-ntp-4.ntp1.ps5.canonical.com) Stratum  : 3 Ref time (UTC)  : Wed Feb 25 14:39:49 2026 System time  : 0.000061887 seconds slow of NTP time Last offset  : +0.001791766 seconds RMS offset  : 0.001791766 seconds Frequency  : 18.468 ppm fast Residual freq  : -0.238 ppm Skew  : 0.038 ppm Root delay  : 0.043355867 seconds Root dispersion : 0.000964885 seconds Update interval : 1.4 seconds Leap status  : Normal

Editare configuratie Chrony

Pentru ca acest client sa foloseasca serverul nostru NTP din LAN, trebuie sa inlocuim pool‑urile implicite Ubuntu cu adresa serverului local. Configuratia este simpla: comentam sursa initiala si adaugam serverul nostru stratum 1.

# nano /etc/chrony/chrony.conf #pool ntp.ubuntu.com iburst maxsources 4 #pool 0.ubuntu.pool.ntp.org iburst maxsources 1 #pool 1.ubuntu.pool.ntp.org iburst maxsources 1 #pool 2.ubuntu.pool.ntp.org iburst maxsources 2 server 192.168.1.23 iburst

Restartam chrony pentru aplicarea noilor configuratii

  • service chrony restart

Urmarirea sincronizarii

Dupa restart, clientul nu se sincronizeaza instant; are nevoie de cateva interogari pentru a valida sursa si a stabili offset‑ul. Folosim watch pentru a vedea in timp real cum trece de la starea initiala, nesincronizata, la sincronizarea completa cu serverul nostru.

# watch -n1 "chronyc sources; echo; chronyc tracking" MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.168.1.23 1 6 17 9 +7517ns[ +21us] +/- 801us Reference ID  : C0A80117 (192.168.1.23) Stratum  : 2 Ref time (UTC)  : Wed Feb 25 14:44:20 2026 System time  : 0.000000002 seconds slow of NTP time Last offset  : +0.000013356 seconds RMS offset  : 0.000013356 seconds Frequency  : 18.468 ppm fast Residual freq  : -3.156 ppm Skew  : 0.063 ppm Root delay  : 0.000740285 seconds Root dispersion : 0.000509834 seconds Update interval : 2.0 seconds Leap status  : Normal

În aceasta faza, clientul vede serverul, dar inca nu il foloseste ca sursa activa. Asteptam in acest ecran pana cand apare sincronizarea completa — se vede clar momentul in care clientul „prinde” serverul nostru.

# watch -n1 "chronyc sources; echo; chronyc tracking" MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.168.1.23 1 6 17 41 +7517ns[ +21us] +/- 801us Reference ID  : C0A80117 (192.168.1.23) Stratum  : 2 Ref time (UTC)  : Wed Feb 25 14:44:20 2026 System time  : 0.000000002 seconds slow of NTP time Last offset  : +0.000013356 seconds RMS offset  : 0.000013356 seconds Frequency  : 18.468 ppm fast Residual freq  : -3.156 ppm Skew  : 0.063 ppm Root delay  : 0.000740285 seconds Root dispersion : 0.000645164 seconds Update interval : 2.0 seconds Leap status  : Normal

Acum chronyc sources arata serverul stratum 1 ca sursa selectata, iar chronyc tracking confirma ca acest client a devenit stratum 2.

Concluzii

Pentru aceasta constructie am folosit un Raspberry Pi 1 deoarece ofera un consum de energie extrem de redus, zgomot electric minim si un mediu stabil, cu un singur nucleu. Aceste caracteristici il fac surprinzator de potrivit pentru sarcini de sincronizare a timpului, chiar daca modelele mai noi de Raspberry Pi ofera mai multa putere de procesare.

Configuratia poate fi imbunatatita prin utilizarea unui Raspberry Pi echipat cu un HAT pentru SSD. Înlocuirea cardului micro‑SD elimina degradarea mediului de stocare si asigura o performanta mai constanta pe termen lung.

Precizia poate fi imbunatatita si prin trecerea de la modulul NEO‑7M la un receptor dedicat pentru aplicatii de timing. Modulele din seria T sunt proiectate special pentru sincronizare si ofera un semnal PPS mai curat si mai stabil.

Merita mentionat si faptul ca unele echipamente comerciale NTP sunt construite chiar pe hardware Raspberry Pi. Acest lucru face comparatia noastra si mai relevanta, deoarece platforma de baza este similara, iar diferentele de performanta provin in principal din alegerea componentelor si optimizarea firmware‑ului, nu din arhitecturi fundamental diferite.

În comparatia cu echipamentele comerciale NTP, rezultatele au fost foarte apropiate. Unitatile dedicate au mentinut un jitter in jur de 0,2 milisecunde, in timp ce sistemul nostru a avut o medie intre 0,4 si 0,6 milisecunde — valori care se incadreaza confortabil in limitele acceptabile pentru sincronizare.

Și rezultatele privind capacitatea de procesare au fost similare. Echipamentele comerciale au gestionat aproximativ 20 pâna la 30 de mii de cereri NTP pe minut, in timp ce sistemul nostru a sustinut intre 15 si 18 mii, demonstrând ca o solutie cu cost redus poate atinge performante apropiate de cele ale unui appliance dedicat.

Per ansamblu, acest proiect arata ca, prin alegeri hardware bine gândite si o configurare corecta, un sistem compact si accesibil poate oferi o acuratete a timpului foarte apropiata de cea a echipamentelor NTP profesionale.

Combinatia dintre Chrony si PPS bazat pe GNSS ofera o sursa de timp stabila si predictibila, potrivita pentru o gama larga de aplicatii. Cu imbunatatiri incrementale, aceasta platforma poate fi rafinata si mai mult si adaptata unor medii de sincronizare mai pretentioase.

Building a GPS based Raspberry Pi NTP Server (NEO‑7M + PPS)



Building a GPS based Raspberry Pi NTP Server (NEO‑7M + PPS)

This video guide walks through the step-by-step process of building a standalone Stratum-1 NTP server using a Raspberry Pi 1 Model B and a u-blox NEO-7M GPS receiver. Below is the technical breakdown and configuration timeline matching the embedded video guide.

Video Timeline & Key Steps

  • 00:00 - 01:30 | Hardware Overview & Pinout
  • External active GPS antenna (~28 dB gain) for stable satellite acquisition.
  • u-blox NEO-7M module delivering both NMEA data and the pulse-per-second (PPS) hardware signal.
  • Raspberry Pi 1 Model B (Chosen for its ultra-low power consumption, minimal electrical noise, and stable single-core environment).
  • 01:30 - 03:10 | OS Flashing via Raspberry Pi Imager
  • Target OS: Raspberry Pi OS Lite (32-bit).
  • Customization Profile: Hostname set to ntp, Timezone set to Europe/Bucharest, SSH enabled, and user pi-ntp created.
  • Note: The serial console is enabled by default during this process and will be manually disabled after boot.
  • 03:10 - 04:30 | First Boot & System Update
  • CRITICAL STEP: Keep the GPS module completely disconnected during the first boot. If wired to the UART pins prematurely, the active default serial login shell will interfere and may cause the Pi to fail to boot.
  • Connect via Putty SSH and update the core system packaging.
  • 04:30 - 06:17 | UART & PPS Kernel Activation
  1. Disable the login shell by removing the console entry from: /boot/firmware/cmdline.txt
  2. Enable hardware UART in: /boot/firmware/config.txt using enable_uart=1
  3. Ensure the PPS driver loads automatically at boot by appending it to the system modules:
    echo 'pps-gpio' >> /etc/modules
  4. Map the PPS overlay to the correct physical pin layout in config.txt:
    dtoverlay=pps-gpio,gpiopin=18
  5. Safely power off the system to perform physical wiring.
  • 06:17 - 07:48 | Hardware Wiring Interface
  • VCC (GPS Module) <--> Pin 2 or 4 (Pi 5V Power)
  • GND (GPS Module) <--> Pin 6 or 14 (Pi Ground)
  • TX (GPS Module) <--> Pin 10 (Pi RXD0 / GPIO 15)
  • RX (GPS Module) <--> Pin 8 (Pi TXD0 / GPIO 14)
  • PPS (GPS Module) <--> Pin 12 (Pi GPIO 18)
  • 07:48 - 10:51 | Interface Diagnostics & gpsd Sync
  • Verify raw NMEA sentence parsing over the serial line: cat /dev/serial0
  • Install pps-tools and verify 1Hz pulse tracking: ppstest /dev/pps0
  • Install and isolate gpsd configuration, forcing it to read both data streams instantly (-n flag) without waiting for external active clients.
  • 10:51 - 15:28 | Disciplining the System Clock with Chrony
  • Isolate Chrony configuration from public pools to force total hardware clock reliance.
  • Set the NMEA shared memory driver (refclock SHM 0) to provide the coarse absolute date context with a standard noselect monitor flag.
  • Bind the precise PPS hardware device (refclock PPS /dev/pps0), locking it directly onto the GPS context, marked as prefer.
  • Monitor system clock calibration live using: watch -n1 "chronyc sources; echo; chronyc tracking" until the server locks into Stratum-1 status.
  • 15:28 - 17:03 | LAN Server Provisioning
  • Configure Chrony access control lists by exposing the local subnet: allow 192.168.1.0/24
  • Confirm that the daemon successfully opened and bound UDP Port 123 using network sockets monitoring (netstat).
  • 17:03 - 19:34 | Network Client Integration (Ubuntu)
  • Strip public time pools from client configuration files and point them directly onto the local Stratum-1 IP footprint (server 192.168.1.23 iburst).
  • Use real-time terminal evaluation to track the node scaling smoothly down into a locked Stratum-2 time client.

Production Benchmarks & Performance Conclusions

  • Jitter Stability: Maintained a steady performance envelope averaging between 0.4ms and 0.6ms, tracking tightly alongside expensive, hardened commercial timekeeping hardware (which averages around 0.2ms).
  • Throughput Capacity: The single-core legacy ARM architecture sustained an operational load profile of 15,000 to 18,000 active NTP requests per minute, approaching appliance-level performance limits at a fraction of the market cost.