11-25-2009 01:47 PM
Hello,
We are porting our application from Traditional DAQ to DAQmx and we are facing a performance issue with DAQmxSetDOTristate. We have implemented a I2C communication by bitbaning the NI card and we need to change the IO pins between input and output frequently. The code below calls DAQmxSetDOTristate, DAQmxReadDigitalScalarU32 and DAQmxWriteDigitalScalarU32 10000 times. The DAQmxSetDOTristate takes 3.4 seconds!!! The DAQmxReadDigitalScalarU32 and DAQmxWriteDigitalScalarU32 only takes 100 seconds. Why is DAQmxSetDOTristate so slow? It should just update one register in the hardware.
I guess the DAQmxSetDOTristate is waiting for some task. If I remove the DAQmxStartTask call the DAQmxReadDigitalScalarU32 loop takes 2.6 seconds too.
I have tried all kinds of task settings but none seems to solve this issue.
DWORD startTick;
DWORD tick1,tick2,tick3;
uInt32 data = 0;
int loop;
iStatus = DAQmxStartTask(g_DOtaskHandle[0]);
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxSetDOTristate(g_DOtaskHandle[0],"Dev1/port0/line0",1);
}
tick1 = GetTickCount() - startTick;
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxReadDigitalScalarU32(g_DOtaskHandle[0],-1,&data,NULL);
}
tick2 = GetTickCount() - startTick;
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxWriteDigitalScalarU32(g_DOtaskHandle[0],0,-1,0,NULL);
}
tick3 = GetTickCount() - startTick;
11-25-2009 02:32 PM - edited 11-25-2009 02:40 PM
Hey Tomas,
What hardware are you using? I am going to assume that you are using either a 6533 or 6534, since the 6535/6/7's do not work with the Traditional DAQ driver. Or are you using some other DAQ device, like a 62xx?
Also, I am curious as to how you had your device configured/programmed when you had the I2C communication working before? One method you can consider is to try Open Collector Mode, if your device has that mode. In the 6533/34 Help is mentions the followin: "An open collector driver drives its output pin to 0 V for logic low. For logic high, the output driver assumes a high-impedance state and does not drive a voltage. Use the Output Drive Type attribute/property to configure the generation lines for open collector."
Also, what rate is your I2C communication running at, as the Open Collector mode might be fast enough for what you are trying to do. Most NI digital devices do not have per cycle Tristating capability, which sounds like what you might be trying to do in software, but check to see if the device you are using has Open Collector mode to use instead. The NI devices that do have Per Cycle Tristate capabilities are the NI 655x devices and the PXIe-6547/8 devices.
But since you said you had it working before, we can help you get back to using your hardware like you were using it before, just with the latest DAQmx driver. Just provide a little more information, and we can go from there. Let me know if you have any questions or concerns in the meantime. Thanks, and have a great day.
Regards,
DJ L.
11-25-2009 02:54 PM
Hello DJ,
Sorry, I forgot to mention which board we are using (I realized just after hitting the submit button).
We are using the PCI-6025E card. Our I2C circuit is connected to DIO0 and DIO4. I don't think the board supports open collector but this would really be what we want.
We have been using the PCI-6025E for 8 years using the traditional DAQ API and it works perfectly. Since it is quite difficult to buy a PC today wout Windows Vista/7 we would like to support DAQmx too. But it just not feasable if the timing is too slow.
It is not an option to change the PCI-6025E or to redesign our tester electronics.
Best regards,
Tomas
11-25-2009 03:18 PM
Just one more thing. In the old traditional DAQ application we call the functions DIG_Line_Config, DIG_In_Line, DIG_Out_Line. Using the 10000 loop test above it takes 100 ms on all functions. Same as the DAQmxReadDigitalScalarU32 and DAQmxWriteDigitalScalarU32 functions in DAQmx. It is only the DAQmxSetDOTristate function which is causing us problems. It must be waiting for something. Can you have someone looking into the source code to see what it is doing?
11-26-2009 07:38 AM
I have found one more strange thing which I believe relates to this problem. The DAQmxWaitUntilTaskDone function does not work. Specifying timeout=-1 and the function will never return. Specifying timeout=0 and I get an error. I have tried all the C examples and I get the same result.
Calling DAQmxWaitUntilTaskDone with timeout=0 gives the following error:
Wait Until Done did not indicate that the task was done within the specified timeout.
Increase the timeout, check the program, and make sure connections for external timing and triggering are in place.
Task Name: DO0
Status Code: -200560
11-30-2009 11:12 AM
Hello Tomas,
I'm looking in to the timing issue with the DAQmxSetDOTristate speed issue. A couple of questions that will help:
For the issue with the DAQmxWaitUntilTaskDone function, are you using a continuous, on-demand, or finite task? DAQmxWaitUntilTaskDone blocks until the task has completed all operations. If you are using continuous or on-demand (no timing configured) then the WaitUntilTaskDone function will never return, because there is no stop condition for the task. Calling WaitUntilTaskDone with a timeout of 0 will throw an error every time unless the task is already done by the time that function is called.
Regards,
12-01-2009 06:57 AM
Hello Seth,
The complete program I am running is listed below. We don't configure any kind of timing at the moment.
DWORD startTick;
DWORD tick1,tick2,tick3;
uInt32 data = 0;
int loop;
iStatus = DAQmxCreateTask("DO0",&g_DOtaskHandle[0]);
iStatus = DAQmxCfgOutputBuffer(g_DOtaskHandle[0],0);
iStatus = DAQmxStartTask(g_DOtaskHandle[0]);
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxSetDOTristate(g_DOtaskHandle[0],"Dev1/port0/line0",1);
}
tick1 = GetTickCount() - startTick;
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxReadDigitalScalarU32(g_DOtaskHandle[0],-1,&data,NULL);
}
tick2 = GetTickCount() - startTick;
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxWriteDigitalScalarU32(g_DOtaskHandle[0],0,-1,0,NULL);
}
tick3 = GetTickCount() - startTick;
12-01-2009 09:37 AM
Hello Tomas,
It doesn't look like you are creating a channel anywhere in your code. Are you using a task that was already defined in Measurement and Automation Explorer? If so, what are the settings for that task? Otherwise, this code should be returning an error that "The specified operation cannot be performed when there are no channels in the task".
Regards,
12-01-2009 07:46 PM
Hello Seth,
Sorry I forgot the DAQmxCreateDOChan line. We are not configuring anything in Measurement and Automation Explorer. Our complete program is:
iStatus = DAQmxCreateTask("DO0",&g_DOtaskHandle[0]);
iStatus = DAQmxCfgOutputBuffer(g_DOtaskHandle[0],0);
iStatus = DAQmxCreateDOChan(g_DOtaskHandle[port],lines,"",DAQmx_Val_ChanForAllLines);
iStatus = DAQmxStartTask(g_DOtaskHandle[0]);
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxSetDOTristate(g_DOtaskHandle[0],"Dev1/port0/line0",1);
}
tick1 = GetTickCount() - startTick;
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxReadDigitalScalarU32(g_DOtaskHandle[0],-1,&data,NULL);
}
tick2 = GetTickCount() - startTick;
startTick = GetTickCount();
for (loop=0;loop<10000;loop++)
{
iStatus = DAQmxWriteDigitalScalarU32(g_DOtaskHandle[0],0,-1,0,NULL);
}
tick3 = GetTickCount() - startTick;
12-02-2009 03:59 PM
Hello Tomas,
So I set this up in LabVIEW with a recreation of all of the functions you list here in the same order. (I don't program in text-based languages very often, but the funstions do the same thing under the hood as far as DAQmx is concerned.) I ran a 10000 iteration loop about 10-15 times and the total time for each run was between 620 - 625 ms total. This was tristating 10,000 times, then reading 10,000 times, then writing 10,000 times on all 32 digital channels of a PCI-6025e. About 400 ms of the full run time was used on the tristate step. What are the specifications of the computer you are running this on? (CPU, RAM, OS, etc.)
Thanks,