Sending I/O Commands
This section contains information that applies to both Windows and Linux.
Once you have established a communications session with a device, interface, or commander, you can start communicating with that session using SICL’s I/O routines. SICL provides formatted I/O and non-formatted I/O routines.
Formatted I/O converts mixed types of data under the control of a format string. The data is buffered, thus optimizing interface traffic. The formatted I/O routines are geared towards instruments, and reduce the amount of I/O code.
Non-formatted I/O sends or receives raw data to or from a device, interface, or commander. With non-formatted I/O, no format or conversion of the data is performed. Thus, if formatted data is required, the formatting must be done by the user.
Information about C Applications applies to both Windows and Linux. Visual Basic sections apply to Windows only. The subtopics on this page are:
- Formatted I/O in C Applications
- Formatted I/O Conversion
- Format Flags
- Field Width
- . Precision
- , Array Size
- Argument Modifier
- Format Codes
- Sample: Formatted I/O (C)
- Format Strings
- Formatted I/O Buffers
- Related Formatted I/O Functions
-
Formatted I/O in Visual Basic Applications
- Formatted I/O Conversion
- Format Flags
- Field Width
- . Precision
- , Array Size
- Argument Modifier
- Format Codes
- Format Strings
- Formatted I/O Buffers
- Related Formatted I/O Functions
- Non-Formatted I/O
Formatted I/O in C Applications
The SICL formatted I/O mechanism is similar to the C stdio mechanism. SICL formatted I/O, however, is designed specifically for instrument communication and is optimized for IEEE 488.2 compatible instruments. The three main functions for formatted I/O in C applications follow.
The iprintf function formats according to the format string and sends data to a device:
iprintf(
id,
format[,
arg1][,
arg2][,...]);
The iscanf function receives and converts data according to the format string:
iscanf(
id,
format[,
arg1][,
arg2][,...]);
The ipromptf function formats and sends data to a device, and then immediately receives and converts the response data:
ipromptf(
id,
writefmt,
readfmt[,
arg1]
arg2
[,][,...]);
The formatted I/O functions are buffered. Also, there are two non-buffered and non-formatted I/O functions called iread and iwrite. These are raw I/O functions and should not be intermixed with formatted I/O functions.
If raw I/O must be mixed, use the ifread/
ifwrite functions. These functions have the same parameters as iread and iwrite, but read or write raw output data to the formatted I/O buffers. See Formatted IO Buffers and Non-Formatted I/O for details.
Formatted I/O Conversion
Formatted I/O functions convert data under the control of the format string. The format string specifies how the argument is converted before it is input or output. A typical format string syntax is:
%[format flags][field width][. precision]
[, array size][argument modifier]format code
Format Flags
Zero or more flags may be used to modify the meaning of the format code. The format flags are only used when sending formatted I/O (iprintf and ipromptf). Supported format flags are:
Format Flag |
Description |
|
Converts to a 488.2 NR1 number. |
|
Converts to a 488.2 NR2 number. |
|
Converts to a 488.2 NR3 number. |
|
Converts to a 488.2 hexadecimal number. |
|
Converts to a 488.2 octal number. |
|
Converts to a 488.2 binary number. |
|
Prefixes number with sign (+ or –). |
|
Left-justifies result. |
|
Prefixes number with blank space if positive or with – if negative. |
|
Uses alternate form. For o conversion, it prints a leading zero. For x or X, a nonzero will have 0x or 0X as a prefix. For e, E, f, g, or G, the result will always have one digit on the right of the decimal point. |
|
Causes left pad character to be a zero for all numeric conversion types. |
This example converts numb into a 488.2 floating point number and sends the value to the session specified by id:
int numb = 61;
iprintf (id, “%@2d&\n”, numb);
Sends: 61.000000
Field Width
is an optional integer that specifies how many characters are in the field. If the formatted data has fewer characters than specified in the field width, it will be padded. The pad character is dependent on various flags. You can use an asterisk (*) in place of the integer to indicate that the integer is taken from the next argument.
This example pads numb to six characters and sends the value to the session specified by id:
long numb = 61;
iprintf (id, “%6ld&\n”, numb);
Pads to six characters: 61
. Precision
is an optional integer preceded by a period. When used with format codes e
, E
, and f
, the number of digits to the right of the decimal point are specified. For the d, i, o, u, x, and X format codes, the minimum number of digits to appear is specified. For the s and S format codes, the precision specifies the maximum number of characters to be read from the argument.
This field is only used when sending formatted I/O (iprintf and ipromptf). You can use an asterisk (*) in place of the integer to indicate that the integer is taken from the next argument.
This example converts numb so that there are only two digits to the right of the decimal point and sends the value to the session specified by id:
float numb = 26.9345;
iprintf (id, “.2f\n”, numb);
Sends: 26.93
, Array Size
The comma operator is a format modifier which allows you to read or write a comma-separated list of numbers (only valid with %d
and %f
format codes). It is a comma followed by an integer. The integer indicates the number of elements in the array. The comma operator has the format of ,
dd where dd is the number of elements to read or write. This example specifies a comma-separated list to be sent to the session specified by id.
int list[5]={101,102,103,104,105};
iprintf (id, “%,5d\n”, list);
Sends: 101,102,103,104,105
Argument Modifier
The meaning of the optional argument modifier h, l, w, z, or Z is dependent on the format code.
Argument |
Format Codes |
Description |
|
|
Corresponding argument is a short integer. |
|
|
Corresponding argument is a float for |
|
|
Corresponding argument is a long integer. |
|
|
Corresponding argument is a pointer to a block of long integers. |
|
|
Corresponding argument is a double for |
|
|
Corresponding argument is a pointer to a block of short integers. |
|
|
Corresponding argument is a pointer to a block of floats. |
|
|
Corresponding argument is a pointer to a block of doubles. |
Format Codes
for sending and receiving formatted I/O are different. The following tables summarize the format codes for each.
Format Codes |
Description |
|
Corresponding argument is an integer. |
|
Corresponding argument is a float. |
|
Corresponding argument is a pointer to an arbitrary block of data. |
|
Corresponding argument is a character. |
|
Controls whether the END indicator is sent with each LF character in the format string. |
|
Corresponding argument is a pointer to a null terminated string. |
|
Sends an ASCII percent (%) character. |
|
Corresponding argument will be treated as an unsigned integer. |
|
Corresponding argument is a double. |
|
Corresponding argument is a pointer to an integer. |
|
Corresponding argument is a pointer to a FILE descriptor opened for reading. |
This example sends an arbitrary block of data to the session specified by the id parameter. The asterisk (*
) is used to indicate that the number is taken from the next argument:
int size = 1024;
char data [1024];
.
.
iprintf (id, “%*b&\n”, size, data);
Sends 1024 characters of block data.
Format Codes |
Description |
|
Corresponding argument must be a pointer to an integer. |
|
Corresponding argument must be a pointer to a float. |
|
Corresponding argument is a pointer to a character. |
|
Corresponding argument is a pointer to a string. |
|
Corresponding argument must be a pointer to an unsigned integer. |
|
Corresponding argument must be a character pointer. |
|
Corresponding argument is a pointer to a FILE descriptor opened for writing. |
This example receives data from the session specified by the id parameter and converts the data to a string:
char data[180];
iscanf (id, “%s”, data);
Sample: Formatted I/O (C)
shows one way to send and receive formatted I/O. This code sample opens a GPIB communications session with a multimeter and uses a comma operator to send a comma-separated list to the multimeter. The lf format codes are used to receive a double from the multimeter.
/* formatio.c
This example program makes a multimeter measurement with a comma-separated list passed with formatted I/O and prints the results */
#include <sicl.h>
#include <stdio.h>
main()
{
INST dvm;
double res;
double list[2] = {1,0.001};
/
* Log message and terminate on error */
ionerror (I_ERROR_EXIT);
/* Open the multimeter session */
dvm = iopen (“gpib0,16”);
itimeout (dvm, 10000);
/*Initialize dvm*/
iprintf (dvm, “*RST\n”);
/*Set up multimeter and send comma-separated
list*/
iprintf (dvm, “CALC:DBM:REF 50\n”);
iprintf (dvm, “MEAS:VOLT:AC? %,2lf\n”, list);
/* Read the results */
iscanf (dvm,”%lf”,&res);
/* Print the results */
printf (“Result is %f\n”,res);
/* Close the multimeter session */
iclose (dvm);
r
eturn 0;
}
Format Strings
for iprintf puts a special meaning on the newline character (\n
). The newline character in the format string flushes the output buffer to the device. All characters in the output buffer will be written to the device with an END indicator included with the last byte (the newline character). This means you can control the point at which the data is written to the device.
If no newline character is included in the format string for an iprintf call, the characters converted are stored in the output buffer. You must make another call to iprintf or a call to iflush to have those characters written to the device.
This can be very useful in queuing up data to send to a device. It can also raise I/O performance by doing a few large writes instead of several smaller writes. You can change this behavior with the isetbuf and isetubuf functions. See Formatted I/O Buffers for details.
The format string for iscanf ignores most white-space characters. Two white-space characters that it does not ignore are newlines (\n) and carriage returns (\r). These characters are treated just like normal characters in the format string, which must match the next non-white-space character read from the device.
Formatted I/O Buffers
The SICL software maintains both a read and a write buffer for formatted I/O operations. Occasionally, you may want to control the actions of these buffers. See the isetbuf function for other options for buffering data.
The write buffer is maintained by the iprintf and the write portion of the ipromptf functions. It queues characters to send to the device so that they are sent in large blocks, thus increasing performance. The write buffer automatically flushes when it sends a newline character from the format string (see the %t
format code to change this feature).
The write buffer also flushes immediately after the write portion of the ipromptf function. It may occasionally be flushed at other non-deterministic times, such as when the buffer fills. When the write buffer flushes, it sends its contents to the device.
The read buffer is maintained by the iscanf and the read portion of the ipromptf functions. The read buffer queues the data received from a device until it is needed by the format string. The read buffer is automatically flushed before the write portion of an ipromptf. Flushing the read buffer destroys the data in the buffer and guarantees that the next call to iscanf or ipromptf reads data directly from the device rather than from data that was previously queued.
NOTE: Flushing the read buffer also includes reading all pending response data from a device. If the device is still sending data, the flush process will continue to read data from the device until it receives an END indicator from the device.
Related Formatted I/O Functions
A set of functions related to formatted I/O follows.
I/O Function |
Description |
|
Obtains raw data directly from the read formatted I/O buffer. This is the same buffer that iscanf uses. |
|
Writes raw data directly to the write formatted I/O buffer. This is the same buffer that iprintf uses. |
|
Converts data via a format string and writes the arguments appropriately. |
|
Reads data from a device/interface, converts this data via a format string, and assigns the values to your arguments. |
|
Sends, then receives, data from a device/instrument. It also converts data via format strings that are identical to iprintf and iscanf. |
|
Flushes the formatted I/O read and write buffers. A flush of the read buffer means that any data in the buffer is lost. A flush of the write buffer means that any data in the buffer is written to the session’s target address. |
|
Sets the size of the formatted I/O read and the write buffers. A size of zero (0) means no buffering. If no buffering is used, performance can be severely affected. |
|
Sets the read or the write buffer to your allocated buffer. The same buffer cannot be used for both reading and writing. You should also be careful when using buffers that are automatically allocated. |
Formatted I/O in Visual Basic Applications
This section contains information specific to the Windows product.
SICL formatted I/O is designed specifically for instrument communication and is optimized for IEEE 488.2 compatible instruments. The two main functions for formatted I/O in Visual Basic applications are:
The ivprintf function, which formats according to the format string and sends data to a device:
Function ivprintf(id As Integer, fmt As
String, ap As Any) As Integer
The ivscanf function, which receives and converts data according to the format string:
Function ivscanf(id As Integer, fmt As
String,ap As Any) As Integer
NOTE: There are certain restrictions when using ivprintf and ivscanf with Visual Basic. For details about these restrictions, see Restrictions Using ivprintf in Visual Basic in the Programming with Sicl > Using iprintf section of this help file, or Restrictions Using ivscanf in Visual Basic in the Programming with Sicl > Using iscanf section.
The formatted I/O functions are buffered. There are two non-buffered and non-formatted I/O functions called iread and iwrite. These are raw I/O functions and do not intermix with the formatted I/O functions.
If raw I/O must be mixed, use the ifread or ifwrite functions. They have the same parameters as iread and iwrite, but read or write raw output data to the formatted I/O buffers. See Formatted IO Buffers and Non-Formatted I/O for details.
Formatted I/O Conversion
The formatted I/O functions convert data under the control of the format string. The format string specifies how the argument is converted before it is input or output. The typical format string syntax is:
%[format flags][field width][. precision]
[, array size][argument modifier]format code
Format Flags
Zero or more flags may be used to modify the meaning of the format code. The format flags are only used when sending formatted I/O (ivprintf). Supported format flags are:
Format Flag |
Description |
|
Converts to a 488.2 NR1 number. |
|
Converts to a 488.2 NR2 number. |
|
Converts to a 488.2 NR3 number. |
|
Converts to a 488.2 hexadecimal number. |
|
Converts to a 488.2 octal number. |
|
Converts to a 488.2 binary number. |
|
Prefixes number with sign (+ or –). |
|
Left justifies result. |
|
Prefixes number with blank space if positive or with – if negative. |
|
Uses alternate form. For o conversion, it prints a leading zero. For x or X, a nonzero will have 0x or 0X as a prefix. For e, E, f, g, or G, the result will always have one digit on the right of the decimal point. |
|
Causes left pad character to be a zero for all numeric conversion types. |
This example converts numb into a 488.2 floating point number to the session specified by id. The function return values must be assigned to variables for all Visual Basic function calls. Also, + Chr$(10) adds the newline character to the format string to indicate that the formatted I/O write buffer should be flushed. (This is equivalent to the \n
character sequence used for C/C++ programs.)
Dim numb As Integer
Dim ret_val As Integer
numb = 61
ret_val = ivprintf(id, “%@2d” + Chr$(10), numb)
Sends: 61.000000
Field Width
is an optional integer that specifies how many characters are in the field. If the formatted data has fewer characters than specified in the field width, it will be padded. The padded character is dependent on various flags. This example pads numb to six characters and sends the value to the session specified by id:
Dim numb As Integer
Dim ret_val As Integer
numb = 61
ret_val = ivprintf(id, “%6d” + Chr$(10), numb)
Pads to six characters: 61
. Precision
is an optional integer preceded by a period. When used with format codes e, E, and f, the number of digits to the right of the decimal point are specified. For the d, i, o, u, x, and X format codes, the minimum number of digits to appear is specified. This field is only used when sending formatted I/O (ivprintf).
This example converts numb so there are only two digits to the right of the decimal point and sends the value to the session specified by id:
Dim numb As Double
Dim ret_val As Integer
numb = 26.9345
ret_val = ivprintf(id, “%.2lf” + Chr$(10), numb)
Sends: 26.93
, Array Size
The comma operator is a format modifier which allows you to read or write a comma-separated list of numbers (only valid with %d and %f format codes). It is a comma followed by an integer. The integer indicates the number of elements in the array. The comma operator has the format of ,dd where dd is the number of elements to read or write.
This example specifies a comma-separated list to be sent to the session specified by id.
Dim list(4) As Integer
Dim ret_val As Integer
list(0) = 101
list(1) = 102
list(2) = 103
list(3) = 104
list(4) = 105
ret_val = ivprintf(id, “%,5d” + Chr$(10),
list(0))
Sends: 101,102,103,104,105
Argument Modifier
The optional argument modifier h, l, w, z, or Z is dependent on the format code.
Argument |
Format Codes |
Description |
h |
d,i |
Corresponding argument is an Integer. |
h |
f |
Corresponding argument is a Single. |
l |
d,i |
Corresponding argument is a Long. |
l |
d,B |
Corresponding argument is an array of Long. |
l |
f |
Corresponding argument is a Double. |
w |
d,B |
Corresponding argument is an array of Integer. |
z |
d,B |
Corresponding argument is an array of Single. |
Z |
d,B |
Corresponding argument is an array of Double. |
Format Codes
for sending and receiving formatted I/O are different. The following tables summarize the format codes for each.
Format Codes |
Description |
|
Corresponding argument is an Integer. |
b, B |
Not supported in Visual Basic. |
c,C |
Not supported in Visual Basic. |
t |
Not supported in Visual Basic. |
s,S |
Not supported in Visual Basic. |
% |
Sends an ASCII percent (%) character. |
o,u,x,X |
Corresponding argument will be treated as an Integer. |
f,e,E,g,G |
Corresponding argument is a Double. |
n |
Corresponding argument is an Integer. |
F |
Corresponding arg is a pointer to a FILE descriptor. |
Format Codes |
Description |
d,i,n |
Corresponding argument must be an Integer. |
e,f,g |
Corresponding argument must be a Single. |
c |
Corresponding argument is a fixed length String. |
s,S,t |
Corresponding argument is a fixed length String. |
o,u,x |
Corresponding argument must be an Integer. |
[ |
Corresponding argument must be a fixed length character String. |
F |
Not supported in Visual Basic. |
This example receives data from the session specified by the id parameter and converts the data to a string:
Dim ret_val As Integer
Dim data As String * 180
ret_val = ivscanf(id, “%180s”, data)
‘ Example: Formatted I/O (Visual Basic)
Option Explicit
'''''''''''''''''''''''''''''''''''''''''''''''
'nonfmt.bas
'The following subroutine measures AC voltage
'on a multimeter and prints out the results.
'''''''''''''''''''''''''''''''''''''''''''''''
Sub Main()
Dim dvm As Integer
Dim strres As String * 20 'Fixed-length String
Dim actual As Long
'Open the multimeter session
'"gpib0" is the SICL Interface name as defined
'in the Connection Expert
'"23" is the instrument gpib address on the bus
'Change these to the SICL Name and gpib address
'for your instrument
dvm = iopen("gpib0,23")
Call itimeout(dvm, 5000)
'Initialize dvm
Call iwrite(dvm, "*RST" + Chr$(10), 5, 1, 0&)
'Set up multimeter and take measurements
Call iwrite(dvm, "CALC:DBM:REF 50" + _
Chr$(10), 16, 1, 0&)
Call iwrite(dvm, "MEAS:VOLT:AC? 1, 0.001") +
Chr$(10), 23, 1, 0&)
'Read measurements
Call iread(dvm, strres, 20, 0&, actual)
'Display the results
MsgBox "Result is " + Left$(strres, actual)
'Close the multimeter session
Call iclose(dvm)
E
xit Sub
End Sub
Format Strings
In the format string for ivprintf, when the special characters Chr$(10) are used, the output buffer to the device is flushed. All characters in the output buffer will be written to the device with an END indicator included with the last byte. This means you can control at what point you want the data written to the device.
If no Chr$(10) is included in the format string for an ivprintf call, the characters converted are stored in the output buffer. It will require another call to ivprintf or a call to iflush to have those characters written to the device. This can be very useful in queuing up data to send to a device. It can also raise I/O performance by doing a few large writes instead of several smaller writes.
The format string for ivscanf ignores most white-space characters. Two white-space characters that it does not ignore are newlines (Chr$(10)) and carriage returns (Chr$(13)
). These characters are treated just like normal characters in the format string, which must match the next non-white-space character read from the device.
Formatted I/O Buffers
The SICL software maintains both a read and write buffer for formatted I/O operations. Occasionally, you may want to control the actions of these buffers.
The write buffer is maintained by the ivprintf function. It queues characters to send to the device so that they are sent in large blocks, thus increasing performance. The write buffer automatically flushes when it sends a newline character from the format string. The write buffer may occasionally be flushed at other non-deterministic times, such as when the buffer fills. When the write buffer flushes, it sends its contents to the device.
The read buffer is maintained by the ivscanf function. It queues the data received from a device until it is needed by the format string. Flushing the read buffer destroys the data in the buffer and guarantees that the next call to ivscanf reads data directly from the device rather than data that was previously queued.
NOTE: Flushing the read buffer also includes reading all pending response data from a device. If the device is still sending data, the flush process will continue to read data from the device until it receives an END indicator from the device.
Related Formatted I/O Functions
These functions are related to formatted I/O in Visual Basic:
I/O Function |
Description |
ifread |
Obtains raw data directly from the read formatted I/O buffer. This is the same buffer that ivscanf uses. |
ifwrite |
Writes raw data directly to the write formatted I/O buffer. This is the same buffer that ivprintf uses. |
ivprintf |
Converts data via a format string and converts the arguments appropriately. |
ivscanf |
Reads data from a device/interface, converts data via a format string, and assigns the value to your arguments. |
iflush |
Flushes the formatted I/O read and write buffers. A flush of the read buffer means that any data in the buffer is lost. A flush of the write buffer means that any data in the buffer is written to the session’s target address. |
Non-Formatted I/O
There are two non-buffered, non-formatted I/O functions called iread and iwrite. These are raw I/O functions and do not intermix with the formatted I/O functions. If raw I/O must be mixed, use the ifread and ifwrite functions that have the same parameters as iread and iwrite, but read/write raw data from/to the formatted I/O buffers.
iread Function
The iread function reads raw data from the device or interface specified by the id parameter and stores the results in the location where buf is pointing.
C sample:
iread(id, buf, bufsize, reason, actualcnt);
VB sample:
Call iread(id, buf, bufsize, reason, actualcnt)
iwrite Function
The iwrite function sends the data pointed to by buf to the interface or device specified by id.
C sample:
iwrite(id, buf, datalen, end, actualcnt);
VB sample:
Call iwrite(id, buf, datalen, end, actualcnt)
Sample: Non-Formatted I/O (C)
This C language program illustrates using non-formatted I/O to communicate with a multimeter over the GPIB interface. The SICL non-formatted I/O functions iwrite and iread are used for communication. A similar example was used to illustrate formatted I/O earlier in this topic.
/* nonfmt.c
This example program measures AC voltage on a multimeter and prints the results*/
#include <sicl.h>
#include <stdio.h>
main()
{
INST dvm;
char strres[20];
unsigned long actual;
/
* Log message and terminate on error */
ionerror (I_ERROR_EXIT);
/* Open the multimeter session */
dvm = iopen (“gpib0,16”);
itimeout (dvm, 10000);
/*Initialize dvm*/
iwrite (dvm, “*RST\n”, 5, 1, NULL);
/*Set up multimeter and take measurements*/
iwrite (dvm,”CALC:DBM:REF 50\n”,16,1,NULL);
iwrite (dvm,”MEAS:VOLT:AC? 1,
0.001\n”,23,1,NULL);
/* Read measurements */
iread (dvm, strres, 20, NULL, &actual);
/* NULL terminate result string and print the
results*/
/* This technique assumes the last byte sent
was a line-feed */
if (actual){
strres[actual - 1] = (char) 0;
printf(“Result is %s\n”, strres);
}
/* Close the multimeter session */
iclose(dvm);
r
eturn 0; }
Sample: Non-Formatted I/O (Visual Basic)
(Windows only)
' nonfmt.bas
' The following subroutine measures AC voltage
‘ on a multimeter and prints the results.
Sub Main ()
Dim dvm As Integer
Dim strres As String * 20
Dim actual As Long
' Open the multimeter session
dvm = iopen(“gpib0,16”)
Call itimeout(dvm, 10000)
' Initialize dvm
Call iwrite(dvm,ByVal “*RST” + Chr$(10), 5,
1,\ 0&)
' Set up multimeter and take measurements
Call iwrite(dvm,ByVal “CALC:DBM:REF 50” +
Chr$(10),16,1, 0&)
Call iwrite(dvm,ByVal “MEAS:VOLT:AC? 1, 0.001”
+ Chr$(10),23,1, 0&)
' Read measurements
Call iread(dvm,ByVal strres, 20, 0&, actual)
' Print the results
Print “Result is “ + Left$(strres, actual)
' Close the multimeter session
Call iclose(dvm)
E
xit Sub
End Sub