Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Slow I/O in mx vs. traditional NI-DAQ

Hello,

I'm not sure if this is the right forum to post this.  But here's my situation.  Our hardware guys came up with a pretty slick method for using the Digital I/O lines on the E series cards that basically expanded the 8 lines into a 16 bit addressing scheme (via bit blasting and writing/reading nibbles at a time -- very cool).  An important part of this scheme is that we need to change the In/Out direction on several of the lines in rapid succession.  (The lines serve double duty for setting addresses then reading data back in.)  This worked great under the Traditional NI-DAQ driver model.  We are planning on switching to M series cards, so the first step was to start using the mx driver model.  I am using C++.

I'm still new to the mx driver model, so there may be something I'm missing.  What I did was set up eight tasks, one for each digital I/O line (we need to individually access each one as they serve as latches, clocks, etc).  I did manage to get it working (there was a stumbling block when we realized the inputs switched from pull-ups to pull-downs on the M series).  But it takes up WAY more CPU time than the traditional method.  Using traditional NI-DAQ, I can blast through everything I need to do in less than five milliseconds.  With the mx driver model, it takes about 275ms.  This causes noticeable hiccups in the rest of my program.

In order to change the direction on a digital line, I stop the old task, clear it, then create a new task in which I create a DI or DO channel depending on the direction I need.  I believe it is this stop/clear/create task that is causing me trouble.  Do I need to be creating eight tasks?  Can I change the direction on a digital I/O line without stopping the task (it was giving me an error when I tried it without a full stop/clear/create task cycle)?  Like I said, I am new to the mx driver model so I may be doing something very wrong.  But the old model simply let me pick a line, and change direction or read or write in simple functions.

I can try to cobble together an example code snippet if you like (it's a little complicated because the software needs to dynamically decide whether it uses NI-DAQmx or Traditional on program startup, depending on what version of the NI drivers the customer has installed, so I have a few layers of abstraction).

Thanks a bunch!

-John

0 Kudos
Message 1 of 8
(5,058 Views)
Hello John,
 
Can you put together a piece of code that will demonstrate this behavior?  If possible, have a user interface button that would allow the user to switch between Traditional NI-DAQ and NI-DAQmx.  I would like to see if I can reproduce this on my computer.

Regards,
Sean C.
0 Kudos
Message 2 of 8
(5,042 Views)

JSA,

 

You don't need to create and destroy a task each time you want to change direction on a line.  Instead, create a digital output task and set the tristate property to true when you want to read from the line and set the tristate property to false when you want to begin driving the line again.  You can set the tristate property by using the DAQmxSetDOTristate function.  By using the tristate property in conjunction with the appropriate Read and Write functions, you can program the direction of the lines without having to destroy and create a new task each time.  I don't know if this will be as fast as the Traditional DAQ performance, but it should be much faster than the 275 ms you're currently observing.

Message 3 of 8
(5,041 Views)
Thank you reddog!  That fixed it.  I'm now back down to < 5 ms for all the I/O I'm doing.

At first I felt silly for not knowing about the DAQmxSetDOTristate function, but even knowing what it was called I had trouble finding documentation on it!  (It's under "Get/Set/Reset DO_Tristate" in the mx C Reference, rather than listed under the function name, which all other C Functions seem to be).

Thanks again, this was a real holdup to the project.

0 Kudos
Message 4 of 8
(5,033 Views)

This was very helpful!! I spent hours reading through help and finally found this. BTW, if I simply toggle the TriState state, then the original value is lost. That is, if I write a '0' to the output port, then tristate then un-tristate, the output is actually a '1'??

rjmiller

0 Kudos
Message 5 of 8
(4,868 Views)
Hi RJM,
 
Setting a digital line to Tristate is setting the line to a state of high impedance. This means that the line is not driven high or low. Therefore, if you set the line to Tristate and then change that property to false, the digital line will still be in a state of high impedance.
 
Regards,
Hal L.
0 Kudos
Message 6 of 8
(4,849 Views)
OH, OK. But if I chnage the property from High Z back to false, I can re-write the port OK to be a low? I guess I'm confussed as to why it stays in High Z if set to false?
 
rjmiller
0 Kudos
Message 7 of 8
(4,842 Views)

Hi RJM,

Once you change the Tristate property back to false, you can set the line to be low again. If you set the Tristate property to true, the line is set to a state of high impedance. Once the Tristate property is set to false, it remains in that state of high impedance because nothing is driving the line low or high yet. However, once the property is set to false, you can drive the line to your preference.  A more detailed description of the Tristate Property is available in the LabVIEW Help. Go to Help >> Search the LabVIEW Help >> Property and Method Reference >> NI-DAQmx Properties >> DAQmx Channel >> Digital Output >> Tristate.

Regards,
Hal L.

0 Kudos
Message 8 of 8
(4,826 Views)