Mezurit 2

Online documentation - GPIB

GPIB messages can be sent and received through channel functions or the gpib() terminal function (version 0.81+). The former method works best when the purpose of the communication is to get or set an instrument parameter which can be stored locally as a floating-point value. The latter method can be used for any purpose because it is up to the user to format the message and interpret the reply.

Channel functions

Instrument parameters can be accessed via GPIB by placing a call to a pre-defined channel function in a virtual channel definition. During the parsing phase a gpib slot is created for each board/address combination mentioned in the channel definitions. The resulting set of gpib slots is read continuously in panel mode, assuming GPIB is not paused. GPIB channel functions are defined using the following function:

GPIB_Device (read_str, read_period, dummy_value, reply_fmt, write_fmt)

read_str str GPIB command needed to get (read) the parameter
read_period floatTime between updates in seconds
dummy_value floatValue to return in dummy mode
reply_fmt str C printf-style format needed to convert a reply to a floating point value
write_fmt str C printf-style format needed to set the parameter (supply empty string if N/A)
return value Callable instance of the GPIB_Device class

Since version 0.81, users can create new their own functions by placing calls to GPIB_Device() in ~/.config/mezurit2/compute.py (see Installed files).

Example: SRS lock-in amplifier

Code: SR830_SineOut = GPIB_Device('SLVL?', 0.5, 50e-3, '%lf', 'SLVL%f')
Channel def.: X1 (mV) = SR830_SineOut(0, 8)
Result: During the parsing phase Mezurit 2 will create a gpib slot for board 0, address 8. In panel mode it will query the device with the command "SLVL?" every 0.5 seconds and decode the reply (e.g. "0.075") as a floating point value 7.5e-2 (displayed as 75 mV). If the user were to set X1 to some value (e.g. 80 mV), Mezurit 2 would immediately send "SLVL0.080000" to the amplifier, then resume reading every 0.5 seconds.

Technical detail: When read_period is much slower than the DAQ rate (which is usually the case), a gpib slot will return the value obtained by the last read operation rather than waiting for a "fresh" value. When a slot has been written more recently than it has been read, it will return the last written value, in effect assuming that the write operation succeeded. This behavior allows smooth high-speed sweeps over GPIB with out bogging down the system (and the instrument) with unnecessary reads during idle periods.

Functions created with GPIB_Device have several additional default parameters which can be modified if necessary: self.eos to set the end-of-string byte (default: 0x0), self.intro to set the identification query (default: "*IDN?"), and self.inverse_fn and self.noninverse_fn to provide an additional layer of abstraction, explained below.

Example: Oxford temperature controller

Code: ITC503_Temp = GPIB_Device('R1\r', 1.0, 300, 'R%lf', '')
ITC503_Temp.eos = 0x400 | 0xd
ITC503_Temp.intro = 'V\r'
Result: GPIB slots created by calling the ITC503_Temp() channel function will use a custom end-of-string byte and identification command.

Members self.inverse_fn and self.noninverse_fn are useful when a GPIB command expects values in undesirable units. Function self.noninverse_fn is applied to the value read via GPIB and self.inverse_fn is applied to a value to be sent over GPIB. The default for both is to do nothing, i.e. the unity function lambda x : x.

Example: Agilent signal generator

Code: A8648_Ampl = GPIB_Device('POW:AMPL?', 0.5, 0.0, '%lf', 'POW:AMPL %1.6f MV')
A8648_Ampl.noninverse_fn = lambda x_dBm : 10 ** (x_dBm / 10)
A8648_Ampl.inverse_fn = lambda x_mV : x_mV * 1e3
Result: GPIB slots created by calling the A8648_Ampl() channel function will handle values in Volts while internally getting values from the source in dBm and setting values in mV. Note that the default value should match the units of the internal reading command - in this case dBm.

These functions are also useful for implementing lookup tables, especially when combined with the nearest_index() function (version 0.81+) detailed below. For an example, see the definition of SR830_Tau() in compute_example.py (for version 0.74, see script_example.py).

nearest_index (list, target)

list [] Pre-sorted (ascending) list containing the valid values
target floatTarget value
return valueint Index of the closest valid value

Important: The syntax used to define GPIB channel functions in version 0.74 is slightly different from that described above, and self.inverse_fn and self.noninverse_fn are not available. More information is available here.

Terminal function (ver. 0.81+)

Plain text GPIB commands can be sent directly from the terminal using the gpib() function. This function also accepts two optional arguments eos and expect_reply which are described in its documentation.

Example: Agilent signal generator

Command: gpib(1, 18, 'CW:FREQ 100 MHZ')
Result: The message "CW:FREQ 100 MHZ" will be sent to the instrument with address 18 using board 1. The reply (if there is one) will be returned as a string.