What's hidden inside online cash registers: development of a fiscal registrar. ESC POS ESC * command to print a bitmap on a printer Legislation: global online checkout control

Few people think about how cashier technology works when shopping in a store. In fact, this is a well-oiled mechanism, not only from a technical point of view, but also from a legal point of view. Everyone knows that the main thing is to receive a check, but only the entrepreneurs themselves know why the check is a fiscal document confirming the purchase.

In this article we will share our experience in developing a cash register and tell you how everything works from the inside.



Vintage cash register

1. System: hardware + software at the cashier

The entire software and hardware complex, which is installed at the cashier’s workplace, can be called a POS system or POS terminal, from the English Point of sale - place of sale.

Let's look at how a POS system works. Since the fundamental difference between the system and the terminal is the location of the fiscal memory (FP) or fiscal storage (FS): for a POS system it is built into the printing device, and for a POS terminal it is located in the computer unit.


Typical cash register. POS system of the Russian company "SHTRIKH-M"

POS system – a software and hardware complex that operates on the basis of a fiscal registrar. Typically consists of a POS computer, monitor and keyboard, receipt printer, fiscal recorder, customer display, cash drawer and reader bank cards. A typical set of cash functions: accounting and issue of goods, receiving and issuing money, canceling a purchase.

The most interesting part of the POS system is fiscal registrar - this is the heart of the system and one of the classes of cash register machines (CCM).

A receipt printer with built-in fiscal memory acts as a fiscal registrar. It receives information via a communication channel, processes it and prints it. Data on cash transactions can be stored in fiscal memory for as long as desired until it needs to be reset.

A server is used to directly transfer data from the fiscal registrar to the tax service fiscal data operator - OFD - a special legal entity that is responsible for receiving, processing, storing and transmitting fiscal data to the tax service.

Last year, Russian entrepreneurs actively discussed the transition to online cash registers and sending checks to the tax office through the OFD in connection with the adoption of Law 54-FZ “On the use of cash register equipment.”


The role of the OFD. Diagram from an article about 54-FZ and the transition to online cash registers

FTS is the Federal Tax Service Russian Federation. In Kazakhstan, this function is performed by the State Revenue Committee of the Ministry of Finance. And in Belarus – the Ministry of Taxes and Duties.

There are several OFDs operating in the Russian Federation, but in Kazakhstan there is only one, Kazakhtelecom JSC.

2. Legislation: global online control of cash registers

Online monitoring of retail operations is already operational in many countries: South Korea (2005), Sweden (2008), Canada (2010), Poland (2011), Croatia (2013). In 2015, this approach began to be implemented in Kazakhstan. And in Belarus, the deadline for connecting cash registers to the remote revenue control system was postponed to July 1, 2018 (the same deadline is scheduled in Russia).

The use of online cash registers in Kazakhstan is regulated by Chapter 90 of the Tax Code. Since 2015, sellers of fuel and alcohol began transmitting receipts to the tax office via the Internet. At the second stage - from 2016 - those involved in the wholesale trade of various materials and equipment were connected to the system; retail sale of furniture, software and electronics; owners of hotels, restaurants, hairdressers and cinemas. The third stage of the project is envisaged.

We refer to laws for a reason; they describe the mandatory technical requirements for software and hardware systems for collecting and sending data to the tax office, which form the basis of those. tasks for development engineers. For example, in the order of the Minister of Finance of the Republic of Kazakhstan, a list of requirements for a cash register for transmitting information about cash payments was published, which was very useful for us in developing a fiscal registrar.

3. Design and business logic of the fiscal registrar

Our basic development device is a thermal receipt printer. The assembly system is Buildroot. Programming - in Qt.

The project required the development of:

1) technical specifications;
2) an exchange protocol with a POS computer, let’s call it the POS-C protocol;
3) daemon application that controls the device:

  • module for data exchange with the OFD server using the CCT protocol (cash register equipment);
  • module for data exchange with a POS computer using the POS-C protocol;
  • print control module;
  • communication interface control module;
  • database interaction module;
  • web server.

1) Data exchange module with the OFD server

The exchange between the device and the server is carried out using the TCP/IP protocol. In this interaction, the device is the client, and the OFD is the server. Protocol Buffers are used as the basis for encoding and decoding information transmitted via the CCP protocol.

Purpose of the web interface:

  1. settings;
  2. viewing device status;
  3. Software Update.


Web interface

4. Conclusion

Based on the listed technologies, we have developed a device with a lot of functions and settings via a web interface, support for various exchange protocols with a POS computer, and the ability to update software.

And now it seems that the Promwad engineering team will never be able to just come to the store and buy something without thinking about all these internals of online cash registers, protocols for data transfer, legal requirements and printing this entire kitchen:
- Take the check, please!
- No, thanks! :-)

P.S. And finally, a moment of humor: British ufologists from the ArtAlienTV team discovered Curiosity rover an object resembling an old cash register.

Protocol basis

The standard task of any receipt printer is to print text. Additionally, you can create custom settings for font, size, density, and other device settings. All information (useful and control) is transmitted in the form of text; the printer “catches” control commands, separates them, and prints only the text part. Thus, control is contained in the text itself. To separate the service part from the information part, special characters are used that are not printed and cannot be entered from a computer keyboard. An example of such a character is “ESC” or the decimal code character 27. Sending this character to the printer means that it is followed by a short print control command. A description of the ESC/POS protocol commands usually comes with the device and is part of the printer documentation.

Approximate printer capabilities

How approximate possibilities For any of the standard receipt printers, you can define the following actions:

  • Increase and decrease font size;
  • Activation of inverse font (white letters on a black background)
  • Barcode printing;
  • Activation sound signal printer;
  • Innings electrical signal to open the cash drawer;
  • Activating the knife on the printer to cut paper.

