def after_parsing(self): minor = int(self.parsed.board) pad = int(self.parsed.primary_address) sad = 0 timeout = 13 send_eoi = 1 eos_mode = 0 self.interface = Gpib(name=minor, pad=pad, sad=sad, timeout=timeout, send_eoi=send_eoi, eos_mode=eos_mode) self.controller = Gpib(name=minor) # this is the bus controller device # force timeout setting to interface self.set_attribute(constants.VI_ATTR_TMO_VALUE, attributes.AttributesByID[constants.VI_ATTR_TMO_VALUE].default)
def __init__(self, device, configuration=1): """ Create an instance of an IOtech device on GPIB @type device : str @param device : device name as defined in /etc/gpib.conf @type configuration : int @param configuration : port I/O directions as in 'ports_out' @return: None """ Gpib.__init__(self, device) self.configure(configuration=configuration) self.write_port(1, int('1111', 2)) self.get_status()
def after_parsing(self): minor = self.parsed.board pad = self.parsed.primary_address self.handle = gpib.dev(int(minor), int(pad)) self.interface = Gpib(self.handle)
class GPIBSession(Session): """A GPIB Session that uses linux-gpib to do the low level communication. """ @staticmethod def list_resources(): return ['GPIB0::%d::INSTR' % pad for pad in _find_listeners()] @classmethod def get_low_level_info(cls): try: ver = gpib.version() except AttributeError: ver = '< 4.0' return 'via Linux GPIB (%s)' % ver def after_parsing(self): minor = self.parsed.board pad = self.parsed.primary_address self.handle = gpib.dev(int(minor), int(pad)) self.interface = Gpib(self.handle) @property def timeout(self): # 0x3 is the hexadecimal reference to the IbaTMO (timeout) configuration # option in linux-gpib. return TIMETABLE[self.interface.ask(3)] @timeout.setter def timeout(self, value): """ linux-gpib only supports 18 discrete timeout values. If a timeout value other than these is requested, it will be rounded up to the closest available value. Values greater than the largest available timout value will instead be rounded down. The available timeout values are: 0 Never timeout. 1 10 microseconds 2 30 microseconds 3 100 microseconds 4 300 microseconds 5 1 millisecond 6 3 milliseconds 7 10 milliseconds 8 30 milliseconds 9 100 milliseconds 10 300 milliseconds 11 1 second 12 3 seconds 13 10 seconds 14 30 seconds 15 100 seconds 16 300 seconds 17 1000 seconds """ self.interface.timeout(bisect(TIMETABLE, value)) def close(self): gpib.close(self.handle) def read(self, count): """Reads data from device or interface synchronously. Corresponds to viRead function of the VISA library. :param count: Number of bytes to be read. :return: data read, return value of the library call. :rtype: bytes, constants.StatusCode """ # 0x2000 = 8192 = END checker = lambda current: self.interface.ibsta() & 8192 reader = lambda: bytes([ord(self.interface.read(1))]) return self._read(reader, count, checker, False, None, False, gpib.GpibError) def write(self, data): """Writes data to device or interface synchronously. Corresponds to viWrite function of the VISA library. :param data: data to be written. :type data: bytes :return: Number of bytes actually transferred, return value of the library call. :rtype: int, VISAStatus """ logger.debug('GPIB.write %r' % data) try: self.interface.write(data) return SUCCESS except gpib.GpibError: # 0x4000 = 16384 = TIMO if self.interface.ibsta() & 16384: return 0, StatusCode.error_timeout else: return 0, StatusCode.error_system_error def _get_attribute(self, attribute): """Get the value for a given VISA attribute for this session. Use to implement custom logic for attributes. :param attribute: Resource attribute for which the state query is made :return: The state of the queried attribute for a specified resource, return value of the library call. :rtype: (unicode | str | list | int, VISAStatus) """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbaREADDR 0x6 # Setting has no effect in linux-gpib. return self.interface.ask(6), SUCCESS elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbaPAD 0x1 return self.interface.ask(1), SUCCESS elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbaSAD 0x2 # Remove 0x60 because National Instruments. sad = self.interface.ask(2) if self.interface.ask(2): return self.interface.ask(2) - 96, SUCCESS else: return constants.VI_NO_SEC_ADDR, SUCCESS elif attribute == constants.VI_ATTR_GPIB_REN_STATE: # I have no idea how to implement this. raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbaUnAddr 0x1b if self.interface.ask(27): return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_SEND_END_EN: # IbaEndBitIsNormal 0x1a if self.interface.ask(26): return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_INTF_NUM: # IbaBNA 0x200 return self.interface.ask(512), SUCCESS elif attribute == constants.VI_ATTR_INTF_TYPE: return constants.InterfaceType.gpib, SUCCESS raise UnknownAttribute(attribute) def _set_attribute(self, attribute, attribute_state): """Sets the state of an attribute. Corresponds to viSetAttribute function of the VISA library. :param attribute: Attribute for which the state is to be modified. (Attributes.*) :param attribute_state: The state of the attribute to be set for the specified object. :return: return value of the library call. :rtype: VISAStatus """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbcREADDR 0x6 # Setting has no effect in linux-gpib. if isinstance(attribute_state, int): self.interface.config(6, attribute_state) return SUCCESS else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbcPAD 0x1 if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: self.interface.config(1, attribute_state) return SUCCESS else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbcSAD 0x2 # Add 0x60 because National Instruments. if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: if self.interface.ask(2): self.interface.config(2, attribute_state + 96) return SUCCESS else: return StatusCode.error_nonsupported_attribute else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbcUnAddr 0x1b try: self.interface.config(27, attribute_state) return SUCCESS except gpib.GpibError: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_SEND_END_EN: # IbcEndBitIsNormal 0x1a if isinstance(attribute_state, int): self.interface.config(26, attribute_state) return SUCCESS else: return StatusCode.error_nonsupported_attribute_state raise UnknownAttribute(attribute)
class GPIBSession(Session): """A GPIB Session that uses linux-gpib to do the low level communication. """ @staticmethod def list_resources(): return ['GPIB0::%d::INSTR' % pad for pad in _find_listeners()] @classmethod def get_low_level_info(cls): try: ver = gpib.version() except AttributeError: ver = '< 4.0' return 'via Linux GPIB (%s)' % ver def after_parsing(self): minor = self.parsed.board pad = self.parsed.primary_address self.handle = gpib.dev(int(minor), int(pad)) self.interface = Gpib(self.handle) @property def timeout(self): # 0x3 is the hexadecimal reference to the IbaTMO (timeout) configuration # option in linux-gpib. return TIMETABLE[self.interface.ask(3)] @timeout.setter def timeout(self, value): """ linux-gpib only supports 18 discrete timeout values. If a timeout value other than these is requested, it will be rounded up to the closest available value. Values greater than the largest available timout value will instead be rounded down. The available timeout values are: 0 Never timeout. 1 10 microseconds 2 30 microseconds 3 100 microseconds 4 300 microseconds 5 1 millisecond 6 3 milliseconds 7 10 milliseconds 8 30 milliseconds 9 100 milliseconds 10 300 milliseconds 11 1 second 12 3 seconds 13 10 seconds 14 30 seconds 15 100 seconds 16 300 seconds 17 1000 seconds """ self.interface.timeout(bisect(TIMETABLE, value)) def close(self): gpib.close(self.handle) def read(self, count): """Reads data from device or interface synchronously. Corresponds to viRead function of the VISA library. :param count: Number of bytes to be read. :return: data read, return value of the library call. :rtype: bytes, constants.StatusCode """ # 0x2000 = 8192 = END checker = lambda current: self.interface.ibsta() & 8192 reader = lambda: self.interface.read(1) return self._read(reader, count, checker, False, None, False, gpib.GpibError) def write(self, data): """Writes data to device or interface synchronously. Corresponds to viWrite function of the VISA library. :param data: data to be written. :type data: bytes :return: Number of bytes actually transferred, return value of the library call. :rtype: int, VISAStatus """ logger.debug('GPIB.write %r' % data) try: self.interface.write(data) return SUCCESS except gpib.GpibError: # 0x4000 = 16384 = TIMO if self.interface.ibsta() & 16384: return 0, StatusCode.error_timeout else: return 0, StatusCode.error_system_error def _get_attribute(self, attribute): """Get the value for a given VISA attribute for this session. Use to implement custom logic for attributes. :param attribute: Resource attribute for which the state query is made :return: The state of the queried attribute for a specified resource, return value of the library call. :rtype: (unicode | str | list | int, VISAStatus) """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbaREADDR 0x6 # Setting has no effect in linux-gpib. return self.interface.ask(6), SUCCESS elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbaPAD 0x1 return self.interface.ask(1), SUCCESS elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbaSAD 0x2 # Remove 0x60 because National Instruments. sad = self.interface.ask(2) if self.interface.ask(2): return self.interface.ask(2) - 96, SUCCESS else: return constants.VI_NO_SEC_ADDR, SUCCESS elif attribute == constants.VI_ATTR_GPIB_REN_STATE: # I have no idea how to implement this. raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbaUnAddr 0x1b if self.interface.ask(27): return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_SEND_END_EN: # IbaEndBitIsNormal 0x1a if self.interface.ask(26): return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_INTF_NUM: # IbaBNA 0x200 return self.interface.ask(512), SUCCESS elif attribute == constants.VI_ATTR_INTF_TYPE: return constants.InterfaceType.gpib, SUCCESS raise UnknownAttribute(attribute) def _set_attribute(self, attribute, attribute_state): """Sets the state of an attribute. Corresponds to viSetAttribute function of the VISA library. :param attribute: Attribute for which the state is to be modified. (Attributes.*) :param attribute_state: The state of the attribute to be set for the specified object. :return: return value of the library call. :rtype: VISAStatus """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbcREADDR 0x6 # Setting has no effect in linux-gpib. if isinstance(attribute_state, int): self.interface.config(6, attribute_state) return SUCCESS else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbcPAD 0x1 if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: self.interface.config(1, attribute_state) return SUCCESS else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbcSAD 0x2 # Add 0x60 because National Instruments. if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: if self.interface.ask(2): self.interface.config(2, attribute_state + 96) return SUCCESS else: return StatusCode.error_nonsupported_attribute else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbcUnAddr 0x1b try: self.interface.config(27, attribute_state) return SUCCESS except gpib.GpibError: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_SEND_END_EN: # IbcEndBitIsNormal 0x1a if isinstance(attribute_state, int): self.interface.config(26, attribute_state) return SUCCESS else: return StatusCode.error_nonsupported_attribute_state raise UnknownAttribute(attribute)
class GPIBSession(Session): """A GPIB Session that uses linux-gpib to do the low level communication. """ @staticmethod def list_resources(): return ['GPIB0::%d::INSTR' % pad for pad in _find_listeners()] def after_parsing(self): minor = self.parsed['board'] pad = self.parsed['primary_address'] self.handle = gpib.dev(int(minor), int(pad)) self.interface = Gpib(self.handle) @property def timeout(self): # 0x3 is the hexadecimal reference to the IbaTMO (timeout) configuration # option in linux-gpib. return TIMETABLE[self.interface.ask(3)] @timeout.setter def timeout(self, value): """ linux-gpib only supports 18 discrete timeout values. If a timeout value other than these is requested, it will be rounded up to the closest available value. Values greater than the largest available timout value will instead be rounded down. The available timeout values are: 0 Never timeout. 1 10 microseconds 2 30 microseconds 3 100 microseconds 4 300 microseconds 5 1 millisecond 6 3 milliseconds 7 10 milliseconds 8 30 milliseconds 9 100 milliseconds 10 300 milliseconds 11 1 second 12 3 seconds 13 10 seconds 14 30 seconds 15 100 seconds 16 300 seconds 17 1000 seconds """ self.interface.timeout(bisect(TIMETABLE, value)) def close(self): gpib.close(self.handle) def read(self, count): """Reads data from device or interface synchronously. Corresponds to viRead function of the VISA library. :param count: Number of bytes to be read. :return: data read, return value of the library call. :rtype: bytes, constants.StatusCode """ # 0x2000 = 8192 = END checker = lambda current: self.interface.ibsta() & 8192 reader = lambda: self.interface.read(1) return self._read(reader, count, checker, False, None, False, gpib.GpibError) def write(self, data): """Writes data to device or interface synchronously. Corresponds to viWrite function of the VISA library. :param data: data to be written. :type data: bytes :return: Number of bytes actually transferred, return value of the library call. :rtype: int, VISAStatus """ logger.debug('GPIB.write %r' % data) try: self.interface.write(data) return SUCCESS except gpib.GpibError: # 0x4000 = 16384 = TIMO if self.interface.ibsta() & 16384: return 0, StatusCode.error_timeout def _get_attribute(self, attribute): """Get the value for a given VISA attribute for this session. Use to implement custom logic for attributes. :param attribute: Resource attribute for which the state query is made :return: The state of the queried attribute for a specified resource, return value of the library call. :rtype: (unicode | str | list | int, VISAStatus) """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_ATN_STATE: # This could be checked with linux-gpib's iblines function, but this # function is not exposed in the Python bindings. raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_ADDR_STATE: if self.interface.ibsta() & 4: return constants.VI_GPIB_LISTENER, SUCCESS elif self.interface.ibsta() & 8: return constants.VI_GPIB_TALKER, SUCCESS else: return constants.VI_GPIB_UNADDRESSED, SUCCESS elif attribute == constants.VI_ATTR_GPIB_CIC_STATE: if self.interface.ibsta() & 32: return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_GPIB_NDAC_STATE: # See VI_ATTR_GPIB_ATN_STATE raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_SRQ_STATE: # See VI_ATTR_GPIB_ATN_STATE raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_SYS_CNTRL_STATE: if self.interface.ask(10): return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_GPIB_HS488_CBL_LEN: return constants.VI_GPIB_HS488_NIMPL, StatusCode.VI_ERROR_NIMPL_OPER elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: return self.interface.ask(1), SUCCESS elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: sad = self.interface.ask(2) if sad: return sad - 96, SUCCESS else: return constants.VI_NO_SEC_ADDR, SUCCESS elif attribute == constants.VI_ATTR_GPIB_REN_STATE: # See VI_ATTR_GPIB_ATN_STATE raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: if self.interface.ask(27): return constants.VI_TRUE, SUCCESS else: return constants.VI_FALSE, SUCCESS elif attribute == constants.VI_ATTR_GPIB_RECV_CIC_STATE: raise NotImplementedError elif attribute == constants.VI_ATTR_INTF_TYPE: return constants.InterfaceType.gpib, SUCCESS raise UnknownAttribute(attribute) def _set_attribute(self, attribute, attribute_state): """Sets the state of an attribute. Corresponds to viSetAttribute function of the VISA library. :param attribute: Attribute for which the state is to be modified. (Attributes.*) :param attribute_state: The state of the attribute to be set for the specified object. :return: return value of the library call. :rtype: VISAStatus """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_HS488_CBL_LEN: return StatusCode.VI_ERROR_NIMPL_OPER elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: raise NotImplementedError raise UnknownAttribute(attribute)
from prologix_gpib_async.prologix_gpib_async import AsyncPrologixGpibEthernetController, EosMode if 'prologix_gpib_async.prologix_gpib_async' in sys.modules: from prologix_gpib_async.ip_connection import NetworkError ip_address = '127.0.0.1' gpib_device = AsyncPrologixGpibEthernetController( ip_address, pad=27, timeout=1000, eos_mode=EosMode.APPEND_NONE) # Uncomment if using linux-gpib #from pyAsyncGpib.pyAsyncGpib.AsyncGpib import AsyncGpib if 'pyAsyncGpib.pyAsyncGpib.AsyncGpib' in sys.modules: # Create the gpib device. We need a timeout of > 10 PLC (20 ms), because the DMM might reply to a conversion request # and unable to reply to a status request during conversion (maximum time 10 PLC) # Set the timeout to 1 second (T1s=11) gpib_device = AsyncGpib(name=0, pad=27, timeout=11) # NI GPIB adapter from Gpib import Gpib gpib_board = Gpib(name=0) gpib_board.config( 0x7, True) # enable wait for SRQs to speed up waiting for state changes gpib_board.close() # This example will log resistance data to the console async def main(): try: async with HP_3478A(connection=gpib_device) as hp3478a: await hp3478a.clear() # flush all buffers await asyncio.gather( hp3478a.set_function(FunctionType.OHMF), # Set to 4-wire ohm hp3478a.set_range(Range.RANGE_30k), # Set to 30 kOhm range hp3478a.set_trigger(
class GPIBSession(Session): """A GPIB Session that uses linux-gpib to do the low level communication. """ @staticmethod def list_resources(): return ['GPIB0::%d::INSTR' % pad for pad in _find_listeners()] @classmethod def get_low_level_info(cls): try: ver = gpib.version() except AttributeError: ver = '< 4.0' return 'via Linux GPIB (%s)' % ver def after_parsing(self): minor = int(self.parsed.board) pad = int(self.parsed.primary_address) sad = 0 timeout = 13 send_eoi = 1 eos_mode = 0 self.interface = Gpib(name=minor, pad=pad, sad=sad, timeout=timeout, send_eoi=send_eoi, eos_mode=eos_mode) self.controller = Gpib(name=minor) # this is the bus controller device self.handle = self.interface.id # force timeout setting to interface self.set_attribute( constants.VI_ATTR_TMO_VALUE, attributes.AttributesByID[constants.VI_ATTR_TMO_VALUE].default) def _get_timeout(self, attribute): if self.interface: # 0x3 is the hexadecimal reference to the IbaTMO (timeout) configuration # option in linux-gpib. gpib_timeout = self.interface.ask(3) if gpib_timeout and gpib_timeout < len(TIMETABLE): self.timeout = TIMETABLE[gpib_timeout] else: # value is 0 or out of range -> infinite self.timeout = None return super(GPIBSession, self)._get_timeout(attribute) def _set_timeout(self, attribute, value): """ linux-gpib only supports 18 discrete timeout values. If a timeout value other than these is requested, it will be rounded up to the closest available value. Values greater than the largest available timout value will instead be rounded down. The available timeout values are: 0 Never timeout. 1 10 microseconds 2 30 microseconds 3 100 microseconds 4 300 microseconds 5 1 millisecond 6 3 milliseconds 7 10 milliseconds 8 30 milliseconds 9 100 milliseconds 10 300 milliseconds 11 1 second 12 3 seconds 13 10 seconds 14 30 seconds 15 100 seconds 16 300 seconds 17 1000 seconds """ status = super(GPIBSession, self)._set_timeout(attribute, value) if self.interface: if self.timeout is None: gpib_timeout = 0 else: # round up only values that are higher by 0.1% than discrete values gpib_timeout = min(bisect(TIMETABLE, 0.999 * self.timeout), 17) self.timeout = TIMETABLE[gpib_timeout] self.interface.timeout(gpib_timeout) return status def close(self): gpib.close(self.handle) def read(self, count): """Reads data from device or interface synchronously. Corresponds to viRead function of the VISA library. :param count: Number of bytes to be read. :return: data read, return value of the library call. :rtype: bytes, constants.StatusCode """ # 0x2000 = 8192 = END checker = lambda current: self.interface.ibsta() & 8192 reader = lambda: self.interface.read(count) return self._read(reader, count, checker, False, None, False, gpib.GpibError) def write(self, data): """Writes data to device or interface synchronously. Corresponds to viWrite function of the VISA library. :param data: data to be written. :type data: bytes :return: Number of bytes actually transferred, return value of the library call. :rtype: int, VISAStatus """ logger.debug('GPIB.write %r' % data) try: self.interface.write(data) count = self.interface.ibcnt() # number of bytes transmitted return count, StatusCode.success except gpib.GpibError: # 0x4000 = 16384 = TIMO if self.interface.ibsta() & 16384: return 0, StatusCode.error_timeout else: return 0, StatusCode.error_system_error def clear(self): """Clears a device. Corresponds to viClear function of the VISA library. :param session: Unique logical identifier to a session. :return: return value of the library call. :rtype: :class:`pyvisa.constants.StatusCode` """ logger.debug('GPIB.device clear') try: self.interface.clear() return 0, StatusCode.success except: return 0, StatusCode.error_system_error def gpib_command(self, command_byte): """Write GPIB command byte on the bus. Corresponds to viGpibCommand function of the VISA library. See: https://linux-gpib.sourceforge.io/doc_html/gpib-protocol.html#REFERENCE-COMMAND-BYTES :param command_byte: command byte to send :type command_byte: int, must be [0 255] :return: return value of the library call :rtype: :class:`pyvisa.constants.StatusCode` """ if 0 <= command_byte <= 255: data = chr(command_byte) else: return StatusCode.error_nonsupported_operation try: self.controller.command(data) return StatusCode.success except gpib.GpibError: return StatusCode.error_system_error def trigger(self, protocol): """Asserts hardware trigger. Only supports protocol = constants.VI_TRIG_PROT_DEFAULT :return: return value of the library call. :rtype: :class:`pyvisa.constants.StatusCode` """ logger.debug('GPIB.device assert hardware trigger') try: if protocol == constants.VI_TRIG_PROT_DEFAULT: self.interface.trigger() return StatusCode.success else: return StatusCode.error_nonsupported_operation except gpib.GpibError: return StatusCode.error_system_error def gpib_send_ifc(self): """Pulse the interface clear line (IFC) for at least 100 microseconds. Corresponds to viGpibSendIFC function of the VISA library. :param session: Unique logical identifier to a session. :return: return value of the library call. :rtype: :class:`pyvisa.constants.StatusCode` """ logger.debug('GPIB.interface clear') try: self.controller.interface_clear() return 0, StatusCode.success except: return 0, StatusCode.error_system_error def _get_attribute(self, attribute): """Get the value for a given VISA attribute for this session. Use to implement custom logic for attributes. :param attribute: Resource attribute for which the state query is made :return: The state of the queried attribute for a specified resource, return value of the library call. :rtype: (unicode | str | list | int, VISAStatus) """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbaREADDR 0x6 # Setting has no effect in linux-gpib. return self.interface.ask(6), StatusCode.success elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbaPAD 0x1 return self.interface.ask(1), StatusCode.success elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbaSAD 0x2 # Remove 0x60 because National Instruments. sad = self.interface.ask(2) if self.interface.ask(2): return self.interface.ask(2) - 96, StatusCode.success else: return constants.VI_NO_SEC_ADDR, StatusCode.success elif attribute == constants.VI_ATTR_GPIB_REN_STATE: # I have no idea how to implement this. raise NotImplementedError elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbaUnAddr 0x1b if self.interface.ask(27): return constants.VI_TRUE, StatusCode.success else: return constants.VI_FALSE, StatusCode.success elif attribute == constants.VI_ATTR_SEND_END_EN: # IbaEndBitIsNormal 0x1a if self.interface.ask(26): return constants.VI_TRUE, StatusCode.success else: return constants.VI_FALSE, StatusCode.success elif attribute == constants.VI_ATTR_INTF_NUM: # IbaBNA 0x200 return self.interface.ask(512), StatusCode.success elif attribute == constants.VI_ATTR_INTF_TYPE: return constants.InterfaceType.gpib, StatusCode.success raise UnknownAttribute(attribute) def _set_attribute(self, attribute, attribute_state): """Sets the state of an attribute. Corresponds to viSetAttribute function of the VISA library. :param attribute: Attribute for which the state is to be modified. (Attributes.*) :param attribute_state: The state of the attribute to be set for the specified object. :return: return value of the library call. :rtype: VISAStatus """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbcREADDR 0x6 # Setting has no effect in linux-gpib. if isinstance(attribute_state, int): self.interface.config(6, attribute_state) return StatusCode.success else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbcPAD 0x1 if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: self.interface.config(1, attribute_state) return StatusCode.success else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbcSAD 0x2 # Add 0x60 because National Instruments. if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: if self.interface.ask(2): self.interface.config(2, attribute_state + 96) return StatusCode.success else: return StatusCode.error_nonsupported_attribute else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbcUnAddr 0x1b try: self.interface.config(27, attribute_state) return StatusCode.success except gpib.GpibError: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_SEND_END_EN: # IbcEndBitIsNormal 0x1a if isinstance(attribute_state, int): self.interface.config(26, attribute_state) return StatusCode.success else: return StatusCode.error_nonsupported_attribute_state raise UnknownAttribute(attribute) def read_stb(self): return self.interface.serial_poll()
class GPIBSession(Session): """A GPIB Session that uses linux-gpib to do the low level communication. """ @staticmethod def list_resources(): return ['GPIB0::%d::INSTR' % pad for pad in _find_listeners()] @classmethod def get_low_level_info(cls): try: ver = gpib.version() except AttributeError: ver = '< 4.0' return 'via Linux GPIB (%s)' % ver def after_parsing(self): minor = int(self.parsed.board) pad = int(self.parsed.primary_address) sad = 0 timeout = 13 send_eoi = 1 eos_mode = 0 self.interface = Gpib(name=minor, pad=pad, sad=sad, timeout=timeout, send_eoi=send_eoi, eos_mode=eos_mode) self.controller = Gpib(name=minor) # this is the bus controller device # force timeout setting to interface self.set_attribute(constants.VI_ATTR_TMO_VALUE, attributes.AttributesByID[constants.VI_ATTR_TMO_VALUE].default) def _get_timeout(self, attribute): if self.interface: # 0x3 is the hexadecimal reference to the IbaTMO (timeout) configuration # option in linux-gpib. gpib_timeout = self.interface.ask(3) if gpib_timeout and gpib_timeout < len(TIMETABLE): self.timeout = TIMETABLE[gpib_timeout] else: # value is 0 or out of range -> infinite self.timeout = None return super(GPIBSession, self)._get_timeout(attribute) def _set_timeout(self, attribute, value): """ linux-gpib only supports 18 discrete timeout values. If a timeout value other than these is requested, it will be rounded up to the closest available value. Values greater than the largest available timout value will instead be rounded down. The available timeout values are: 0 Never timeout. 1 10 microseconds 2 30 microseconds 3 100 microseconds 4 300 microseconds 5 1 millisecond 6 3 milliseconds 7 10 milliseconds 8 30 milliseconds 9 100 milliseconds 10 300 milliseconds 11 1 second 12 3 seconds 13 10 seconds 14 30 seconds 15 100 seconds 16 300 seconds 17 1000 seconds """ status = super(GPIBSession, self)._set_timeout(attribute, value) if self.interface: if self.timeout is None: gpib_timeout = 0 else: # round up only values that are higher by 0.1% than discrete values gpib_timeout = min(bisect(TIMETABLE, 0.999 * self.timeout), 17) self.timeout = TIMETABLE[gpib_timeout] self.interface.timeout(gpib_timeout) return status def close(self): self.interface.close() self.controller.close() def read(self, count): """Reads data from device or interface synchronously. Corresponds to viRead function of the VISA library. :param count: Number of bytes to be read. :return: data read, return value of the library call. :rtype: bytes, constants.StatusCode """ # 0x2000 = 8192 = END checker = lambda current: self.interface.ibsta() & 8192 reader = lambda: self.interface.read(count) return self._read(reader, count, checker, False, None, False, gpib.GpibError) def write(self, data): """Writes data to device or interface synchronously. Corresponds to viWrite function of the VISA library. :param data: data to be written. :type data: bytes :return: Number of bytes actually transferred, return value of the library call. :rtype: int, VISAStatus """ logger.debug('GPIB.write %r' % data) try: self.interface.write(data) count = self.interface.ibcnt() # number of bytes transmitted return count, StatusCode.success except gpib.GpibError: # 0x4000 = 16384 = TIMO if self.interface.ibsta() & 16384: return 0, StatusCode.error_timeout else: return 0, StatusCode.error_system_error def clear(self): """Clears a device. Corresponds to viClear function of the VISA library. :param session: Unique logical identifier to a session. :return: return value of the library call. :rtype: :class:`pyvisa.constants.StatusCode` """ logger.debug('GPIB.device clear') try: self.interface.clear() return StatusCode.success except gpib.GpibError: return StatusCode.error_system_error def gpib_command(self, command_byte): """Write GPIB command byte on the bus. Corresponds to viGpibCommand function of the VISA library. See: https://linux-gpib.sourceforge.io/doc_html/gpib-protocol.html#REFERENCE-COMMAND-BYTES :param command_byte: command byte to send :type command_byte: int, must be [0 255] :return: Number of written bytes, return value of the library call. :rtype: int, :class:`pyvisa.constants.StatusCode` """ if 0 <= command_byte <= 255: data = chr(command_byte) else: return 0, StatusCode.error_nonsupported_operation try: return self.controller.command(data), StatusCode.success except gpib.GpibError: return 0, StatusCode.error_system_error def assert_trigger(self, protocol): """Asserts hardware trigger. Only supports protocol = constants.VI_TRIG_PROT_DEFAULT :return: return value of the library call. :rtype: :class:`pyvisa.constants.StatusCode` """ logger.debug('GPIB.device assert hardware trigger') try: if protocol == constants.VI_TRIG_PROT_DEFAULT: self.interface.trigger() return StatusCode.success else: return StatusCode.error_nonsupported_operation except gpib.GpibError: return StatusCode.error_system_error def gpib_send_ifc(self): """Pulse the interface clear line (IFC) for at least 100 microseconds. Corresponds to viGpibSendIFC function of the VISA library. :param session: Unique logical identifier to a session. :return: return value of the library call. :rtype: :class:`pyvisa.constants.StatusCode` """ logger.debug('GPIB.interface clear') try: self.controller.interface_clear() return StatusCode.success except gpib.GpibError: return StatusCode.error_system_error def _get_attribute(self, attribute): """Get the value for a given VISA attribute for this session. Use to implement custom logic for attributes. :param attribute: Resource attribute for which the state query is made :return: The state of the queried attribute for a specified resource, return value of the library call. :rtype: (unicode | str | list | int, VISAStatus) """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbaREADDR 0x6 # Setting has no effect in linux-gpib. return self.interface.ask(6), StatusCode.success elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbaPAD 0x1 return self.interface.ask(1), StatusCode.success elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbaSAD 0x2 # Remove 0x60 because National Instruments. sad = self.interface.ask(2) if self.interface.ask(2): return self.interface.ask(2) - 96, StatusCode.success else: return constants.VI_NO_SEC_ADDR, StatusCode.success elif attribute == constants.VI_ATTR_GPIB_REN_STATE: try: lines = self.controller.lines() if not lines & gpib.ValidREN: return constants.VI_STATE_UNKNOWN, StatusCode.success if lines & gpib.BusREN: return constants.VI_STATE_ASSERTED, StatusCode.success else: return constants.VI_STATE_UNASSERTED, StatusCode.success except AttributeError: # some versions of linux-gpib do not expose Gpib.lines() return constants.VI_STATE_UNKNOWN, StatusCode.success elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbaUnAddr 0x1b if self.interface.ask(27): return constants.VI_TRUE, StatusCode.success else: return constants.VI_FALSE, StatusCode.success elif attribute == constants.VI_ATTR_SEND_END_EN: # IbaEndBitIsNormal 0x1a if self.interface.ask(26): return constants.VI_TRUE, StatusCode.success else: return constants.VI_FALSE, StatusCode.success elif attribute == constants.VI_ATTR_INTF_NUM: # IbaBNA 0x200 return self.interface.ask(512), StatusCode.success elif attribute == constants.VI_ATTR_INTF_TYPE: return constants.InterfaceType.gpib, StatusCode.success raise UnknownAttribute(attribute) def _set_attribute(self, attribute, attribute_state): """Sets the state of an attribute. Corresponds to viSetAttribute function of the VISA library. :param attribute: Attribute for which the state is to be modified. (Attributes.*) :param attribute_state: The state of the attribute to be set for the specified object. :return: return value of the library call. :rtype: VISAStatus """ if attribute == constants.VI_ATTR_GPIB_READDR_EN: # IbcREADDR 0x6 # Setting has no effect in linux-gpib. if isinstance(attribute_state, int): self.interface.config(6, attribute_state) return StatusCode.success else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_PRIMARY_ADDR: # IbcPAD 0x1 if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: self.interface.config(1, attribute_state) return StatusCode.success else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_SECONDARY_ADDR: # IbcSAD 0x2 # Add 0x60 because National Instruments. if isinstance(attribute_state, int) and 0 <= attribute_state <= 30: if self.interface.ask(2): self.interface.config(2, attribute_state + 96) return StatusCode.success else: return StatusCode.error_nonsupported_attribute else: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_GPIB_UNADDR_EN: # IbcUnAddr 0x1b try: self.interface.config(27, attribute_state) return StatusCode.success except gpib.GpibError: return StatusCode.error_nonsupported_attribute_state elif attribute == constants.VI_ATTR_SEND_END_EN: # IbcEndBitIsNormal 0x1a if isinstance(attribute_state, int): self.interface.config(26, attribute_state) return StatusCode.success else: return StatusCode.error_nonsupported_attribute_state raise UnknownAttribute(attribute) def read_stb(self): try: return self.interface.serial_poll(), StatusCode.success except gpib.GpibError: return 0, StatusCode.error_system_error