You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyUSB控制ESC打印机数据发送延迟/缓存问题及刷新方法咨询

解决ESC打印机PyUSB脚本的缓存问题

看起来你遇到的是典型的USB设备驱动缓存+打印机自身缓冲区的双重问题,我来一步步帮你排查解决:

首先分析问题根源

  1. 内核驱动抢占设备:你代码里注释掉了detach_kernel_driver的逻辑,如果系统里已经加载了打印机的内核驱动(比如Linux下的usblp模块),PyUSB的操作会被内核驱动拦截,数据会被内核缓存起来,导致你修改脚本后第一次运行还是发送旧的缓存数据。
  2. 打印机未收到刷新指令: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 06:48:12