热敏打印机技术报告

热敏打印机技术报告

目前为止,接触了多款热敏打印机,主要目的是为了实现打印80mm和110mm两种规格的热敏小票。所谓热敏打印机简单的来说就是通过打印头上的半导体加热元件接触热敏打印机并产生化学反应来生成图像,具体的可以查查百科。

型号模块

热敏打印机的款式具体可以按照以下几种来分类

  1. 打印行宽:常见的有57mm,80mm和110mm等
  2. 打印dpi:(即每英寸打印的点数,1英寸=2.54厘米)常见的有200dpi(行:72mm/576点),300dpi等;
  3. 连接方式: usb,蓝牙,wifi,串口或并口。基本上以usb为主,如果是内嵌打印机可以通过串口和并口连接。一般来说打印机支持多种连接方式;
  4. 结构设计: 工业模型和嵌入式

比如以下这款打印机就是属于 80mm,200dpi,usb连接为主的工业热敏打印机
工业热敏打印机

这款就是属于 110mm,200dpi,usb连接/串口的嵌入式热敏打印机
嵌入式热敏打印机

接入方式

本次开发使用的所有热敏打印机都是使用 usb 方式接入,所以会比较详细的介绍该种接入方式,除此以外,先简单的说明一下其他的接入方式。

串口

基本所有的串口开发都会依赖于 google 的 android-serivalport-api 项目,其中比较重要的是一个so库 libserial_post.so和两个类SerialPort.javaSerialPortFinder.java

串口通信简单来说是按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口编程简单来说:打开串口->串口配置->串口操作(读写)->关闭串口。

打开串口需要串口的硬件地址和波特率,硬件地址取决于主板上的串口地址名称,一般来说格式为“/dev/tty..”,可能有些主板的名称不一样,这一点可以询问主板商。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 传入串口文件,波特率
**/
public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

/* Check access permission */
if (!device.canRead() || !device.canWrite()) {
try {
/* Missing read/write permission, trying to chmod the file */
Process su;
su = Runtime.getRuntime().exec("/system/bin/su");
String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
+ "exit\n";
su.getOutputStream().write(cmd.getBytes());
if ((su.waitFor() != 0) || !device.canRead()
|| !device.canWrite()) {
throw new SecurityException();
}
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException();
}
}

mFd = open(device.getAbsolutePath(), baudrate, flags);
if (mFd == null) {
Log.e(TAG, "native open returns null");
throw new IOException();
}
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}

如代码所示,需要传入 串口地址和波特率 来获取串口的文件数据流。
后续就是通过数据流来接收特定格式的数据进行处理和返回,这样整个串口通信就完成了。

socket

使用网络通信也是一种连接方式,将打印机作为服务端,接受socket数据,应用程序作为客户端,以定好的ip地址和端口,发送数据给服务端。
这个方式依赖于打印机已经植入服务端的代码,所以依赖于打印机的厂商是否有设置这个功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

/**客户端**/
//创建客户端+端口
DatagramSocket mmClientSocket = new DatagramSocket(dest_port, InetAddress.getByName(local_address));
//发送打包数据
mmClientSocket.send(new DatagramPacket(cmd, cmd.length, InetAddress.getByName(this.IPAddress), this.PortNumber));

/**服务端**/
// 创建服务端+端口
DatagramSocket server = new DatagramSocket(dest_port, InetAddress.getByName(local_address));
// 准备接收容器
byte[] container = new byte[1024];
// 封装成包 new DatagramPacket(byte[] b,int length)
DatagramPacket packet = new DatagramPacket(container, container.length);
// 接收数据,使用 DatagramSocket的实例的 receive( DatagramPacket ) 方法进行接收
server.receive(packet);

使用 DatagramSocketDatagramPacket 是不错的选择,这两个类是基于UDP协议进行通信的包装类。

BLE蓝牙

蓝牙通信,同样需要打印机有蓝牙模块能使客户端发现打印机,其他步骤与普通的蓝牙通信无区别,基操:开启蓝牙->搜索蓝牙设备->连接蓝牙设备->发送消息->断开蓝牙连接->关闭销毁蓝牙

USB

项目中使用USB进行控制打印机,这种连接方式是所有打印机都支持的一种方式。
在USB通信中,android.hardware.usb包下提供了USB开发的相关类。

需要了解的有UsbManager、UsbDevice、UsbInterface、UsbEndpoint、UsbDeviceConnection、UsbRequest、UsbConstants:
1、UsbManager:获得Usb的状态,与连接的Usb设备通信。
2、UsbDevice:Usb设备的抽象,它包含一个或多个UsbInterface,而每个UsbInterface包含多个UsbEndpoint。Host与其通信,先打开UsbDeviceConnection,使用UsbRequest在一个端点(endpoint)发送和接收数据。
3、UsbInterface:定义了设备的功能集,一个UsbDevice包含多个UsbInterface,每个Interface都是独立的。
4、UsbEndpoint:endpoint是interface的通信通道。
5、UsbDeviceConnection:host与device建立的连接,并在endpoint传输数据。
6、UsbRequest:usb 请求包。可以在UsbDeviceConnection上异步传输数据。注意是只在异步通信时才会用到它。
7、UsbConstants:usb常量的定义,对应linux/usb/ch9.h

1
2
//使用批量传输的方式(使用与大批量数据),其他的还有控制传输(数据量小,无损),中断传输(鼠标,键盘)和同步传输(实时性高,电话等)等
this.mUsbDeviceConnection.bulkTransfer(this.mUsbEndpointOut, data, data.length, 2147483647);

Usb的插入和拔出是以系统广播的形式发送的,只要我们注册这个广播即可。其对应的分别为 UsbManager.ACTION_USB_DEVICE_ATTACHEDUsbManager.ACTION_USB_DEVICE_DETACHED .

tips:如果需要在usb插入时启动某一Activity,可以在manifest中插入

1
2
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/usbfilter" />

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" />
</resources>

其中需要设备的厂商id和设备id

指令规范

市面上绝大部分打印机兼容esc/pos指令,ESC/POS©指令体系是由EPSON发明的一套专有POS打印机指令系统。
部分指令

虽说指令是相同的,但还有一些是不一样的,比如与打印机相关的一些状态判断,像是否连接,切刀是否合上,是否缺纸等的判断每个厂商的检查方法都是不一样的。这一部分就需要去根据厂商提供的sdk进行适配。

文章作者: cpacm
文章链接: http://www.cpacm.net/2019/09/03/热敏打印机技术报告/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 cpacm
打赏
  • 微信
  • 支付宝

评论