Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Inconveniences of the .NET interface to NI-VISA ?

Hi,
 
I'm currently investigating the .NET interface to NI-VISA (VisaNS namespace) using C# as an alternative to the C interface.
So far, everything went smooth ... Smiley Happy
 
Now I want to read data from an oscilloscope, which are known to be 16-bit words, returned as IEEE 488.2 Arbitrary Block Program Data.
Using the C interface, it is as simple as viScanf (instr, "%#hb", &recordLength, capturedDataPtr);
 
I did look for an equivalent in the VisaNS namespace.
The closest I found is MessageBasedSession.ReadByteArray()
So I first process the preamble (e.g. #42048) and then read the 2048 bytes using ReadByteArray.
So I end up with byte[] capturedDataAsBytes, but what I really want is an array of Int16 ... Smiley Mad
 
Perhaps it is due to my limited knowledge, but what is the most efficient way of casting the array of bytes to an array of shorts ?
Or is there an equivalent for reading IEEE 488.2 Arbitrary Block Program Data that I'm not aware of ?
 
Many thanks in advance.
0 Kudos
Message 1 of 12
(5,543 Views)
You can use the .NET Framework Buffer class to do this, with the static BlockCopy method:
Buffer.BlockCopy(bytes, 0, shorts, 0, bytes.Length);
 
However, this will not work correctly if the byte ordering is reversed coming from the instrument, so before you make the copy you'll have to swap bytes...
 
//Note that this only works right if the length of the array is even - if you're off by one you'll get an IndexOutOfRangeException.
for (int i = 0; i < bytes.Length; i+= 2)
{
    byte tmp = bytes[i];
    bytes[i] = bytes[i+1];
    byte[i + 1] = tmp;
}
 
...and then do the block copy as above.
 
 
0 Kudos
Message 2 of 12
(5,530 Views)

I thought I'd also mention that an upcoming version of the VISA .NET API will include support for formatted IO operations that should make the code for retrieving binary-encoded data like in your example much simpler.

0 Kudos
Message 3 of 12
(5,527 Views)

Glenn,

thanks. This is the solution I had in mind ... just wanted to verify if there were more elegant solutions.
I'm really looking forward to the new release of the VISA .NET API ... for obvious reasons Smiley Wink ... any idea when we may expect it ?

Thanks again.

0 Kudos
Message 4 of 12
(5,518 Views)
I can't commit to any specific dates for unreleased/unannounced products, but I've made myself a note to add a new reply to this thread once it ships showing how you would read definite length block data with the new formatting support.
0 Kudos
Message 5 of 12
(5,510 Views)
Hello Frans,
   VIsa 3.4 is now available for download. You can get it at http://digital.ni.com/softlib.nsf/webcategories/85256410006C055586256BAC002C51FA?opendocument.
 
The .NET API includes two new classes: MessageBasedSessionReader and MessageBasedSessionWriter (there are also examples of how to use them in the documentation.)
 
so your particular case of reading back definite length block data into an array of 16-bit words would be:
 
// Assumes you've already opened a session to the device.
int elementsToRead = 1024;
MessageBasedSessionReader reader = new MessageBasedSessionReader(session);
reader.BinaryEncoding = BinaryEncoding.DefiniteLengthBlockData;
reader.ReadInt16s(elementsToRead);
 
There are also methods for reading binary data of different sizes (int32, double, etc.), reading strings back with different termination methods, reading back numbers, etc.
 
MessageBasedSessionWriter includes numerous Write methods for performing formatted writes, as well.
 
Hope this helps with your future development!
0 Kudos
Message 6 of 12
(5,429 Views)
Sorry, that last line of code should have been:
short[] data = reader.ReadInt16s(elementsToRead);
 
...otherwise the data would get discarded - probably not what you want!
0 Kudos
Message 7 of 12
(5,433 Views)

Glenn,

thanks for keeping the promise !

Unfortunately Smiley Sad I'm looking for the indefinite/arbitrary length version ... after downloading the latest version, I found that only the life of those using definite length has become easier in the VISA .NET world, the unfortunate indefinite length guys like me still need to parse the block header (preamble) ...

The documentation states: "MessageBasedSessionReader can not read binary data in the IndefiniteLengthBlockData encoding. If the data source returns binary data in indefinite length blocks, you must manually parse the block header and read the data using the RawBigEndian encoding."

Regards,
Frans

0 Kudos
Message 8 of 12
(5,400 Views)
I haven't tried this out, as I don't have a device that returns indefinite length block data, but try setting the Encoding property to DefiniteLenghtBlockData and doing the read. Even though the data is in indefinite format, you might find that it works out all right. I'm going to revisit the implementation of this for our next release and see if I can't strengthen our support for indefinite length format. Thanks for bringing this to my attention.
 
Incidently, I've never seen a device return indefinite length block data - what kind of instrument are you communicating with?
0 Kudos
Message 9 of 12
(5,367 Views)

Glenn,

there's some confusion at my end ...
I assumed that "arbitrary" length (corresponding to "%b" using viScanf) was a synonym for "indefinite".
Apparently this is not the case ("%b" using viPrintf is referred to as "definite" length, while "%B" refers to "indefinite" length).

I will try your proposal next week (when I have access to the instrument) and let you know the outcome.

Thanks.
Frans.

0 Kudos
Message 10 of 12
(5,211 Views)