Project:ESC/POS Label Printing

From CoMakingSpace Wiki

ProjectInfoBox

ESC/POS Label Printing

Project-default.png
Status: ongoing
Initiator: Ada


I am doing inventory and want to print labels. I found this thermoprinter in a pile of cables that I want to use for printing inventory labels.

Hardware

My printer talks TTL that you can plug into the UART of a Raspberry Pi.

I connected my printer's RX to a Raspberry Pi's TX and both printer and Pi to some power.

There is a large amount of 57mm thermopaper available. You can even buy adhesive thermopaper which is ideal for this project.

Software

After plugging in the Printer, you can communicate with it over a serial port. In my case (a Fedora Server 38) this is /dev/ttyS0. You need to set the baud rate correctly for the printer to be able to understand your commands. My printer is at 19200 baud and assuming that your user is in the dialout group this can then be done with

stty -F /dev/ttyS0 19200

This printer speaks ESC/POS. ESC/POS is a printer description language extending ESC/P for point of sale (POS) devices. The printer's spec sheet comes with an explanation of the commands it understands, but it is poorly translated from Chinese, rendering some sections unintelligible. A description of the standard is available from Epson which can be helpful for understanding some less obvious commands.

Hello world

Principally, the printer accepts CP437 characters so you can generally just start printing with regular ASCII by piping strings into the serial port:

printf "Hello world!\n" | tee /dev/ttyS0

This makes the printer print out Hello world! and advance the paper by one line. If however you want to do something more fancy you will need to use some extra commands.

Most commands are prefixed with the ASCII Escape character 0x1b, \x1b in printf, and ESC for the purpose of this document.

Formatting

Most commands are documented as something like ESC 3 n. This means an Escape character, the character 3 and an argument. ESC 3 sets the line-height in pixels so the sequence ESC "3" 24 will set it to 24 pixels. It just so happens that my printer's characters are 24 pixels high. If I now want to set the line-height to 24 I can give this to the printer:

printf "\x1b3\x18" | tee /dev/ttyS0

Note that I used \x18 to get the character with decimal value 24 (hex 0x18). All lines printed after this will have line-height 24. To show a better example of this, we can print a couple of block characters (0xDB in CP437) and spaces over some lines:

printf "\x1b3\x18\xdb \xdb \xdb \xdb \xdb\n \xdb \xdb \xdb \xdb\n" | tee /dev/ttyS0