Linux下58mm热敏打印机驱动安装与配置指南

一、驱动方案选择

Linux下主要有三种驱动58mm热敏打印机的方法:

方案 适用场景 优点 缺点
开源zj-58驱动 大多数ESC/POS兼容打印机 通用性强,支持切割、开钱箱等高级功能 需要编译安装
厂商官方驱动 特定品牌打印机(如芯烨) 官方支持,稳定性好 可能只支持特定型号
CUPS Generic驱动 简单文本打印 无需额外驱动,配置简单 功能有限,不支持高级特性

二、开源zj-58驱动安装(推荐)

2.1 安装依赖

bash 复制代码
# Ubuntu/Debian
sudo apt update
sudo apt install cups cups-client cups-bsd cups-filters build-essential git

# CentOS/RHEL/Fedora
sudo yum install cups cups-client cups-filters gcc make git

2.2 下载并编译zj-58驱动

bash 复制代码
# 克隆项目
git clone https://github.com/klirichek/zj-58.git
cd zj-58

# 编译安装
make
sudo make install

# 安装PPD文件
sudo cp zj58.ppd /usr/share/cups/model/

2.3 通过CUPS配置打印机

bash 复制代码
# 方法1:使用lpadmin命令
sudo lpadmin -p ZJ-58 -E -v usb://Zjiang/ZJ-58 -m zj58.ppd

# 方法2:使用CUPS Web界面
# 1. 打开浏览器访问 http://localhost:631
# 2. 点击"Administration" → "Add Printer"
# 3. 选择USB打印机(通常显示为"Zjiang ZJ-58"或类似)
# 4. 选择"Provide PPD File",上传zj58.ppd
# 5. 设置默认选项

三、厂商官方驱动安装

3.1 芯烨(Xprinter)驱动

bash 复制代码
# 下载驱动(以Ubuntu为例)
wget http://www.xprinter.net/download/linux/xprinter-linux-driver.deb

# 安装
sudo dpkg -i xprinter-linux-driver.deb
# 如果依赖有问题
sudo apt install -f

# 配置打印机
sudo lpadmin -p Xprinter-58 -E -v usb://Xprinter/XP-58 -m xprinter.ppd

3.2 其他品牌驱动获取

  • 佳博(Gprinter):访问官网技术支持页面
  • 爱宝(Aibao):联系厂商获取Linux驱动
  • EPSON TM系列 :使用epson-escpos包或官方驱动

四、使用CUPS Generic驱动

4.1 基本配置

bash 复制代码
# 添加打印机(使用Generic驱动)
sudo lpadmin -p Thermal-Printer -E -v usb://Generic/TEXT-ONLY -m drv:///sample.drv/textonly.ppd

# 或使用raw模式
sudo lpadmin -p Thermal-Raw -E -v usb://Zjiang/ZJ-58 -m raw

4.2 自定义PPD文件

创建自定义PPD文件/etc/cups/ppd/thermal-custom.ppd

ppd 复制代码
*PPD-Adobe: "4.3"
*FormatVersion: "4.3"
*FileVersion: "1.0"
*LanguageVersion: English
*LanguageEncoding: ISOLatin1
*PCFileName: "thermal.ppd"
*Product: "(Generic 58mm Thermal Printer)"
*Manufacturer: "Generic"
*ModelName: "58mm Thermal ESC/POS"
*ShortNickName: "Thermal 58mm"
*NickName: "Generic 58mm Thermal Printer ESC/POS"
*PSVersion: "(3010.000) 0"
*LanguageLevel: "3"
*ColorDevice: False
*DefaultPageSize: 80x297
*PageSize 80x297/Receipt 80x297: "<</PageSize[288 1051]/ImagingBBox null>>setpagedevice"
*OpenUI *PageSize/Page Size: PickOne
*DefaultPageSize: 80x297
*PageSize 80x297/Receipt 80x297: "<</PageSize[288 1051]>>setpagedevice"
*CloseUI: *PageSize

五、USB权限配置

5.1 临时解决方案

bash 复制代码
# 查看打印机USB信息
lsusb
# 输出示例:Bus 001 Device 003: ID 0483:5740 STMicroelectronics Printer

# 临时更改权限
sudo chmod 666 /dev/usb/lp0
# 或
sudo chmod 666 /dev/bus/usb/001/003

5.2 永久解决方案(udev规则)

bash 复制代码
# 创建udev规则
sudo nano /etc/udev/rules.d/99-thermal-printer.rules

# 添加以下内容(根据lsusb结果修改idVendor和idProduct)
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="5740", MODE="0666", GROUP="lp"

# 重新加载udev规则
sudo udevadm control --reload-rules
sudo udevadm trigger

