2020-9-30 17:16:20 [显示全部楼层]
查看: 1830|回复: 13

Lattepanda 使用 Python 控制热敏打印机 (文章节选)

[复制链接]
本帖最后由 pATAq 于 2021-1-19 00:16 编辑

前言

原创文章,转载引用请务必注明链接,水平有限,如有疏漏,欢迎指正。
已更新完整版:https://mc.dfrobot.com.cn/thread-308160-1-1.html
首先感谢葛老师和版主 rzyzzxw 的帖子,受益匪浅,自己跟着学习了一下,也做些补充与心得分享。原文『热敏打印机两日通』比较长,尚未完工,节选使用 Python 库操作热敏打印机的部分,实测这种打印效果较好,相比于直接驱动,失了些易用性但更灵活。


硬件环境:

  • Lattepanda Delta 432
  • Thernal Printer (Model:GY-ETH402)

软件环境:

  • Pop!_OS 20.04 (based on Ubuntu)/ Windows 10
  • Python3 + python-escpos library

1、热敏打印机安装与测试

1.1 热敏打印机基本信息

本文采用的热敏打印机购自 DFRobot 商城,深圳歌翼科技出品,产品基本信息如下:

  • EH402 采用 TTL 和 USB 通讯接口,所以无法使用 RS232 接口自主升级固件
  • 工作电压 5~9v ,电压越高,打印速度越快
  • 实际支持中文字库 GB18030,虽然歌翼页面介绍是 GB2312
  • 使用 58 30 (纸宽 纸卷直径) 热敏打印纸
  • 采用 ESC/POS 兼容指令集进行打印
  • 分辨率 203DPI, 8 px/mm 每行最多打印 384px,即纸张虽然是58mm,但是可打印纸宽为 48mm。
  • TTL 通讯时,如果每次打印数据量大于 1K,在连接 RX/TX 基础上,需要再连接流控 DTR

常见的通用热敏打印机有两种规格,一种是 58mm 纸卷,一种是 80mm 纸卷,使用 ESC/POS 指令集进行控制。

产品页面提供了 Windows 下的打印机驱动,可以直接显示为打印机使用,Linux 下则可以使用 CUPS 配合 ZJ-58 驱动,此方式比较方便,但是实测过程中,打印效果并不是最好的。

1.2 安装与配置

建议先阅读官方资料

【纸卷安装方式】

【接口与模式】

  • 包括 TTL 和 USB 两种连接方式
  • 包括串口和打印口两种模式

通电前按住顶端走纸键两秒,通电后放开,可以显示当前模式(默认为 TTL 打印口模式),根据字样提示按住走纸键两秒,可以切换为 USB 串口模式

表述其实有迷惑性,原文是 当前USB配置,我以为这个设置和 TTL 通讯接口 无关,改动的都是 USB 接口 的模式。且原以为打印口就是使用的 USB-to-TTL 串口模块,电脑上直接识别为打印机;串口就是使用设备(单片机)等的 UART 引脚与打印机的串口引脚连接,两种接口与两种模式绑定且互斥,而实际上是2x2四种可能,不绑定不互斥。但是有些组合可能能用,但是会有问题,后面会介绍。我们这里以 USB 接口连接为例。

我们保证打印机处于 串口 模式,Linux 下使用 lsusb 命令可以看到名为

Bus 001 Device 007: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port 的设备,对应的串口号为 ttyUSB0

如果将 USB 设置为 打印口 模式,Linux 下识别为 Bus 001 Device 005: ID 0fe6:811e ICS Advent Parallel Adapter ,无对应的串口号。该模式下虽然可以打印,但是会存在乱码和打印图片时最大打印长度为 255 像素 的问题。

2、打印测试

安装使用 python-escpos

我这里以 Ubuntu Linux 为例,在 Windows 下也是差不多的。

# 安装 Python3 和 pip
sudo apt install python3 python3-pip
# 安装 python-escpos 库(使用第三方镜像加速下载)
python3 -m pip install python-escpos -i http://mirrors.cloud.tencent.com/pypi/simple --trusted-host mirrors.cloud.tencent.com

