Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx asynchronous noregeneration Analog Output possible?

Hi all,
I am using a PCI-6221 M series and DAQmx C function to generate squarewave with varying amplitude, I use the following codes:
  
   DAQmxCreateTask("",&taskHandle);
   DAQmxCreateAOVoltageChan(taskHandle,"/Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL);
   DAQmxCfgSampClkTiming(taskHandle,"",200000,DAQmx_Val_Rising,DAQmx_Val_ContSamps,1000);
   DAQmxSetWriteRegenMode(taskHandle,DAQmx_Val_DoNotAllowRegen);  
   DAQmxWriteAnalogF64(taskHandle,26400,0,10.0,DAQmx_Val_GroupByChannel,square_1_amp_data,&written,NULL);
   DAQmxStartTask(taskHandle);
   while (t!=0)
   {DAQmxWriteAnalogF64(taskHandle,26400,0,10.0,DAQmx_Val_GroupByChannel,square_1_amp_data,&written,NULL);
    MdigGrab(MilDigitizer, PhaseImage[0]);
    sprintf(filename, "E:\\images\\0.bmp");
    MbufExport(filename, M_BMP, PhaseImage[0]);
    t=0;}
 
I would like to know if "DAQmxWriteAnalogF64(taskHandle,26400,0,10.0,DAQmx_Val_GroupByChannel,square_1_amp_data,&written,NULL);" is already running asynchronously?
If it is not, then how can I ensure "DAQmxWriteAnalogF64" running in asynchronous mode so that I can run other function like "MdigGrab" on the same time without waiting the DAQmxWriteAnalog64 to finish???
 
Thank you all!
Rolly
 
0 Kudos
Message 1 of 7
(4,591 Views)
What I actually mean is that:
how to instruct the DAQmxWriteAnalogF64 to begin operation and returns prior to the completion or termination of the operation?
 
Can anyone help? Thank you very much!
0 Kudos
Message 2 of 7
(4,578 Views)
DAQmxWriteAnalogF64 will wait for space to be available in your analog output buffer before copying the data and returning. You could explicitly configure your buffer size such that, depending on your sample clock rate, amount of data per write and loop rate, there is always, or almost always space in the buffer when you need it. See the NI-DAQmx help topic Key NI-DAQmx Concepts -> Reading and Writing Data -> Buffering for more information.
 
If all you are doing is changing amplitude of your waveform, try using the external reference for your analog output channel. You should be able to connect your other ao channel to the external reference and, by writing single values to the second ao channel, change the amplitude of your waveform. You will have to figure out the timing aspects of this however.
0 Kudos
Message 3 of 7
(4,569 Views)
Hey Rolly,

Well, the DAQmxWrite doesn't actually write to the board, but to the buffer in memory, so, in a sense, it is asynchronous, in that it doesn't have to wait for the data to come out to return control to your program, but it is always synchronous in that it has to copy all data to the buffer before it returns. if you find that you spend too much time in that function it may be due to lack of space in the buffer. The call to DAQmxWrite will always block (wait) until there is enough free space in the buffer for it to write all it's samples. You can optimize this by creating a bigger output buffer (you can do this by writing both waveforms at the beginning, you may have to create a bigger array that contains both waveforms). This way, when you go write you won't have to wait for the previous waveform to come out before you can finish writing the current one. You could also query the driver for the space available in the buffer, and only call DAQmxWrite if there's enough space available. you can know this by calling:
DAQmxGetWriteSpaceAvail(TaskHandle taskhandle, uInt32 *data);

I hope this helps

Daniel
0 Kudos
Message 4 of 7
(4,565 Views)

Hi Daniel,

I wonder if it is possible to increase the output buffer size for the array by using "DAQmxCfgOutputBuffer"?

Since the array has 26400 elements, what is the maximum allowable buffer size specified by DAQmxCfgOutputBuffer? I tried 26400*16=422400, but I cannot verify if DAQmxWriteAnalogF64 returns immediately after adjusting the buffer size.

Thank you!

Rolly

0 Kudos
Message 5 of 7
(4,558 Views)
Rolly,

Yes, you're absolutely right, DAQmxCfgOutputBuffer will do the behavior you expect. As I said before (and thayles confirmed), the DAQmxWrite call won't return immediately, it will return as soon as it finishes copying the points to the software buffer. So, you may have the following scenarios:
1) Your while loop runs much faster than your generation (the other tasks besides the DAQmxWrite are always short and mostly deterministic).
   In this case, having a larger buffer won't buy you a thing, unless you modify your code, even if you make a buffer that is 16 times larger, that will only cause the Write to return faster the first 16 times, until it fills the buffer, after that it will only be able to fill it at the same rate as it's being emptied by the hardware (so your loop will only be able to run once every 132ms) In order to improve performance, I suggest you make your buffer twice as big as it is now and then do something like this:
while(t!=0)
{
    DAQmxGetWriteSpaceAvail(taskhandle, &data)
    if(data >= 26400)
    {
        DAQmxWriteAnalogF64(taskHandle,26400,0,10.0,DAQmx_Val_GroupByChannel,square_1_amp_data,&written,NULL);
    }

    MdigGrab(MilDigitizer, PhaseImage[0]);
    sprintf(filename, "E:\\images\\0.bmp");
    MbufExport(filename, M_BMP, PhaseImage[0]);
    t=0;
}

2) Your while loop runs at least as fast as your generation in average, but it isn't very deterministic (this is the case when most of the time you simply poll a flag very quickly, but then sometimes you spend a long time performing a task)
This is when having a large buffer will pay off. Take into account, however, that if you decide to change your waveforms there will be a longer latency before you see the new waveforms generated. I still recommend you use the code above so you can go as fast as possible when you're quick and as long as possible when you're not.

Let me know how it went

Daniel
0 Kudos
Message 6 of 7
(4,542 Views)

Hi Daniel,

Sorry for reply late and thanks for your detail explanation. I am able to overcome my problem quite accidentally before trying out your code. Let me explain my scenario:

(1) I tried to increase the array size from 26400 to 52800 and there are 4 such arrays with different amplitude, and I also increase the DAQmxCfgOutputBuffer to 5280000, 100 times of the array size. As I execute the code, I saw stack overflow error and I was forced to quit by VC++. I tried several config of the buffer size but soon discovered that with array size of 52800, stack overflow persisted. I can only change back to 26400, and code executes as it did.

(2) I am suppose to capture an image "during" the DAQ device generate each of the waveform and before amplitude change. "during" is important because if I capture things happened "before" the DAQ actually write the wfm, I got error. I tried Sleep();after DAQmxCfgOutputBuffer in the while loop but it was not good and somehow the program freeze. I then added some timer_wait function form the Matrox since I am using their framegrabber. I added 132msec to wait following DAQmxWriteAnalogF64, then it suddenly solved my problem. The images I capture is now correct!

Anyway I have to thank you for help me all times!!Smiley Very Happy

Best Regards,

Rolly

0 Kudos
Message 7 of 7
(4,533 Views)