# 将用户添加到lp和dialout组
sudo usermod -aG lp,dialout $USER
# 需要重新登录生效

参考代码 linux下的58热敏打印机驱动程序 www.youwenfan.com/contentcsu/57184.html

六、测试打印

6.1 基本测试

bash 复制代码
# 测试文本打印
echo "测试打印" | lp -d Thermal-Printer

# 发送ESC/POS命令直接测试
echo -e "\x1B\x40\x1B\x61\x01Hello World!\x0A\x0A\x0A" > /dev/usb/lp0

# 打印文件
lp -d Thermal-Printer document.txt

6.2 ESC/POS命令测试脚本

创建测试脚本test_printer.sh

bash 复制代码
#!/bin/bash
# ESC/POS命令测试脚本

PRINTER_DEVICE="/dev/usb/lp0"

# 初始化打印机
echo -e "\x1B\x40" > $PRINTER_DEVICE

# 设置居中
echo -e "\x1B\x61\x01" > $PRINTER_DEVICE

# 打印标题
echo -e "58mm热敏打印机测试\x0A" > $PRINTER_DEVICE

# 设置左对齐
echo -e "\x1B\x61\x00" > $PRINTER_DEVICE

# 打印分隔线
echo -e "========================\x0A" > $PRINTER_DEVICE

# 打印测试信息
echo -e "时间: $(date)\x0A" > $PRINTER_DEVICE
echo -e "驱动: zj-58\x0A" > $PRINTER_DEVICE
echo -e "状态: 正常\x0A" > $PRINTER_DEVICE

# 设置双倍高度
echo -e "\x1B\x21\x10" > $PRINTER_DEVICE
echo -e "测试完成\x0A" > $PRINTER_DEVICE

# 恢复默认
echo -e "\x1B\x21\x00" > $PRINTER_DEVICE

# 切纸(如果支持)
echo -e "\x1D\x56\x41\x03" > $PRINTER_DEVICE

# 进纸3行
echo -e "\x1B\x64\x03" > $PRINTER_DEVICE

echo "测试命令已发送"

6.3 Python测试脚本

python 复制代码
#!/usr/bin/env python3
# test_thermal_printer.py

import subprocess
import time

