windows下python实现usb收发通信

最近在研究python调用热敏打印机的对接实现方式,发现打印机厂家提供了标准ESC/POS调用指令,就想着能不能在windows下使用python直接与打印机通过usb进行通信,实现ESC/POS指令的收发!最终证明是可以的,只是前期遇到一些问题(问问AI基本上也都解决啦)。

python在windows下可以使用python-escpos库对接打印机(它封装了 ESC/POS 指令,支持 USB、串口、网络打印机等),但是因为我想测试同一台电脑上连接2个相同型号打印机(厂商 ID 和产品 ID 完全相同)没办法区分打印机,所以只能使用python直接在底层与usb设备进行usb设备选择及通信。

一、安装库文件

pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple  python-escpos pyusb libusb

二、下载dll文件

下载libusb-1.0.20.7z的压缩包【https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-1.0.20/libusb-1.0.20.7z/download】,解压后将MS64dlllibusb-1.0.dll复制到C:WindowsSystem32。如果还不行的话再将同一目录下的libusb-1.0.lib到Python路径下的libsite-packagesusb文件夹中。

三、下载Zadig替换通用usb驱动

可以去官网下载网速比较慢【https://zadig.akeo.ie/】或者自行百度下一般都有其他下载站提供下载。

风险提示:

在计算机设备管理器中,可以选择设备右键更新驱动来还原驱动

四、python与usb通信测试

1、查找指定设备,注意不是所有的usb设备都有serial序列号,甚至有的厂家设备序列号都一样!

import usb.core

# 查找指定设备
idVendor = 0x5a5a #设备管理器里可以查看
idProduct = 0x8009 #设备管理器里可以查看

printers = usb.core.find(find_all=True, idVendor=idVendor, idProduct=idProduct) # 查找特定设备
#printers = usb.core.find(find_all=True)  # 这种写法会列出所有usb设备
for dev in printers:
    # 获取序列号
    serial = usb.util.get_string(dev, dev.iSerialNumber)
    print(f"idVendor:0x{dev.idVendor:04X}, idProduct:0x{dev.idProduct:04X},序列号: {serial}, Bus: {dev.bus}, Address: {dev.address}")

2、根据序列号设备id查找设备后,发送并接收usb数据

import usb.core
import usb.util
# 查找指定设备
idVendor = 0x5a5a #设备管理器里可以查看
idProduct = 0x8009 #设备管理器里可以查看

"""
printers = usb.core.find(find_all=True, idVendor=idVendor, idProduct=idProduct) # 查找特定设备
#printers = usb.core.find(find_all=True)  # 这种写法会列出所有usb设备
for dev in printers:
    # 获取序列号
    serial = usb.util.get_string(dev, dev.iSerialNumber)
    printer=dev
    print(f"idVendor:0x{dev.idVendor:04X}, idProduct:0x{dev.idProduct:04X},序列号: {serial}, Bus: {dev.bus}, Address: {dev.address}")

if printers is None:
    raise ValueError("No printer found")

"""

target_serial = "206035763031"  #要查找的序列号

printer = None
printers = usb.core.find(find_all=True, idVendor=idVendor, idProduct=idProduct)
for dev in printers:
    current_serial = usb.util.get_string(dev, dev.iSerialNumber)
    if current_serial == target_serial:
        printer = dev

out_ep=0x01 # 输出端点一般是固定的
input_ep=0x81 #输入端点 如果接收不到数据可以再试下0x82 0x83
command = bytes.fromhex("AA 04 01 55")  # 转换为字节
printer.write(out_ep, command)  # 发送数据

# 读取打印机返回数据(假设返回 12 字节:AA 0C 01 data1-data8 55)
try:
    response = printer.read(input_ep, 12, timeout=5000)  # 5秒超时 读取usb返回数据
    print(response)

except usb.core.USBError as e:
    print(f"读取失败: {e}")

# 关闭usb
usb.util.dispose_resources(printer)

参考文档:

Windows环境下基于Python的PyUSB库开发USB通讯

基于互联网精神,在注明出处的前提下本站文章可自由转载!

本文链接:https://ranjuan.cn/win-python-usb-com/

赞赏

微信赞赏支付宝赞赏

发表评论