What is ESC/POS, and how do I use it?

ESC/POS is the command set which makes receipt printers print-

Introduction

Before we begin, there’s three things you need to know about ESC/POS:

  1. Most modern receipt printers support it in some form.
  2. It’s dead simple to write.
  3. Commands start with an ESC character (ASCII 27).

The most useful reference for the protocol is this Epson FAQ, which I’ve used previously to implement an ESC/POS printer driver for PHP.

Download printing library (PHP code)

Incidentally, the receipt printed in the above video is an example from the escpos-php repository. I’ll step through this print-out, as it demonstrates all of the basic ESC/POS features.

Command structure

Four specific ASCII characters make appearances in the command sequences-

Abbreviation Name Code (Hex)
NUL Null 0x00
LF Line Feed 0x0A
ESC Escape 0x1B
GS Group Separator 0x1D

Regular text is simply sent to the printer, separated by line-breaks. Commands begin with ESC or GS, and are followed by a printable character, and sometimes some numbers

Numbers are simply passed as a character. For example, ‘5’ is passed as 0x05.

Examples

These examples are taken from the output of demo.php.

Initialisation

When you first connect to the printer, you should initialise it. This reverts to default formatting, rather than the triple-underlined double-strike font which the previous print-out may have been using.

The command to reset the formatting is:

ESC @
require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);
$printer -> close();
00000000  1b 40                                             |.@|
00000003

“Hello world” text

This is the simplest type of receipt, and contains only unformatted text.

'Hello world' receipt example
Text is simply sent to the printer, separated by line-feeds.
require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Text */
$printer -> text("Hello world\n");
$printer -> cut();
$printer -> close();
00000000  1b 40 48 65 6c 6c 6f 20  77 6f 72 6c 64 0a 1d 56  |.@Hello world..V|
00000010  41 03                                             |A.|
00000012

Line feeds

The printer can quickly skip past a given number of lines with this command.

Line feed receipt example
The commands are:

LF
ESC d [ number ]
ESC v [ number ]

The first command feeds forward, the second feeds in reverse. From the example, it can be seen that the demo printer does not support reverse paper feeding.

require_once(dirname(__FILE__) . "/escpos-php/Escpos.php");
$printer = new Escpos();

/* Line feeds */
$printer -> text("ABC");
$printer -> feed(7);
$printer -> text("DEF");
$printer -> feedReverse(3);
$printer -> text("GHI");
$printer -> feed();
$printer -> cut();
$printer -> close();
00000000  1b 40 41 42 43 1b 64 07  44 45 46 1b 65 03 47 48  |.@ABC.d.DEF.e.GH|
00000010  49 0a 1d 56 41 03                                 |I..VA.|
00000016

Print modes

Print modes include font height, width and boldness into a single attribute.

Font mode receipt example
The command is:

ESC ! [number]

The font modes are made from logically OR’ing together a selection of attributes. 0 represents plan Font A text. Mode flags are:

Mode Number
Font A (no mode) 0
Font B 1
Emphasized 8
Double height 16
Double width 32
Underline 128

The example receipt illustrates the effect of each flag.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Font modes */
$modes = array(
    Printer:::MODE_FONT_A,
    Printer:::MODE_FONT_B,
    Printer:::MODE_EMPHASIZED,
    Printer:::MODE_DOUBLE_HEIGHT,
    Printer:::MODE_DOUBLE_WIDTH,
    Printer:::MODE_UNDERLINE);
for($i = 0; $i < 2 ** count($modes); $i++) {
    $bits = str_pad(decbin($i), count($modes), "0", STR_PAD_LEFT);
    $mode = 0;
    for($j = 0; $j < strlen($bits); $j++) {
        if(substr($bits, $j, 1) == "1") {
            $mode |= $modes[$j];
        }
    }
    $printer -> selectPrintMode($mode);
    $printer -> text("ABCDEFGHIJabcdefghijk\n");
}
$printer -> selectPrintMode(); // Reset
$printer -> cut();
$printer -> close();
00000000  1b 40 1b 21 00 41 42 43  44 45 46 47 48 49 4a 61  |.@.!.ABCDEFGHIJa|
00000010  62 63 64 65 66 67 68 69  6a 6b 0a 1b 21 80 41 42  |bcdefghijk..!.AB|
00000020  43 44 45 46 47 48 49 4a  61 62 63 64 65 66 67 68  |CDEFGHIJabcdefgh|
00000030  69 6a 6b 0a 1b 21 20 41  42 43 44 45 46 47 48 49  |ijk..! ABCDEFGHI|
00000040  4a 61 62 63 64 65 66 67  68 69 6a 6b 0a 1b 21 a0  |Jabcdefghijk..!.|
00000050  41 42 43 44 45 46 47 48  49 4a 61 62 63 64 65 66  |ABCDEFGHIJabcdef|
00000060  67 68 69 6a 6b 0a 1b 21  10 41 42 43 44 45 46 47  |ghijk..!.ABCDEFG|
00000070  48 49 4a 61 62 63 64 65  66 67 68 69 6a 6b 0a 1b  |HIJabcdefghijk..|
00000080  21 90 41 42 43 44 45 46  47 48 49 4a 61 62 63 64  |!.ABCDEFGHIJabcd|
00000090  65 66 67 68 69 6a 6b 0a  1b 21 30 41 42 43 44 45  |efghijk..!0ABCDE|
000000a0  46 47 48 49 4a 61 62 63  64 65 66 67 68 69 6a 6b  |FGHIJabcdefghijk|
000000b0  0a 1b 21 b0 41 42 43 44  45 46 47 48 49 4a 61 62  |..!.ABCDEFGHIJab|
000000c0  63 64 65 66 67 68 69 6a  6b 0a 1b 21 08 41 42 43  |cdefghijk..!.ABC|
000000d0  44 45 46 47 48 49 4a 61  62 63 64 65 66 67 68 69  |DEFGHIJabcdefghi|
000000e0  6a 6b 0a 1b 21 88 41 42  43 44 45 46 47 48 49 4a  |jk..!.ABCDEFGHIJ|
000000f0  61 62 63 64 65 66 67 68  69 6a 6b 0a 1b 21 28 41  |abcdefghijk..!(A|
00000100  42 43 44 45 46 47 48 49  4a 61 62 63 64 65 66 67  |BCDEFGHIJabcdefg|
00000110  68 69 6a 6b 0a 1b 21 a8  41 42 43 44 45 46 47 48  |hijk..!.ABCDEFGH|
00000120  49 4a 61 62 63 64 65 66  67 68 69 6a 6b 0a 1b 21  |IJabcdefghijk..!|
00000130  18 41 42 43 44 45 46 47  48 49 4a 61 62 63 64 65  |.ABCDEFGHIJabcde|
00000140  66 67 68 69 6a 6b 0a 1b  21 98 41 42 43 44 45 46  |fghijk..!.ABCDEF|
00000150  47 48 49 4a 61 62 63 64  65 66 67 68 69 6a 6b 0a  |GHIJabcdefghijk.|
00000160  1b 21 38 41 42 43 44 45  46 47 48 49 4a 61 62 63  |.!8ABCDEFGHIJabc|
00000170  64 65 66 67 68 69 6a 6b  0a 1b 21 b8 41 42 43 44  |defghijk..!.ABCD|
00000180  45 46 47 48 49 4a 61 62  63 64 65 66 67 68 69 6a  |EFGHIJabcdefghij|
00000190  6b 0a 1b 21 01 41 42 43  44 45 46 47 48 49 4a 61  |k..!.ABCDEFGHIJa|
000001a0  62 63 64 65 66 67 68 69  6a 6b 0a 1b 21 81 41 42  |bcdefghijk..!.AB|
000001b0  43 44 45 46 47 48 49 4a  61 62 63 64 65 66 67 68  |CDEFGHIJabcdefgh|
000001c0  69 6a 6b 0a 1b 21 21 41  42 43 44 45 46 47 48 49  |ijk..!!ABCDEFGHI|
000001d0  4a 61 62 63 64 65 66 67  68 69 6a 6b 0a 1b 21 a1  |Jabcdefghijk..!.|
000001e0  41 42 43 44 45 46 47 48  49 4a 61 62 63 64 65 66  |ABCDEFGHIJabcdef|
000001f0  67 68 69 6a 6b 0a 1b 21  11 41 42 43 44 45 46 47  |ghijk..!.ABCDEFG|
00000200  48 49 4a 61 62 63 64 65  66 67 68 69 6a 6b 0a 1b  |HIJabcdefghijk..|
00000210  21 91 41 42 43 44 45 46  47 48 49 4a 61 62 63 64  |!.ABCDEFGHIJabcd|
00000220  65 66 67 68 69 6a 6b 0a  1b 21 31 41 42 43 44 45  |efghijk..!1ABCDE|
00000230  46 47 48 49 4a 61 62 63  64 65 66 67 68 69 6a 6b  |FGHIJabcdefghijk|
00000240  0a 1b 21 b1 41 42 43 44  45 46 47 48 49 4a 61 62  |..!.ABCDEFGHIJab|
00000250  63 64 65 66 67 68 69 6a  6b 0a 1b 21 09 41 42 43  |cdefghijk..!.ABC|
00000260  44 45 46 47 48 49 4a 61  62 63 64 65 66 67 68 69  |DEFGHIJabcdefghi|
00000270  6a 6b 0a 1b 21 89 41 42  43 44 45 46 47 48 49 4a  |jk..!.ABCDEFGHIJ|
00000280  61 62 63 64 65 66 67 68  69 6a 6b 0a 1b 21 29 41  |abcdefghijk..!)A|
00000290  42 43 44 45 46 47 48 49  4a 61 62 63 64 65 66 67  |BCDEFGHIJabcdefg|
000002a0  68 69 6a 6b 0a 1b 21 a9  41 42 43 44 45 46 47 48  |hijk..!.ABCDEFGH|
000002b0  49 4a 61 62 63 64 65 66  67 68 69 6a 6b 0a 1b 21  |IJabcdefghijk..!|
000002c0  19 41 42 43 44 45 46 47  48 49 4a 61 62 63 64 65  |.ABCDEFGHIJabcde|
000002d0  66 67 68 69 6a 6b 0a 1b  21 99 41 42 43 44 45 46  |fghijk..!.ABCDEF|
000002e0  47 48 49 4a 61 62 63 64  65 66 67 68 69 6a 6b 0a  |GHIJabcdefghijk.|
000002f0  1b 21 39 41 42 43 44 45  46 47 48 49 4a 61 62 63  |.!9ABCDEFGHIJabc|
00000300  64 65 66 67 68 69 6a 6b  0a 1b 21 b9 41 42 43 44  |defghijk..!.ABCD|
00000310  45 46 47 48 49 4a 61 62  63 64 65 66 67 68 69 6a  |EFGHIJabcdefghij|
00000320  6b 0a 1b 21 00 41 42 43  44 45 46 47 48 49 4a 61  |k..!.ABCDEFGHIJa|
00000330  62 63 64 65 66 67 68 69  6a 6b 0a 1b 21 80 41 42  |bcdefghijk..!.AB|
00000340  43 44 45 46 47 48 49 4a  61 62 63 64 65 66 67 68  |CDEFGHIJabcdefgh|
00000350  69 6a 6b 0a 1b 21 20 41  42 43 44 45 46 47 48 49  |ijk..! ABCDEFGHI|
00000360  4a 61 62 63 64 65 66 67  68 69 6a 6b 0a 1b 21 a0  |Jabcdefghijk..!.|
00000370  41 42 43 44 45 46 47 48  49 4a 61 62 63 64 65 66  |ABCDEFGHIJabcdef|
00000380  67 68 69 6a 6b 0a 1b 21  10 41 42 43 44 45 46 47  |ghijk..!.ABCDEFG|
00000390  48 49 4a 61 62 63 64 65  66 67 68 69 6a 6b 0a 1b  |HIJabcdefghijk..|
000003a0  21 90 41 42 43 44 45 46  47 48 49 4a 61 62 63 64  |!.ABCDEFGHIJabcd|
000003b0  65 66 67 68 69 6a 6b 0a  1b 21 30 41 42 43 44 45  |efghijk..!0ABCDE|
000003c0  46 47 48 49 4a 61 62 63  64 65 66 67 68 69 6a 6b  |FGHIJabcdefghijk|
000003d0  0a 1b 21 b0 41 42 43 44  45 46 47 48 49 4a 61 62  |..!.ABCDEFGHIJab|
000003e0  63 64 65 66 67 68 69 6a  6b 0a 1b 21 08 41 42 43  |cdefghijk..!.ABC|
000003f0  44 45 46 47 48 49 4a 61  62 63 64 65 66 67 68 69  |DEFGHIJabcdefghi|
00000400  6a 6b 0a 1b 21 88 41 42  43 44 45 46 47 48 49 4a  |jk..!.ABCDEFGHIJ|
00000410  61 62 63 64 65 66 67 68  69 6a 6b 0a 1b 21 28 41  |abcdefghijk..!(A|
00000420  42 43 44 45 46 47 48 49  4a 61 62 63 64 65 66 67  |BCDEFGHIJabcdefg|
00000430  68 69 6a 6b 0a 1b 21 a8  41 42 43 44 45 46 47 48  |hijk..!.ABCDEFGH|
00000440  49 4a 61 62 63 64 65 66  67 68 69 6a 6b 0a 1b 21  |IJabcdefghijk..!|
00000450  18 41 42 43 44 45 46 47  48 49 4a 61 62 63 64 65  |.ABCDEFGHIJabcde|
00000460  66 67 68 69 6a 6b 0a 1b  21 98 41 42 43 44 45 46  |fghijk..!.ABCDEF|
00000470  47 48 49 4a 61 62 63 64  65 66 67 68 69 6a 6b 0a  |GHIJabcdefghijk.|
00000480  1b 21 38 41 42 43 44 45  46 47 48 49 4a 61 62 63  |.!8ABCDEFGHIJabc|
00000490  64 65 66 67 68 69 6a 6b  0a 1b 21 b8 41 42 43 44  |defghijk..!.ABCD|
000004a0  45 46 47 48 49 4a 61 62  63 64 65 66 67 68 69 6a  |EFGHIJabcdefghij|
000004b0  6b 0a 1b 21 01 41 42 43  44 45 46 47 48 49 4a 61  |k..!.ABCDEFGHIJa|
000004c0  62 63 64 65 66 67 68 69  6a 6b 0a 1b 21 81 41 42  |bcdefghijk..!.AB|
000004d0  43 44 45 46 47 48 49 4a  61 62 63 64 65 66 67 68  |CDEFGHIJabcdefgh|
000004e0  69 6a 6b 0a 1b 21 21 41  42 43 44 45 46 47 48 49  |ijk..!!ABCDEFGHI|
000004f0  4a 61 62 63 64 65 66 67  68 69 6a 6b 0a 1b 21 a1  |Jabcdefghijk..!.|
00000500  41 42 43 44 45 46 47 48  49 4a 61 62 63 64 65 66  |ABCDEFGHIJabcdef|
00000510  67 68 69 6a 6b 0a 1b 21  11 41 42 43 44 45 46 47  |ghijk..!.ABCDEFG|
00000520  48 49 4a 61 62 63 64 65  66 67 68 69 6a 6b 0a 1b  |HIJabcdefghijk..|
00000530  21 91 41 42 43 44 45 46  47 48 49 4a 61 62 63 64  |!.ABCDEFGHIJabcd|
00000540  65 66 67 68 69 6a 6b 0a  1b 21 31 41 42 43 44 45  |efghijk..!1ABCDE|
00000550  46 47 48 49 4a 61 62 63  64 65 66 67 68 69 6a 6b  |FGHIJabcdefghijk|
00000560  0a 1b 21 b1 41 42 43 44  45 46 47 48 49 4a 61 62  |..!.ABCDEFGHIJab|
00000570  63 64 65 66 67 68 69 6a  6b 0a 1b 21 09 41 42 43  |cdefghijk..!.ABC|
00000580  44 45 46 47 48 49 4a 61  62 63 64 65 66 67 68 69  |DEFGHIJabcdefghi|
00000590  6a 6b 0a 1b 21 89 41 42  43 44 45 46 47 48 49 4a  |jk..!.ABCDEFGHIJ|
000005a0  61 62 63 64 65 66 67 68  69 6a 6b 0a 1b 21 29 41  |abcdefghijk..!)A|
000005b0  42 43 44 45 46 47 48 49  4a 61 62 63 64 65 66 67  |BCDEFGHIJabcdefg|
000005c0  68 69 6a 6b 0a 1b 21 a9  41 42 43 44 45 46 47 48  |hijk..!.ABCDEFGH|
000005d0  49 4a 61 62 63 64 65 66  67 68 69 6a 6b 0a 1b 21  |IJabcdefghijk..!|
000005e0  19 41 42 43 44 45 46 47  48 49 4a 61 62 63 64 65  |.ABCDEFGHIJabcde|
000005f0  66 67 68 69 6a 6b 0a 1b  21 99 41 42 43 44 45 46  |fghijk..!.ABCDEF|
00000600  47 48 49 4a 61 62 63 64  65 66 67 68 69 6a 6b 0a  |GHIJabcdefghijk.|
00000610  1b 21 39 41 42 43 44 45  46 47 48 49 4a 61 62 63  |.!9ABCDEFGHIJabc|
00000620  64 65 66 67 68 69 6a 6b  0a 1b 21 b9 41 42 43 44  |defghijk..!.ABCD|
00000630  45 46 47 48 49 4a 61 62  63 64 65 66 67 68 69 6a  |EFGHIJabcdefghij|
00000640  6b 0a 1b 21 00 1d 56 41  03                       |k..!..VA.|
00000649