def test_cups_print():
    """测试CUPS打印"""
    try:
        # 创建测试文件
        with open('/tmp/test_print.txt', 'w', encoding='utf-8') as f:
            f.write("=" * 32 + "\n")
            f.write("     58mm热敏打印机测试\n")
            f.write("=" * 32 + "\n")
            f.write(f"时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write("驱动: zj-58 CUPS Filter\n")
            f.write("状态: 测试中...\n")
            f.write("=" * 32 + "\n")
        
        # 发送打印任务
        result = subprocess.run(['lp', '-d', 'Thermal-Printer', '/tmp/test_print.txt'], 
                              capture_output=True, text=True)
        
        if result.returncode == 0:
            print("打印任务已提交")
            print(f"任务ID: {result.stdout.strip()}")
            return True
        else:
            print(f"打印失败: {result.stderr}")
            return False
            
    except Exception as e:
        print(f"错误: {e}")
        return False

def test_raw_escpos():
    """测试原始ESC/POS命令"""
    escpos_commands = [
        b'\x1b\x40',           # 初始化
        b'\x1b\x61\x01',       # 居中
        b'58mm Printer Test\n\n',
        b'\x1b\x61\x00',       # 左对齐
        b'=' * 32 + b'\n',
        b'Raw ESC/POS Test\n',
        b'Time: ' + time.strftime('%H:%M:%S').encode() + b'\n',
        b'\n\n\n',             # 进纸3行
        b'\x1d\x56\x41\x03',   # 切纸
    ]
    
    try:
        with open('/dev/usb/lp0', 'wb') as printer:
            for cmd in escpos_commands:
                printer.write(cmd)
                printer.flush()
        print("原始ESC/POS命令已发送")
        return True
    except Exception as e:
        print(f"原始打印失败: {e}")
        return False

if __name__ == "__main__":
    print("选择测试方式:")
    print("1. CUPS打印测试")
    print("2. 原始ESC/POS测试")
    print("3. 两种都测试")
    
    choice = input("请输入选择 (1/2/3): ").strip()
    
    if choice == '1':
        test_cups_print()
    elif choice == '2':
        test_raw_escpos()
    elif choice == '3':
        test_cups_print()
        time.sleep(2)
        test_raw_escpos()
    else:
        print("无效选择")

七、高级功能配置

7.1 切割功能配置(zj-58驱动)

bash 复制代码
# 编辑驱动配置文件
sudo nano /usr/share/cups/zj-58.conf

# 添加切割配置
CutterEnable Yes
CutterAfterEachJob Yes
CutterAfterEachPage No

7.2 钱箱控制

bash 复制代码
# 发送开钱箱命令
echo -e "\x1B\x70\x00\x19\xFA" > /dev/usb/lp0
# 或通过CUPS
lp -o "CashDrawer=1" -d Thermal-Printer /dev/null

7.3 条码打印

python 复制代码
# barcode_print.py
import escpos.printer as printer

# 使用python-escpos库
p = printer.Usb(0x0483, 0x5740)
p.barcode('123456789012', 'EAN13', 64, 2, '', '')
p.cut()

八、故障排除

8.1 常见问题及解决方案

问题 可能原因 解决方案
权限被拒绝 用户不在lp/dialout组 sudo usermod -aG lp,dialout $USER
设备未找到 USB未识别或驱动问题 检查lsusb,重新插拔
打印乱码 字符编码不匹配 设置正确的字符集:lp -o charset=UTF-8
不切纸 切割器未启用或硬件不支持 检查驱动配置,确认打印机型号
打印偏移 页面尺寸设置错误 调整PPD中的PageSize设置
CUPS服务未启动 cups服务未运行 sudo systemctl start cups

8.2 诊断命令

bash 复制代码
# 检查CUPS服务状态
systemctl status cups

# 查看打印队列
lpstat -t

# 查看打印机状态
lpstat -p Thermal-Printer -l

# 查看打印任务
lpq -P Thermal-Printer

# 清除打印队列
cancel -a Thermal-Printer

# 查看USB设备详细信息
lsusb -v -d 0483:5740

# 查看内核消息
dmesg | grep -i usb
dmesg | grep -i printer

8.3 调试模式

bash 复制代码
# 启用CUPS调试日志
sudo cupsctl --debug-logging
sudo systemctl restart cups

# 查看CUPS错误日志
tail -f /var/log/cups/error_log

# 查看访问日志
tail -f /var/log/cups/access_log

# 禁用调试
sudo cupsctl --no-debug-logging

九、编程接口

9.1 Python ESC/POS库

bash 复制代码
# 安装python-escpos
pip install python-escpos
python 复制代码
from escpos.printer import Usb

# 连接打印机
p = Usb(0x0483, 0x5740)

# 打印文本
p.text("Hello World\n")
p.set(align='center')
p.text("居中文本\n")
p.set(align='left')

# 打印条码
p.barcode('123456789012', 'EAN13')

# 打印二维码
p.qr("https://example.com")

# 切纸
p.cut()

# 开钱箱
p.cashdraw(2)

9.2 C语言示例

c 复制代码
// print_thermal.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    int fd = open("/dev/usb/lp0", O_WRONLY);
    if (fd < 0) {
        perror("无法打开打印机设备");
        return 1;
    }
    
    // ESC/POS命令
    unsigned char init[] = {0x1B, 0x40};  // 初始化
    unsigned char center[] = {0x1B, 0x61, 0x01};  // 居中
    unsigned char text[] = "58mm Printer Test\n";
    unsigned char cut[] = {0x1D, 0x56, 0x41, 0x03};  // 切纸
    
    write(fd, init, sizeof(init));
    write(fd, center, sizeof(center));
    write(fd, text, sizeof(text) - 1);
    write(fd, cut, sizeof(cut));
    
    close(fd);
    return 0;
}
相关推荐
运维老郭7 小时前
K8s故障排查:一条分层排查路径解决99%线上问题
运维·云原生·kubernetes
AC赳赳老秦7 小时前
项目闭环管理:用 OpenClaw 对接 Jira / 禅道,实现需求 - 任务 - 进度 - 验收全流程自动化
运维·人工智能·python·自动化·devops·jira·openclaw
遇见火星7 小时前
centos7和centos8设置本地镜像为yum安装源的方法
linux·运维·服务器
piaopiaolanghua7 小时前
[Ai问答] Docker是否支持跨架构镜像,譬如ARM/X86
linux·运维·服务器
Elastic 中国社区官方博客7 小时前
通过 Elastic MCP Server 将 Cursor 连接到生产日志
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索·mcp
努力努力再努力FFF7 小时前
运维工程师想学习AI来提升系统自动化水平,该怎么切入?
运维·人工智能·学习
木木_王7 小时前
嵌入式Linux学习 | 数据结构(Day06)全解:线性表 + 栈队列 + 静态库 / 动态库(原理 + 代码 + 编译实战 + 易错点)
linux·数据结构·笔记·学习
howareyou237 小时前
Linux中用户态的函数是如何通过系统调用进入内核态的(二)
linux·服务器·linux系统调用
杨云龙UP7 小时前
Oracle 19c多租户架构下设置用户密码永不过期及登录锁定策略说明_20260430
linux·运维·服务器·数据库·oracle