You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows系统下使用PyUSB从USB设备获取数据?附代码求助

排查Windows下PyUSB读取USB设备数据的问题

我帮你梳理下这段代码里的问题,再给你调整后的可用版本,顺便提下Windows下必须注意的驱动事项:

1. 代码里的明显错误

  • 变量名写错了:write_data方法里你调用self._dev.write(1,startlist,100),但方法参数是sendlist,这里应该改成sendlist,不然运行会直接报NameError。
  • 混用PyUSB的新旧API:你同时用了旧的usb.busses()(属于libusb 0.1的兼容接口)和新的usb.core.find(libusb 1.0的现代API),这两套API的设备对象完全不兼容——比如你用旧API的device.open()拿到的handle,和新API的self._dev根本不是一回事,混用肯定会出问题。建议直接抛弃旧API,全用PyUSB 1.0的现代接口。

2. 核心逻辑的遗漏点

  • 没Claim USB接口:绝大多数USB设备,你必须先获取接口的使用权(也就是claim接口)才能进行数据传输,你的代码里完全没这一步,这是读取失败的核心原因之一。
  • 设备占用问题:Windows下系统可能会默认加载内核驱动占用设备,导致PyUSB无法访问,所以需要先分离内核驱动。

3. 调整后的完整可运行代码

import usb.core
import usb.util

class UsbDevice(object):
    def __init__(self, vend_id, prod_id):
        # 用现代API查找设备
        self.dev = usb.core.find(idVendor=vend_id, idProduct=prod_id)
        if self.dev is None:
            raise ValueError("设备没找到!请检查VID/PID是否正确,或者设备有没有连接")
        
        # 处理Windows下的内核驱动占用问题
        if self.dev.is_kernel_driver_active(0):
            try:
                self.dev.detach_kernel_driver(0)
                print("已分离内核驱动")
            except usb.core.USBError as e:
                print(f"分离内核驱动失败: {str(e)}")
        
        # Claim接口0(大部分设备用接口0,根据你的设备实际情况调整)
        try:
            usb.util.claim_interface(self.dev, 0)
            print("已获取接口使用权")
        except usb.core.USBError as e:
            print(f"获取接口使用权失败: {str(e)}")
            raise

    def write_data(self, ep_out, data, timeout=1000):
        """向OUT端点写入数据,data可以是列表或字节数组"""
        try:
            # 把列表转成字节数组再发送
            written_bytes = self.dev.write(ep_out, bytes(data), timeout)
            return written_bytes
        except usb.core.USBError as e:
            print(f"写入数据失败: {str(e)}")
            return 0

    def read_data(self, ep_in, size, timeout=1000):
        """从IN端点读取数据,返回列表格式"""
        try:
            raw_data = self.dev.read(ep_in, size, timeout)
            # 把返回的数组转成普通列表方便查看
            return list(raw_data)
        except usb.core.USBError as e:
            # 超时是正常情况,不用报错
            if e.args[0] == 110:  # Windows下的超时错误码
                return []
            print(f"读取数据失败: {str(e)}")
            return []

if __name__ == '__main__':
    # 替换成你的设备VID和PID
    DEVICE_VID = 0xAAAA
    DEVICE_PID = 0xAA97
    try:
        my_device = UsbDevice(DEVICE_VID, DEVICE_PID)
        # 发送0x44到OUT端点0x01
        written = my_device.write_data(0x01, [0x44])
        print(f"成功写入 {written} 字节")
        
        # 循环读取数据
        while True:
            received_data = my_device.read_data(0x85, 100)
            if received_data:
                print(f"读取到数据: {received_data}")
    except ValueError as e:
        print(e)
    except Exception as e:
        print(f"程序运行异常: {str(e)}")

4. Windows下必须注意的关键事项

  • 安装正确的驱动:Windows默认不会给非标准USB设备装合适的驱动,你得用Zadig工具给设备安装WinUSB或libusb-win32驱动。打开Zadig后,找到对应VID/PID的设备,选好驱动类型,点击安装/替换——这一步是重中之重,没有正确驱动,PyUSB根本没法访问设备。
  • 权限问题:如果还是报访问错误,试试以管理员身份运行你的Python脚本。
  • 确认端点信息:确保你用的端点地址(0x01和0x85)是设备实际支持的,可以用USBView工具查看设备的端点配置。

内容的提问来源于stack exchange,提问作者YPHFree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:45