Underline

Underline receipt example
The command is:

ESC – [ number ]

The argument is set to 0 for no underline, 1 for underline, 2 for heavy underline.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Underline */
for($i = 0; $i < 3; $i++) {
    $printer -> setUnderline($i);
    $printer -> text("The quick brown fox jumps over the lazy dog\n");
}
$printer -> setUnderline(0); // Reset
$printer -> cut();
$printer -> close();
00000000  1b 40 1b 2d 00 54 68 65  20 71 75 69 63 6b 20 62  |.@.-.The quick b|
00000010  72 6f 77 6e 20 66 6f 78  20 6a 75 6d 70 73 20 6f  |rown fox jumps o|
00000020  76 65 72 20 74 68 65 20  6c 61 7a 79 20 64 6f 67  |ver the lazy dog|
00000030  0a 1b 2d 01 54 68 65 20  71 75 69 63 6b 20 62 72  |..-.The quick br|
00000040  6f 77 6e 20 66 6f 78 20  6a 75 6d 70 73 20 6f 76  |own fox jumps ov|
00000050  65 72 20 74 68 65 20 6c  61 7a 79 20 64 6f 67 0a  |er the lazy dog.|
00000060  1b 2d 02 54 68 65 20 71  75 69 63 6b 20 62 72 6f  |.-.The quick bro|
00000070  77 6e 20 66 6f 78 20 6a  75 6d 70 73 20 6f 76 65  |wn fox jumps ove|
00000080  72 20 74 68 65 20 6c 61  7a 79 20 64 6f 67 0a 1b  |r the lazy dog..|
00000090  2d 00 1d 56 41 03                                 |-..VA.|
00000096

