Repository navigation
Home
- Overview / Visión General
- DSP Engine & Escapement Physics / Motor DSP y Física del Escape
- ADC Clock Calibration via PPS/GPS & Local SNTP / Calibración de Reloj ADC mediante PPS/GPS y SNTP Local
Advanced Timegrapher (adv-tg) es un cronocomparador de alta precisión por software para calibres mecánicos y de cuarzo. Diseñado bajo una arquitectura desacoplada en Python 3.12+ sobre NumPy (sin dependencias en C++ o SciPy en tiempo de ejecución), captura las señales acústicas de los escapes mecánicos a través de micrófonos piezoeléctricos de contacto (p. ej., CM18 USB piezo) y calcula en tiempo real:
-
Marcha (Rate): desvío diario en segundos por día (
$\text{s/d}$ ). -
Error de batimiento (Beat Error): asimetría temporal del tic y el tac en milisegundos (
$\text{ms}$ ). -
Amplitud: ángulo de oscilación del volante en grados (
$^\circ$ ). -
Deriva del reloj ADC: error de cristal del códec de audio en partes por millón (
$\text{ppm}$ ).
[ Micrófono / CM18 ]
│
▼
[ Capa 1: Captura de Audio ] ──► Proceso hijo independiente (PortAudio/sounddevice)
│ Ring buffer circular SPSC sin contención de GIL
▼
[ Capa 2: Detección DSP ] ──► Filtro pasabanda fase cero + Envolvente Hilbert FIR
│ Plantillas medianas para tic/tac (t_fine)
▼
[ Capa 3: Métricas ] ──► Regresión ponderada por paridad + Jackknife robusto
│
▼
[ Capa 4: Disciplina ADC ] ──► Estimador Theil-Sen sobre envolvente inferior / PPS
│
▼
[ Capa 5: GUI (PyQt6) ] ──► Cinta de papel en pyqtgraph, osciloscopio P1/P2/P3
Advanced Timegrapher (adv-tg) is a software-based acoustic timegrapher engineered for mechanical and quartz watch movements. Implemented in Python 3.12+ and NumPy without runtime SciPy or compiled C++ dependencies, it ingests contact acoustic signals from mechanical escapements using piezo microphones (such as the CM18 USB clamp) to measure in real time:
-
Rate: daily drift expressed in seconds per day (
$\text{s/d}$ ). -
Beat Error: time difference between tick and tock events in milliseconds (
$\text{ms}$ ). -
Amplitude: balance wheel oscillation rotation in degrees (
$^\circ$ ). -
ADC Clock Drift: sound card crystal frequency offset in parts per million (
$\text{ppm}$ ).
Cada alternancia acústica se descompone en tres sub-eventos físicos de impacto:
-
$P_1$ (Desbloqueo / Unlocking): La elipse entra en la horquilla del áncora y levanta la paleta de reposo. -
$P_2$ (Impulso / Impulse): El diente de la rueda de escape recorre el plano de impulso de la paleta. -
$P_3$ (Caída / Drop): El siguiente diente de la rueda de escape impacta contra la cara de reposo de la paleta complementaria.
-
Frecuencia y Periodo Nominal:
$$f = \frac{\text{BPH}}{7200} \quad [\text{Hz}], \qquad P_{\text{nominal}} = \frac{3600}{\text{BPH}} \quad [\text{s}]$$ -
Amplitud del Volante (
$A$ ): Calculada a partir del ángulo de alzamiento (Lift Angle,$\text{LA}$ ) y el tiempo transcurrido durante el ángulo de impulso ($t_{\text{lift}} = P_3 - P_1$ ):$$A = \frac{\text{LA}}{2 \cdot \sin(\pi \cdot f \cdot t_{\text{lift}})}$$ -
Marcha (Rate):
$$\text{Rate} = \left(\frac{P_{\text{nominal}}}{P_{\text{medido}}} - 1\right) \cdot 86400 \quad [\text{s/d}]$$ -
Conversión ppm a s/d:
$$1 \text{ ppm} = 0.0864 \text{ s/d}$$
-
Filtrado: Filtro Butterworth IIR pasabanda aplicado en modo bidireccional (
filtfilt) para anular la distorsión de fase. - Envolvente: Filtro analítico de transformada de Hilbert FIR con ventanado Blackman y suavizado temporal.
-
Alineación Fina (
$t_{\text{fine}}$ ): Generación de plantilla mediana móvil sobre los últimos 24 batimientos por paridad para independizar la medida del ruido de caída en$P_3$ .
Each recorded acoustic beat represents three distinct physical events:
-
$P_1$ (Unlocking): Roller jewel contacts the pallet fork notch, lifting the locking face. -
$P_2$ (Impulse): Escape wheel tooth slides over the impulse plane of the pallet jewel. -
$P_3$ (Drop): Consecutive escape wheel tooth drops onto the locking face of the opposite pallet.
-
Lift Time:
$$t_{\text{lift}} = P_3 - P_1$$ -
Amplitude:
$$A = \frac{\text{LA}}{2 \cdot \sin(\pi \cdot f \cdot t_{\text{lift}})}$$ -
Rate:
$$\text{Rate} = \left(\frac{P_{\text{nominal}}}{P_{\text{measured}}} - 1\right) \cdot 86400 \quad [\text{s/d}]$$
3. ADC Clock Calibration via PPS/GPS & Local SNTP / Calibración de Reloj ADC mediante PPS/GPS y SNTP Local
Los conversores analógico-digitales (ADC) de tarjetas de audio de consumo utilizan osciladores de cristal sin compensación térmica que suelen desviar entre
| Nivel de Confianza | Fuente de Calibración | Incertidumbre Típica |
|---|---|---|
| Nivel 0 | Sin calibrar | |
| Nivel 1 | Reloj de sistema sin disciplinar | No se aplica en la marcha |
| Nivel 2 | Reloj de sistema disciplinado por NTP público | |
| Nivel 3 | Hardware externo (PPS/GPS o cuarzo patrón) |
Inyecta un pulso transitorio a exactamente 1.000000000 s utilizando la salida PPS (Pulse Per Second) de un módulo satelital.
┌───────────────────────┐
│ Módulo GPS (NEO-6M) │
│ │
│ PPS ├────┐ Pulso 1 Hz (100 ms)
└───────────────────────┘ │
▼
┌────────────────────────────────────────────────────────┐
│ Circuito Disparador / Oscilador 4 kHz │
│ (NE555 / Transistor NPN / Buzzer Piezoeléctrico) │
└────────────────────────────┬───────────────────────────┘
│
▼ Clic acústico resonante (4 kHz, 10 ms)
┌────────────────────────────────────────────────────────┐
│ Micrófono Piezoeléctrico CM18 USB │
└────────────────────────────┬───────────────────────────┘
│ Audio USB
▼
┌────────────────────────────────────────────────────────┐
│ Host PC (`adv_tg.tools.adc_clock`) │
└────────────────────────────────────────────────────────┘
-
Generación del Pulso: El pin PPS del módulo GPS (u-blox NEO-6M o similar) entrega un flanco positivo con jitter
$< 50\text{ ns}$ al obtener fijación 3D de satélites. - Generación Acústica: La entrada del micrófono corta la componente continua mediante capacitores de acoplo. El pulso activa un buzzer pasivo sintonizado a 4 kHz durante 10 ms, acoplado a la pinza del micrófono.
-
Cálculo de Muestras Reales:
Con una tasa nominal de muestreo
$F_s = 48000\text{ Hz}$ , el número de muestras entre flancos de subida del buzzer debe compararse contra el valor nominal: $$\Delta N_k = \text{sample_index}k - \text{sample_index}{k-1}$$ -
Estimación Robusta Theil-Sen:
$$\text{Deriva}_{\text{ppm}} = \left( 1 - \frac{\text{mediana}(\Delta N_k)}{F_s} \right) \times 10^6$$ Tras registrar entre 300 y 600 pulsos (5 a 10 minutos), la incertidumbre$\sigma$ se reduce a$< 0.1\text{ ppm}$ . El valor se guarda enadc_calibration.jsoncon nivel 3.
Convierte un nodo de red local (por ejemplo, una Raspberry Pi) en un servidor de tiempo Stratum-1 conectado a un receptor GPS con soporte PPS por hardware.
[ Constelación GPS ]
│
▼
[ Módulo GPS NEO-6M ] ──┬── UART (/dev/ttyAMA0) ──► Sentencias NMEA (Tiempo absoluto)
└── PPS (GPIO 18) ──► Flancos de subida (/dev/pps0)
│
▼
[ Kernel Linux PPS + chrony ] (Servidor Stratum-1 en LAN)
│
▼ Red Local Ethernet / Wi-Fi (Jitter < 0.2 ms)
[ PC de Medida con adv_tg ]
│
`CLOCK_MONOTONIC` disciplinado a < 0.1 ppm
# Disciplina PPS a nivel de kernel
refclock PPS /dev/pps0 refid PPS precision 1e-9 poll 0 prefer
# Referencia de tiempo NMEA por puerto serie
refclock SHM 0 refid NMEA precision 1e-1 offset 0.128 delay 0.2 poll 0 noselect
# Permitir consultas directas de la subred local
allow 192.168.1.0/24- El equipo que corre
adv_tgsincroniza su reloj de sistema con el servidor Stratum-1 local en intervalos cortos vía NTP. - Cada bloque de audio de PortAudio se etiqueta con su índice de fin de muestra y la marca de tiempo de nanosegundos del sistema (
CLOCK_MONOTONICen Linux otime.time_nsen macOS/Windows). - El módulo
ClockDriftTracker(Capa 4) procesa la envolvente inferior de los tiempos de llegada usando Theil-Sen para eliminar el jitter del planificador del sistema operativo y del bus USB. - Con el sistema anfitrión disciplinado con precisión de microsegundos, la calibración alcanza estabilidad comparable a un Nivel 3 sin requerir hardware acústico adicional.
Low-cost USB sound cards incorporate crystal oscillators that routinely deviate by
| Confidence Level | Calibration Source | Typical Uncertainty |
|---|---|---|
| Level 0 | Uncalibrated defaults | |
| Level 1 | Undisciplined system clock | Discarded for rate correction |
| Level 2 | System clock synced via public NTP | |
| Level 3 | Hardware reference (PPS/GPS or reference quartz) |
-
Hardware Setup: A u-blox NEO-6M GNSS receiver emits a 1 Hz pulse (100 ms duration,
$< 50\text{ ns}$ jitter). - Acoustic Transducer: Drives a 4 kHz piezo buzzer attached directly to the microphone clamp.
- Drift Extraction: $$\text{Drift}{\text{ppm}} = \left( 1 - \frac{\Delta \text{Samples}}{F_s \cdot \Delta T{\text{GPS}}} \right) \times 10^6$$
- A 10-minute acquisition yields an uncertainty
$\sigma < 0.1\text{ ppm}$ , recorded directly intoadc_calibration.json.
-
Hardware Architecture: A dedicated local node (e.g., Raspberry Pi) paired with a GPS module using hardware PPS (
/dev/pps0) and NMEA serial data. -
Time Service:
chronyconfigured as a Stratum-1 reference clock on the local subnet. -
Client Synchronization: The workstation running
adv_tgdisciplines its operating system monotonic clock against the LAN Stratum-1 server, eliminating wide-area network jitter. -
Internal Processing: The
ClockDriftTrackerengine applies Theil-Sen linear regression to the lower arrival envelope of incoming audio blocks, establishing sound card crystal offsets without physical acoustic coupling.