染卷不卷'blog

12年站长,AI实践中。互联网 IT行业,工作见闻、技术教程全分享。

python / 程序源码

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通讯

染卷

本站文章也会定期同步到微信公众号,可以关注下避免错过~

建站 12年 3天
微信公众号

发表评论

邮箱不会公开,带 * 为必填。