How to synchronize multiple DAQ devices
Two DAQ devices rated ±50 ppm can drift 0.36 s apart in an hour, and a shared trigger, a shared clock or a marker signal each removes a different part of that error.
Each DAQ device paces its samples from its own crystal oscillator, and no two crystals run at exactly the same frequency, so two devices that start together drift apart. Work out how far they drift over your recording, then pick the least complicated method that keeps the error within what your analysis tolerates.
Four ways to line devices up
| Method | What it fixes | What remains | Wiring |
|---|---|---|---|
| Independent clocks, timestamps | Nothing in hardware; starts aligned by the host | Start offset of host latency plus drift that grows with time | None |
| Independent clocks plus a shared marker signal | Offset and drift, corrected after the run | Small residual error between markers; no cycle-level phase guarantee | One spare input per device |
| Shared start trigger | Start offset, to within trigger latency | Drift, because each device still uses its own clock | One trigger line |
| Shared sample clock or reference clock | Offset and drift | Sub-sample skew from cables and input paths | Clock line (plus a trigger) |
Calculating clock drift
Take two devices rated ±50 ppm. In the worst case one runs 50 ppm fast and the other 50 ppm slow, a relative difference of 100 ppm. Over one hour:
3600 s × 100e-6 = 0.36 s per hour
At 10 kS/s that is 3,600 samples of disagreement after one hour, and 2.88 s after an eight-hour soak test. Use the datasheet numbers for your devices. NI’s USB-6001 specifies its timebase at ±100 ppm, so two of them can drift apart by up to 200 ppm, or 0.72 s per hour. The USB-6008 states timing accuracy as 100 ppm of the actual sample rate.
A temperature that changes over minutes doesn’t care about 0.36 s. A phase comparison does. A time error Δt at frequency f is a phase error of 360° × f × Δt, so at 50 Hz a 1 ms error is 18°. Cross-correlating vibration signals between devices, computing power from voltage on one device and current on another, or comparing event order at millisecond resolution all need more than independent clocks.
Shared trigger vs shared clock
A shared start trigger removes the start offset. Every device waits for the same edge, so sample zero lines up to within each device’s trigger latency (MCC specifies 1 µs plus one clock cycle on the USB-1608G). After that each device counts its own crystal and drift accumulates as before, so a trigger alone suits runs of a few seconds.
A shared sample clock also removes drift. One device exports its conversion clock and the others sample on its edges, so their sample counts can’t diverge. With a shared reference clock, often 10 MHz, each device phase-locks its own timebase to the reference and derives its sample clock from it. Either way you still need a shared trigger, or the devices count the same clock from different starting edges.
How NI hardware does it
NI-DAQmx routes clocks and triggers itself when the hardware allows it:
- Inside a CompactDAQ chassis, modules in the same task share the chassis timing, and NI’s documentation says NI-DAQmx synchronizes analog input modules of different types in one task automatically.
- Multidevice tasks (NI calls this channel expansion) let one task span several devices, with the driver routing the clocks and triggers. PXI Express modules must be in the same identified chassis, PCI boards need a RTSI cable connected and registered in MAX, and NI notes that USB X Series devices can’t be used this way.
- Manual routing works where a multidevice task doesn’t. One task takes another’s sample clock and start trigger, through the PXI backplane, a RTSI cable or a PFI wire you connect yourself.
- Across Ethernet chassis, the cDAQ-9185 and cDAQ-9189 synchronize their onboard 100 MHz oscillators over the network using IEEE 802.1AS, with no clock cables.
import nidaqmx
from nidaqmx.constants import AcquisitionType
with nidaqmx.Task() as lead, nidaqmx.Task() as follow:
lead.ai_channels.add_ai_voltage_chan("Dev1/ai0")
follow.ai_channels.add_ai_voltage_chan("Dev2/ai0")
lead.timing.cfg_samp_clk_timing(1000.0, sample_mode=AcquisitionType.CONTINUOUS)
follow.timing.cfg_samp_clk_timing(1000.0, source="/Dev1/ai/SampleClock",
sample_mode=AcquisitionType.CONTINUOUS)
follow.triggers.start_trigger.cfg_dig_edge_start_trig("/Dev1/ai/StartTrigger")
follow.start() # arm the follower first
lead.start() # its start trigger starts both
# read from both tasks in your loop ...
That routing only resolves when the two devices share a bus NI-DAQmx can route over, such as a PXI chassis or a registered RTSI cable. Between USB devices, export the signal to a PFI pin on one, wire it to a PFI pin on the other, and use that terminal name as the source.
How MCC hardware does it
MCC’s multifunction USB devices put the clock and trigger on screw terminals:
| Device | Trigger in | A/D clock in / out | Max external clock |
|---|---|---|---|
| USB-1608G / GX | TRIG | AICKI / AICKO | 250 kHz (G), 500 kHz (GX) |
| USB-1808X | ITRIG | ICLKI / ICLKO | 500 kHz (125 kHz on the USB-1808) |
| USB-1208FS-Plus | TRIG_IN | SYNC (bidirectional) | 50 kHz |
To lock two USB-1608Gs, wire AICKO on the leader to AICKI on the follower and connect their grounds. The follower’s scan uses an external clock (ScanOption.EXTCLOCK in uldaq, ScanOptions.EXTCLOCK in mcculw) and starts first, so it is waiting when the leader’s clock begins. The USB-1608G datasheet notes that burst mode is always enabled when sampling from the external clock, so all channels in a scan are converted back to back on each clock edge.
How LabJack hardware does it
LabJack’s T7 and T8 have two stream modes for this. Externally clocked stream paces scans from a clock on CIO3 (T7) or FIO2 (T8), set up with the STREAM_CLOCK_SOURCE register. Triggered stream waits for an edge on a DIO_EF-capable pin, chosen with STREAM_TRIGGER_INDEX. Both are T7/T8 features in LabJack’s datasheet, so a T4 can’t take an external clock. Normal stream rate limits still apply, 100 kS/s for the T7 at the ±10 V range and lowest resolution indexes. Setup on macOS is in logging data from a LabJack T7 on a Mac.
Aligning recordings after the fact
When devices can’t share a clock, feed one marker signal into a spare input on every device, such as a 1 Hz square wave from a function generator, a counter output or a pulse from a microcontroller. Start the marker after all devices are recording, so each one sees the same first edge. Afterward, find the edge times on each device’s own time axis and fit a straight line between them. The slope is the relative clock rate and the intercept is the start offset.
import numpy as np
def edge_times(x, fs):
# rising-edge times in seconds, interpolated between samples
th = (x.max() + x.min()) / 2
i = np.flatnonzero((x[:-1] < th) & (x[1:] >= th))
return (i + (th - x[i]) / (x[i + 1] - x[i])) / fs
ta = edge_times(marker_a, fs_a) # device A, its own clock
tb = edge_times(marker_b, fs_b) # device B, its own clock
m = min(len(ta), len(tb))
slope, offset = np.polyfit(tb[:m], ta[:m], 1)
print(f"offset {offset * 1e3:.2f} ms, rate difference {(slope - 1) * 1e6:.1f} ppm")
t_b = slope * np.arange(len(signal_b)) / fs_b + offset # B's samples on A's axis
The residuals of the fit show how good the correction is. Over a long run, temperature changes make the drift slightly non-linear, so a piecewise fit between neighboring edges does better than one line. Then resample device B onto device A’s time axis before comparing the signals sample by sample.
What “one timeline” can mean on a mixed-vendor bench
A bench with MCC, LabJack, Digilent and NI hardware usually has no common clock bus. You can sometimes wire one vendor’s clock output into another’s external clock input after checking logic levels and rate limits in both datasheets, if the software supports external clocking on each device. Otherwise one timeline means host-aligned starts within milliseconds, drift of tens to hundreds of ppm, and markers to correct it afterward. That covers thermal, power and endurance work and answers “what happened when.” For phase-coherent measurements, keep the channels that must agree on one device or one clock domain. More on this setup is in running a mixed-vendor DAQ bench.
DAQAtlas, which is in development, records devices from different vendors into one run with shared markers and a single review timeline. It does not claim a shared hardware clock between vendors. The beta list is open.