06-06-2020 01:23 AM
Hi,
I am new to NIDQ and we plan to communicate with NIDAQ with C API. There are analog input and output channels and digital IO channels.
What are the good practices in creating tasks?
1. Should I create one task for each channels?
2. What are the overheads involved in creating a separate task for each channel?
Thanks,
Manu
Solved! Go to Solution.
06-06-2020 08:19 AM
Some devices may have special considerations or capabilities, but here are some generally-true rules to follow.
1. You'll usually want to have 1 task for all your AI channels. Further, any I/O type that uses a hardware sample clock will (probably) *need* to group all its channels into 1 task.
Beyond that, it can be fairly application-dependent. AI is probably usually hw-clocked and subject to the restriction of 1 task for all channels. The sensible way to handle the other I/O (AO, DI, DO) will very much depend on your application. For on-demand software-timed I/O, it's sometimes convenient and logically sensible to have one task for each channel.
2. The overhead accrues only during startup as long as you aren't repeatedly defining and clearing your tasks. It isn't usually an issue you need to worry about.
The bigger concern is that having separate tasks for each channel pretty much necessarily means you're in software-timed on-demand mode which itself will limit the speed of I/O updates. But generally still in the low single digits worth of millisec.
-Kevin P
06-06-2020 09:45 AM - edited 06-06-2020 09:48 AM
Hi Kevin,
Thanks for responding to my query. I am confused.
In the following sample code a task is created, a channel is configured, writes a channel value and then stopping and clearing the task. Will the following steps work, If I want to write to another channel - named Dev1/ao1 with the same task?
1. Do not call DAQmxStopTask and DAQmxClearTask
2. Call DAQmxCreateAOVoltageChan with new channel parameter Dev1/ao1
Is this a good approach?
Note: The write operations will happen only once in 10 sec or longer period.
float64 data[1] = {1.0};
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,""));
DAQmxErrChk (DAQmxStartTask(taskHandle));
DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL));
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
Thanks,
Manu
06-07-2020 11:31 PM
I'm not 100% certain how things work through the text API, but I *believe* that once you've assigned "Dev1/ao0" to the task, I don't think you can remove it. And after you've run the task with only ao0 in it, I'm not sure you can add ao1 to that same task any more.
If you're only generating on one channel at a time, you'd need distinct tasks for each channel. If you only need to to change channels once every 10 seconds, it should be fine to stop and clear the old task and then create a new one.
You could probably also create all the different individual tasks during initialization, and later only choose which one to start and then stop during a particular time period.
-Kevin P
06-10-2020 11:49 AM
It might help to understand sort of what a "task" is. A task is what you use to interact with your channels. A channel is simply an AO port, or an AI port, or a counter, or whatever. To *do* anything with it, you create a Task, which configures the channel (e.g., differential/single ended mode, min/max range, etc), configures timing (e.g., hardware-clocked signal, single sample, etc), triggering (enabled/disabled, analog trigger, etc).
A task can contain multiple channels but only one timing source and one trigger source (if any). If you need to output one signal at 10 kHz and one at 5 kHz, you'll need two tasks as those have separate timing requirements (or you could double-sample the 5 kHz one and run it at 2x the speed).
AFAIK Kevin is right about removing channels from tasks. For your application of sending a new value once every 10 seconds, I'd just create a new task, don't bother with timing or triggering, write a single sample, then stop and clear the task. The start/stop overhead is on the order of milliseconds. Doing it 1000 times a second is problematic, but doing it once every 10 seconds isn't an issue.
The drawback to opening and closing a task every time you need it is the timing overhead. The drawback to keeping the tasks open is that you have to keep a list of tasks somewhere, which can be annoying if you only need the task very intermittently. I have used both methods with great success over the years.
Think of it like writing a number down in a notebook. "Starting the task" is getting the notebook out of the drawer and grabbing your pencil. "Stopping the task" is putting it all away. If you have one number to write down every hour, you can probably just put it away after each one, and it won't clutter your desk. If you have a number to write down every second, you don't have time to take it out and put it away for every number.
Last... if you see a post by Kevin_Price, listen to what he says 🙂 He's probably the most knowledgeable person on the board when it comes to DAQmx, and is EASILY more knowledgeable than the NI support reps I've spoken with about my various issues.