I am struggling with what seems to be a rather simple task using DAQmx. The card I am using is NI PCIe-6353.
I want to generate a TTL output on a channel with, let's say 100 kHz, and use this trigger internally to trigger an analog output. I want to trigger each output if possible, not only the start (although it should be the same thing if they use the same clock, I think). In the end the generated trigger and the AO have to be synchronized.
The VI I attached might already do that but I am not sure if it is correct. Also, I am a little confused why I have to wire the frequency to the AO channel if I have an internal reference and what clock to use.
Here, I made just a couple little mods that ought to make this part work.
The signal you call a "trigger" is actually being used as a "sample clock" for the AO task. In DAQmx, a trigger serves a distinct purpose from a clock.
I'm not certain what DAQmx does with the "rate" value you have to wire for your AO task. Long ago when I used to simply wire the value 1 (meaning 1 sample per clock cycle) when I used external clocks for AI tasks. I thought it was a meaningless dummy value that didn't matter. I later learned that DAQmx tries to "help out" automatically in certain ways based on the wired sample rate value. For AI tasks, the rate is used to help automatically determine a task buffer size and when I was wiring a "1", I was putting myself in greater danger of a buffer overflow.
For an AO task, there'd be a chance that the rate you wire in is used to determine how often to service the task buffer, thus sending the right # of samples at the right rate to keep AO generation going. It's probably prudent to wire a good value there because it might matter.
Thanks for the help. Just to make sure:
With every signal on the Counter output (PFIO12 in my case), the voltage on the AO channel changes to the next value in provided in the array. So if the CO stops or is paused, the AO also pauses. That is also the reason why the actual DAQmx trigger VI is not required, correct?
It is important that the CO and the AO are exactly at the same time.
I tried it with your modifications but have some strange issue. While the CO runs through all provided samples, e.g. 100,000, the AO only puts out around 987 values. This might be an issue that is not connected but I did not have that before. Any ideas?
I assume the CO pulses are "triggering" some other external equipment somehow, right?
CO and AO will be in perfect* hardware sync. DAQmx Timing.vi has an input for you to define the 'active edge', which specifies whether AO should generate a sample on the rising or falling edge of the CO output. The default value is rising edge when left unwired. You should set it be the same as whatever the external equipment reacts to, rising or falling.
I don't know of a hardware, driver, or task reason why AO would put out fewer samples. I can only suspect something about your software. Did you leave my sequencing in place where the AO task is started *before* the CO task? Are you waiting until after you've confirmed that all CO pulses are generated before *stopping* the AO task?
Thanks for your reply. You are correct. The CO is connected to external hardware and acts as a TTL trigger signal that has to be perfectly synchronized with the AO channels.
Unfortunately, I cannot get it to work the way you postet it.
The CO and AO are not synchronized if I follow your example. Somehow the voltages are put out very quickly while the CO is still running in the specified manner.
The only way I can get it to work is the way shown in my first post. To me that way seems to make sense but I am not sure it is the best way or even the correct way. I cannot check if the pulses are perfectly synchronized.
Ctr0 is set up for the CO with a certain frequency. The internal output of this ctr is then used as clock for the AO leading to synchronized output. DAQmx does not let me connect the ctr0 (even after typecast) to the AO clock. Only the "/ctr0InternalOutput works" At least that is the idea.
Is there something I am missing or why is your VI not working for me?
As far as I can tell, the code I posted should properly sync AO and CO by:
- using the CO output pulses as the sample clock for AO
- starting CO pulses last (after starting the AO task)
Are you simply running my code all by itself? That could explain the undesired behavior you see.
I never meant it to be run stand-alone, it was only intended to illustrate *how* to sync. Much like your original code, it looked like it would be used as a subvi. You'd call it with your particular config params and array of AO data to generate. After calling it, you'd be in some kind of loop that would keep the tasks alive. And then there'd be some way to exit the loop and clear the tasks.
I implemented the code in exactly the same way in a much bigger program but could not get it to work. I figured there is probably some small issue somewhere else I have not found (like not waiting for the task to finish etc.).
So I made a small program to test your solution and compare it against my solution using the "/ctr0InternalOutput" instead of the actual output like "PFI12" or so.
In this example (attached) i did not have the issue and everything seems to work just fine. Comparison between the two option gives the same result, as expected. In your opinion, is one of the two options better or really just the same thing?
Is this implementation, following the clock of the CO, a better way to do it than just defining a common start trigger, and letting the CO and AO basically run freely with the same frequency?
I got into the habit of sharing sample clocks whenever possible back when I regularly needed to sync tasks across 2 or more boards. In that case, using a trigger alone wouldn't maintain sync over the life of the tasks as each board would derive a sample clock from its own timebase, and those timebases would vary slightly from one another.
I basically kept the habit for single-board tasks, though they *will* maintain sync with a start trigger alone. Sharing the sample clock *does* make it easier to line up the phasing of the sample clock's active edge though.
Sorry, can't look at your latest code unless you back-save to LV2016 or earlier. (I only rarely have access to a system loaded with 2018).