Open sgoadhouse opened 2 years ago
I have seen USB hubs sometimes cause havoc in VISA over USB (each time the user moved the mouse connected on the hub, the connection would drop). So if you can test without, I would suggest you try that first.
I have a similar issue here. I use the USB connector directly without USB hubs.
This issue is happening intermittently, and 70% of the time open_resource will give me the error.
I found that if I reseat the USB plug (same USB insert and same orientation on my mac), the issue disappeared.
This is like black magic. Keysight 34460A is the instrument that I am connecting to.
This is the error code that open_resource gave me:
---------------------------------------------------------------------------
USBError Traceback (most recent call last)
Input In [2], in <cell line: 5>()
3 print(USB_ID)
4 # inst = rm.open_resource('USB0::10893::5633::MY57102284::0::INSTR', read_termination='\r', send_end=False)
----> 5 inst = rm.open_resource('USB0::10893::5633::MY57102284::0::INSTR')
File /usr/local/lib/python3.10/site-packages/pyvisa/highlevel.py:3284, in ResourceManager.open_resource(self, resource_name, access_mode, open_timeout, resource_pyclass, **kwargs)
3278 if not present:
3279 raise ValueError(
3280 "%r is not a valid attribute for type %s"
3281 % (key, res.__class__.__name__)
3282 )
-> 3284 res.open(access_mode, open_timeout)
3286 for key, value in kwargs.items():
3287 setattr(res, key, value)
File /usr/local/lib/python3.10/site-packages/pyvisa/resources/resource.py:278, in Resource.open(self, access_mode, open_timeout)
274 logger.debug("%s - opening ...", self._resource_name, extra=self._logging_extra)
275 with self._resource_manager.ignore_warning(
276 constants.StatusCode.success_device_not_present
277 ):
--> 278 self.session, status = self._resource_manager.open_bare_resource(
279 self._resource_name, access_mode, open_timeout
280 )
282 if status == constants.StatusCode.success_device_not_present:
283 # The device was not ready when we opened the session.
284 # Now it gets five seconds more to become ready.
285 # Every 0.1 seconds we probe it with viClear.
286 start_time = time.time()
File /usr/local/lib/python3.10/site-packages/pyvisa/highlevel.py:3209, in ResourceManager.open_bare_resource(self, resource_name, access_mode, open_timeout)
3180 def open_bare_resource(
3181 self,
3182 resource_name: str,
3183 access_mode: constants.AccessModes = constants.AccessModes.no_lock,
3184 open_timeout: int = constants.VI_TMO_IMMEDIATE,
3185 ) -> Tuple[VISASession, StatusCode]:
3186 """Open the specified resource without wrapping into a class.
3187
3188 Parameters
(...)
3207
3208 """
-> 3209 return self.visalib.open(self.session, resource_name, access_mode, open_timeout)
File /usr/local/lib/python3.10/site-packages/pyvisa_py/highlevel.py:167, in PyVisaLibrary.open(self, session, resource_name, access_mode, open_timeout)
158 return (
159 VISASession(0),
160 self.handle_return_value(None, StatusCode.error_invalid_resource_name),
161 )
163 cls = sessions.Session.get_session_class(
164 parsed.interface_type_const, parsed.resource_class
165 )
--> 167 sess = cls(session, resource_name, parsed, open_timeout)
169 return self._register(sess), StatusCode.success
File /usr/local/lib/python3.10/site-packages/pyvisa_py/sessions.py:325, in Session.__init__(self, resource_manager_session, resource_name, parsed, open_timeout)
322 default_timeout = attributes.AttributesByID[attr].default
323 self.set_attribute(attr, default_timeout)
--> 325 self.after_parsing()
File /usr/local/lib/python3.10/site-packages/pyvisa_py/usb.py:81, in USBSession.after_parsing(self)
80 def after_parsing(self) -> None:
---> 81 self.interface = self._intf_cls(
82 int(self.parsed.manufacturer_id, 0),
83 int(self.parsed.model_code, 0),
84 self.parsed.serial_number,
85 )
87 for name in ("SEND_END_EN", "SUPPRESS_END_EN", "TERMCHAR", "TERMCHAR_EN"):
88 attribute = getattr(constants, "VI_ATTR_" + name)
File /usr/local/lib/python3.10/site-packages/pyvisa_py/protocols/usbtmc.py:293, in USBTMC.__init__(self, vendor, product, serial_number, **kwargs)
288 self.usb_intr_in = find_endpoint(
289 self.usb_intf, usb.ENDPOINT_IN, usb.ENDPOINT_TYPE_INTERRUPT
290 )
292 self.usb_dev.reset()
--> 293 self.usb_dev.set_configuration()
295 time.sleep(0.01)
297 self._capabilities = self._get_capabilities()
File /usr/local/lib/python3.10/site-packages/usb/core.py:915, in Device.set_configuration(self, configuration)
906 def set_configuration(self, configuration = None):
907 r"""Set the active configuration.
908
909 The configuration parameter is the bConfigurationValue field of the
(...)
913 without arguments is enough to get the device ready.
914 """
--> 915 self._ctx.managed_set_configuration(self, configuration)
File /usr/local/lib/python3.10/site-packages/usb/core.py:113, in synchronized.<locals>.wrapper(self, *args, **kwargs)
111 try:
112 self.lock.acquire()
--> 113 return f(self, *args, **kwargs)
114 finally:
115 self.lock.release()
File /usr/local/lib/python3.10/site-packages/usb/core.py:159, in _ResourceManager.managed_set_configuration(self, device, config)
156 raise ValueError("Invalid configuration " + str(config))
158 self.managed_open()
--> 159 self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
161 # cache the index instead of the object to avoid cyclic references
162 # of the device and Configuration (Device tracks the _ResourceManager,
163 # which tracks the Configuration, which tracks the Device)
164 self._active_cfg_index = cfg.index
File /usr/local/lib/python3.10/site-packages/usb/backend/libusb1.py:812, in _LibUSB.set_configuration(self, dev_handle, config_value)
810 @methodtrace(_logger)
811 def set_configuration(self, dev_handle, config_value):
--> 812 _check(self.lib.libusb_set_configuration(dev_handle.handle, config_value))
File /usr/local/lib/python3.10/site-packages/usb/backend/libusb1.py:604, in _check(ret)
602 raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
603 else:
--> 604 raise USBError(_strerror(ret), ret, _libusb_errno[ret])
606 return ret
USBError: [Errno 19] No such device (it may have been disconnected)
In terminal, after pyvisa-info, everything looks good:
Machine Details:
Platform ID: macOS-12.5.1-x86_64-i386-64bit
Processor: i386
Python:
Implementation: CPython
Executable: /usr/local/opt/python@3.10/bin/python3.10
Version: 3.10.6
Compiler: Clang 13.1.6 (clang-1316.0.21.2.5)
Bits: 64bit
Build: Aug 30 2022 05:12:36 (#main)
Unicode: UCS4
PyVISA Version: 1.12.0
Backends:
ivi:
Version: 1.12.0 (bundled with PyVISA)
Binary library: Not found
py:
Version: 0.5.3
ASRL INSTR: Available via PySerial (3.5)
USB INSTR: Available via PyUSB (1.2.1). Backend: libusb1
USB RAW: Available via PyUSB (1.2.1). Backend: libusb1
TCPIP INSTR: Available
TCPIP SOCKET: Available
GPIB INSTR:
Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of funcionality.
No module named 'gpib'
I have a workaround for this bug. There's a device reset()
issued immediately before set_configuration()
in pyvisa_py/protocols/usbtmc.py
. It might be causing the device to momentarily drop off the bus while macOS re-enumerates it, but this is just speculation on my part. Anyway, by delaying the configuration call by half a second, it fixes this issue for me. I hope this works for the rest of you.
import usb
import time
old_config = usb.core.Device.set_configuration
def new_with_delay(*args, **kwargs):
time.sleep(0.5)
old_config(*args, **kwargs)
usb.core.Device.set_configuration = new_with_delay
Trying to open a PyVISA connection to pyvisa-py to a USB device. Sometimes it works and other times it fails. The USB device is connected to the MacBook Pro through a USB Hub, if that matters.
I stripped down my code to make it more reproducible and testPYVISA.py is attached. My resource string is:
USB0::0x1AB1::0x0E11::DP8B153600499::INSTR
If I run
python testPYVISA.py
and it works, I see:When it fails, which is quite often, I get:
To check if it may be an issue with my PyUSB/libusb1 installation or something else related to USB, I pulled out most of the code from
__init__
frompyvisa_py/protocols/usbtmc.py
and created testUSB2.py. I never get an error when running this script.If I set the environment variable
PYUSB_DEBUG
to'debug'
, thenpython testPYVISA.py
often works (~90% of the time). If I setPYUSB_DEBUG
to''
, thenpython testPYVISA.py
works about 40% of the time.It seems as if the various bits of code called before the failing
self.usb_dev.set_configuration()
may be accessing USB to check things but the OS has not completed closing the USB connection beforeself.usb_dev.set_configuration()
is called resulting in the message. This is my deduction from seeing that a simpleself.usb_dev.set_configuration()
works fine and that adding a bunch of debug output which slows things down when opening the device throughpyvisa-py
works most of the time.To Reproduce
Steps to reproduce the behavior:
python testPYVISA.py
testPYVISA.py testUSB2.py
Output of
pyvisa-info