Cuts

The command is:

ESC V [ number ]

The argument apparently represents whether to perform a ‘partial’ (65) or ‘full’ (66) cut, but has no effect on my model of printer.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Cuts */
for($i = 0; $i < 5; $i++) {
    $printer -> cut(Printer:::CUT_PARTIAL);
    $printer -> cut(Printer:::CUT_FULL);
}
$printer -> cut();
$printer -> close();
00000000  1b 40 1d 56 42 03 1d 56  41 03 1d 56 42 03 1d 56  |.@.VB..VA..VB..V|
00000010  41 03 1d 56 42 03 1d 56  41 03 1d 56 42 03 1d 56  |A..VB..VA..VB..V|
00000020  41 03 1d 56 42 03 1d 56  41 03 1d 56 41 03        |A..VB..VA..VA.|
0000002e

Emphasis

Receipt emphasis example
The command is:

ESC E [ number ]

Use 1 to enable emphasis, and 0 to disable it.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Emphasis */
for($i = 0; $i < 2; $i++) {
    $printer -> setEmphasis($i == 1);
    $printer -> text("The quick brown fox jumps over the lazy dog\n");
}
$printer -> setEmphasis(false); // Reset
$printer -> cut();
$printer -> close();
00000000  1b 40 1b 45 00 54 68 65  20 71 75 69 63 6b 20 62  |.@.E.The quick b|
00000010  72 6f 77 6e 20 66 6f 78  20 6a 75 6d 70 73 20 6f  |rown fox jumps o|
00000020  76 65 72 20 74 68 65 20  6c 61 7a 79 20 64 6f 67  |ver the lazy dog|
00000030  0a 1b 45 01 54 68 65 20  71 75 69 63 6b 20 62 72  |..E.The quick br|
00000040  6f 77 6e 20 66 6f 78 20  6a 75 6d 70 73 20 6f 76  |own fox jumps ov|
00000050  65 72 20 74 68 65 20 6c  61 7a 79 20 64 6f 67 0a  |er the lazy dog.|
00000060  1b 45 00 1d 56 41 03                              |.E..VA.|
00000067

