Question:

Sometimes my GPIB program hangs up when trying to read a measured result. What am I doing wrong?

Answer:
The following explanation and code examples of using the timeout feature may be helpful.

Background

One of the most common remote user interface operations performed on an Agilent 8920 Family of Test Sets is to query and read a measurement result. Generally, this operation is accomplished by sending the query command to the Test Set, followed immediately by a request to read the requested measurement result. Using the Mountain BASIC (RMB) language, this operation would be written using the OUTPUT and ENTER command as follows:


 OUTPUT 714;"MEAS:RFR:POW?"

 ENTER 714;Power


Using this programming structure, the control program will stay on the ENTER statement until it is satisfied, that is, until the Test Set has returned the requested measurement result. This structure works correctly as long as the Test Set returns a valid measurement result. If, for some reason, the Test Set does not return a measurement result, the control program becomes "hung" on the ENTER statement and program execution effectively stops.

In order to prevent the control program from becoming "hung" programmers usually enclose the operation with some form of timeout function. The form of the timeout will of course depend upon the programming language being used. The purpose of the timeout is to specify a fixed amount of time that the control program will wait for the Test Set to return the requested result. After this time has expired the control program will abandon the ENTER statement and try to take some corrective action to regain control of the Test Set.

If the control program does not send the proper commands in the proper sequence when trying to regain control of the Test Set, unexpected operation will result. When this condition is encountered, power must be cycled on the Test Set to regain control.

This situation can be avoided entirely by first sending a Selected Device Clear (SDC) interface message to put the Test Set? GPIB subsystem into a known state followed immediately by a command to terminate the requested measurement cycle. These commands issued in this order will allow the control program to regain control of the Test Set. Any other sequence of commands will result in unexpected operation.

The following programs demonstrate a recommended technique for querying and entering data from the Test Set. This technique will prevent the Test Set from getting into a "hung" state such that power must be cycled on the Test Set to regain manual or programmatic control.

There are a variety of programming constructs which can be used to implement this technique. In the programming examples presented, a function call is implemented which returns a numeric measurement result. The function call has two pass parameters; the query command (passed as a quoted string) and a time-out value (passed as a integer number).

The time-out value represents how long you want to wait, in seconds, for the Test Set to return a valid measurement result. If a valid measurement result is not returned by the Test Set within the time-out value, the function returns a very large number. The calling program can check the value and take appropriate action.

The following program examples (HP(R) BASIC "ON TIMEOUT", HP(R) BASIC "MAV", C++ ON TIMEOUT, and C++ MAV) are written so as to be self-explanatory. In practice, the length of: variable names, line labels, function names, etc., will be implementation dependent.

HP(R) BASIC "ON TIMEOUT" Example Program The following example program demonstrates a recommended technique which can be utilized in situations where a measurement result timeout value of 32.767 seconds or less is adequate. In the RMB language, the timeout parameter for the ON TIMEOUT command has a maximum value of 32.767 seconds. If a timeout value of greater than 32.767 seconds is required refer to the HP(R) BASIC "MAV" Bit Example Program.

Measurement result timeout value is defined to mean the amount of time the control program is willing to wait for the Test Set to return a valid measurement result to the control program.

Lines 10 thru 230 in this example set up a measurement situation to demonstrate the use of the recommended technique. The recommended technique is exampled in the Measure Function.

Lines 50 and 60 should be included in the beginning of all control program. These lines are required to ensure that the Test Set is properly reset. This covers the case where the program was previously run and was stopped with the Test Set in an error condition.


10 COM /Io_names/ INTEGER Inst_addr,Bus_addr

20 CLEAR SCREEN

30 Inst_addr=714

40 Bus_addr=7

50 CLEAR Inst_addr

60 OUTPUT Inst_addr;"TRIG:ABORT"

70 OUTPUT Inst_addr;"*RST"

80 OUTPUT Inst_addr;"DISP RFAN"

90 !

100 ! Execute a call to the Measure function with a request to measure RF

