05-11-2026 10:25 AM
I am using NI-DAQmx (Python) to control a single channel analog read/write operation. I have Ao0 directly connected to Ai1 and Ai2 in parallel and Ai8 and Ai9 connected to ground for differential reading. The issue I'm having is that when reading any single channel, my analog input lags behind my analog output signal by one sample regardless of sampling frequency. When I try to do a multi-channel read/write only the first analog input channel has this lag.
I am using the analog input sample clock to drive the write task timing and have connected the write task start trigger to the read task rising trigger signal's rising edge (see code below).
I can work around this problem by always recording an additional sample on my first analog input channel and throwing away the first sample, but that seems really clunky for such a simple task. Is there a better way around this?
Solved! Go to Solution.
05-11-2026 11:04 AM
I'm curious why you don't do this using LabVIEW and DAQmx. Also, what are the timing parameters, i.e. sampling rate (1 Hz? 1 kHz? 1 MHz?), what are the # of samples per acquisition (1, 1000?), and why are you using Finite sampling? When you have DAQ tasks that need to run "related" to each other, seems to me DAQmx provides the functionality (and may even have Examples!) that you need. But then, I've never used Python (and feel some anxieties around snakes) ...
Bob Schor
05-11-2026 11:15 AM
To address your questions in order:
I really want to use a python or other programming suite to interface with the DAQ because I'll need to combine DAQ data with data from other hardware/software components later and a flexible language like python running everything in the background will (I think) make my life easier.
I've tried running with a sampling rate ranging from 1Hz to 10kHz and consistently get a delay of exactly one sample between the analog input relative to the analog output. I've tried varying the number of samples from ~10 to ~1000 and haven't had any effect there either. I'm using finite sampling because I know how many samples I'm taking in advanced so I think that mode makes sense, but correct me if I'm wrong there.
The only thing that I can think of right now is that events happen in this order for each cycle of the analog input sampling clock:
1) Ai0 records its sample
2) Ao0 changes its state to match the desired voltage
3) all other analog in channels record their samples
The analog in channels are multiplexed on my DAQ, which could maybe introduce enough delay that by the time the first channel is done being read the analog output channel has had time to set to its new value. If that's the case I feel like there should be SOME way to correct for that by like adding a delay to the analog in sampling or making the analog in channels sample on the falling edge of the sampling clock or something.
05-11-2026 02:09 PM - edited 05-11-2026 02:14 PM
@Kentum wrote:
The only thing that I can think of right now is that events happen in this order for each cycle of the analog input sampling clock:1) Ai0 records its sample
2) Ao0 changes its state to match the desired voltage
3) all other analog in channels record their samples
Not really. 1) and 2) happen pretty much exactly at the same time. BUT!
There is no quantum entanglement between the AO pin and the AI pin so the transfer between the analog output to the analog input is not instantaneous even if you could make the connecting wire 0mm long. And to make things worse, the Digital to Analog Converter needs some time to produce the analog voltage at its output, then it passes through an analog amplifier and then through some PCB traces to the IO connector, then through your wire to the analog input, from there through some PCB traces to the multiplexer, and from there to the analog input of the Analog to Digital Converter. This is together in the range of several microseconds, but by that time the analog input has long sampled its input and only sees the changed voltage at the next sample. Electrical signals travel at roughly 200'000 km/s through copper wires/traces. Yes that is almost the speed of light, but it is not instantaneous. And the speed through electric circuitry like DAC and analog amplifiers is even slower.
05-11-2026 02:12 PM
Your explanation is what I was thinking though I could have worded my explanation better perhaps. In any case, I guess the one sample offset issue is consistent enough that I can just hard-code an extra 1 sample for the AI channel and just discard the first sample from the first AI channel. It's a bit annoying there's not a more polished way to get around this issue, but thank you for your help!
05-11-2026 02:24 PM
It actually depends on your speed. For really fast sampling rates (which is not likely a concern with a USB-6421 although above a few 100kS/s it could start to be relevant) the delay through everything may be larger than what the sample interval is.
Also there are different types of ADC and DAC hardware. So called Delta-Sigma DAC and ADCs require for instance a certain amount of clock cycles for a specific signal to pass through the converter as they basically have internally multiple stages that convert a successively smaller error signal to get the desired result. But your typical measurement DAQ hardware does not use such converters. They are mainly employed for high resolution, high speed conversion as they are relatively cost effective at the cost of a higher signal delay. But for high quality audio that delay is often not important and for vibration analysis it can be compensated for as it is a fixed amount of clock cycles.
05-11-2026 07:43 PM
There are ways to control the timing, but I'm afraid I'm no help at all with the syntax needed to implement in Python. Here's a method I prefer:
1. Use an onboard counter to generate the pulse train that both AO and AI will use as their sample clock. By using a counter output, you get to control the pulse width, i.e., the delay from AO to AI.
2. Be sure to set polarity such that AO generates its sample on the leading edge while the AI task initiates its sample on the trailing edge.
3. With this method, it's crucial to start both AO and AI tasks before starting the counter output task.
4. Triggering is not needed. The shared use of a common sample clock signal (along with proper start sequencing) is sufficient to sync the tasks.
5. You can also optionally configure the AI "convert clock" rate if you need to multiplex across multiple AI channels. Because part of the sample period is "used up" before the trailing edge initiates AI, you may need a faster convert rate to squeeze all the conversions into the remaining portion of the sample period.
-Kevin P
05-12-2026 03:19 AM
While what you write is indeed an option, doing that even in LabVIEW is definitely not for the faint at heart. Going to program your own advanced counter task to trigger and synchronize multiple other tasks is one of the ZEN Master tasks to attempt with DAQmx. Absolutely possible if your hardware has enough hardware resources for it but an exercise in tinkering, trial and error and persistence.
Doing it in Python is just an extra trouble, as there are far less examples in the wild to do similar things than there are for LabVIEW. And without examples you are going to have to study the low level docs for your hardware in quite some depth as well as half of the vast DAQmx API.
05-19-2026 09:23 AM
Hello all. Sorry for the delay in getting this response out there. I had reached out to NI support (who were very helpful) around the same time I made the original forum post. In the end, the solution I like the most has been to modify the "delay_from_samp_clk_delay" parameter of the read task. Combined with using the AI sample clock for my write task, this effectively creates a phase delay between my read and write tasks, which are still synchronous. The code for task setup now looks like this:
The important lines are:
05-19-2026 09:28 AM
In the Python nidaqmx environment, I can accomplish a similar thing by simply assigning a delay between AI sample clock and the read task using: