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)
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!
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.
And the
__send()
functionThe error message I get in return is as follows
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 thatset_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.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: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 movedself.device.set_configuration(self.cfg)
out of the if statement so that the device will always be set.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