Depending on the model and capabilities of the printer, these actions are activated using ESC/POS commands. In this case, the printer monitors each command and executes it immediately.

When to use ESC/POS commands

Using ESC/POS commands is possible whenever the printer supports them (almost all printers) and when working directly with the printer, without using an intermediate Windows driver A. Microinvest Warehouse Pro Light controls the device directly, sending the necessary commands to the printer. They work flawlessly and using USB printer without intermediate driver and USB to COM emulation.

When it is impossible to use ESC/POS commands

There are 3 cases when using ESC/POS commands is impossible in principle: 1. Fiscal registrars. Fiscal printers use a complex communication protocol that is absolutely incompatible with the ESC/POS protocol. As a result, the printer does not respond to ESC/POS commands; 2. When controlling the printer via installed Windows driver. In this case, the driver itself executes ESC/POS commands, and categorically rejects such commands sent software. As a result, there is no impact on the printer; 3. When printing intermediates are used, such as a print server or other similar technologies. In this case, ESC/POS commands are filtered and lost during communication, without even reaching the printer. When building a system, it is necessary to properly plan printer management. We recommend that each printer be linked directly to the control computer, and work directly according to the protocol, without a driver.

Command coding

ESC/POS commands are encoded through one or more special characters and command parameters. All this is described in the corresponding section (Header, Details, Totals or Footer) in the printer settings in Microinvest Warehouse Pro Light or Microinvest Device Manager. Basic commands controls are:

Their actions are described in the printer documentation and standardized by the ESC/POS protocol.

Popular teams

A sample list of the most popular teams ESC/POS protocol:

  • !- Activates font A;
  • !- Activates font B;
  • !- Double height font;
  • !- Double-width font;
  • !- Font A with normal height;
  • E - Includes bold font;
  • E - Turns off bold font;
  • B - Includes inverse printing;
  • B - Turns off inverse printing;
  • i – Activates the knife on the printer.

Despite the fact that the listed commands are standardized according to excerpts from the ESC/POS protocols different printers, but each of them has its own technology for executing commands and the results may vary depending on the manufacturer or model. To achieve the desired effect, you need to test and select the commands that are executed by the printers.

Other information

ESC/POS is a very powerful printer control technology. Through this protocol You can get excellent results from virtually every modern printer. Unfortunately, there is no 100% compatibility between different devices, so each command needs to be tested on a real specific device. Some commands depend on execution time. So, for example, activating a knife can get ahead of the print with the contents and cut off the receipt in the wrong place. Therefore, using ESC/POS commands requires real-life testing and careful configuration, depending on the printer model.

Some Helpful Resources

  • Documentation for all products;
  • Microinvest technical support forum, where you can quickly get an answer to your question;

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).

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
G.S. 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

Initialization

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:

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.

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.

The commands are:

LF
ESCd[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 | [email protected]| 00000010 49 0a 1d 56 41 03 |I..VA.| 00000016

Print modes

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

The command is:

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);

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 6 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..!| 00130 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| 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| 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 6 4 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.| 80 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| 8 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 6 8 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| 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

$printer -> text("ABCDEFGHIJabcdefghijk\n"); ) $printer -> selectPrintMode(); // Reset $printer -> cut(); $printer -> close();

The command is:

Underline

ESC – [number]

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(); [email protected] 00000000 1b 40 1b 2d 00 54 68 65 20 71 75 69 63 6b 20 62 |

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

The command is:

Cuts

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.< 5; $i++) { $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

cut(Printer:::CUT_PARTIAL); [email protected]$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 |

The command is:

| 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

ESC E [number]< 2; $i++) { $printer ->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 [email protected] 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

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(); [email protected] 00000000 1b 40 1b 47 00 54 68 65 20 71 75 69 63 6b 20 62 |

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< count($fonts); $i++) { $printer ->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

setFont($fonts[$i]); [email protected] 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

The command is:

ESC a [number]

Use 0 to justify left, 1 to center 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(); [email protected] 00000000 1b 40 1b 61 00 41 20 6d 61 6e 20 61 20 70 6c 61 |

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

The commands are:

Barcodes
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.

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]); [email protected]$printer -> feed(); ) $printer -> cut(); $printer -> close();

00000000 1b 40 1d 68 50 42 61 72 63 6f 64 65 20 30 20 0a |

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

ESC * is one of several "picture bit" commands in ESC/POS. It accepts "column format" data, which can only represent one row of 8 or 24 pixels. So there are two good options here.

Printing multiple lines using ESC*

It sounds like you can print one line, so I'll assume that the data format itself isn't the problem.

You can print multiple lines by simply repeating the command to print additional lines separated by \n line breaks. This requires chopping the image and padding it with space so that it is a multiple of 8 or 24 pixels in height (again, due to the format).

Because of line spacing, you need to issue a command to resize the linear channels while printing the image, and then another command to reset them at the end. I use ESC 3 0x10 for 16 channel lines (bytes 0x1b 0x33 0x10) and ESC 2 (bytes 0x1b 0x32) for reset. This printing method has excellent compatibility with older printers, but you may end up with some thin

horizontal lines

This bit of the image command accepts various "raster format" data. I'm taking advantage of the fact that a blob in this format is identical to binary data in a widely used format bitmap PBM (specifically binary data in files with a P4 header).

The height of the image will be limited depending on the size of your print buffer, but can be up to 65535 pixels. Due to representation, the width must be divisible by 8.



2024 wisemotors.ru. How it works. Iron. Mining. Cryptocurrency.