杰瑞科技汇

Python如何正确导入并使用usblib?

Of course! This is a very common point of confusion for developers new to USB programming in Python.

Python如何正确导入并使用usblib?-图1
(图片来源网络,侵删)

Let's break it down.

The Short Answer

There is no standard, built-in Python library called usblib. The Python standard library does not contain a module for directly communicating with USB devices.

However, you are likely thinking of one of two excellent third-party libraries:

  1. pyusb: The most popular and pure-Python library. It's a thin wrapper around the native libusb library.
  2. pywin32 (specifically win32com.client): The standard way to do this on Windows only. It uses the Windows OS's COM interface to the Windows Driver Model (WDM) for USB.

The Correct Libraries and How to Use Them

Here is a detailed guide on the two main approaches.

Python如何正确导入并使用usblib?-图2
(图片来源网络,侵删)

Option 1: pyusb (Cross-Platform: Windows, macOS, Linux)

pyusb is a great choice if you want your code to work on different operating systems. It requires the underlying libusb library to be installed on your system.

Installation

First, you need to install pyusb using pip:

pip install pyusb

Important: You also need to install the native libusb library on your system.

  • On Windows: Download the installer from the libusb official website and run it. The installer will add libusb-1.0.dll to a location where Python can find it.
  • On macOS (using Homebrew):
    brew install libusb
  • On Debian/Ubuntu:
    sudo apt-get update
    sudo apt-get install libusb-1.0-0-dev

How to Use pyusb

The workflow is generally:

Python如何正确导入并使用usblib?-图3
(图片来源网络,侵删)
  1. Find your USB device using its Vendor ID (VID) and Product ID (PID).
  2. Get a "handle" to the device.
  3. Detach the kernel driver if necessary (common on Linux).
  4. Set the active configuration.
  5. Send and receive data using "endpoints".

Example Code:

Let's find a device and print its information. You'll need to find the VID and PID for your specific device. You can find these using tools like:

  • Windows: USBDeview or Device Manager.
  • Linux: Run lsusb in the terminal.
  • macOS: Run system_profiler SPUSBDataType in the terminal.
import usb.core
import usb.util
# --- Find the Device ---
# Replace these with your device's Vendor ID and Product ID
# VID = 0x1234  # Example VID
# PID = 0x5678  # Example PID
# For this example, let's try to find a specific device.
# Let's use the VID/PID for a common FTDI USB-to-Serial chip.
VID = 0x0403
PID = 0x6001
# Find the device
dev = usb.core.find(idVendor=VID, idProduct=PID)
if dev is None:
    raise ValueError("Device not found")
print(f"Found Device: {dev}")
print(f"Device ID: Vendor={dev.idVendor:04x}, Product={dev.idProduct:04x}")
# --- Basic Interaction ---
# You need to claim the interface before you can use it
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
# Detach kernel driver if active (Linux)
if dev.is_kernel_driver_active(0):
    print("Detaching kernel driver...")
    dev.detach_kernel_driver(0)
    usb.util.release_interface(dev, intf)
# Set the active configuration. Some devices require this.
# dev.set_configuration()
# Get an endpoint instance
# The endpoint address depends on your device's configuration
ep = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT
)
if ep is None:
    raise ValueError("Could not find an OUT endpoint")
# Write data to the endpoint
data_to_send = b'\x01\x02\x03\x04' # Example data
bytes_written = ep.write(data_to_send)
print(f"Wrote {bytes_written} bytes to endpoint {ep.bEndpointAddress}")
# Now, let's read from an IN endpoint
ep_in = usb.util.find_descriptor(
    intf,
    # match the first IN endpoint
    custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN
)
if ep_in is None:
    raise ValueError("Could not find an IN endpoint")
# Read data from the endpoint
# The size depends on your device's endpoint packet size
data_read = ep_in.read(ep_in.wMaxPacketSize)
print(f"Read from endpoint {ep_in.bEndpointAddress}: {data_read}")
# Release the interface
usb.util.release_interface(dev, intf)

Option 2: pywin32 (Windows Only)

This is the "native" way to interact with USB devices on Windows. It's more complex and Windows-specific but gives you access to all the features of the Windows USB stack.

Installation

You need to install the pywin32 library:

pip install pywin32

This will also install the necessary COM support libraries.

How to Use pywin32

This approach involves:

  1. Connecting to the Windows Device Manager.
  2. Enumerating devices to find your USB device.
  3. Getting a handle to the device's driver interface.
  4. Sending I/O Control Codes (IOCTLs) to the driver to communicate.

Example Code:

This example is more complex because it involves dealing with Windows APIs. It demonstrates how to find a device and send a simple control transfer.

import win32com.client
import pythoncom
def find_usb_device(vid_pid):
    """
    Finds a USB device by its VID:PID.
    vid_pid should be a string like "VID_1234&PID_5678".
    """
    try:
        # Initialize COM
        pythoncom.CoInitialize()
        # Get a handle to the WMI service
        wmi = win32com.client.Dispatch("WMI")
        # Query for PnP devices with the given hardware ID
        # The hardware ID format is "USB\VID_XXXX&PID_YYYY\..."
        query = f"SELECT * FROM Win32_PnPEntity WHERE DeviceID LIKE '%USB\\{vid_pid}%'"
        devices = wmi.ExecQuery(query)
        if not devices:
            print(f"Device with VID:PID {vid_pid} not found.")
            return None
        # For simplicity, we take the first match
        device = devices[0]
        print(f"Found Device: {device.Name}")
        print(f"Device ID: {device.DeviceID}")
        return device
    except Exception as e:
        print(f"An error occurred: {e}")
        return None
    finally:
        # Uninitialize COM
        pythoncom.CoUninitialize()
def send_control_transfer(device_path, request_type, request, value, index, data):
    """
    Sends a control transfer to the device.
    This is a simplified example and requires a proper driver.
    """
    try:
        # This part is highly dependent on having a driver that can handle CreateFile
        # and DeviceIoControl. For many simple USB devices, you need a custom
        # or generic driver (like libusb-win32's driver).
        print(f"Attempting to send control transfer to {device_path}...")
        print(f"Request: {request:02x}, Value: {value:04x}, Index: {index:04x}")
        # The actual implementation of CreateFile and DeviceIoControl is complex
        # and involves calling Windows API functions directly via ctypes or
        # a library that exposes them.
        # This is a placeholder for where that code would go.
        print("NOTE: Full control transfer implementation is not shown here.")
        print("It requires handling CreateFile, DeviceIoControl, and error codes.")
        return True # Placeholder
    except Exception as e:
        print(f"Error sending control transfer: {e}")
        return False
if __name__ == "__main__":
    # Example: Find a device with VID=0x0403 (FTDI) and PID=0x6001
    # The hardware ID string is VID_0403&PID_6001
    target_vid_pid = "VID_0403&PID_6001"
    device = find_usb_device(target_vid_pid)
    if device:
        # The DeviceID string contains the instance path needed for CreateFile
        # e.g., "USB\VID_0403&PID_6001\6&12345678&0&A1234567"
        # We would need to parse this to get the "\\?\USB#VID_..." path.
        print("\nTo send data, you would need to:")
        print("1. Install a driver for the device (e.g., libusb-win32).")
        print("2. Use the '
分享:
扫描分享到社交APP
上一篇
下一篇