Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

problem with correlated DIO on USB-6341

Solved!
Go to solution

I am testing an application that does correlated DIO written in C++ with a USB-6341. I'm using NI-DAQmx version 16.0.0f0.

 

Because this application will be used by people with a variety of different DAQ devices, I've tried to write it to handle lots of contingencies. So when I set up a correlated DIO task for output, I try to determine the correct channel width:

 

               uInt32 dataBytes;

               if (NIerror = DAQmxGetWriteRawDataWidth(h, &dataBytes))

On my USB-6341 dataBytes returns 1, so I try to write out data using DAQmxWriteDigitalU8(), but that returns an error telling me:

device USB6341:-200565: Specified digital channel contains more bits than supported by the 8-bit version of DAQmx Port Write.

Use the version of DAQmx Port Write that supports wider digital ports.

If I remove the test and force it to use DAQmxWriteDigitalU32() then it works.

 

 

I'm afraid that if I try to always use DAQmxWriteDigitalU32() I may have trouble with other devices that don't support 32-bit channels.

 

Is this a bug in NI-DAQmx related to USB-6341? Have I misunderstood something about how this works?

John Weeks

WaveMetrics, Inc.
Phone (503) 620-3001
Fax (503) 620-6754
www.wavemetrics.com
0 Kudos
Message 1 of 10
(4,415 Views)

Take all of this with a sizeable grain of salt, maybe more of a salt lick than a grain.

 

Drawing from the LabVIEW context help for the RawDataWidth property as well as a vague and partial recollection of some things I've read here over the years, I don't think that the RawDataWidth property is meant to tell you the width of a DI/DO port. It's more directly related to the API and also potentially the conditions for data transfer from device to system RAM.

 

I kinda recall an old thread where someone had trouble with a USB digital task using an 8 bit port.  I believe that the USB driver would only transfer samples in 32-bit chunks.  Until enough samples were acquired by the board to fill the next "unit of transfer", attempts to read all available samples would return 0 samples.  Only after a set of 4 8-bit samples had been acquired would the call to DAQmx Read return any actual data, namely 4 8-bit samples.

 

I don't think that's *exactly* the same as your RawDataWidth property, but suspect some similar special behaviors to watch for.  I think that if RawDataWidth is 32 bits, then even if your port & task only have 8 bits, you have to convert your DO samples  to 32-bit datatypes before writing them to your DO task.  The task would likely mask off all the upper bits and only use the lower 8.

 

I had to do a little poking around to find how to query port widths from a DAQmx device.  I'll attach a LabVIEW snippet, hope it helps you find the right function call in the text API.  I suspect that may need to continue querying the RawDataWidth as well to use it for its slightly different purpose.

 

 

-Kevin P

 

DO port width query.png

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 10
(4,394 Views)

John,

 

The DAQmx call to get the DO port width is DAQmxGetPhysicalChanDOPortWidth

 

More info about this call can be found here:

http://zone.ni.com/reference/en-XX/help/370471AB-01/mxcprop/func29a7/

 

J. Calvert

Applications Engineering

National Instruments

0 Kudos
Message 3 of 10
(4,378 Views)

J. Calvert- thanks for taking an interest in my problem!

 

DAQmxGetPhysicalChanDOPortWidth doesn't actually get me the information I need. Using this code:

 

                   std::string physChannel(devName+"/port0/line0:3");

                   NIerror = DAQmxGetPhysicalChanDOPortWidth(physChannel.c_str(), &dataBytes);

                   std::ostringstream msg;

                   msg << "DAQmxGetPhysicalChanDOPortWidth for " << physChannel << " is " << dataBytes << " and error =" << NIerror << "\r";

 

Please excuse me for re-using a badly-named variable, "dataBytes" 🙂

 

I get 8 as the answer. That would lead me to expect that DAQmxWriteDigitalU8() would work, but in fact I have to use DAQmxWriteDigitalU32(). The value of physChannel was "USB6341/port0". 

 

I'm beginning to get the impression that there is no way to get the information I need- whether to choose a byte array or uInt32 array for the buffer, and whether to call DAQmxWriteDigitalU8() or DAQmxWriteDigitalU32(). Right now I've simply added an option for the user to specify which to use, which is less than satisfying.


The DAQmx call to get the DO port width is DAQmxGetPhysicalChanDOPortWidth

 

More info about this call can be found here:

http://zone.ni.com/reference/en-XX/help/370471AB-01/mxcprop/func29a7/

 

That documentation is pretty, er, spartan.

 

 


 

John Weeks

WaveMetrics, Inc.
Phone (503) 620-3001
Fax (503) 620-6754
www.wavemetrics.com
0 Kudos
Message 4 of 10
(4,375 Views)

John,

 

The USB-6341 only has 8-bit DIO ports. That is why the DAQmxGetPhysicalChanDOPortWidth is returning 8 bits. It is strange that it is allowing you to write a U32 to the port at all, so I'm not sure what is going on there. 

 

What arguments are you using when you create your DO channel? 

 

J. Calvert

Applications Engineering

National Instruments

0 Kudos
Message 5 of 10
(4,357 Views)

@elcalverado wrote:

John,

 

The USB-6341 only has 8-bit DIO ports. That is why the DAQmxGetPhysicalChanDOPortWidth is returning 8 bits. It is strange that it is allowing you to write a U32 to the port at all, so I'm not sure what is going on there. 

 

What arguments are you using when you create your DO channel? 

 


Not only does it accept a 32-bit write, an 8-bit write gives an  error.

DAQmxCreateDOChan(h, lines.c_str(), NULL, grouping)

lines is an std::string with "/USB6341/port0/line0:3", and grouping = 1, which is 

DAQmx_Val_ChanForAllLines

John Weeks

WaveMetrics, Inc.
Phone (503) 620-3001
Fax (503) 620-6754
www.wavemetrics.com
0 Kudos
Message 6 of 10
(4,353 Views)
Solution
Accepted by topic author WM_John_Weeks

John,

It seems that this is a known issue with DAQmx and a corrective action request has been filed to address this issue. For now, using the DAQmxWriteDigitalU32 should work fine whether the device has 8-bit or 32-bit ports.

 

0 Kudos
Message 7 of 10
(4,341 Views)

Thanks for confirming my suspicion.

 

After "corrective action" willDAQmxWriteDigitalU32 start to fail?

 

And- does this affect only USB-6341, or is it a general problem with devices having 8-bit ports?

John Weeks

WaveMetrics, Inc.
Phone (503) 620-3001
Fax (503) 620-6754
www.wavemetrics.com
0 Kudos
Message 8 of 10
(4,338 Views)

John,

 

Even after this is fixed, you shouldn't run into a problem. When a U32 is written to the 8-bit port, it should coerce it to a U8 (in other words, just look at the 8 LSBs)

0 Kudos
Message 9 of 10
(4,290 Views)

So then the only problem with using the 32-bit version is the extra memory used.

John Weeks

WaveMetrics, Inc.
Phone (503) 620-3001
Fax (503) 620-6754
www.wavemetrics.com
0 Kudos
Message 10 of 10
(4,283 Views)