Double-strike

Double-strike receipt example
The command is:

ESC G [ number ]

Use 1 to enable, or 0 to disable. On the model tested here, this appears to be identical to the “emphasis” mode above.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Double-strike (looks basically the same as emphasis) */
for($i = 0; $i < 2; $i++) {
    $printer -> setDoubleStrike($i == 1);
    $printer -> text("The quick brown fox jumps over the lazy dog\n");
}
$printer -> setDoubleStrike(false);
$printer -> cut();
$printer -> close();
00000000  1b 40 1b 47 00 54 68 65  20 71 75 69 63 6b 20 62  |.@.G.The quick b|
00000010  72 6f 77 6e 20 66 6f 78  20 6a 75 6d 70 73 20 6f  |rown fox jumps o|
00000020  76 65 72 20 74 68 65 20  6c 61 7a 79 20 64 6f 67  |ver the lazy dog|
00000030  0a 1b 47 01 54 68 65 20  71 75 69 63 6b 20 62 72  |..G.The quick br|
00000040  6f 77 6e 20 66 6f 78 20  6a 75 6d 70 73 20 6f 76  |own fox jumps ov|
00000050  65 72 20 74 68 65 20 6c  61 7a 79 20 64 6f 67 0a  |er the lazy dog.|
00000060  1b 47 00 1d 56 41 03                              |.G..VA.|
00000067

Fonts

Receipt fonts example
The command is:

ESC M [ number ]

There are three possible fonts, documented as “A”, “B” and “C”, and numbered 0, 1, and 2. Many printers, including this one, don’t have Font C.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Fonts (many printers do not have a 'Font C') */
$fonts = array(
    Printer:::FONT_A,
    Printer:::FONT_B,
    Printer:::FONT_C);
for($i = 0; $i < count($fonts); $i++) {
    $printer -> setFont($fonts[$i]);
    $printer -> text("The quick brown fox jumps over the lazy dog\n");
}
$printer -> setFont(); // Reset
$printer -> cut();
$printer -> close();
00000000  1b 40 1b 4d 00 54 68 65  20 71 75 69 63 6b 20 62  |.@.M.The quick b|
00000010  72 6f 77 6e 20 66 6f 78  20 6a 75 6d 70 73 20 6f  |rown fox jumps o|
00000020  76 65 72 20 74 68 65 20  6c 61 7a 79 20 64 6f 67  |ver the lazy dog|
00000030  0a 1b 4d 01 54 68 65 20  71 75 69 63 6b 20 62 72  |..M.The quick br|
00000040  6f 77 6e 20 66 6f 78 20  6a 75 6d 70 73 20 6f 76  |own fox jumps ov|
00000050  65 72 20 74 68 65 20 6c  61 7a 79 20 64 6f 67 0a  |er the lazy dog.|
00000060  1b 4d 02 54 68 65 20 71  75 69 63 6b 20 62 72 6f  |.M.The quick bro|
00000070  77 6e 20 66 6f 78 20 6a  75 6d 70 73 20 6f 76 65  |wn fox jumps ove|
00000080  72 20 74 68 65 20 6c 61  7a 79 20 64 6f 67 0a 1b  |r the lazy dog..|
00000090  4d 00 1d 56 41 03                                 |M..VA.|
00000096

Justification

Receipt justification example
The command is:

ESC a [ number ]

Use 0 to justify left, 1 to centre the text, or 2 to right-align it.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Justification */
$justification = array(
    Printer:::JUSTIFY_LEFT,
    Printer:::JUSTIFY_CENTER,
    Printer:::JUSTIFY_RIGHT);
for($i = 0; $i < count($justification); $i++) {
    $printer -> setJustification($justification[$i]);
    $printer -> text("A man a plan a canal panama\n");
}
$printer -> setJustification(); // Reset
$printer -> cut();
$printer -> close();
00000000  1b 40 1b 61 00 41 20 6d  61 6e 20 61 20 70 6c 61  |.@.a.A man a pla|
00000010  6e 20 61 20 63 61 6e 61  6c 20 70 61 6e 61 6d 61  |n a canal panama|
00000020  0a 1b 61 01 41 20 6d 61  6e 20 61 20 70 6c 61 6e  |..a.A man a plan|
00000030  20 61 20 63 61 6e 61 6c  20 70 61 6e 61 6d 61 0a  | a canal panama.|
00000040  1b 61 02 41 20 6d 61 6e  20 61 20 70 6c 61 6e 20  |.a.A man a plan |
00000050  61 20 63 61 6e 61 6c 20  70 61 6e 61 6d 61 0a 1b  |a canal panama..|
00000060  61 00 1d 56 41 03                                 |a..VA.|
00000066

Barcodes

Barcoded receipt example
The commands are:

GS h [ number ]
ESC k [ number ] [ text ] NUL

The first command sets the barcode height — measured in dots, while the second one prints the actual barcode. The number represents the barcode standard, which for most purposes should be “4”, representing CODE39. 6 standards are supported by the PHP driver.

You will notice that due to driver glitches or printer incompatibility, not all of the barcodes print! As above, my advice is to use CODE39 if you run into this.

require __DIR__ . '/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Barcodes */
$barcodes = array(
    Printer:::BARCODE_UPCA,
    Printer:::BARCODE_UPCE,
    Printer:::BARCODE_JAN13,
    Printer:::BARCODE_JAN8,
    Printer:::BARCODE_CODE39,
    Printer:::BARCODE_ITF,
    Printer:::BARCODE_CODABAR);
