LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx Disappointing Single Measurement Speed

I'm experimenting with DAQmx. I'd like to do arbitrary operations, i.e. do some singe measurements on chn. 3, a daq on 3 and 6, then maybe some single on 6 etc.

 

With the traditional DAQ using AI_VRead my code takes 0.16 ms per single read, using DAQmx takes 5.40 ms.

 

The DAQmx code currently does the full DAQmxCreateTask -> DAQmxCreateAIVoltageChan -> DAQmxStartTask -> DAQmxReadAnalogScalarF64 -> DAQmxClearTask cycle every time. The only way to optimize this is to precreate x Tasks, configure them and keep them at the verified state so they don't lock the hardware.

 

Or is there a far better way to do this?

-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 1 of 10
(4,610 Views)

You do not have to create the task and channel or start/stop the task for each measurement.

 

Create the task, the channel, start it and leave it running.

Then, whenever you need a measurement just call a read function.

 

You can close the task when your app is terminating. 

S. Eren BALCI
IMESTEK
0 Kudos
Message 2 of 10
(4,605 Views)
Thanks for your answer, but this doesn't work for me. Once a task is in or over the "reserved" state, in blocks the hardware. You can't do anything else with this channel(s) the task has. But I'd like to do single measurements on chn. X and daq on chn X, maybe together with other channels, mabe not. All this at random during runtime, if you will.
-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 3 of 10
(4,597 Views)

Well, you can assign all channels to a single task if you like.

You can keep this task active during your application.

 

But you might have to store the current states (output values) of all channels, so that you can update (change) a single channel.

Actually, in this method you update all channels each time but only one (or more) will have a different value according to your needs.

 

How does that sound? 

S. Eren BALCI
IMESTEK
0 Kudos
Message 4 of 10
(4,583 Views)

It is also possible to create a separate task for each channel and only update the one you want to.

 

During the startup phase of your program you can create, configure and start the tasks.

Keep them active during the application run time.

Cleanup upon exit. 

S. Eren BALCI
IMESTEK
0 Kudos
Message 5 of 10
(4,579 Views)

Thanks for your ideas. But I see some problems.

 

One Task with all channels works with outputs, but with inputs on most cards you divide the sample clock by the number of channels you capture. Also you'll have to have on Task per card if you have multiple threads doing different things at the same time (not unsolvable, though).

 

With one Task per channel you'll have to synchronize the tasks so they capture multiple channels as one task with multiple channels would do. Say you have to capture two analog signals and have to rate their voltage levels and determine the direction of rotation by comparing the rising edges. And visualize the signals.

 

But can multiple tasks use the same clock source? If so, how do you make them start at the same clock edge?

-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 6 of 10
(4,556 Views)
Just tried one task per cannel. You can't get more than one task in 'reserved' state or even started on the same PCI card.
-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 7 of 10
(4,554 Views)

Found a bug in DAQmx 9.1: I created one task with all channels in it and selected the one channel I wish to read from with DAQmxSetReadAttribute(..,DAQmx_Read_ChannelsToRead,..). It fails when called twice with the same channel(s). It appears the second call disables the selection because DAQmxReadAnalogScalarF64 complains it has multiple channels to read from and not one.

 

A workaround is to call it with an empty channel list before selecting the channel(s).

-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 8 of 10
(4,507 Views)

Another possibility for that workaround may be using the DAQmxResetReadAttribute.

 

Not much difference of course, but it shows the programmer's intention better 😉

S. Eren BALCI
IMESTEK
0 Kudos
Message 9 of 10
(4,502 Views)

My intention would be not needing it at all... 😄

 

Anyway, after some fiddling about I'm now down to 1.6ms per read. Still 10 times slower than traditional DAQ. 😞

 

By the way, is it possible that a DAQmx task uses at least 150k of memory (I looked at GetProcessMemoryInfo's WorkingSetSize)?

-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 10 of 10
(4,481 Views)