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:
-
Select
File
>
New
from the menu. Select theProject
tab. -
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 theOK
button. -
The Win32 Application wizard will appear. Select
An empty project
and clickFinish
. -
Click
Project > Add to Project > Files...
Browse to the sample folder. Select the source filesscope.c
,scope.rc
, andscope.h
to add them to the project. Also addsicl32.lib
from thelib
directory (by default,C:\Program Files\Agilent\IO Libraries Suite\lib)
. -
Select
Project
>
Settings
from the menu and click theC
/C
++
tab. SelectCode Generation
from theCategory
list box. Then, selectMultithreaded
DLL
from theUse run-time library
list box, and then clickOK
. -
Select
Tools
>
Options
from the menu and click theDirectories
tab in theOptions
dialog box. SelectInclude Files
from theShow Directories for:
list box, click theNew
icon, click below the last directory in the list box, and browse to the IO Libraries Suiteinclude
directory (by default,C:\Program Files\Agilent\ IO Libraries Suite\include
), and then clickOK
. -
Select
Build >
Build
samplename.exe
to build the application.
If there are no errors reported, you can execute the program by selecting Build >
Execute
samplename.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.
- Put
scope.c
andscope.h
under the same directory - Run command on command line terminal:
gcc scope.c -I/opt/keysight/iolibs/include -lsicl -o scope
- 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.
|
Visual Basic source for the SCOPE sample program. |
|
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:
- Connect a Keysight 54601A oscilloscope to your interface.
- Run Visual Basic 6.0.
- Open the project file
scope.vbp
by selectingFile
>
Open Project
from the Visual Basic menu. - Edit the
scope.frm
file to set the scope_address constant to the address of your oscilloscope. To do this:- If a Project Tree is not already visible, select
View
>
Project Explorer
from the Visual Basic menu. - Under
Forms
, right-clickscope.frm
and selectView Code
. - Edit the following line so the address is set to the address of the oscilloscope:
Private Const scope_address = "gpib0,7" '
Address of SCOPE
- If a Project Tree is not already visible, select
- Run the program by pressing the
F5
key or by clicking theRUN
button on the Visual Basic Toolbar. - Press the
Waveform
button to get and display the waveform. - Press the
Integral
button to calculate and display the integral. - After performing these steps, you can create a standalone executable (
.exe
) version of this program by selectingFile
>
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.
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 |
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. |