$printer -> setBarcodeHeight(80);
for($i = 0; $i < count($barcodes); $i++) {
    $printer -> text("Barcode $i " . "\n");
    $printer -> barcode("9876", $barcodes[$i]);
    $printer -> feed();
}
$printer -> cut();
$printer -> close();
00000000  1b 40 1d 68 50 42 61 72  63 6f 64 65 20 30 20 0a  |.@.hPBarcode 0 .|
00000010  1d 6b 00 39 38 37 36 00  0a 42 61 72 63 6f 64 65  |.k.9876..Barcode|
00000020  20 31 20 0a 1d 6b 01 39  38 37 36 00 0a 42 61 72  | 1 ..k.9876..Bar|
00000030  63 6f 64 65 20 32 20 0a  1d 6b 02 39 38 37 36 00  |code 2 ..k.9876.|
00000040  0a 42 61 72 63 6f 64 65  20 33 20 0a 1d 6b 03 39  |.Barcode 3 ..k.9|
00000050  38 37 36 00 0a 42 61 72  63 6f 64 65 20 34 20 0a  |876..Barcode 4 .|
00000060  1d 6b 04 39 38 37 36 00  0a 42 61 72 63 6f 64 65  |.k.9876..Barcode|
00000070  20 35 20 0a 1d 6b 05 39  38 37 36 00 0a 42 61 72  | 5 ..k.9876..Bar|
00000080  63 6f 64 65 20 36 20 0a  1d 6b 06 39 38 37 36 00  |code 6 ..k.9876.|
00000090  0a 1d 56 41 03                                    |..VA.|
00000095

Resources

Linked previously in this post:

And if you’ve just received an Epson printer and need to figure out how it works:

Update 2015-03-10: Re-wrote examples for the newer version of escpos-php.

Update 2016-04-22: Updated examples again to match the latest driver code.

