Single-subject methods case study, Tepna physiological-signal suite
Background. Pulse-arrival time (PAT), the delay from the ECG R-peak to the peripheral pulse foot, is an attractive cuff-free vascular marker, and consumer wearables can now supply both legs — a chest ECG (Polar H10) and a peripheral raw-PPG (Polar Verity Sense) — logged simultaneously by one phone. It is widely assumed that same-phone logging yields a common time base. Objective. Test whether beat-level cross-device PAT is recoverable from such captures. Methods. Twenty overnight sessions (one subject; H10 on the chest, Verity on the left ankle; both streamed to one Android phone via Polar Sensor Logger) were auto-paired; 11 met a start-alignment + beat-parity co-recording gate (145,586 coupled beats). Production detectors (Pan–Tompkins R-peaks; 3-LED-consensus PPG feet) timed each fiducial on its device's own clock; the R→foot lag and its drift across the night were measured, and two passive accelerometer re-synchronisation schemes were attempted. Results. The two streams are the same heartbeats (89% beat coupling, 48 ms beat-to-beat spread on the best night), yet the R→foot lag drifts ~1.1 s per night, consistent at 47.7 ppm (range 37.7–55.3) across nights — i.e. ordinary quartz-crystal tolerance. The phone timestamp does not remove it: over 6.6 h the Verity's phone-timestamp elapsed equals its device sensor-clock elapsed to within the phone's millisecond rounding, proving the logger writes start + device-elapsed — each stream rides its own crystal. Passive re-synchronisation from the two accelerometers failed by both windowed and event-triggered cross-correlation (recovered offsets noisier than the drift itself), because chest and ankle motion are decorrelated in sleep. Conclusion. One phone is not one clock. Beat-level fusion of independently-clocked consumer wearables requires a single acquisition clock (host-side SDK capture); it cannot be salvaged post-hoc from app-timestamped dual-BLE logs, at least when the two sensors sit on decorrelated body segments.
Keywords: pulse arrival time · cross-device synchronization · clock drift · crystal tolerance · consumer wearables · sensor fusion · Polar H10 · Verity Sense · reproducibility · negative results
Pulse-arrival time — the interval from the ECG R-peak to the foot of a downstream pulse wave — tracks arterial tone and blood pressure and needs no cuff, which makes it a standing target for consumer-wearable fusion. The premise is simple: record a chest ECG and a peripheral raw-PPG at the same time and subtract their beat times. Consumer hardware now supplies both legs, and a single phone app (Polar Sensor Logger) can stream and log two Bluetooth-Low-Energy sensors together, writing a "Phone timestamp" column that looks like a shared clock. This paper asks whether that premise survives contact with the data, and reports that it does not — for a specific, quantified, and generalizable reason. The contribution is not a physiological result but a timing-methodology one: a measurement of the inter-device drift, a demonstration that same-phone logging does not synchronize the streams, and two failed attempts to repair it post-hoc, each with its mechanism. The claims are scoped to a single subject and one device pair; the drift magnitude, however, is a property of quartz-crystal tolerance and is expected to generalize.
Capture. One subject wore a Polar H10 chest strap (raw ECG, ~130 Hz) and a Polar Verity Sense on the left ankle (raw 3-LED PPG, ~176 Hz) overnight. Both sensors streamed over BLE to a single Android phone running Polar Sensor Logger, which writes per-stream CSV/TXT with a "Phone timestamp" and a device "sensor timestamp [ns]" column. Twenty nights were collected. Pairing. Files were auto-grouped into nights by filename stamp (sessions before noon folded into the previous evening); the largest ECG and largest PPG per night were paired. A night entered the analysis only if it passed a co-recording gate — start times within 5 s and beat counts within 12 % — which excludes non-simultaneous fragments; 11 of 21 eligible nights passed. Fiducials. R-peaks were detected by the production Pan–Tompkins pipeline (ECGDSP); PPG feet by a 3-LED-consensus detector (PPGDSP). Each fiducial's absolute time was reconstructed from its file's start anchor plus its own device's elapsed time (ECG: sample index ÷ device rate; PPG: device nanosecond clock). Coupling. Each R-peak was matched to the first following foot; a beat "couples" if that lag lies within ±90 ms of a ±30 s local-median baseline (a global baseline wrongly penalizes a slowly-drifting-but-coherent lag). Drift was the range of the per-5-minute median lag; its ppm rate is drift ÷ overlap duration. ACC re-sync. Two schemes estimated the relative clock offset from the two accelerometers' motion envelopes: (a) sliding 2-min windowed normalized cross-correlation; (b) event-triggered — strong isolated chest movements, each cross-correlated in a tight ±1.6 s window against the ankle. Recovered offsets were interpolated and subtracted, then coupling was recomputed. All analysis is browser-local and reproducible from PAT Feasibility.html.
Co-recording is genuine, not assumed. On the representative night of 2026-07-06 the ECG and PPG start 1.4 s apart, run the same 401 min, and yield 19,922 vs 19,926 beats (0.02 % apart); 89.5 % of R-peaks couple to a coherent foot with a 47.5 ms beat-to-beat spread. Across the 11 gated nights the median coupling is 69 % and the median beat-to-beat spread 45 ms. Whatever follows is therefore a timing problem, not a detection or a wrong-pairing problem — the detectors are seeing one heart on two devices.
Despite tight per-beat coupling, the lag baseline wanders across the night by a median of 1,156 ms — of the order of a full cardiac cycle at the subject's ~50 bpm. Normalized to the recording length this is 47.7 ppm (37.7–55.3), and it is strikingly consistent night to night (Table 1) — the signature of a fixed difference between two quartz crystals, not a variable physiological or environmental effect. The drift is non-linear (median linear-fit R² = 0.03): it wanders rather than ramping, so a two-point (start+end) correction cannot capture it. Because 1 s of drift is ~20–30× the physiological PAT signal (tens of ms), absolute PAT is unmeasurable and even a relative-trend readout is swamped.
| Night | overlap (min) | coupling (%) | median lag (ms) | drift (ms) | drift (ppm) |
|---|---|---|---|---|---|
| 2026-06-10 | 428 | 69 | 622 | 1162 | 45.3 |
| 2026-06-11 | 463 | 71 | 694 | 1047 | 37.7 |
| 2026-06-12 | 428 | 70 | 732 | 1174 | 45.7 |
| 2026-06-15 | 446 | 84 | 703 | 1304 | 48.7 |
| 2026-06-24 | 364 | 61 | 584 | 1089 | 49.8 |
| 2026-06-25 | 418 | 73 | 705 | 1225 | 48.8 |
| 2026-06-27 | 414 | 69 | 792 | 1252 | 50.4 |
| 2026-06-28 | 416 | 40 | 392 | 973 | 39.0 |
| 2026-06-30 | 338 | 38 | 420 | 1122 | 55.3 |
| 2026-07-01 | 432 | 34 | 587 | 1156 | 44.6 |
| 2026-07-06 | 401 | 90 | 454 | 1147 | 47.7 |
Table 1 · The 11 gated co-recording nights (145,586 coupled beats). Median drift 47.7 ppm — within the ±20–50 ppm tolerance band of ordinary wearable-grade quartz. 2026-07-06 (highlighted) is the worked example in §3.1.
The natural objection is that a single phone should supply a single clock, so timing each fiducial on its device crystal (as §2) merely fails to use the shared reference. It does not exist. For the Verity 2026-07-06 file, the "Phone timestamp" advances by 23,811.246 s between first and last row while the device "sensor timestamp [ns]" advances by 23,811.2467 s — equal to within the phone column's 1-ms rounding over 6.6 h (Table 2). The logger therefore writes phone timestamp = session start + device-elapsed: it anchors the start to the phone wall-clock once, then counts on the device's own crystal. Each stream's "phone timestamp" consequently rides its own crystal, and the two diverge at exactly the inter-device rate of §3.2. Same-phone logging pins the two streams' start to a common instant (±1.4 s) but never their sample timing.
| Elapsed over 6.6 h (Verity 2026-07-06) | value (s) |
|---|---|
| "Phone timestamp" column | 23,811.246 |
| Device "sensor timestamp [ns]" column | 23,811.2467 |
| Difference | < 0.001 (phone ms rounding) |
Table 2 · The phone timestamp tracks the device clock exactly → it is not an independent acquisition clock.
Because both devices carry accelerometers and both feel the subject's sleep movements, the drift should in principle be traceable from shared motion — the movements act as spontaneous sync markers, no user action required. It is not, at this placement. Windowed cross-correlation of the two motion envelopes cut the median drift only 1,156 → 1,127 ms (2.5 %); event-triggered matching on strong isolated movements did nothing (1,156 → 1,158 ms). In both, the recovered per-window offset ranged over 2–3 s — wider than the ~1.15 s drift it was meant to estimate — i.e. the cross-correlation locked onto noise. The cause is anatomical: a chest strap and an ankle band register largely different motion (torso versus leg), so even a gross whole-body turn produces uncorrelated accelerometer signatures with no reliable common lag. Motion re-sync needs the two inertial sensors on the same body segment, which defeats the purpose.
The result is a clean separation of two things usually conflated: co-recording and synchronisation. Two consumer sensors on one phone are co-recording — same subject, same night, same heartbeats, startable to ~1 s — but they are not synchronised, because no shared clock ever times their samples. The ~48 ppm drift is not a bug in any one product; it is the physics of two free-running crystals, and its consistency across nights (Table 1) is the proof. The practical corollary is a hierarchy of what same-phone logs can and cannot support: night-level and epoch-level fusion (sleep staging, ODI–HRV correlation) tolerate ~1 s of relative drift and are fine; beat-level fusion (PAT, cross-device PWV, beat-to-beat lag) is not. The only durable fix is to remove the second clock: acquire both sensors through one host that timestamps BLE arrivals on a single clock — a Polar-SDK capture on a small always-on host — so relative crystal drift never enters. Passive motion re-sync remains viable in principle for co-located inertial sensors (e.g. two wrist devices), but not across chest and ankle. We deliberately report the failed repairs because they bound the problem: the cheap software fixes were tried on real data and do not work, which is what justifies the hardware requirement.
PAT Feasibility.html (+ pat-feasibility.js, pat-feasibility-worker.js) run over the capture folder — drop the folder, "Process eligible nights", read the per-night table and aggregate. It reuses the production ECGDSP / PPGDSP detectors verbatim.Date.UTC, never a locale parse), so results are viewer-timezone-independent.*_ECG.txt + Verity *_PPG.txt (+ both *_ACC.txt) folder.PAT Feasibility.html · pat-feasibility.js · pat-feasibility-worker.js (batch coupling + ACC-sync).PAT-FEASIBILITY-2026-07-08-BRIEF.md (feasibility verdict + unblock path).papers/dead-ends.html (this finding is wall 2.7).CLAUDE.md §🎙️, §🔒; single-host capture: POLAR-SDK-CAPTURE-2026-07-07-BRIEF.md, CAPTURE-HOST.