如果安装成功没有报错的话,下一步我们介绍如何初始化设备并打印  hello world! 。好在官方有非常详尽的文档可供参考,地址如下:

https://python-escpos.readthedocs.io/en/latest/user/usage.html

注意该库不同版本间部分函数可能不通用。官方介绍了多种模式来初始化热敏打印机,从而可以进行控制发送命令,分别是:

  • USB
  • Serial
  • Network
  • File
  • Dummy

我们这里选择 USB 模式,上面 lsusb 获得了该打印机的 ID 067b:2303,我们需要获取一下参数,方法为:

sjqlwy@LattePanda:~$ lsusb -vvv -d 067b:2303 | grep iInterface
      iInterface              0 
sjqlwy@LattePanda:~$ lsusb -vvv -d 067b:2303 | grep bEndpointAddress
        bEndpointAddress     0x81  EP 1 IN
        bEndpointAddress     0x02  EP 2 OUT
        bEndpointAddress     0x82  EP 2 IN

其中 bEndpointAddress 选择前两个 INOUT

sudo python3
from escpos.printer import Usb
p = Usb(0x067b, 0x2303, 0, 0x82, 0x02)

p.text("Hello World\n")
p.text("你好,世界\n")
# gb18030 支持繁體字
p.codepage = 'gb2312' 
p.text("你好,世界\n")

此时出现了第一个问题,打印中文会出现乱码,设置 codepage 可以解决。具体按下不表。

# 打印条形码
p.barcode('1324354657687', 'EAN13', 64, 2, '', '')
# 打印 QR 二维码
content = "https://www.cnblogs.com/sjqlwy"
p.qr(content, size=13)
# 打印图片,注意需要预处理好,最大384*384,否则会出现乱码。
p.image("32.png")

至此,我们就可以通过各种组合打印出自己想要的小票了。同时我总结的问题:

  1. 当打印机 USB 接口模式设置为 打印口 时,上述方式同样可以得到相关参数并进行初始化,但是打印过程中会有问题。所以建议 USB 接口绑定 串口 模式
  2. 如果打印的图像只有 255像素 高,请设置为串口模式
  3. 代码注意中英文标点
  4. 打印的图片需要预处理好,太大会打印乱码,此时拔掉打印机电源来省纸
  5. 请购买品质良好的打印纸,我这个就不行
  6. 如果出现有时候正常打印图片,有时候又是乱码,请设置 image() 的 printing implementations 我这里使用的 impl='bitImageColumn 正常,具体移步 官方文档
  7. font A 和 font B 主要是不同大小的英文字母,中文没有 font A/B 的区分

3、高级设置

image-20200928144953503

当我们想设计打印一个如上图所示排队号票的时候,应该怎么做呢?

Plan A

文字用 text() 打印,图像用 image() 打印。需要设置文本格式,使用 set() 函数。

问题:

  • 该打印机有闪存芯片用于存储默认打印参数,比如居中、字号、加粗、下划线等
  • 每次修改完参数后,需要延迟数秒来生效
  • 频繁修改打印参数可能会烧坏闪存芯片

综上,导致此方案会使一张小票需要很长时间才能打印出来,而且还有烧坏闪存芯片的风险

Plan B

将小票内容生成后,转换为图像格式,使用 image() 打印,比如借助 PIL 库,这个方案大家可以自行尝试

Plan C

固定部分用图像,可变部分用文字,比如这张小票,编号和时间是变量,其他都可以使用图像,大大减少闪存读写。

from pyfirmata import Arduino, util
from datetime import datetime
from escpos.printer import Usb
import time
# from tinydb import TinyDB, Query

# db = TinyDB("/home/xin/Projects/Lshop/db.json")
# parcel = Query()

p = Usb(0x067b, 0x2303, 0, 0x81, 0x02)
p.codepage = 'gb18030'
board = Arduino("/dev/ttyACM0")

n = 0
def Label(n):
    p.image('/home/xin/Pictures/label-head.png', impl='bitImageColumn')
    time.sleep(1)
    p.set(align='center', font='b', text_type='B', width=4, height=4)
    p.text(str(n) + '\n')
    p.text('\n')
    time.sleep(5)           # Sleep to prevent printer buffer overflow
    p.set(width=1, height=1)
    p.text('时间:' + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '\n')
    p.image('/home/xin/Pictures/label-bottom.png', impl='bitImageColumn')
    # content = "https://www.cnblogs.com/sjqlwy"
    # p.qr(content, size=13)
    p.cut()

