GPIB system and method which provides asynchronous event notification5974541Abstract A GPIB system which includes asynchronous event notification. The GPIB application first provides a notify request to GPIB driver level software, preferably an ibnotify call or a GPIB Notify OLE control. The notify request includes a unit descriptor which uniquely identifies the GPIB device, event information regarding a plurality of GPIB events to monitor, a reference to a callback function in the GPIB application, and user defined reference data for the callback function. In response to the notify request, the GPIB driver level software begins monitoring events specified by the event information. When an event occurs which is being monitored, the GPIB driver level software recognizes the event and invokes the callback function. The invocation of the callback function is performed asynchronously to the GPIB application. The callback function may include one or more calls to one or more functions in the GPIB driver software. The callback function also uses the user defined reference data to aid in handling the event. Claims We claim: Description FIELD OF THE INVENTION
______________________________________
ibwrt(ud, command, count)
Write a Command
ibwait(ud, RQS)
Wait For the Device To Request Service
ibrd(ud, data, count)
Read The Data
______________________________________
A command is written to the device specified by the unit descriptor ud and then the application waits until the device requests service to read back the desired data. The time spent waiting on the RQS GPIB event is lost. Another approach for waiting on a GPIB event to occur is to write a command to the device and then periodically poll the device until the desired event has occurred. Between polls to the device, other operations can be carried out by the application. For example,
______________________________________
ibwrt(ud, command, count);
Write a Command
while (!(ibsta & RQS)) {
End Loop If Device Requested Service
Other Processing Do Other Program Tasks
ibwait(ud,0); Check For Device Requesting Service
}
ibrd(ud,count); Read The Data
______________________________________
However, this still requires periodic polling calls to be made from the application. These polls take processor time away from other tasks. Depending on the polling frequency, this also means there will be some delay in how quickly the device is serviced once it is ready to respond to the command. A more efficient solution to this problem is to use an asynchronous callback function according to the present invention, which is called immediately upon the occurrence of a GPIB event. Win32 GPIB applications can asynchronously receive event notifications using the ibnotify function or the GpibNotify OLE control. This is useful if the user desires the application to be notified asynchronously about the occurrence of one or more GPIB events. Using ibnotify, or GpibNotify, the application does not need to check the status of the GPIB device. When the GPIB device requests service, the GPIB driver software automatically notifies the application that the event has occurred by invoking a callback function. The callback function executes when any of the GPIB events specified in the event mask parameter have occurred. FIG. 3: Flowchart Diagram Referring now to FIG. 3, a flowchart diagram illustrating operation of the present invention is shown. As discussed above, the present invention comprises a method of asynchronously notifying a user when one or more GPIB events occur in a GPIB system, wherein the system comprises a GPIB application which interfaces through GPIB driver software to a GPIB device. The GPIB driver software is preferably configured to use interrupts. As shown, in step 302 the GPIB driver software receives an asynchronous notify request from the GPIB application. As discussed above, the asynchronous notify request includes a unit descriptor, event information regarding a plurality of GPIB events to monitor, a reference to a callback function in the GPIB application, and user defined reference data for the callback function. The unit descriptor uniquely identifies the GPIB device. The event information preferably comprises a bit mask comprising a plurality of bits, wherein the bits in the bit mask are set to indicate monitoring of events. In step 304 the GPIB driver software begins monitoring events specified by the event information, i.e., begins monitoring events specified by the bits set in the bit mask. The monitoring is performed in response to receiving the asynchronous notify request. In the preferred embodiment, the events comprise state changes of the GPIB device identified by the unit descriptor. At some point in time, a relevant event is generated in the GPIB system. In other words, at some point in time an event occurs which is being monitored by the GPIB driver software in step 304. In step 306 the GPIB driver software determines that an event specified by the event information has occurred. In the preferred embodiment, an interrupt is generated in response to the event occurring. Thus the step of determining that an event specified by the event information has occurred includes receiving the interrupt indicating that the event has occurred and notifying the GPIB application of the event. In step 308 the GPIB driver software invokes the callback function in response to the determination that the event has occurred. According to the present invention, the GPIB driver software invokes the callback function asynchronously to the GPIB application. The callback function may include one or more calls to one or more functions in the GPIB driver software. If so, then during execution of the callback function to handle the event, the callback function invokes the one or more functions in the GPIB driver software. Also, the callback function to handle the event preferably uses the user-defined reference data. The callback function preferably returns a return value which is interpreted as a mask value. As described above, this return mask value is used to automatically rearm the asynchronous event notification mechanism. If the return mask value is 0, the asynchronous event notification mechanism is not rearmed. ibnotify/GPIB Notify Function Definition The purpose of ibnotify and GPIBNotify is to provide asynchronous event notification, e.g., to notify the user of one or more GPIB events by invoking the user callback. ibnotify is a function, and GpibNotify is an OLE control. 1. ibnotify Format for ibnotify C Format: int ibnotify (int ud, int mask, GpibNotifyCallback.sub.-- t Callback, void*RefData) Visual Basic Format: Not supported. Refer to the GpibNotify OLE control discussion below.
______________________________________
Input for ibnotify:
ud Unit descriptor
mask Bit mask of GPIB events to notice
Callback Pointer to the callback function (see prototype below)
RefData User-defined reference data for the callback
Output for ibnotify:
Function Return
The value of ibsta
______________________________________
Description of ibnotify: If mask is non-zero, ibnotify monitors the events specified by mask, and when one or more of the events is true, the Callback is invoked. For a board-level ibnotify call, all mask bits are valid except for ERR and RQS. For a device-level ibnotify call, the only valid mask bits are CMPL, TIMO, END, and RQS. If TIMO is set in the notify mask, ibnotify calls the callback function when the timeout period has elapsed, if one or more of the other specified events have not already occurred. If TIMO is not set in the notify mask, then the callback is not called until one or more of the specified events occur. Notification is performed when the state of one or more of the mask bits is true. Thus if a request is made to be notified when CMPL is true, and CMPL is currently true, the Callback is invoked immediately. For device-level usage, notification on RQS is not guaranteed to work if automatic serial polling is disabled. By default, automatic serial polling is enabled. A given ud can have only one outstanding ibnotify call at any one time. If a current ibnotify is in effect for ud, it is replaced by a subsequent ibnotify call. An outstanding ibnotify call for ud can be canceled by a subsequent ibnotify call for ud that has a mask of zero. If an ibnotify call is outstanding and one or more of the GPIB events the call is waiting on become true, the Callback is invoked. The ibnotify mask bits are defined in the following table:
______________________________________
Notify Mask Layout
Mnemonic
Bit Pos Hex Value
Description
______________________________________
TIMO 14 4000 Use the timeout period (see ibtmo) to
limit the notify period
END 13 2000 END or EOS is detected
SRQI 12 1000 SRQ is asserted (board only)
RQS 11 800 Device requested service (device only)
CMPL 8 100 I/O is complete (board only)
LOK 7 80 GPIB board is in Lockout State (board
only)
REM 6 40 GPIB board is in Remote State (board
only)
CIC 5 20 GPIB board is CIC (board only)
ATN 4 10 Attention is asserted (board only)
TACS 3 8 GPIB board is Talker (board only)
LACS 2 4 GPIB board is Listener (board only)
DTAS 1 2 GPIB board is in Device Trigger State
(board only)
DCAS 0 1 GPIB board is in Device Clear State
(board only)
______________________________________
Callback Prototype for ibnotify: int.sub.-- stdcall Callback (int LocalUd, int LocalIbsta, int LocalIberr, long LocalIbcntl, void*RefData)
______________________________________
Callback Parameters
______________________________________
LocalUd Board or device descriptor
LocalIbsta Value of ibsta
LocalIberr Value of iberr
LocalIbcntl Value of ibcntl
RefData User-defined reference data for the callback
______________________________________
Callback Return Value: Bit mask of the GPIB events to notice next The Callback function executes in a separate thread in the user's process. Therefore, the callback function has access to any process global data, but no access to thread local data. If the Callback needs to access global data, the user application must protect that access using a synchronization primitive (for example, a semaphore) because the Callback is running in a different thread context. Alternatively, the issue of data protection can be avoided entirely if the Callback simply posts a message to the user application using the Windows PostMessageo function. The Callback function can call any of the NI-488 or NI-488.2 functions with the exception of ibnotify. When the Callback is invoked, the values of the GPIB global variables (ibsta, iberr, ibcntl) are undefined. The status variables passed to Callback should be examined, instead of the GPIB globals, to determine why the Callback was invoked. It is noted that it is possible that the Callback may be invoked because of an error condition rather than because of the setting of one or more of the requested mask bits. The return value of the Callback is interpreted as a mask value, which is used to automatically rearm the asynchronous event notification mechanism. If the return value is zero, it is not rearmed. If the return value is non-zero, the asynchronous event notification mechanism is rearmed with the return mask value. If the Callback rearm fails due to an error, the Callback is invoked with LocalIbsta set to ERR, LocalIberr set to EDVR, and LocalIbcntl set to IBNOTIFY.sub.-- REARM.sub.-- FAILED. Like ibwait, ibstop, and ibonl, the invocation of the ibnotify Callback can cause the resynchronization of the handler after an asynchronous I/O operation has completed. In this case, the global variables passed into the Callback after I/O has completed contain the status of the I/O operation. For an overview of asynchronous event notification in a GPIB application, refer to the Asynchronous Event Notification section. For more information on usage, refer to the ibnotify Usage section. Possible Errors for ibnotify: EARG: A bit set in mask is invalid. ECAP: ibnotify has been invoked from within an ibnotify Callback finction, or the handler cannot perform notification on one or more of the specified mask bits. EDVR: Either ud is invalid or the NI-488.2M driver is not installed. ibcntl contains a system-dependent error code. ENEB: The interface board is not installed or is not properly configured. Possible Errors for ibnotify Callback EDVR: The Callback return failed to rearm the Callback. 2. GPIBNotify Format for the GpibNotify OLE Control Visual Basic: status&=GpibNotifyx.SetupNotify ud%, mask%; where x is the instance of the GpibNotify OLE control.
______________________________________
Input for the GpibNotify OLE Control
______________________________________
ud Unit descriptor
mask Bit mask of GPIB events to notice
______________________________________
The mask parameter is optional. Alternative ways to set the mask value include using the SetSetupMask method or changing its value on the SetupMask page of the GpibNotify control properties.
______________________________________
Output for the GpibNotify OLE Control:
______________________________________
Function Return The value of ibsta
______________________________________
Description of the GpibNotify OLE Control: If mask is non-zero, GpibNotify monitors the events specified by mask, and when one or more of the events is true, the Callback is invoked. For a board-level GpibNotify call, all mask bits are valid except for ERR and RQS. For a device-level GpibNotify call, the only valid mask bits are CMPL, TIMO, END, and RQS. Notification is performed when the state of one or more of the mask bits is true, so if a request is made to be notified when CMPL is true, and CMPL is currently true, the Callback is invoked immediately. For device-level usage, notification on RQS is not guaranteed to work if automatic serial polling is disabled. By default, automatic serial polling is enabled. A given ud can have only one outstanding GpibNotify call at any one time. If a current GpibNotify is in effect for ud, it is replaced by a subsequent GpibNotify call. An outstanding GpibNotify call for ud can be canceled by a subsequent GpibNotify call for ud that has a mask of zero. If a GpibNotify call is outstanding and one or more of the GPIB events it is waiting on become true, the Callback is invoked. After a SetupNotify call is made, the global GPIB status variables (ibsta, iberr, ibcnt, and ibcntl) are undefined. Instead, the thread-specific GPIB status variable functions (ThreadIbsta(), ThreadIberr(), ThreadIbcnt() and ThreadIbcntl()) should be used to examine the GPIB status variables returned by the SetupNotify call. This restriction only applies to the SetupNotify call; for the rest of the GPIB calls, the application can continue to examine ibsta, iberr, ibcnt, and ibcntl. It is noted that Visual Basic exhibits odd behavior if the GpibNotify control is destroyed before the Callback has been executed. For this reason, the user application should cancel any outstanding Callbacks by calling SetupNotify with a mask of zero before the control is destroyed. In addition, the application should give any blocked Callback threads an opportunity to run before destroying the control by executing a Sleep 0 call. Callback Prototype for the GpibNotify OLE Control Private Sub GpibNotifyx.sub.-- Notify(ByVal LocalUd As Long, ByVal LocalIbsta As Long, ByVal LocalIberr As Long, ByVal LocalIbcntl As Long, RearmMask As Long) where x is the instance of the Notify callback routine. Each GpibNotify call has its own Callback routine.
______________________________________
Callback Parameters
______________________________________
LocalUd Board or device descriptor
LocalIbsta Value of ibsta
LocalIberr Value of iberr
LocalIbcntl Value of ibcntl
RearmMask Bit mask of the GPIB events to notice next
______________________________________
The Callback function can call any of the NI-488 or NI-488.2 functions with the exception of GpibNotify. When the Callback is invoked, the values of the GPIB global variables (ibsta, iberr, ibcnt, ibcntl) are undefined. The status variables passed to Callback should be examined, instead of the GPIB globals, to determine why the Callback was invoked. Notice that it is possible that the Callback may be invoked because of an error condition rather than because of the setting of one or more of the requested mask bits. The RearmMask is interpreted as a mask value that the GPIB software uses to automatically rearm the asynchronous event notification mechanism. If RearmMask is set to zero, the Callback is not rearmed. If RearmMask is set to non-zero, the Callback is rearmed with the RearmMask value. If the Callback rearm fails because of an error, the Callback is invoked with LocalIbsta set to ERR, LocalIberr set to EDVR and LocalIbcntl set to IBNOTIFY.sub.-- REARM.sub.-- FAILED, which is defined in niglobal.bas. Like ibwait, ibstop and ibonl, the invocation of the GpibNotify Callback can cause the resynchronization of the handler after an asynchronous I/O operation has completed. In this case, the global variables passed into the Callback after I/O has completed contain the status of the I/O operation. Possible Errors for the GpibNotify OLE Control EARG: A bit set in mask is invalid. ECAP: GpibNotify has been invoked from within an GpibNotify Callback function, or the handler cannot perform notification on one or more of the specified mask bits. EDVR: Either ud is invalid or the NI-488.2M driver is not installed. ibcntl contains a system-dependent error code. ENEB: The interface board is not installed or is not properly configured. Possible Errors for the GpibNotify OLE Control Callback EDVR: The GpibNotify OLE control was unable to rearm the Callback. Ibnotify Usage The ibnotify function is passed a unit descriptor, the bit mask of the desired GPIB events, the address of the user-defined callback function, and user-defined reference data. ibnotify has the following prototype:
______________________________________
ibnotify (
int ud, //unit descriptor
int mask, //bit mask of GPIB events
GpibNotifyCallback.sub.-- t Callback, //callback function
void *RefData//user-defined reference data
______________________________________
The ibnotify callback has the following prototype:
______________________________________
int.sub.-- stdcall MyCallBack (
int LocalUd,
//unit descriptor
int LocalIbsta,
//ibsta value
int LocalIberr,
//iberr value
long LocalIbcntl,
//ibcntl value
void *RefData
//user-defined reference data
______________________________________
The Callback function is passed a unit descriptor, the current values of the GPIB global variables, and the user-defined reference data that was passed to the original ibnotify call. The GPIB driver interprets the return value for the Callback as a mask value that is used to automatically rearm event notification if the return value is non-zero. The following code is an example of how a user application might use ibnotify. Assume that the GPIB device is a multimeter, and the GPIB device is programmed to acquire a reading by sending it "SEND DATA". The multimeter requests service when it has a reading ready, and each reading is a floating point value. In this example, global variables are shared by the Callback thread and the main thread, and the access of the global variables is not protected by synchronization. In this case, synchronization of access to these global variables is not necessary because of the way they are used in the application: only a single thread is writing the global values and that thread always just adds information (increases the count or adds another reading to the array of floats).
__________________________________________________________________________
int.sub.-- stdcall MyCallback (int ud, int LocalIbsta, int LocalIberr,
long LocalIbcntl, void *RefData);
int ReadingsTaken=0;
float Readings[1000];
BOOL DeviceError=FALSE;
char expectedResponse=0.times.43;
int main( )
int ud;
//Assign a unique identifier to the device and store it in the
//variable ud.ibdev opens an available device and assigns it to
//access GPIBO with a primary address of 1, a secondary address of
0,
//a timeout of 10 seconds, the END message enabled, and the EOS
mode
//disabled. If ud is less than zero, then print an error message
//that the call failed and exit the program.
ud=ibdev
(0,
//connect board
1, //primary address of GPIB device
0, //secondary address of GPIB device
T10s,
//10 second I/O timeout
1, //EOT mode turned on
0);
//EOS mode disabled
if (ud<0) {
printf ("ibdev failed..backslash.n");
return 0;
}
//Issue a request to the device to send the data. If the ERR bit
//is set in ibsta, then print an error message that the call failed
//and exit the program.
ibwrt (ud, "SEND DATA", 9L);
if (ibsta & ERR) {
printf ("unable to write to device..backslash.n");
return 0;
}
//set up the asynchronous event notification on RQS
ibnotify (ud, RQS, MyCallback, NULL);
if (ibsta & ERR) {
printf ("ibnotify call failed..backslash.n");
return 0;
}
while ((ReadingsTaken<1000)&&!(DeviceError)) {
//Your application does useful work here. For example, it
//might process the device readings or do any other useful work.
}
//disable notification
ibnotify (ud, 0, NULL, NULL);
//Call the ibonl function to disable the hardware and software.
ibonl (ud, 0);
return 1;
}
int.sub.-- stdcall MyCallback (int LocalUd, int LocalIbsta, int
LocalIberr,
long LocalIbentl, void *RefData)
{
char SpollByte;
char ReadBuffer[40];
//If the ERR bit is set in LocalIbsta, then print an error message
//and return.
if (LocalIbsta & ERR) {
printf ("GPIB error %d has occurred. No more callbacks..backslash.
n",
LocalIberr);
DeviceError=TRUE;
return 0;
}
//Read the serial poll byte from the device. If the ERR bit is set
//in ibsta, then print an error message and return.
LocalIbsta=ibrsp (LocalUd, &SpollByte);
if (LocalIbsta & ERR) {
printf ("ibrsp failed. No more callbacks..backslash.n");
DeviceError=TRUE;
return 0;
}
//If the returned status byte equals the expected response, then
//the device has valid data to send; otherwise it has a fault
//condition to report.
if (SpollByte !=expectedResponse) {
printf("Device returned invalid response. Status
byte=0x%x.backslash.n",
SpollByte);
DeviceError=TRUE;
return 0;
}
//Read the data from the device. If the ERR bit is set in ibsta,
//then print an error message and return.
LocalIbsta=ibrd (LocalUD, ReadBuffer, 40L);
if (LocalIbsta & ERR) {
printf ("ibrd failed. No more callbacks..backslash.n");
DeviceError=TRUE;
return 0;
}
//Convert the data into a numeric value.
sscanf (ReadBuffer, "%f", &Readings[ReadingsTaken]);
ReadingsTaken+=1;
if (ReadingsTaken>=1000) {
return 0;
}
else {
//Issue a request to the device to send the data and rearm
//callback on RQS.
LocalIbsta=ibwrt (LocalUD, "SEND DATA", 9L);
if (LocalIbsta & ERR) {
printf ("ibwrt failed. No more callbacks..backslash.n");
DeviceError=TRUE;
return 0;
}
else {
return RQS;
}
}
}
__________________________________________________________________________
As noted above, the ibnotify Callback is executed in a separate thread of execution from the rest of the user application. If the application might be performing other GPIB operations while it is using ibnotify, the per-thread GPIB global variables that are provided by the Thread functions should be used. In addition, if the user application needs to share global variables with the Callback, a synchronization primitive (for example, semaphore) should be used to protect access to any global variables. GPIBNotify Usage The GpibNotify OLE control is implemented using a method called SetupNotify and an event called Notify. The SetupNotify method is used to enable the GPIB driver to look for one or more GPIB conditions for a particular GPIB handle. After it is set up, the OLE control fires the Notify event when one or more of the GPIB conditions is TRUE. A user-defined callback is invoked when the Notify event is fired. This section covers the major highlights regarding a sample program that uses the GpibNotify control. The program contains three buttons: Run, Message, and Quit. Clicking the Run button sets into motion a chain of commands that read ten measurements from a Fluke 45 multimeter. First, the program obtains a handle to the device. Next, it sends a set of commands that initialize the Fluke 45 multimeter. Then a trigger command is sent. Next the program asks the device to send data. Lastly, it issues a SetupNotify to the GpibNotify OLE control with a mask of the RQS GPIB condition. When the RQS GPIB condition is TRUE, the Notify event is fired and the user-defined callback is invoked. Each time through the callback, the RearmMask is set to RQS so that the event notification is rearmed for the next RQS GPIB condition. After the callback has read ten measurements from the Fluke 45 multimeter, the RearmMask is set to zero in order to disable the event notification mechanism. Clicking the Message button causes a message to be displayed in a text box every time the button is clicked. Clicking the Quit button closes the program. It is noted that the GpibNotify OLE control is implemented using the apartment model. Therefore, the GpibNotify OLE control only works correctly if the user application responds to Windows messages in a timely fashion. Description of the GpibNotify OLE Control for Visual Basic In Visual Basic, asynchronous callback functions are not supported. However, it is still possible to set up the equivalent of an asynchronous callback function for GPIB events by using an OLE control. The present invention includes an OLE control, referred to as GPIBNotify, designed for use with Visual Basic that encompasses the same functionality as the C ibnotify function. The GpibNotify OLE control is preferably automatically installed and registered with the operating system when the GPIB driver software is installed. Alternatively, the user can manually install and register the GpibNotify OLE control. Referring now to FIG. 4, in order to add the GpibNotify OLE control to the toolbox, the user performs the following steps: 1. Select Tools from the menu bar. 2. Select Custom Controls . . . from the drop-down list. 3. In the Custom Controls dialog box that appears, put an X in the box to the left of the gpibNotify OLE Control module by clicking on the box itself as shown in FIG. 4. Click OK. As shown in FIG. 5, an icon is added to the user's Toolbox. The new icon contains a picture of a bell with the label NOTIFY. An example of the updated Toolbox is shown in FIG. 5. The new NOTIFY item is located in the lower right hand corner. Once the GpibNotify OLE control has been added to the toolbox it can be placed on a Visual Basic form in the same manner as any other control. For each GpibNotify OLE control that the user desires to add, the user follows the instructions below: 1. Double-click on the NOTIFY icon in the ToolBox. This places the GPIB notify icon onto the user's form as shown in FIG. 6. 2. To add code to the callback routine, the user double-clicks on the GPIB notify icon. The callback routine is named GpibNotifyX.sub.-- Notify, where X is the particular numbered GpibNotify control. Each GpibNotify OLE control is numbered. The first control is numbered 1, the next control is numbered 2, and so on. Setting Up The Event Mask And Installing The Callback Routine For each GpibNotify control, a mask must be set up to determine which events will trigger the callback. There are three different ways that the mask can be set in Visual Basic. METHOD 1: The easiest way to set the event mask is to modify the GpibNotify Control Properties page. To access that page, the user follows the steps below: 1. Right-click on the GPIB notify icon as it appears on the form. 2. Select Properties . . . from the drop-down list. 3. In the GpibNotify Control Properties dialog box, click on the box to the left of the GPIB event for each and every GPIB event that you wish to monitor. 4. When the user has finished selecting all the desired GPIB events, click OK. To use the call, the user enters the following line of code in his/her application: GpibNotifyX.SetupNotify ud where X is the numbered control that the user wants to invoke and ud is the unit descriptor that was obtained by using either ibdev or ibfind. METHOD 2: Another method is to assign a SetupMask value to the SetupNotify function by declaring an integer value and setting it to the desired GPIB event(s) as shown below: Dim mask As Integer mask=XXX where XXX is the desired GPIB event(s) (for example, CMPL, RQS, TIMO) that you wish to invoke the callback with. The call to SetupNotify would look like this: GpibNotifyX.SetupNotify ud, mask where X is for the particular numbered control that the user desires to invoke and where ud is the unit descriptor that was obtained using either ibdev or ibfind. If the user has set up the GpibNotify control properties page as in method 1, calling GpibNotifyX.SetupNotify with a mask parameter will override the choices made on the properties page. METHOD 3: The third method is to initialize the SetupMask for the desired GPIB events by directly modifying the SetupMask property as shown below. This method will also override the control properties page. GpibNotifyX.SetupMask=RQS Then the user can call the SetupNotify function with only a unit descriptor: GpibNotifyX.SetupNotify ud GpibNotify OLE Control Example in Visual Basic The example below is intended only to show the basic program flow for using the GpibNotify OLE control. The example shows how a GPIB application could acquire data. This example shows the basic program flow for using the GpibNotify OLE control. It is written to work with a fictitious device with GPIB address two. The device responds to the string "SEND DATA" by asserting SRQ when the data is available. The data is a floating point value. The program uses a blank form containing only a GpibNotify OLE control. The GpibNotify procedure and the form load procedure are the only defined procedures for the example. They are shown below. This example is only designed to be run once. It could be easily modified to run multiple times by placing the form load procedure inside a command button click procedure and rearming the GpibNotify mask with RQS instead of zero. In addition to registering the OLE control a Visual Basic project using GPIB commands must include the niglobal.bas and vbib-32.bas modules. These modules are available with the GPIB Software.
__________________________________________________________________________
Visual Basic Example
__________________________________________________________________________
Visual Basic Private Sub Form.sub.-- Load()
' Assign a unique identifier to the device and store
' it in the variable ud. ibdev opens an available
' device and assigns it to access GPIB0 with a primary
' address of 2, a secondary address of 0, a timeout of
' 10 seconds, the END message enabled, and the EOS
' mode disabled. If us id less than zero, then print
' an error message that the call failed and exit
' the program.
Call ibdev(0, 2, 0, T10s, 1, 0, ud)
If (ud < 0) Then
MsgBox "ibdev error. I'm quitting!", 16
End
End If
' Install the GpibNotify callback mechanism for the OLE
' Control by calling its SetupNotify Procedure with an
' event mask for the RQS Event.
GpibNotify1.SetupMask = RQS
GpibNotify1.SetupNotify ud
' Check to see if there was an error invoking the GpibNotify Callback
mechanism.
If (TreadIbsta() And EERR) Then
msg$ = "Error invoking Notification for RQS! ibsta = &H" +
Hex$(ThreadIbsta())
MsgBox msg$, vbCritical, "GPIB Notification Error!"
msg$ = "iberr = " + Str$(ThreadIberr())
MsgBox msg$, vbCritical, "GPIB Notification Error!"
' Call the ibon1 function to disable the hardware and software.
Call ibon1(ud, 0)
End
End If
If (ThreadIbsta() And &H4000) Then
MsgBox ("Notification for RQS timed out.")
End
End If
' Write a command to the instrument to generate data and
' assert the SRQ line when the data is available.
wrtbuf$ = "SEND DATA"
Call ibwrt(ud, wrtbuf$)
If (ibsta And EERR) Then
MsgBox ("ibwrt Error!")
' Call the ibon1 function to disable the hardware and software.
Call ibon1(ud, 0)
End
End If
End Sub
Private Sub GpibNotify1.sub.-- Notify(ByVal LocalUd As Long, ByVal
LocalIbsta As Long,
By Val LocalIberr As Long, ByVal LocalIbcntl As Long, RearmMask As Long)
' This is the user-defined callback routine that
' gets invoked when one or more GPIB events in the
' mask that is passed to the SetupNotify method occurs.
' For this sample program, a data point will be read and
' displayed from the device.
Dim SPollByte As Integer
' If ERR bit is set in LocalIbsta that is passed into
' this subroutine, then print an error message and
' exit the function.
If LocalIbsta And EERR Then
MsgBox "Error with GPIB Notify #1-No more callbacks.", 16
Exit Sub
End If
' NOTE: for the rest of this subroutine, the global
' version of ibsta is used when checking to see
' if the error bit is set or not.
' Read the serial poll status byte. If the
' error bit EERR is set in ibsta, display an error
' message and exit.
Call ibrsp(LocalUd, SPollByte)
If (ibsta And EERR0 Then
MsgBox ("ibrs) Error!")
RearmMask = 0
Exit Sub
End If
' If the returned status byte is &H50 then the instrument
' has valid data to send
If(SPollByte .diamond. &H50) Then
MsgBox("Serial poll byte is NOT &H50.")
RearmMask = 0
Exit Sub
End If
' Read the data. If the error bit EERR is
' set in ibsta, display an error message
' and exit.
rdbuf$ = Space$(20)
Call ibrd(LocalUd, rdbuf$)
If (ibsta And EERR) Then
MsgBox ("ibrd Error!")
RearmMask = 0
Exit Sub
End If
' Display the Reading.
MsgBox (rdbuf$)
' Rearm Mask is set to zero to disable the
' Callback mechanism. This example is only
' designed to run once to show flow for using
' GpibNotify Control.
RearmMask = 0
End Sub
__________________________________________________________________________
Conclusion Although the system and method of the present invention has been described in connection with the preferred embodiment, it is not intended to be limited to the specific form set forth herein, but on the contrary, it is intended to cover such alternatives, modifications, and equivalents, as can be reasonably included within the spirit and scope of the invention as defined by the appended claims.
|
Same subclass Same class Consider this |
||||||||||
