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

ESC/POS打印机打印二维码后无响应的原因及解决方法

问题描述

使用sendToPrinter函数向ESC/POS打印机发送文本指令时工作正常,但发送二维码指令后打印机无响应,且后续所有打印指令(文本或二维码)均失效,必须重启打印机才能恢复。相关代码如下:

bool Printer::sendToPrinter(const std::string &devicePath, const std::string &text) {
    std::string qrCodeCommands =
            "\x1B\x40"
            "\x1D\x28\x6B\x04\x00\x31\x41\x32\x00"
            "\x1D\x28\x6B\x03\x00\x31\x43\x03"
            "\x1D\x28\x6B\x03\x00\x31\x45\x31"
            "\x1D\x28\x6B\x0F\x00\x31\x50\x30"
            "Hello world"
            "\x1D\x28\x6B\x03\x00\x31\x51\x30";

    std::string processedText = "\x1B\x40" + qrCodeCommands + "\n\n";

#ifdef _WIN32
    HANDLE hPrinter = CreateFile(devicePath.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hPrinter == INVALID_HANDLE_VALUE) {
        log("Failed to open printer device: " + devicePath);
        return false;
    }

    DWORD bytesWritten = 0;
    if (!WriteFile(hPrinter, processedText.c_str(), processedText.size(), &bytesWritten, NULL)) {
        log("Failed to send data to printer.");
        CloseHandle(hPrinter);
        return false;
    }

    if (bytesWritten != processedText.size()) {
        log("Mismatch in bytes written to printer.");
        CloseHandle(hPrinter);
        return false;
    }

    CloseHandle(hPrinter);
#else
    const int fd = open(devicePath.c_str(), O_WRONLY);
    if (fd < 0) {
        log("Failed to open printer device: " + devicePath);
        return false;
    }

    ssize_t bytesWritten = write(fd, processedText.c_str(), processedText.size());
    if (bytesWritten < 0) {
        log("Failed to send data to printer.");
        close(fd);
        return false;
    }

    if (bytesWritten != static_cast<ssize_t>(processedText.size())) {
        log("Mismatch in bytes written to printer.");
        close(fd);
        return false;
    }

    close(fd);
#endif

    log("Data successfully sent to printer: " + text);
    return true;
}
问题原因
  1. 重复发送打印机初始化指令:qrCodeCommands中已经包含\x1B\x40(打印机初始化指令),但processedText又重复添加了一次该指令。重复初始化会打乱打印机的状态机,导致后续指令无法正常解析。
  2. QR码数据指令的长度参数错误:QR码数据指令\x1D\x28\x6B\x0F\x00\x31\x50\x30中的0F\x00是后续数据的长度(pL=15,pH=0),但实际后续的31\x50\x30+Hello world总长度为14字节,长度不匹配会导致打印机进入异常解析状态,直接卡死。
  3. 缺少缓冲区刷新指令:发送完QR码指令后,没有发送强制打印/刷新缓冲区的指令,打印机可能一直等待后续数据,无法完成当前打印任务,进而阻塞后续指令。
解决方法

1. 移除重复的初始化指令

删除processedText开头的\x1B\x40,避免重复初始化。

2. 修正QR码数据指令的长度参数

计算正确的数据长度:31\x50\x30(3字节)+Hello world(11字节)=14字节,因此长度参数应为0E\x00,对应指令修改为\x1D\x28\x6B\x0E\x00\x31\x50\x30。

3. 添加缓冲区刷新与走纸指令

在QR码打印指令后添加\x0D\x0A\x0D\x0A(换行走纸)或\x1D\x50\x00(打印并走纸),确保打印机执行完当前任务并刷新缓冲区。

修正后的完整指令示例

std::string qrCodeCommands =
        "\x1B\x40"                          // 初始化打印机
        "\x1D\x28\x6B\x04\x00\x31\x41\x32\x00"  // 设置QR码版本为2
        "\x1D\x28\x6B\x03\x00\x31\x43\x03"      // 设置QR码模块大小为3
        "\x1D\x28\x6B\x03\x00\x31\x45\x31"      // 设置纠错级别为M
        "\x1D\x28\x6B\x0E\x00\x31\x50\x30"      // 开始QR码数据传输(长度14)
        "Hello world"                       // QR码内容
        "\x1D\x28\x6B\x03\x00\x31\x51\x30"      // 打印QR码
        "\x0D\x0A\x0D\x0A";                 // 换行走纸,刷新缓冲区

std::string processedText = qrCodeCommands;

额外建议

  • 发送指令前,确保打印机处于就绪状态,避免在异常状态下发指令。
  • 可以添加指令校验逻辑,确保每个ESC/POS指令的长度参数与实际数据长度匹配。

内容的提问来源于stack exchange,提问作者Stefan Zindović

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:40:02