Multifunction DAQ

Showing results for 
Search instead for 
Did you mean: 

Good Practise for creating tasks for channels

Go to solution


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?




0 Kudos
Message 1 of 5

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


Message 2 of 5

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));






0 Kudos
Message 3 of 5
Accepted by topic author ManuMP

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

0 Kudos
Message 4 of 5
Accepted by topic author ManuMP

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.

0 Kudos
Message 5 of 5