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/】或者自行百度下一般都有其他下载站提供下载。
风险提示:
1、Zadig替换驱动原来的驱动程序就不能用了,我打印机测试的exe程序在替换后就连不上打印机了!解决办法就是在windows设备管理器里面重新选择驱动(选驱动列表最下面一个)更新,然后就可以了。也就是说Zadig替换原驱动后其实会生成一个备份驱动,如果你要用原生驱动那么就更新驱动为最下面的最新驱动,如果你想要使用Zadig通用驱动就更新该设备的驱动为驱动列表上面的驱动!
2、在Zadig中千万不要选错设备了,如果你不确定可以先Options--List All Devices看下有哪些设备,然后把你要更新驱动的usb设备拔掉,然后再对比下看少了哪个设备!


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



更新完之前的厂家测试程序就可以正常连接打印机测试了!如果还想回去继续使用python调试usb通信那么再更新选择下驱动即可!

四、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/
微信赞赏
支付宝赞赏
发表评论