PyUSB控制ESC打印机数据发送延迟/缓存问题及刷新方法咨询
解决ESC打印机PyUSB脚本的缓存问题
看起来你遇到的是典型的USB设备驱动缓存+打印机自身缓冲区的双重问题,我来一步步帮你排查解决:
首先分析问题根源
- 内核驱动抢占设备:你代码里注释掉了
detach_kernel_driver的逻辑,如果系统里已经加载了打印机的内核驱动(比如Linux下的usblp模块),PyUSB的操作会被内核驱动拦截,数据会被内核缓存起来,导致你修改脚本后第一次运行还是发送旧的缓存数据。 - 打印机未收到刷新指令:ESC打印机本身有数据缓冲区,默认情况下可能不会立即打印所有数据,需要特定指令触发缓冲区刷新,否则会攒着数据或者保留之前的缓存内容。
具体修复方案
1. 强制分离内核驱动
修改你的Connector类的__init__方法,取消注释并完善内核驱动分离逻辑,确保PyUSB完全控制设备:
def __init__(self, idVendor=0x0123, idProduct=0x1234, showUsbDevices=False): self.idVendor = idVendor self.idProduct = idProduct if showUsbDevices: pass self.device = self.FindAndConnect() if self.device is not None: # 遍历所有接口,分离已绑定的内核驱动 for interface in range(self.device.bNumInterfaces): if self.device.is_kernel_driver_active(interface): try: self.device.detach_kernel_driver(interface) print(f"已分离接口 {interface} 的内核驱动") except usb.core.USBError as e: print(f"分离接口 {interface} 驱动失败: {str(e)}") self.device.reset() self.device.set_configuration() self.cfg = self.device.get_active_configuration() data_itfs = list(usb.util.find_descriptor(self.cfg, find_all=True,custom_match=lambda e: (e.bInterfaceClass == 0xA))) intf = data_itfs[0] self.device.set_interface_altsetting(intf) itf_num = intf.bInterfaceNumber print ("inf descriptor:===============", intf) print("numer:===============",itf_num) self.messageOut = usb.util.find_descriptor(intf, custom_match=lambda e: not (e.bEndpointAddress & 0x80)) self.messageIn = usb.util.find_descriptor(intf, custom_match=lambda e: (e.bEndpointAddress & 0x80))
2. 发送打印机刷新指令
在send方法的最后,添加ESC打印机的缓存刷新指令,强制打印机立即打印并清空缓冲区。常用的指令有几种,你可以根据自己的打印机型号选择:
ESC @(十六进制\x1B\x40):初始化打印机,清空所有缓存FF(十六进制\x0C):换页,强制打印缓存内容GS V 0(十六进制\x1D\x56\x00):切纸并清空缓存(热敏打印机常用)
修改后的send方法:
def send(self, data): if self.device is not None: print(data.decode("IBM852")) # 发送主数据,确认写入字节数 sent_bytes = self.messageOut.write(data) print(f"已发送 {sent_bytes} 字节数据") # 发送刷新指令,这里用ESC @初始化打印机 flush_cmd = b'\x1B\x40' flush_sent = self.messageOut.write(flush_cmd) print(f"已发送 {flush_sent} 字节刷新指令") # 短暂延迟,确保打印机处理完所有数据 import time time.sleep(0.2)
3. 确保脚本结束前释放资源
在你的测试脚本test.py最后,手动触发资源释放,避免因为脚本过快退出导致数据残留:
usb_= Connector(showUsbDevices=False) usb_.send(b'I HATE YOU') # 手动释放USB资源 usb.util.dispose_resources(usb_.device)
验证效果
修改完代码后,先运行一次脚本(可能还是会打旧内容,因为之前的缓存还在),然后再修改内容运行,应该就能立即打印新内容了。如果还是有问题,可以尝试更换刷新指令,或者增加延迟时间(比如0.5秒)。
内容的提问来源于stack exchange,提问作者blackmoon
相关产品推荐
相关产品推荐

