Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmxWriteAnalogF64 slow in communication

Solved!
Go to solution

Hello,

 

I'm using a USB cDAQ-9174 chassis with 9263 4xOutput module and a 9215 4xInput module. I'd like to implement a PID control loop with input ai0 and output ao0. To do that I need to know how fast the computer can talk to the device to ouput a single value, given that the computer needs to make calculations based on the input it got and then decide on an output.

 

To test the maximum output rate I created the following loop based on DAQmxWriteAnalogF64 function that I run inside a function on my program:

 

errorChk(DAQmxCreateTask("singleOutTask",&taskOut));
errorChk(DAQmxCreateAOVoltageChan(taskOut,"cDAQ1Mod1/ao0","pidOutChannel",-10.0,10.0,DAQmx_Val_Volts,""));
while(!stop){ // The loop will run until stop=true. outArray[0] = 0; errorChk(DAQmxWriteAnalogF64(taskOut, 1, true, 10.0, DAQmx_Val_GroupByChannel, outArray, NULL, NULL)); outArray[0] = 5; errorChk(DAQmxWriteAnalogF64(taskOut, 1, true, 10.0, DAQmx_Val_GroupByChannel, outArray, NULL, NULL)); } errorChk(DAQmxStopTask(taskOut)); errorChk(DAQmxClearTask(taskOut));


After creating the task and the AOVoltageChannel the program enters a loop where it will toggle the ouput on/off (0/5Vlts). Efectively this creates a square wave on the output, that I can evaluate it's period with an oscilloscope and find the output update time.
With this code I found that the output was taking around 25ms to change, wich implies a signal frequency of 20Hz. This is too slow for my application.

I based this code on the single output from NIDAQmx examples to create this loop, that, in many regards,  is similar to what I would need to do to implement the PID controler.

This comunication seems very slow compared to the read function DAQmxReadAnalogF64 that reads values from an ongoing input task, wich means that the USB can communicate faster than this.

Is there a way to output values faster? My computer can produce results from a calculation in about 1us (even faster), so there would be planty of time to output values if communication is quick.

Thank you.

If you need more information, please let me know.

A. Vieira

 

 

0 Kudos
Message 1 of 5
(6,681 Views)

Hi AVieira,

 

I think you're getting confused with 2 notions :

- the device output rate, which is determined by the settings of the onboard clock rate of the device. You can change this parameter with the function DAQmxCfgSampClkTiming (http://zone.ni.com/reference/en-XX/help/370471AE-01/daqmxcfunc/daqmxcfgsampclktiming/). The maximum device output rate is given by the specifications of your device.

- the shortest time between 2 successive calls to the DAQmxWriteAnalogF64 function (and the subsequent actions it performs on your device) in your application (which is what you measure with your code),This time depends on your Operating System, Driver, software code, mode you use to transfer data between the RAM of your PC and the memory of your device, amount of data you transfer to the device, etc...

 

These 2 notions becomes a single concept only if you configure your DAQ device to perform "Programmed I/O", which is not the default behaviour. By default, DAQmx buffers data in the memory of your device, which permits to acheieve much higher throughput (ouput rates) than by simple successive calls to DAQmx functions (see http://zone.ni.com/reference/en-XX/help/370466V-01/mxcncpts/datatrans/ for the various data transfer mechanisms).

 

Check this document to have a better understanding of sampling rate: http://digital.ni.com/public.nsf/allkb/3E3D74E26B8A5B83862575CA0053E4B5

Also, check the labWindows/CVI example "ContGen-IntClk" to see how DAQmx functions must be used to ouput data at a given ouput rate.

 

I hope this will help

Pierre-Emmanuel BELLES
Certified LabVIEW Developper
Certified TestStand Architect

0 Kudos
Message 2 of 5
(6,665 Views)

Hello pbelles

 

Thanks for answering my question. 
It seems that what I would want to do is to configure the device for "Programmed I/O", but I don't know how to do it in this devices. Do you know how?
The functions available are listed here. Some of the functions or it's options aren't supported by the divices i'm using.

 

I did try using the DAQmxCfgSampClkTiming function to set the sampleMode to DAQmx_Val_HWTimedSinglePoint, but this mode is not supported by the device I'm using (I get error 200077 - "Requested value is not a supported value for this property."

I have been using buffered write wherever I can in my software, but to performe a PID controller I need a faster single value output.

Thank you

0 Kudos
Message 3 of 5
(6,642 Views)
Solution
Accepted by topic author AVieira

I found the answer.

It's the example "Mult Volt Updates-SW Timed.c" from the NI-DAQmx examples. It uses the function DAQmxWriteAnalogScalarF64 to write the values, instead of DAQmxWriteAnalogF64.

With this function my loop goes from a 20Hz writing frequency to 1kHz.
I had checked this example before and the reason It didn't work that time (apparently) is that it uses DAQmxStartTask before entering the loop, although the autoStart parameter is set for DAQmxWriteAnalogScalarF64. So if you start the task before writing values it works 50x faster!.


Full solution:

float64 outValue;
errorChk(DAQmxCreateTask("pidOutTask",&taskOut));
errorChk(DAQmxCreateAOVoltageChan(taskOut,"cDAQ1Mod1/ao0","pidOutChannel",-10.0,10.0,DAQmx_Val_Volts,""));
errorChk(DAQmxStartTask(taskOut));
while(!stop){ // The loop will run until stop=true. outValue = 0; errorChk(DAQmxWriteAnalogScalarF64(taskOut,1,10.0,outValue,NULL)); // With either autostart = 1 or 0 will work fine outValue = 5; errorChk(DAQmxWriteAnalogScalarF64(taskOut,1,10.0,outValue,NULL)); } errorChk(DAQmxStopTask(taskOut)); errorChk(DAQmxClearTask(taskOut));

 

Maybe there are still some things one could do to improve this. I still believe that it woudn't be hard for the bus to communicate even faster.
I still dream with some way to make the device constantly write at a well defined frequency (that can be really high) and the computer updates the buffer with next value to write (or something similar). In such a case I just need to ensure that the computer writes the value to the buffer fast enough. That would be so ideal! It would ensure a constant write frequency, which the example above does not.

Thank you

Message 4 of 5
(6,599 Views)

Hey AVieira! Thanks a lot for sharing your solution. Just wanted to say this helped me a lot 🙂

0 Kudos
Message 5 of 5
(2,437 Views)