03-18-2022 02:44 PM
Hello! I am currently using LabView to write control code for a PCIe-6738 Board to use as an eight-channel function generator. In this application, I would like for each of the eight channels to output a differently-shaped waveform. While I am familiar with many of the basics of LabView programming, I am in the process of acclimating to the usage of Tasks and Physical Channels.
Ideally, I would want my final VI to be capable of creating this measurement:
- The user selects the waveform shape, frequency, and phase for eight separate waveforms.
- The user selects eight total physical channels, one for each of the created waveform.
- The device outputs the waveforms selected by the user on the appropriately-selected channel simultaneously.
So far, I have a full understanding of how to:
- Create a task with the physical channels I care about.
- Use the DAQmx Write command to write waveform data to the task.
- Use this task to output to my device and take a measurement.
What I do not understand is how I would different waveform data to separate channels within my task file. I know that one possible (if brute force) method would be to create eight concurrent tasks, write to each, and then sequence them to start at the same time. For the sake of keeping this synchronized and easy-to-read, however, it would be preferable for this to be performed within a single task. Is this possible?
I do not have code to post that I believe would be contributory towards this discussion, though I can recreate/send whatever would be convenient for your reference.
03-18-2022 05:55 PM
You can put multiple channels in a single task. Look in the Example Finder for some examples of how to set up a task like this.
03-18-2022 07:10 PM
In PCIe-6738, there is only one timing engine, this means there can be only one hardware-timed task running on the hardware. If you need 8 channels or all channels of the card to be hardware-timed simultaneously, then all the channels must be part of the same task in order to utilize the timing engine.
Only the DSA series of instruments such as 4463 has 2 timing engines.
03-19-2022 08:01 AM
Several things to know & do.
1. As already stated, all 8 channels *must* be in one single task.
2. When you write an array of waveforms to the task, index 0 goes to the first channel in the channel list, index 1 goes to the next, and so on. If you specify the channels simply like "Dev1/ao0:7", the array index will match the channel #.
3. DAQmx uses circular buffering for continuous tasks. The # of samples you write to the task prior to starting it will determine the *actual* buffer length. DAQmx will keep wrapping around from end back to beginning to generate continuously.
4. First catch. For smooth waveforms, you don't want any discontinuities from the last sample in the buffer back to the first.
5. Second catch. For waveforms with different freqs that all share the same sample rate, you generally *can't* make them all end exactly where you'd like at the end of the buffer.
6. So instead, you'll have to plan to be in the mode of continuously feeding data to the task, staying a little ahead of the generation process. DAQmx helps you out quite a bit with this -- if you try to write too fast or too often, DAQmx will block and wait until it's safe to overwrite part of the buffer with the new data you give it. (There are edge cases where it can't totally compensate for you, but it generally does quite a good job.)
7. A longstanding rule of thumb is to service task buffers about 10 times a second, dealing with 1/10 sec worth of data each time. This tends to work out over a very wide range of sample rates. So if you use, say, 10 kHz as a sample rate, you should write 1000 samples at a time to each channel in the task.
8. It's actually gonna be a good idea *not* to add any wait timers in the loop. Just the call to DAQmx Write. The first several loops may iterate very quickly if you didn't prefill the buffer prior to task start. But once you fill it up, each new call to DAQmx Write will block and wait until the new samples won't overwrite anything that hasn't already been delivered down to the board.
Note: the standard waveform generation functions have phase inputs and outputs you can use to make sure that each new chunk of waveform data will follow smoothly after the previous one. Use such built-in functions if your waveform shapes permit -- they'll save you a lot of detail work tracking waveform phase to manage smoothness.
-Kevin P