110 ! power. The time out value is specified as 10 seconds. The value

120 ! returned by the function is assigned to the variable Measure_result.

130 !

140 Measure_result=FNMeasure("MEAS:RFR:POW?",10)

150 !

160 ! Check the result of the function call.

170 !

180 IF Measure_result=9.E+99 THEN 

190 PRINT "Measurement failed."

200 ELSE

210 PRINT "Power = ";Measure_result

220 END IF

230 END

240 !***********************************************************

250 ! Recommended Technique:

260 !***********************************************************

270 DEF FNMeasure(Query_command$,Time_out_value)

280 COM /Io_names/ INTEGER Inst_addr,Bus_addr

290 DISABLE 

300 ON TIMEOUT Bus_addr,Time_out_value GOTO Timed_out

310 OUTPUT Inst_addr;"TRIG:MODE:RETR SING;:TRIG:IMM"

320 OUTPUT Inst_addr;Query_command$

330 ENTER Inst_addr;Result

340 OUTPUT Inst_addr;"TRIG:MODE:RETR REP"

350 ENABLE

360 RETURN Result

370 Timed_out:!

380 ON TIMEOUT Bus_addr,Time_out_value GOTO Cannot_recover

390 CLEAR Inst_addr

400 OUTPUT Inst_addr;"TRIG:ABORT;MODE:RETR REP"

410 ENABLE 

420 RETURN 9.E+99

430 Cannot_recover:!

440 DISP "Cannot regain control of Test Set."

450 STOP

460 FNEND


HP(R) BASIC "MAV" Example Program

The following Rocky Mountain BASIC example program demonstrates a technique which can be used in situations where a 32.767 measurement result timeout value is not adequate.

Measurement result timeout value is defined to mean the amount of time the control program is willing to wait for the Test Set to return a valid measurement result to the control program.

The technique uses the MAV (Message Available) bit in the Test Set's GPIB Status Byte to determine when there is data in the Output Queue. A polling loop is used to query the Status byte. The timeout duration for returning the measurement result is handled by the polling loop. A GPIB interface activity timeout is also set up to handle time-outs resulting from problems with the GPIB interface.

Lines 10 thru 230 in this example set up a measurement situation to demonstrate the use of the recommended technique. The recommended technique is exampled in the Measure Function.

Lines 50 and 60 should be included in the beginning of all control program. These lines are required to ensure that the Test Set is properly reset. This covers the case where the program was previously run and was stopped with the Test Set in an error condition.


10 COM /Io_names/ INTEGER Inst_addr,Bus_addr

20 CLEAR SCREEN

30 Inst_addr=714

40 Bus_addr=7

50 CLEAR Inst_addr

60 OUTPUT Inst_addr;"TRIG:ABORT"

70 OUTPUT Inst_addr;"*RST"

80 OUTPUT Inst_addr;"DISP RFAN"

90 !

100 ! Execute a call to the Measure function with a request to measure RF

110 ! power. The time out value is specified as 50 seconds. The value

120 ! returned by the function is assigned to the variable Measure_result.

130 !

140 Measure_result=FNMeasure("MEAS:RFR:POW?",50)

150 !

160 ! Check the result of the function call.

170 !

180 IF Measure_result=9.E+99 THEN 

190 PRINT "Measurement failed."

200 ELSE

210 PRINT "Power = ";Measure_result

220 END IF

230 END

240 !***********************************************************

250 ! Recommended Technique:

260 !***********************************************************

270 DEF FNMeasure(Query_command$,Time_out_value)

280 COM /Io_names/ INTEGER Inst_addr,Bus_addr

290 DISABLE 

300 ON TIMEOUT Bus_addr,5 GOTO Timed_out

310 OUTPUT Inst_addr;"TRIG:MODE:RETR SING;:TRIG:IMM"

320 OUTPUT Inst_addr;Query_command$

330 Start_time=TIMEDATE

340 REPEAT

350 WAIT .1

360 Status_byte=SPOLL(Inst_addr)

