Additional Sample Programs

This section contains two additional sample programs that provide guidelines to help you develop SICL applications. The first example is for both operating systems, and the second (Visual Basic) is for Windows only.

Sample: Oscilloscope Program (C)

This C sample programs an oscilloscope (such as a Keysight 54601), uploads the measurement data, and instructs the oscilloscope to print its display to a printer. This program uses many SICL features and illustrates some important C and Windows programming techniques for SICL.

Program Files

The oscilloscope sample files are available at http://www.keysight.com/find/iosuite. The sample includes the source program and a number of files to help you build the sample with specific compilers, depending on the Windows environment used.

Building the Project File (Windows)

( This "building" section applies only in Windows.)

This section shows how to create the project file for this sample using Microsoft Visual C++ 6.0.

To compile and link the sample program with Microsoft Visual C:

  1. Select File > New from the menu. Select the Project tab.

  2. Type the name you want for the project in the edit box labeled Project name. Then, select Win32 Application from the project type list box. Specify a directory location for the project in the Location edit box. Click the OK button.

  3. The Win32 Application wizard will appear. Select An empty project and click Finish.

  4. Click Project > Add to Project > Files... Browse to the sample folder. Select the source files scope.c, scope.rc, and scope.h to add them to the project. Also add sicl32.lib from the lib directory (by default, C:\Program Files\Agilent\IO Libraries Suite\lib).

  5. Select Project > Settings from the menu and click the C/C++ tab. Select Code Generation from the Category list box. Then, select Multithreaded DLL from the Use run-time library list box, and then click OK.

  6. Select Tools > Options from the menu and click the Directories tab in the Options dialog box. Select Include Files from the Show Directories for: list box, click the New icon, click below the last directory in the list box, and browse to the IO Libraries Suite include directory (by default, C:\Program Files\Agilent\ IO Libraries Suite\include), and then click OK.

  7. Select Build > Buildsamplename.exe to build the application.

If there are no errors reported, you can execute the program by selecting Build > Executesamplename.exe. An application window will open. Several commands are available from the Action menu, and any results or output will be printed in the program window. To end the program, select File > Exit from the program menu.

Compiling the Program (Linux)

( This "compiling" section applies only in Linux.)

This section shows how to compile program with SICL library using GCC.

  1. Put scope.c and scope.h under the same directory
  2. Run command on command line terminal: gcc scope.c -I/opt/keysight/iolibs/include -lsicl -o scope
  3. If there are no errors reported, you can execute by running command ./scope. Several commands are available from the Action menu, and any results or output will be printed in the program window. To end the program, press Ctrl+C on the keyboard.

Program Overview

You may want to view the program with an editor as you read through this section. The entire program is not listed here because of its length. This program illustrates specific SICL features and programming techniques and is not meant to be a robust Windows application. See the SICL online Help for detailed information on the SICL features used in this program.

Custom Error Handler

The oscilloscope program defines a custom error handler that is called whenever an error occurs during a SICL call. The handler is installed using ionerror before any other SICL function call is made, and will be used for all SICL sessions created in the program.

void SICLCALLBACK my_err_handler(INST id, int
error)
{
...
sprintf(text_buf[num_lines++], “session id=%d,
error = %d:%s”, id, error, eterrstr(error));

sprintf(text_buf[num_lines++], “Select ‘File |
Exit’ to exit program!”);...

// If error is from scope, disable I/O actions
// by graying out menu picks.
if (id == scope) {
... code to disallow further I/O requests
from user
}
}

The error number is passed to the handler, and igeterrstr is used to translate the error number into a more useful description string. If desired, different actions can be taken depending on the particular error or id that caused the error.

Locks

SICL allows multiple applications to share the same interfaces and devices. Different applications may access different devices on the same interface, or may alternately access the same device (a shared resource). If your program will be executing along with other SICL applications, you may want to prevent another application from accessing a particular interface or device during critical sections of your code. SICL provides the ilock/iunlock functions for this purpose.

void get_data (INST id)
{
... non-SICL code

/* lock device to prevent access from other
applications */
ilock(scope);

...

SICL I/O code to program scope and get data

/* release the scope for use by other
applications */
iunlock(scope);

... non-SICL code
}

Lock the interface or device with ilock before critical sections of code, and release the resource with iunlock at the end of the critical section. Using ilock on a device session prevents any other device session from accessing the particular device. Using ilock on an interface session prevents any other session from accessing the interface and any device connected to the interface.

Formatted I/O

SICL provides extensive formatted I/O functionality to help facilitate communication of I/O commands and data. The sample program uses a few of the capabilities of the iprintf/iscanf/ipromptf functions and their derivatives.

The iprintf function is used to send commands. As with all of the formatted I/O functions, the data is actually buffered. In this call, the \n at the end of the format:

iprintf(id,”:waveform:preamble?\n”);

causes the buffer to be flushed and the string to be output. If desired, several commands can be formatted before being sent and then all commands outputted at once. The formatted I/O buffers are automatically flushed whenever the buffer fills (see isetbuf) or when an iflush call is made.

When reading data back from a device, the iscanf function is used. To read the preamble information from the oscilloscope, use the format string “%,20f\n”:

iscanf(id,”%,20f\n”,pre);

This string expects to input 20 comma-separated floating point numbers into the pre array.

To upload the oscilloscope waveform data, use the string “%#wb\n”. The wb indicates that iscanf should read word-wide binary data. The # preceding the data modifier tells iscanf to get the maximum number of binary words to read from the next parameter (&elements):

iscanf(id,”%#wb\n”,&elements,readings);

The read will continue until an EOI indicator is received or the maximum number of words have been read.

Interface Sessions

Sometimes it may be necessary to control the GPIB bus directly instead of using SICL commands. This is accomplished using an interface session and interface-specific commands. This sample uses igetintfsess to get a session for the interface to which the oscilloscope is connected. (If you know which interface is being used, it is also possible to just use an iopen call on that interface.)

Then, igpibsendcmd is used to send some specific command bytes on the bus to tell the printer to listen and the oscilloscope to send its data. The igpibatnctl function directly controls the state of the ATN signal on the bus.

void print_disp (INST id)
{
INST gpib0intf ;
...

gpib0intf = igetintfsess(id);
...

/* tell oscilloscope to talk and printer to
listen. The listen command is formed by adding
32 to the device address of the device to be a
listener. The talk command is formed by adding
64 to the device address of the device to be a
talker. */

cmd[0] = (unsigned char)63 ; // 63 is unlisten
cmd[1] = (unsigned char)(32+1) ; /* printer at
addr 1, make it a listener */
cmd[2] = (unsigned char)(64+7) ; /* scope at
addr 7,make it a talker */
cmd[3] = ‘\0’; /* terminate the string */

length = strlen (cmd) ;

igpibsendcmd(gpib0intf,cmd,length);
igpibatnctl(gpib0intf,0);

...
}

SRQs and iwaithdlr

Many instruments are capable of using the service request (SRQ) signal on the GPIB bus to signal the controller that an event has occurred. If an application needs to respond to SRQs, an SRQ handler must be installed with the ionsrq call. All SRQ handlers are called whenever an SRQ occurs.

In the sample handler, the oscilloscope status is read to verify that the oscilloscope asserted SRQ, and then the SRQ is cleared and a status message is displayed. If the oscilloscope did not assert SRQ, the handler prints an error message.

void SICLCALLBACK my_srq_handler(INST id)
{
unsigned char status;

/* make sure it was the scope requesting
service */
ireadstb(id,&status);

if (status &= 64) {
/* clear the status byte so the scope can
assert SRQ again if needed. */
iprintf(id,”*CLS\n”);
sprintf(text_buf[num_lines++], “id = %d, SRQ
received!, stat=0x%x”, id,status);
} else {
sprintf(text_buf[num_lines++],
“SRQ received, but not from the scope”);
}
InvalidateRect(hWnd, NULL, TRUE);
}

In the routine that commands the oscilloscope to print its display, the oscilloscope is set to assert SRQ when printing is finished. While the oscilloscope is printing, the sample program has the application suspend execution. SICL provides the function iwaithndlr that will suspend execution and wait until either an event occurs that would call a handler, or a specified timeout value is reached.

In the sample, interrupt events are turned off with iintroff so that all interrupts are disabled while interrupts are being set up. Then, the SRQ handler is installed with ionsrq. Code to program the oscilloscope to print and send an SRQ is next, then the call to iwaithdlr, with a timeout value of 30 seconds. When the oscilloscope finishes printing and sends the SRQ, the SRQ handler will be executed and then iwaithdlr will return. A call to iintron re-enables interrupt events.

void print_disp (INST id)
{
...

iintroff();
ionsrq(id,my_srq_handler);/* Not supported on
82335 */

/* tell the scope to SRQ on ‘operation
complete’ */
iprintf(id,”*CLS\n”);
iprintf(id,”*SRE 32 ; *ESE 1\n”) ;

/* tell the scope to print */
iprintf(id,”:print ; *OPC\n”) ;

... code to tell the scope to print

/* wait for SRQ before continuing program */
iwaithdlr(30000L);
iintron();

sprintf (text_buf[num_lines++],”Printing
complete!”) ;
...
}

Sample: Oscilloscope Program (Visual Basic)

This section contains information specific to the Windows product.

This Visual Basic sample program uses SICL to get and plot waveform data from a Keysight 54601A (or compatible) oscilloscope. This routine is called each time the cmdGetWaveform command button is clicked.

Program Files

The oscilloscope sample files are available at http://www.keysight.com/find/iosuite. The files are listed in the following table.

Files Used for the Oscilloscope Sample Program

SCOPE.FRM

Visual Basic source for the SCOPE sample program.

SCOPE.VBP

Visual Basic project file for the SCOPE sample program.

SCOPE.VBW

Visual Basic workspace file for the SCOPE sample program.

Loading and Running the Program

Follow these steps to load and run the SCOPE sample program:

  1. Connect a Keysight 54601A oscilloscope to your interface.
  2. Run Visual Basic 6.0.
  3. Open the project file scope.vbp by selecting File > Open Project from the Visual Basic menu.
  4. Edit the scope.frm file to set the scope_address constant to the address of your oscilloscope. To do this:
    1. If a Project Tree is not already visible, select View > Project Explorer from the Visual Basic menu.
    2. Under Forms, right-click scope.frm and select View Code.
    3. Edit the following line so the address is set to the address of the oscilloscope:
      Private Const scope_address = "gpib0,7" '
      Address of SCOPE
  5. Run the program by pressing the F5 key or by clicking the RUN button on the Visual Basic Toolbar.
  6. Press the Waveform button to get and display the waveform.
  7. Press the Integral button to calculate and display the integral.
  8. After performing these steps, you can create a standalone executable (.exe) version of this program by selecting File > Make scope.exe... from the Visual Basic menu.

Program Overview

You may want to view the program with an editor as you read through this section. The entire program is not listed here because of its length. This program illustrates specific SICL features and programming techniques and is not meant to be a robust Windows application. See the SICL online Help for detailed information on the SICL features used in this program.

Functions of the Sample Program

Listing

Description

CmdGetWaveform_Click

Subroutine that is called when the cmdGetWaveform command button is pressed. The command button is labeled Waveform.

On Error

This Visual Basic statement enables an error handling routine within a procedure. In this sample, an error handler is installed starting at label ErrorHandler within the cmdOutputCmd_Click subroutine.

The error handling routine is called any time an error occurs during the processing of the cmdGetWaveform_Click procedure. SICL errors are handled in the same way that Visual Basic errors are handled with the On Error statement.

CmdGetWaveform.Enabled

The button that causes the cmdGetWaveform_Click routine to be called is disabled when code is executing inside cmdOutputCmd_Click. This is good programming style.

iopen

An iopen call is made to open a device session for the oscilloscope. The device address for the oscilloscope is in the scope_address string.In this sample, the default address is “gpib0,7.” The interface name gpib0 is the name given to the interface with Connection Expert. The bus (primary) address of the oscilloscope follows, in this case 7. You may want to change the scope_address string to specify the correct address for your configuration.

igetintfsess

igetintfsess is called to return an interface session id for the interface to which the oscilloscope instrument is connected. This interface session will be used by the following iclear call to send an interface clear to reset the interface.

iclear

The iclear function is called to reset the interface.

itimeout

itimeout is called to set the timeout value for the oscilloscope's device session to 3 seconds.

ivprintf

The ivprintf function is called four times to set up the oscilloscope and then request the oscilloscope's preamble information. In each case Chr$(10) is appended to the format string passed as the second argument to ivprintf. This tells ivprintf to flush the formatted I/O write buffer after writing the string specified in the format string.

ivscanf

The ivscanf function is called to read the oscilloscope's preamble information into the preamble array. The preamble array is passed as the third parameter to ivscanf. This passes the address of the first element of the preamble array to the ivprintf SICL function.

ivprintf

ivprintf is called to prompt the oscilloscope for its waveform data. Again, Chr$(10) is appended to the format string passed as the second argument to ivprintf. This tells ivprintf to flush the formatted I/O write buffer after writing the string specified in the format string.

iread

iread is called to read in the oscilloscope's waveform. The waveform is read in as a specified number of bytes. The format string passed as the third parameter to iread specifies that a maximum of 2010 Byte values be read into the Byte array. A null value, vbNull, is passed as the fourth value and a Long variable, actual, returns the number of bytes actually read. 0& may also be used for a null value.

iclose

The iclose subroutine closes the scope_id device session for the oscilloscope as well as the intf_id interface session obtained with igetintfsess.

cmdGetWaveform.Enabled

The button that causes the cmdGetWaveform_Click routine to be called is re-enabled when execution inside cmdGetWaveform_Click is finished. This allows the program to get another waveform.

Exit Sub

This Visual Basic statement causes the cmdGetWaveform_Click subroutine to be exited after normal processing has completed.

errorhandler:

This label specifies the beginning of the error handler that was installed for this subroutine. This handler is called whenever a run-time error occurs.

Error$

This Visual Basic function is called to get the error message for the error. The error returned is the most recent run-time error when no argument is passed to the function.

iclose

The iclose subroutine is called inside the error handler to close the scope_id device session for the oscilloscope as well as the intf_id interface session obtained with igetintfsess.

CmdGetWaveform.Enabled

This re-enables the button that causes the cmdGetWaveform_Click routine to be called. This allows the program to get another waveform.

Exit Sub

This Visual Basic statement causes the cmdGetWaveform_Click subroutine to be exited after processing an error in the subroutine's error handler.