Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Latency writing analog output in NI 9265

Hello all,

 

I have an application C++ Application where I must write a value into a cDAQ 9265 (mA Output module) on an USB cDAQ-9178 rack

 

Here a sippet from my code :

//declare variables
float64 buffer[32];
TaskHandle  taskHandle=0;
int32 bytesPerSamp=4;

//Create Task
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));

//Add channels to task
DAQmxErrChk (DAQmxCreateAOCurrentChan  (taskHandle, "cDAQ3Mod2/ao0" , "" , 0 , 0.02,  DAQmx_Val_CurrentUnits2_Amps ,  ""));
DAQmxErrChk (DAQmxCreateAOCurrentChan  (taskHandle, "cDAQ3Mod2/ao1" , "" , 0 , 0.02,  DAQmx_Val_CurrentUnits2_Amps ,  ""));


/*********************************************/
// Start task
/*********************************************/
DAQmxErrChk (DAQmxStartTask(taskHandle));

/****************************************
//Loop
//**************************************** While (something) { // do something ... buffer[0]=k1; buffer[1]=k2; //write outputs DAQmxErrChk(DAQmxWriteAnalogF64(taskHandle, 1, false, 0, DAQmx_Val_GroupByScanNumber, buffer, &bytesPerSamp,0)); }

 

This snippet runs ok on my PC with Win 7, but the problem is that each intereation of the "DAQmxWriteAnalogF64" takes between 1 and 2 ms. In my application I need it to run under 1ms.

 

Running the same snippet on a virtual machine with Win XP (running on the same computer) I get sometimes <1ms (great!) but sometimes the latency goes up to 15ms.

 

To check the duration time of each call I'm looking at the NI I/O Trace application.

 

I searched in lots of forums and people sayst that I can add a intern clock to the task before starting it.

Then I add before the start the following line the line:

DAQmxCfgSampClkTiming(taskHandle,"",100000.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,100000);

 

Then I started having the error -200462 when starting of the task saying:

"Generation cannot be started because the output buffer is empty.

Write data before starting a buffered generation. The following actions can empty the buffer: changing the size of the buffer, unreserving a task, setting the Regeneration Mode property, changing the Sample Mode, or configuring retriggering."

 

It seams to be a very simple issue, but I can't see the solution.

 

Thanks for any help.

0 Kudos
Message 1 of 7
(4,812 Views)

Just in order to give some more details:

 

I' trying now to do the same test using a Digital input module (CDaq - NI9375) and got similar results

 

When I run the code below on the Win 7 I get 1 to 2ms each cycle of "DAQmxReadDigitalLines"

When I run the code on the Win XP virtual machine (that is running over my Win 7 PC) I get <1ms per cycle but very oft I get 15ms to execute once the "DAQmxReadDigitalLines" command.

 

Thanks for any help!

 

Here my code:

//declare variables
float64 buffer[32];
TaskHandle  taskHandle=0;
int32 bytesPerSamp=4;
int32 SampPerChan=1; uInt8 val[32];
//Create Task DAQmxErrChk (DAQmxCreateTask("",&taskHandle)); //Add channels to task DAQmxCreateDIChan(taskHandle, "CDAQ3MOD4/port0/line0,CDAQ3MOD4/port0/line1","",DAQmx_Val_ChanPerLine); /*********************************************/ // Start task /*********************************************/ DAQmxErrChk (DAQmxStartTask(taskHandle)); /****************************************
//Loop
//**************************************** While (something) { // do something ... val[0]=0;
val[1]=1; //write outputs DAQmxReadDigitalLines(taskHandle, 1, 10.0,DAQmx_Val_GroupByScanNumber, val ,32,  &SampPerChan    , &bytesPerSamp, 0)
}
0 Kudos
Message 2 of 7
(4,804 Views)

Hello aranteg

 

The problem you have is that you are implementing a "software timed" analog generation. This means that your generation is controlled by loop iterations. Instead of that, you need to implement a "hardware timed" generation, so using onboard clock (a sample clock in your DAQ hardware) you are going to control the generation.

 

It's right, you need to use the DAQmxCfgSampClkTiming function in order to convert your task from software timed to hardware timed. You are getting the error -200462 because you need to write to the buffer before you start the task when the generation is hardware timed. (you were not getting the error before because if the task does not have timing you can start it, then write to the buffer).

 

Capture.PNG

 

You can also try to use the examples installed together with DAQmx. You go to start menu>>all programs>>National Intruments>>DAQmx>>Text-Based Code Support

 

Regards

Frank R.

0 Kudos
Message 3 of 7
(4,788 Views)

Hello Frank R.

 

Thanks for you answer.

 

I added the "DAQmxWriteAnalogF64" before starting the task. I tried writing only one sample (cause this is what I need, per loop I want to write one sample) but then the error message was already on the first write action:

Spoiler
 -200609 Generation cannot be started, because the selected buffer size is too small. Increase the buffer size.

I increased the buffer size to two and now the first "write" works but then ate the second "write" I got the error:

Spoiler
-200292 Some or all of the samples to write could not be written to the buffer yet. More space will free up as samples currently in the buffer are generated.
To wait for more space to become available, use a longer write timeout. To make the space available sooner, increase the sample rate.

 

If I set the timeout to a infinit wait then it never returns from the write function.

 

my actual code:

//declare variables
float64 buffer[32];
TaskHandle  taskHandle=0;
int32 bytesPerSamp=4;

//Create Task
DAQmxCreateTask("",&taskHandle);

//Add channels to task
DAQmxErrChk (DAQmxCreateAOCurrentChan  (taskHandle, "cDAQ3Mod2/ao0" , "" , 0 , 0.02,  DAQmx_Val_CurrentUnits2_Amps ,  ""));
DAQmxErrChk (DAQmxCreateAOCurrentChan  (taskHandle, "cDAQ3Mod2/ao1" , "" , 0 , 0.02,  DAQmx_Val_CurrentUnits2_Amps ,  ""));

/*********************************************/
// Sample clock
/*********************************************/
DAQmxCfgSampClkTiming(taskHandle,"",100000.0,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,1000000);
DAQmxWriteAnalogF64(taskHandle,2,false,0,DAQmx_Val_GroupByScanNumber,buffer,&bytesPerSamp,NULL)


/*********************************************/
// Start task
/*********************************************/
DAQmxStartTask(taskHandle);

/****************************************
//Loop
//****************************************
While (something) {

// do something ...

buffer[0]=k1;
buffer[1]=k2;      	
			
//write outputs
DAQmxWriteAnalogF64(taskHandle, 2, false, 0,    DAQmx_Val_GroupByScanNumber, buffer, &bytesPerSamp,0);
}

 

Probaly what I need is a "fast software timed write function" or a "one sample intern triggered funcion" is there something like this!?

 

I read all the analog output examples but none was very helpful. In all examples either you have to write a lot of samples (and those functions work fast enough but it makes no sense to me to write a lot of samples every cycle) or you have this "software timed" where you can write one value per channel but with a very long (>1ms) call duration time.

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

Hello all, I added thefollowing line before the start of task:

DAQmxSetWriteRelativeTo(taskHandle,	DAQmx_Val_FirstSample)

 Now it is writing the outputs in < 1ms.

 

I'll test a little more and if everything works correctly I will post the corrected code later.

 

Thanks

0 Kudos
Message 5 of 7
(4,757 Views)

Hello all,

 

the actual code works until I decide to stop the task. When I stop it then I become the error -200018

Spoiler

Error -200108

DAC conversion attempted before data to be converted was available.

Decrease the output frequency to increase the period between DAC conversions, or reduce the size of your output buffer in order to write data more often. If you are using an external clock, check  your signal for the presence of noise or glitches.

 

Please help!! 🙂

 

0 Kudos
Message 6 of 7
(4,749 Views)

 

Hello all, I'm back to this problem.

The fact is my "Write" function is running normally under 1 ms but from time to time it takes 1 ms (running in Win 7) or 15 ms (running on a Win XP).

I have the same happening with a "DAQmxReadDigitalLines", "DAQmxReadAnalogF64", "DAQmxWriteAnalogF64", "DAQmxWriteDigitalLines", therefore I belive this is a general setup problem.
I tested this on two different PCs with win 7 and two other using Win XP and everywere I get the problem of the calls not running allways under 1ms. This timming problem is making my application my application unfeasible.

Thanks for any indication that may help!

 

 

//declare variables
float64 buffer[32];
TaskHandle  taskHandle=0;
int32 bytesPerSamp=4;

//Create Task
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));

//Add channels to task
DAQmxErrChk (DAQmxCreateAOCurrentChan  (taskHandle, "cDAQ3Mod2/ao0" , "" , 0 , 0.02,  DAQmx_Val_CurrentUnits2_Amps ,  ""));
DAQmxErrChk (DAQmxCreateAOCurrentChan  (taskHandle, "cDAQ3Mod2/ao1" , "" , 0 , 0.02,  DAQmx_Val_CurrentUnits2_Amps ,  ""));


//Set timing
DAQmxCfgSampClkTiming(taskHandle,"",  100000.0,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,100000);

//Write data
DAQmxWriteAnalogF64(taskHandle, 4, false, 0,    DAQmx_Val_GroupByScanNumber, buffer, &bytesPerSamp,0);

DAQmxSetWriteRelativeTo(taskHandle,	DAQmx_Val_FirstSample)


// Start task
DAQmxErrChk (DAQmxStartTask(taskHandle));


//Loop
While (something) {

	// do something ...

	buffer[0]=k1;
	buffer[1]=k2;      	
				
	//write outputs
	//******************* This runs in < 1 ms but ever ~10 calls takes more than 1ms
	DAQmxErrChk(DAQmxWriteAnalogF64(taskHandle, 2, false, 0,    DAQmx_Val_GroupByScanNumber, buffer, &bytesPerSamp,0);

}

//Stoptask
//******************* Here I get error -200018 (???)
DAQmxErrChk(DAQmxStopTask(firstTaskAI),'Stopping task AI');

 

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