一、驱动方案选择
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;
}