370 IF BIT(Status_byte,4) THEN 

380 ENTER Inst_addr;Result

390 OUTPUT Inst_addr;"TRIG:MODE:RETR REP"

400 ENABLE

410 RETURN Result

420 END IF

430 UNTIL TIMEDATE-Start_time>=Time_out_value

440 Timed_out:!

450 ON TIMEOUT Bus_addr,5 GOTO Cannot_recover

460 CLEAR Inst_addr

470 OUTPUT Inst_addr;"TRIG:ABORT;MODE:RETR REP"

480 RETURN 9.E+99

490 Cannot_recover: !

500 DISP "Cannot regain control of Test Set."

510 STOP

520 FNEND

To top of page

C++ ON TIMEOUT Example Program

The following example C++ program follows the same program flow as the Rocky Mountain BASIC ON TIMEOUT example program. There are some minor differences between the Rocky Mountain BASIC program and the C++ program due to language differences, such as no end-of-line branching in C++. The C++ program includes an error handler to properly handle the error value passed back from the GPIB card library calls.

 

// Recommended Procedure for reading measurement

// results from an Agilent 892NX Platform.

// Compiled on Borland C++ 4.51

// Agilent 82335B GPIB Card

// GPIB Interface and Command Libraries for DOS

// REV B.00.00 Date Code: 3204

// include files


 #include 


 #include 


 #include 


 #include 


 #include 


 #include 



// Agilent 82335B GPIB Card C libraries


 extern "C" // must declare the libraries as C code so C++ linker

 { // does not cause the function names to get corrupted.

 #include 


 #include 


 }


// define program constants


 #define ISC 7 


// GPIB Interface Select Code = 7


 #define TEST_SET 714 


// Test Set address = 714


// declare functions


 float Measure (char *, int);

 void error_handler (int, char *);


//Main


int main()


