如何使用PyUSB写入控制端点



我有一个USB设备,下面的代码是

import usb.core
import usb.util
device = usb.core.find(idVendor=0xC251, idProduct=0x2201)
print(device)

产生

DEVICE ID c251:2201 on Bus 002 Address 020 =================
bLength                :   0x12 (18 bytes)
bDescriptorType        :    0x1 Device
bcdUSB                 :  0x200 USB 2.0
bDeviceClass           :    0x0 Specified at interface
bDeviceSubClass        :    0x0
bDeviceProtocol        :    0x0
bMaxPacketSize0        :   0x40 (64 bytes)
idVendor               : 0xc251
idProduct              : 0x2201
bcdDevice              :  0x100 Device 1.0
iManufacturer          :    0x1 LASER Driver 
iProduct               :    0x2 LASER Driver IJS
iSerialNumber          :    0x3 0001A0000000
bNumConfigurations     :    0x1
CONFIGURATION 1: 100 mA ==================================
bLength              :    0x9 (9 bytes)
bDescriptorType      :    0x2 Configuration
wTotalLength         :   0x22 (34 bytes)
bNumInterfaces       :    0x1
bConfigurationValue  :    0x1
iConfiguration       :    0x0 
bmAttributes         :   0xc0 Self Powered
bMaxPower            :   0x32 (100 mA)
INTERFACE 0: Human Interface Device ====================
bLength            :    0x9 (9 bytes)
bDescriptorType    :    0x4 Interface
bInterfaceNumber   :    0x0
bAlternateSetting  :    0x0
bNumEndpoints      :    0x1
bInterfaceClass    :    0x3 Human Interface Device
bInterfaceSubClass :    0x0
bInterfaceProtocol :    0x0
iInterface         :    0x4 HID
ENDPOINT 0x81: Interrupt IN ==========================
bLength          :    0x7 (7 bytes)
bDescriptorType  :    0x5 Endpoint
bEndpointAddress :   0x81 IN
bmAttributes     :    0x3 Interrupt
wMaxPacketSize   :   0x40 (64 bytes)
bInterval        :    0x1

在Python 3下的Ubuntu 20.04中。可以看出,不存在OUT端点。我不是USB方面的专家,但据我所知,我们需要一个输出端点来向设备发送数据,所以这个设备看起来像只读设备。

然而,我知道有一些方法可以向设备发送/写入数据,因为它是一个激光控制器,从Windows我可以打开/关闭激光,改变强度等。我有这个控制器的部分C++源代码用于Windows,它使用hidapi。根据CCD_ 2的文档;控制端点";当没有其他输出端点时,这里似乎就是这样。所以现在我想使用PyUSB从Python中复制这一点。

到目前为止,我有这个

import usb.core
import usb.util
import array
device = usb.core.find(idVendor=0xC251, idProduct=0x2201)
if device is None:
raise RuntimeError('Device not found')
interface = device[0].interfaces()[0]
endpoint = device[0].interfaces()[0].endpoints()[0] # This is the in endpoint, I can read the status of the laser from here and it works fine.
if device.is_kernel_driver_active(interface.bInterfaceNumber):
device.detach_kernel_driver(interface.bInterfaceNumber)
cmd = chr(90) # This is the command to turn off the laser.
packet = chr(0) + cmd + chr(0)*(64-len(cmd)-1) # The first byte has to be always 0, see https://codedocs.xyz/GerryFerdinandus/hidapi/group__API.html#gad14ea48e440cf5066df87cc6488493af
packet = array.array('B', [ord(c) for c in packet])
bytes_sent = endpoint.write(packet)
print(bytes_sent) # This prints out 64 so it is fine.

它似乎在写,但激光器什么也不做(应该关闭(。我怀疑它不知怎么写进了";IN端点";而不是进入";控制端点";。我想将此packet发送到控制端点。如何做到这一点?

PD:我也试过

device.write(0x0, packet)

但这产生CCD_ 4。

要写入端点0,需要device.ctrl_transfer(bmRequestType, bmRequest, wValue, wIndex, packet)而不是endpoint.write(packet)

bmRequestTypebmRequestwValuewIndex对应于USB控制请求中的相同元素。Windows软件使用hidapi的事实表明,控制传输是根据USB HID规范进行的。

Stack Overflow上的这个答案描述了如何在普通PyUSB上进行USB HID设置/获取操作。

但是,由于您移植的源代码使用hidapi,因此使用Python-hidapi接口可能会使过程更加简单。这个问题有一个在Python中使用hidapi的例子,答案也谈到了替代方案。

相关内容

  • 没有找到相关文章

最新更新