while True:
    reading =  board.digital[2].read()
    if reading == 1:
        n = n + 1
        Label(n)

4、如何查找帮助(十分重要)

由于 python-escpos 库更新频繁,很多方法、参数可能会有变动。当你遇到各种 no methond 报错时,可以参考。

sudo -E python3
from escpos.printer import Usb
p = Usb(0x067b, 0x2303, 0, 0x81, 0x02)
# 查看对象包含的方法
>>> print(dir(p))
['__abstractmethods__', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_image_send_graphics_data', '_int_low_high', '_raw', '_send_2d_code_data', 'barcode', 'block_text', 'cashdraw', 'charcode', 'close', 'codepage', 'columns', 'control', 'cut', 'device', 'hw', 'idProduct', 'idVendor', 'image', 'in_ep', 'line_spacing', 'open', 'out_ep', 'panel_buttons', 'qr', 'set', 'text', 'timeout']
# 查看方法的可用参数,不同打印机可能不一样,使用方法参考官方文档,但是以下面显示的为准
>>> print(help(p.set))

小结

不知道为何关于这篇关于热敏打印机的使用的文章如此难写,不过探索过程中也很有趣。本文概括如下:

  • 使用 python-escpos 控制热敏打印机,灵活性更优,打印效果更好
  • 建议使用 USB 接口绑定 串口 模式
  • 虽然可以使用自动缩放,但是提前设计好打印内容更美观
  • 打印图像时好时乱码请选择合适的 impl 参数
  • 官方文档是宝库,但是也是有错误,有了问题看帮助

2.png 1.jpg




rzyzzxw  版主

发表于 2020-9-30 17:40:44

特别帅
回复

使用道具 举报

gray6666  初级技神 来自手机

发表于 2020-9-30 17:53:29

pATAq 发表于 2020-9-30 17:16
[md]# 前言

原创文章,转载引用请务必注明链接,水平有限,如有疏漏,欢迎指正。

写的很棒,重新燃起了我玩热敏打印机的欲望
回复

使用道具 举报

hnyzcj  版主

发表于 2020-9-30 18:04:47

gray6666 发表于 2020-9-30 17:53
写的很棒,重新燃起了我玩热敏打印机的欲望

怎么燃气
回复

使用道具 举报

pATAq  版主
 楼主|

发表于 2020-9-30 20:12:09

gray6666 发表于 2020-9-30 17:53
写的很棒,重新燃起了我玩热敏打印机的欲望

最近房子快装好了,准备做个甲醛/噪音记录仪,监测室内24小时变化,到时候试试使用 Plan B 绘制个图表
回复

使用道具 举报

pATAq  版主
 楼主|

发表于 2020-9-30 20:12:42


哈哈,谢谢捧场
回复

使用道具 举报

pATAq  版主
 楼主|

发表于 2020-9-30 20:13:00


打火机
回复

使用道具 举报

gray6666  初级技神

发表于 2020-10-2 19:45:21

来一场疯狂的散热片烧烤
回复

使用道具 举报

佛系唐法官  中级技师

发表于 2020-10-10 14:38:31

真棒!!!
回复

使用道具 举报

 初级技师

发表于 2020-10-10 20:43:37

我家里就有一个热敏打印机
回复

使用道具 举报

pATAq  版主
 楼主|

发表于 2020-10-10 23:05:34

诩 发表于 2020-10-10 20:43
我家里就有一个热敏打印机

哈哈,挺好玩的
回复

使用道具 举报

 初级技师

发表于 2020-10-11 13:08:29

pATAq 发表于 2020-10-10 23:05
哈哈,挺好玩的

           是啊
回复

使用道具 举报

 初级技师

发表于 2020-10-11 13:24:22

pATAq 发表于 2020-10-10 23:05
哈哈,挺好玩的

         是呀
回复

使用道具 举报

RRoy  初级技匠

发表于 2020-10-27 16:02:52

涨姿势了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2021 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail