12-12-2014 03:46 AM
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.
12-12-2014 04:49 AM
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)
}
12-12-2014 05:52 PM - edited 12-12-2014 05:55 PM
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).
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.
12-15-2014 03:37 AM
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:
I increased the buffer size to two and now the first "write" works but then ate the second "write" I got the error:
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.
12-15-2014 04:57 AM
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
12-15-2014 11:14 AM
Hello all,
the actual code works until I decide to stop the task. When I stop it then I become the error -200018
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!! 🙂
01-12-2015 11:35 AM
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');