81 Replies to “What is ESC/POS, and how do I use it?”

  1. Hi dear!

    I’m learning to do POS receipts.
    I’m trying to print a message Hello World.
    But I get the error.
    Fatal error: Call to a member function write() on a non-object in C:\wamp\www\escpos-php-master\Escpos.php on line 460.
    I ask for help.

  2. Hi Mike

    I found your tutorial very interesting, and easy to understand, but I’m having such hard times to make the codes run

    Errors: ‘Argument passed to Escpos::__construct() must implement interface PrintConnector, null given.’

    Can you help me? Is there any setup that I have to do to make it works?

    Thanks very much!

  3. I want to use your code but have an error.

    Warning: require(D:\XAMPP\htdocs\php_fiscal\escpos-php-master\example/../vendor/autoload.php): failed to open stream: No such file or directory in D:\XAMPP\htdocs\php_fiscal\escpos-php-master\example\demo.php on line 3

    Fatal error: require(): Failed opening required ‘D:\XAMPP\htdocs\php_fiscal\escpos-php-master\example/../vendor/autoload.php’ (include_path=’.;D:\XAMPP\php\PEAR’) in D:\XAMPP\htdocs\php_fiscal\escpos-php-master\example\demo.php on line 3

    EPSON ARGENTINA TM-U220A

    contact with me if a have to buy a licence

    thanks

  4. Hey, this depends on the printer and driver you’re using. If you’re using escpos-php, then please ask on the bug tracker with details of the type of printer you’re using, and a snippet showing what you’re doing now.

  5. Hi, I got the printing working on Espon TM-T82 with RPi. Just one question, is it possible to use different fonts or unicode fonts?

  6. Hello Mike,

    The printer is: pos-80-mini-thermal-printer (Excelvan) .

    My code is:
    $price = sprintf(“%0.2f €\n”, $value);
    $printer->text($price);

    and I you are printing the character ‘ñ’ instead of ‘€’.

    Thank’s

  7. @Anderson- I’ll direct you to the bug tracker for this one. I don’t have a profile for Excelvan printers yet, so you should use the SimpleCapabilityProfile (details in the docs), which only supports ASCII.

  8. Hi Mike,
    Thank you for your reply. I tried to insert UTF-8 input into text() function, I got “?” output. I guess the system font comes with the printer doesn’t have all the characters set. Is it possible to change the printer’s font somehow?

    I also tried to convert the unicode text to image using imagettftext() and graphics() function. The only issue is, it takes about 20 seconds to print a ticket. I tried to reduce the image resolution and print the header in advance but still about 9 seconds left.

    If I connect the printer to windows machine and print the ticket in same format from MS Words, it prints instantly. Do you know what’s the underlying format that windows / MS Words use or is it because of the windows driver comes with the printer?

  9. HI Mike, My printer is stuck in a loop.
    It is printing same again and again. I restarted PC and printer. but no luck seems print command is stuck somewhere in PC.

    Thanks

  10. @Thomas – Hey, I can’t really comment on MS Word or the vendor drivers do, as I don’t use either.

    Again, this post does not go into this UTF-8 stuff, so it’s a bit off-topic here. Please consider posting a snippet and description of the output to the escpos-php issue tracker (best include the printer make/model, every printer encodes differently). I think there are existing examples of what you’re trying to do, so I may be able to point you in the right direction with this extra detail.

  11. @Mandeep – I’m not in a position to answer this type of query. I think you would be more likely to get a response via a software vendor or formal support channel. Best of luck!

  12. Hi Mike,

    Thank you for your great work! and just want to konw how to set the font name? say, I want to use arial, or times new roman?

  13. @Scot, there is no ESC/POS command for this, most printers just have “Font A” (normal) and “Font B” (small). The escpos-php driver can also render text to an image and print that instead, using a component called ImagePrintBuffer. This requires the imagick plugin, and allows you to use any font.

    Please search for examples of its usage in the code, and feel free to ask any questions on the issue tracker if this doesn’t answer your question: https://github.com/mike42/escpos-php/issues.

  14. Hi mike. Your examples helped me a lot.
    I’m using c# and I need to set up the page width and height.
    Do you know how to do this?
    Thanks.

  15. We really need a tool for parsing ESC/POS files and convert the textual parts there to text . Do you know any tool which gives us that?
    Thanks

  16. Hi Mike,
    I’m developing my own USB based 2″ POS Thermal printer, in which, I’ve implemented ESC POS commands. I need to know what is the binary data format in which a page from Notepad is sent via USB.

    There are lots of documents available online, describing ESC/POS commands. However, how should I go about interpreting the binary data that follows the commands?

    I’ve tried sending these directly to the printer’s strobes in the form of a dotline image, but it prints something else.

    Any help/ C language source code in this regard shall be highly appreciated.

    Regards
    Kavita

  17. @Kativa- This post doesn’t go into image formats, but you would need to look for commands like ‘ESC *’, ‘ESC ( L’, and ‘GS v 0’ commands in the output, then interpret each one according to the manual. The binary data is either ‘raster format’ or ‘column format’ depending on the command. Best of luck!

  18. Thanks. This library is great.

    I was wondering if instead of printing the receipt can I save the output to a file (like image or pdf).

    thanks,

    ankit

  19. hello Mike from mexico. Diseño systems of points of sale y la verdad es muy interesante encontrar a aguien que entiende como funciona esto. saludos

  20. i realize this is more about the ESCPOS lingo itself, but perhaps you still can help.
    i have downloaded a bitmap into the NV area of the POS printer i have. Epson T88II.
    what command will make the printer PRINT the content of the NV area? I find i need to steer this little fellow around in detail, from my non-php application. i have made commands to cut and to print the info i need, next is how to make the lilttle fellow start each new job with the logo item in the NV. any hints ? The manuals are confusing me..

  21. Hi,
    Is it possible to print text of different sizes in the same line (large font and smaller font ) and both vertically aligned top ?

    If possible can u help me on these.

  22. HI Mike,
    Can you help me with printing ARABIC WORDS with your codes. Is there any way using your particular driver. We are doing in PHP code.

  23. Hi mike, first i have to thank you for this lib. i’m using server with php setup. Is that possible to connect multiple printer with this server, if possible please give me the explanation .

  24. @Henrik – I’ve never been able to get NV images to work correctly, but I would recommend the online ESC/POSmanuals from espon-biz.com as a starting point for that level of complexity (requires log-in).

  25. @Geoff – That’s not an ESC/POS printer, but for reference, you need echo -e for thr escape codes. Check out-

    $ echo -e "\x27\x32\x49hello" | hexdump -C
    00000000  27 32 49 68 65 6c 6c 6f  0a                       |'2Ihello.|
    
  26. @vignesh – Depends what you want to do, but yes. Check out the selection of PrintConnector objects, and feel free to file a new issue on the issue tracker with details of your use case if you think the library needs a dedicated multiple-printing interface to support it.

  27. Mike, I’m trying to COM port in Bixolon SRP 350II but the printer don’t print.

    I used a COM port monitor and can see how the code send the code to the printer.

    Any idea?

  28. Hello Mike, Can you tell more about printing bit images or logos on ESCPOS command?
    I am using ESC* command to print logo. Is this an appropriate command?

  29. I’m facing a similar isse, but with an ON 500 thermal printer. I’m kaing a C# console and deskpot application that uses “RawPrinterHelper”, however, I don’t know the language used by the thermal printer (or any idea about what kind of language is). I tried with no success find manual for this thermal printer. I’m having problems with settings about font, speed, cut.

  30. @Alberto Chirinos – This is probably not the best place to get an answer. If you’re programming, you could try posting a mimimal working example to StackOverflow. If not, you should contact your POS system vendor.

  31. Hello Mike,

    I really really appreciate with your escpos. But I have problem with printer connector file. I make a POS apps using php and try to use escpos, but that apps have to install in Windows.

    Can you tell me the connector file for Windows to change this statement “/dev/usb/lp0″ or ” php://stdout” (I using that, but it not works).

    I hope you can help me. Thanks in advance Mike.

  32. I forget to say, the apps and printers are installed on the local computer and not shared with other computer (my client request)

  33. I Need a eample of a QR code printed with the Epson Printer
    I hope ypu can help me with the comands that are needed.

    I thank you.

  34. Hi Mike, My PHP app is Online and any registered-user can print from anywhere from their own…how to get this work?

    Regards

  35. Hi Mike,

    I really really appreciate with your escpos, is that possible using this script to print on Epson LQ or Epson LX ?

    Thanks

  36. Hi @Mike,

    I have tried to connect printer on windows server but it is not working.

    My code is:
    $connector = new NetworkPrintConnector(“10.0.0.40”, 9100);

    $printer = new Printer($connector);
    $printer -> text(“Hello World!\n”);
    $printer -> cut();
    $printer -> close();

    but nothing is working.

    Please help to resolve this issue.

    Thanks
    SK

  37. @Herliansyah Espon LQ and LX printers speak ESC/P2, which is not the same as ESC/POS. Very simple prints will work, but for anything more advanced, you probably want an ESC/P2 library instead.

  38. Hello Mike42! Thanks for your project, its very usefull
    Im having a curious bug that I have to fix it but can’t find a way
    On same settings and php file my chinese zj5890 it makes how I want it but on my epson t20II it doesnt…On the first it fits the 32 characters on per line but on the epson only 31 -.-‘
    Heres the receipts with 58mm paper https://ibb.co/ngOeoR
    Could you help me? Any ideas? Thank you very much

  39. @Julio- If you are working with escpos-php, you might consider opening a question on the issue tracker[1]. The left margin looks quite large, and there may be a command that can be implemented to adjust it.

    Otherwise, you would have to make everything one character shorter, or use FONT_B, where everything is printed smaller.

    [1] https://github.com/mike42/escpos-php/issues

  40. @Mitul – Yes, you can develop your receipts without a printer to some extent. You need to use the FilePrintConnector to produce a file as output, which can then be converted to HTML with the esc2html utility1.

  41. require DIR . ‘/../autoload.php’;
    use Mike42\Escpos\Printer;
    use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
    $connector = new WindowsPrintConnector(“Receipt Printer”);
    $printer = new Printer($connector);

    try {
    // Enter the share name for your USB printer here

    /* Print a "Hello world" receipt" */
    $printer -> text("text text");
    $printer -> cut();

    /* Close printer */
    $printer -> close();

    } catch(Exception $e) {
    echo “Couldn’t print to this printer: ” . $e -> getMessage() . “\n”;
    }
    this code print simple text but why not print barcode

  42. Hi All,
    I use this code :
    $profile = CapabilityProfile::load(“simple”);
    $connector = new WindowsPrintConnector(“smb://172.17.4.11/printertiket”);
    $printer = new Printer($connector);
    on Windows 7 as a Xampp server. And its work.

    But, when i use Windows Server 2016 as Xampp Server, it have an error : “copy(\172.17.4.61\printerphp): failed to open stream: Invalid argument”

    Any solution for this?
    Thank you before..

  43. Mike can you please tell me how to print image with thermal printer in c#…. i did not get any help that is useful for me. I am not able to print arabic char thats why i converted them to image but the image cannot print through mhy printer

  44. Hi mike, i wanna ask is the escpos-php compatible with this printer zijiang ZJ-5802 ? i plan to purchase if it’s compatible

  45. POS Printer easily access from localhost but when I tried to access from website then it’s not.
    Please help me regarding this issue.
    my code is:

    include_once(“print/autoload.php”);
    use Mike42\Escpos\Printer;
    use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
    use Mike42\Escpos\PrintConnectors\FilePrintConnector;
    use Mike42\Escpos\EscposImage;

    try
    {
    $connector = new WindowsPrintConnector(“PRINTER_NAME”);
    $printer = new Printer($connector);
    $printer -> text(“Hello World”);
    $printer -> cut();
    $printer -> close();
    }
    catch (Exception $e)
    {
    echo “Couldn’t print to this printer: ” . $e -> getMessage() . “\n”;
    }

  46. @Ankit – Printing is server-side, which has its limitations. It takes some extra work if your printer and server are not on the same LAN.

    It is an architectural problem- You either need to deploy your PHP server inside the network to void the problem, relay the prints through an agent (with Javascript), or connect up a secure tunnel so that your printer can be seen from the server.

    The escpos-php FAQ has some ideas you can investigate-
    https://github.com/mike42/escpos-php/blob/4fff198b2a5d07f5d2fb8dc00e361935abd36447/doc/FAQ.md#can-i-print-from-my-server-on-the-internet

  47. Hi,

    I have a requirement for printing the text after reversing it
    E.g.
    if the text is 1234 the printer should print 4321 i can add other options to this text like bold etc.
    just wanted to check is there any ESC command for this.

  48. @chandresh – I don’t believe you can reverse a string like that using an ESC/POS command, you need to reverse it before you send it.

    Each language has their own way of doing this. Eg, str_reverse is suitable for ASCII if you are using PHP.

  49. Hello Mike.
    In their examples above, they work with ESCPOS printers via bluetooth.
    Would you have some examples?

    My best regards

  50. Hello, Mike
    At first, I’m just to mike 42 php, and i need your advice to me for esc/pos with mike42 php for Xprinter XP-Q260NK,
    I cannot print out in Thai, Tables code pages 70:PC874, 255 (Thai). yes I’ve try to set code page 70 and 255 but it’s not works.

    Thanks,

  51. Hello Mike,

    Could you please add an example of QR Code with the Hexdump ?
    I am using a SNBC BTP – R180 printer.
    Thanks,

  52. Hola estoy implementando ésta librería, hice todos los pasos y no me sale ningún error, simplemente no me imprime nada. Hice la impresión de prueba y si me arroja la impresión de prueba. También compartí la impresora. El problema es solo que cuando llamo localhost/probarTicket/ticket.php. Solo se queda en blanco la pagina y no imprime nada.

  53. @Anthony- Your script is probably erroring out. Check that you have error logging enabled in php.ini, then check the PHP error logs. You can also try executing your scripts on the command-line.

Leave a Reply

Your email address will not be published. Required fields are marked *