{


// declare local variables


 char *command;

 int time_out_value;

 float measured_value;


// begin program


 error_handler(IOTIMEOUT(ISC,5),"IOTIMEOUT");

 error_handler(IOCLEAR(TEST_SET),"IOCLEAR");

 command = "TRIG:ABORT";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: TRIG ABORT");

 command = "*RST";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: *RST");

 command = "DISP RFAN";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: DISP:RFAN");

 command = "MEAS:RFR:POW?";

 time_out_value = 5;

 measured_value = Measure(command,time_out_value);

 if (measured_value == FLT_MAX)

 printf("Measurement failed.

");

 else

 printf("Measured power = %f

",measured_value);

 printf("


Finished ... Hit the ENTER key

");

 getch();

 return EXIT_SUCCESS;

} // End of Main program


// function definitions


void error_handler(int error, char *routine)

{


 if (error != NOERR)

 {

 printf("HP-IB error in call to: %s: %d,%s

",routine,error,errstr(error));

 printf("


Hit the ENTER key to exit the program.

");

 getch();

 exit(1);

 }

 return;

}


float Measure(char *query_cmd, int time_out_value)


{


// local variables


 char *command;

 int error;

 float meas_result;


// measure function code

 meas_result = FLT_MAX;

 error_handler(IOTIMEOUT(ISC, time_out_value),"IOTIMEOUT");

 command = "TRIG:MODE:RETR SING;:TRIG:IMM";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: TRIG command");

 error_handler(IOOUTPUTS(TEST_SET,query_cmd,strlen(query_cmd)),"IOOUTPUTS: QUERY command");

 error = IOENTER(TEST_SET,&meas_result);

 if (error == NOERR) // no errors occurred when reading measurement result

 {

 command = "TRIG:MODE:RETR REP";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: TRIG command");


 }


 else if (error == ETIME ) // measurement timed out


 {

 error_handler(IOCLEAR(TEST_SET),"Cannot regain control of Test Set.");

 command = "TRIG:ABORT;MODE:RETR REP";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"Cannot regain control of Test Set.");

 }


 else // an error occurred but it is not a timeout error


 {

 error_handler( error,"IOENTER: measurement result");

 }


 return meas_result;

}

C++ MAV Example Program

The following example C++ program follows the same program flow as the Rocky Mountain BASIC (RMB) MAV example program. There are some minor differences between the RMB program and the C++ program due to language differences, such as no end-of-line branching in C++. The C++ program includes an error handler to properly handle the error value passed back from the GPIB card library calls.


// Recommended Procedure for reading measurement

// results from an Agilent 892NX Platform.

// Compiled on Borland C++ 4.51

// Agilent 82335B GPIB Card

// GPIB Interface and Command Libraries for DOS


// REV B.00.00 Date Code: 3204


// include files

 #include 


 #include 


 #include 


 #include 


 #include 


 #include 


 #include 



// Agilent 82335B GPIB Card C libraries


 extern "C" // must declare the libraries as C code so C++ linker

 { // does not cause the function names to get corrupted.


 #include 


 #include 


 }


// define program constants


 #define ISC 7 

// GPIB Interface Select Code = 7

 #define TEST_SET 714 

// Test Set address = 714


// declare functions


 float Measure (char *, int);

 void error_handler (int, char *);


// Main


int main()

{

// declare local variables


 char *command;

 int time_out_value;

 float measured_value;


// begin program


 error_handler(IOTIMEOUT(ISC,5),"IOTIMEOUT");

 error_handler(IOCLEAR(TEST_SET),"IOCLEAR");

 command = "TRIG:ABORT";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: TRIG ABORT");

 command = "*RST";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: *RST");

 command = "DISP RFAN;RFAN:INP ''ANT''";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: DISP:RFAN");

 command = "MEAS:RFR:POW?";

 time_out_value = 50;

 measured_value = Measure(command,time_out_value);

 if (measured_value == FLT_MAX)


 printf("Measurement failed.

");

 else

 printf("Measured power = %f

",measured_value);


 printf("


Finished ... Hit the ENTER key

");

 getch();

 return EXIT_SUCCESS;


} // End of Main program


// function definitions

void error_handler(int error, char *routine)

{

 if (error != NOERR)

 {


 printf("HP-IB error in call to: %s: %d,%s

",routine,error,errstr(error));

 printf("


Hit the ENTER key to exit the program.

");

 getch();

 exit(1);

 }

 return;

}


float Measure(char *query_cmd, int time_out_value)


{


// local variables


 char *command;

 int status_byte;

 float meas_result;

 time_t start_time,current_time;


// measure function code

 meas_result = FLT_MAX;

 error_handler(IOTIMEOUT(ISC, 5),"IOTIMEOUT");

 command = "TRIG:MODE:RETR SING;:TRIG:IMM";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: TRIG command");

 error_handler(IOOUTPUTS(TEST_SET,query_cmd,strlen(query_cmd)),"IOOUTPUTS: QUERY command");

 start_time=time(NULL);

 do

 {

 delay(100);

 error_handler(IOSPOLL(TEST_SET,&status_byte),"IOSPOLL");

 if (status_byte & 16)

 {

 error_handler(IOENTER(TEST_SET,&meas_result),"IOENTER: measurement result");

 command = "TRIG:MODE:RETR REP";

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"IOOUTPUTS: TRIG command");

 return meas_result;

 }

 current_time=time(NULL);

 }


 while (current_time - start_time < time_out_value);


// measurement timed out 

 error_handler(IOCLEAR(TEST_SET),"Cannot regain control of Test Set."); 

 command="TRIG:ABORT;MODE:RETR REP" ; 

 error_handler(IOOUTPUTS(TEST_SET,command,strlen(command)),"Cannot regain control of Test Set."); 

 return meas_result; 


} 

 

(c) Copyright Agilent Technologies 1997, 2000. All Rights Reserved.

This information is subject to change without notice and is provided "as is" with no warranty. Agilent Technologies shall not be liable for any direct, indirect, special, incidental or consequential damages in connection with the use of this material.