Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] usb.core.USBError: [Errno None] libusb0-dll:err [claim_interface] could not claim interface 1, invalid configuration 0 #46

Open
JonBensi opened this issue Aug 6, 2018 · 1 comment

Comments

@JonBensi
Copy link

JonBensi commented Aug 6, 2018

Hello,

I was working on a test for a device (LadyBug LB5918A Power Sensor) and decided to use python source code that a peer had already written to communicate with it. The code was only tested in a linux environment and being the masochist I am I decided to see if I could at least just identify the device on windows. After using pip to install pyusb & usbtmc, creating an inf filter with libusb-win32, I ran a brief test script to see if I could just query the device ("*IDN?"). Here's the section of the init from the API were the code fails.

try:
	self.PID = PID
	self.VID = VID
	# Initialize USBTMC interface with the LadyBug.
	self.instr =  usbtmc.Instrument(self.VID, self.PID)
	#self.instr =  usbtmc.Instrument(0x1A0D, 0x15D8)
	self.connected = True
	self.log.debug('Connecting to device with VID: '+str(self.VID)+' and PID: '+str(self.PID))
	self._send('SYST:PRES DEF')
	self.log.debug(str(self._request('*IDN?')))
	#self.clearErr()
except Exception as e: 
	self.exceptionHandler(e)

And the __send() function

def _send(self,msg):
		self.log.debug(str('Writing: '+str(msg)))
		self.instr.write(msg+'\n')
		err = str(self.instr.ask('SYST:ERR?\n'))
		if err != '+0,"No error"':
			self.log.debug(str('LadyBug Error: '+str(err)))

The error message I get in return is as follows

2018-08-03 15:29:08,970 :: ladyBug(DEBUG) :: __init__
2018-08-03 15:29:08,996 :: ladyBug(DEBUG) :: Connecting to device with VID: 6669 and PID: 5592
2018-08-03 15:29:08,997 :: ladyBug(DEBUG) :: Writing: SYST:PRES DEF
Traceback (most recent call last):
  File "ladyBug-test.py", line 10, in <module>
    lb = ladyBug.meter(0x1a0d,0x15d8,True)
  File "C:\Users\jonathan.bensing\LadyBug-API\ladyBug.py", line 49, in __init__
    self.exceptionHandler(e)
  File "C:\Users\jonathan.bensing\LadyBug-API\ladyBug.py", line 249, in exceptionHandler
    self.instr.open()
  File "C:\Python27\lib\site-packages\usbtmc\usbtmc.py", line 313, in open
    usb.util.claim_interface(self.device, self.iface)
  File "C:\Python27\lib\site-packages\usb\util.py", line 205, in claim_interface
    device._ctx.managed_claim_interface(device, interface)
  File "C:\Python27\lib\site-packages\usb\core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "C:\Python27\lib\site-packages\usb\core.py", line 167, in managed_claim_interface
    self.backend.claim_interface(self.handle, i)
  File "C:\Python27\lib\site-packages\usb\backend\libusb0.py", line 521, in claim_interface
    _check(_lib.usb_claim_interface(dev_handle, intf))
  File "C:\Python27\lib\site-packages\usb\backend\libusb0.py", line 431, in _check
    raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] libusb0-dll:err [claim_interface] could not claim interface 1, invalid configuration 0

After a lot of googling, I couldn’t seem to find any conclusive reason why this shouldn’t work on windows seeing that I had followed all the steps correctly for both PyUSB and USBTMC setup. I tried just the PyUSB module to identify the device which I was able to do and I then tried to write to the device commands which I know I was most likely doing wrong. I did notice that for most of the examples of PyUSB, the set_configuration() function was used a lot to attach to a device. One post that had a similar error said that set_configuration(1) should be used and in a rather fluke way I was able to get the device working, so below is the script that cause the device to function properly.

myVendorId =0x1a0d
myProductId=0x15d8
import usb.core
dev = usb.core.find(idVendor=myVendorId, idProduct=myProductId)
print dev
dev.set_configuration(1)
import ladyBug
lb = ladyBug.meter(0x1a0d,0x15d8,True)
exit()

So I then decided to go through the USBTMC api to see where the issue may be occurring. I believe that the culprit is here in the open() function:

    def open(self):
        if self.connected:
            return
        # initialize device
        # find first USBTMC interface
        for cfg in self.device:
            for iface in cfg:
                if (self.device.idVendor == 0x1334) or \
                   (iface.bInterfaceClass == USBTMC_bInterfaceClass and
                    iface.bInterfaceSubClass == USBTMC_bInterfaceSubClass):
                    self.cfg = cfg
                    self.iface = iface
                    break
                else:
                    continue
            break
        if self.iface is None:
            raise UsbtmcException("Not a USBTMC device", 'init')
        try:
            self.old_cfg = self.device.get_active_configuration()
        except usb.core.USBError:
            # ignore exception if configuration is not set
            pass
        if self.old_cfg is not None and self.old_cfg.bConfigurationValue == self.cfg.bConfigurationValue:
            # already set to correct configuration
            # release kernel driver on USBTMC interface
            self._release_kernel_driver(self.iface.bInterfaceNumber)
        else:
            # wrong configuration or configuration not set
            # release all kernel drivers
            if self.old_cfg is not None:
                for iface in self.old_cfg:
                    self._release_kernel_driver(iface.bInterfaceNumber)
            # set proper configuration
            self.device.set_configuration(self.cfg)

        # claim interface
        usb.util.claim_interface(self.device, self.iface)

After stepping through the code manually, the issue is where self.device.set_configuration(self.cfg) is never being called. I’m not sure the reasoning behind having the configuration not being set, because it seems that (on windows at least) the old_cfg bConfigurationValue will always be the same as the active cfg bConfigurationValue. And within the usbtmc code I simple moved self.device.set_configuration(self.cfg) out of the if statement so that the device will always be set.

        if self.old_cfg is not None and self.old_cfg.bConfigurationValue == self.cfg.bConfigurationValue:
            # already set to correct configuration

            # release kernel driver on USBTMC interface
            self._release_kernel_driver(self.iface.bInterfaceNumber)
        else:
            # wrong configuration or configuration not set

            # release all kernel drivers
            if self.old_cfg is not None:
                for iface in self.old_cfg:
                    self._release_kernel_driver(iface.bInterfaceNumber)

        # set proper configuration
        self.device.set_configuration(self.cfg)

I’m not sure if this is intended but I believe that this is how it should be in the code. I hope this helps!

Jon

@RobertGawron
Copy link

I had the same problem and this fix solved it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants