Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Device.Write() vs ibwrt()

Note: Should this question be cross posted in a GPIB Forum?  If so, can a moderator do this?
 
The Question:  Can Device.Write() method send an array of short int to a GPIB device in the same way that ibwrt() does?
 
The Facts:
GPIB instrument is Stanford Research DS345 Synthesized Function Generator.  To load arbitrary waveform
data in the "vector" mode, requires sending an array of short ints.  The maximum value of an element is
16299, clearly of size short and larger than a byte.  Never the less the following C++ code worked fine
in loading the instrument and produced the desired waveform:
 
short data[] = {0, 0, 50, 200, 150, 175, -300, 225, 2000};
// Send the actual data array:
ibwrt(Dev, data, 4*number+2); //number of bytes = 4 per data
    //point(x and y), +2 for checksum
 
In this program I was NOT using any version of Measurement Studio - it was strictly C++ (VC6) using NI488.2
for the calls to ibwrt() via the ni488.h header file.
Note that ibwrt() takes the following parameters: device handle, a pointer to the first location in memory
where the data is stored (the array base address), and the total number of bytes to transfer.

I want to recreate the same program in Microsoft Visual C#.NET 2003 using the class library
NationalInstruments.NI4882.Device.  In the Device class there is an overloaded method called Write()
which accepts either a string object or a Byte arrray as a parameter.
 
The Problem:
Device.Write(Byte[]) does not appear to accept an array of shorts.  If it did, using perhaps in implicit
conversion to the byte type, data would be lost in the conversion.  Same problem with using an explicit
ConvertTo.Byte() .NET function.  When you try to convert a short int to a byte, you will get a
System.OverflowException.  The .NET Framework for the Convert class says "an exception will be thrown if
the result [of the conversion] is larger than can be represented by the particular conversion method's
return value type [here, byte]."
And you can't seem to trick Device.Write() because you can't tell it to send 2x the number of shorts because the Write() has no byte count paratmeter, and it probably gets its byte count from the .NET Framework's Length method.  (myArray.Length returns the number of elements, not the number of bytes).
 
The Question:
How can I send an array of short values to the DS345 over the GPIB using Measurement Studio's
NI882.Device class methods?
 
Do I have to convert my array from an array of N shorts to an array of 2N bytes before passing it to the
 Device.Write() method?  If so, how?  Also, do I have to worry about byte swapping?  (Little Endian is used here
since this is an Intel system).
 
Why does ibwrt() handle an array of shorts OK, but not Device.Write()? 
 
The irony is that ALL data is sent byte-wide over the GPIB since the data bus is only 8 bits wide. 
Clearly the GPIB controller handles this.  Why doesn't Device.Write() allow the controller to handle the
data conversion as it does with ibwrt?
0 Kudos
Message 1 of 2
(4,094 Views)

ibwrt doesn't do any data type conversion - it just accepts any kind of pointer through a void* parameter, and then treats it as an array of bytes to send. Because . NET is a strongly typed system, we don't have those kind of untyped parameters in methods. If you need to send an array of data of a different type, you can copy it into a byte[] using the Buffer class, as below:

short[] myData = new short[256];

int byteLength = Buffer.ByteLength(myData);

byte[] myBytes = new byte[byteLength];

Buffer.BlockCopy(myData, 0, myBytes, 0, byteLength);

Device.Write(myBytes);

As you noted, if you have byte ordering to consider, like if you need to send the data in big-endian rather than little-endian format, you'll have to explicitly swap the bytes yourself. You would need to do this in C if you were using ibwrt, too.

Note that NI-VISA provides a set of IO functions for performing data formatting and encoding, which make this kind of scenario much easier to handle. In our .NET API for VISA, we provide a MessageBasedSessionWriter class which would allow you to send an array of shorts without having to copy the data in to a temporary buffer. This class also handles byte ordering issues for you, as well.

0 Kudos
Message 2 of 2
(4,082 Views)