Printing Qr Codes Through an Esc/Pos Thermal Printer

How to print QR code (or bitmap) to thermal printer?

Turns out there's nothing wrong with my ESC/POS codes. After tracing around and finding the point where the software prints, i ran my own test and sent it to the serial port, producing a QR code.

Here's what i used for reference:

uint8_t myEscTst[] = { 0x1B, 0x40, 0x1B, 0x21, 0x00, 'H', 'e', 'l', 'l', 'o', ',', ' ', 't', 'h', 'e', 'r', 'm', 'a', 'l', ' ', 'w', 'o', 'r', 'l', 'd', '!', 0x1B, 0x64, 0x03 };
write(serialFD, myEscTst, sizeof(myEscTst));

uint8_t qrEsc165[] = { 0x1D, 0x28, 0x6B, 0x04, 0x00, 0x31, 0x41, 0x32, 0x00 };
write(serialFD, qrEsc165, sizeof(qrEsc165));

uint8_t qrEsc167[] = { 0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x43, 0x08 };
write(serialFD, qrEsc167, sizeof(qrEsc167));

uint8_t qrEsc169[] = { 0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x45, 0x31 };
write(serialFD, qrEsc169, sizeof(qrEsc169));

uint8_t qrEsc180[] = { 0x1D, 0x28, 0x6B, 0x0E, 0x00, 0x31, 0x50, 0x30, 'i', ' ', 'a', 'm', ' ', 'a', ' ', 't', 'e', 's', 't' };
write(serialFD, qrEsc180, sizeof(qrEsc180));

uint8_t qrEsc181[] = { 0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x51, 0x30 };
write(serialFD, qrEsc181, sizeof(qrEsc181));

uint8_t qrEsc182[] = { 0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x52, 0x30 };
write(serialFD, qrEsc182, sizeof(qrEsc182));

uint8_t qrEscLn3[] = { 0x1B, 0x64, 0x03 };
write(serialFD, qrEscLn3, sizeof(qrEscLn3));

ESC/POS commands for QR prints only the content

If you are referring to these pages in EPSON, the numbers for the parameters written in them are decimal, not hexadecimal.

GS ( k <Function 165>

GS ( k <Function 167>

GS ( k <Function 169>

GS ( k <Function 180>

GS ( k <Function 181>

GS ( k <Function 182>

Or is it the right parameter for a Custom VKP printer?

I can't judge it because I don't have the ESC/POS command reference for the Custom VKP printer.

  • From the numerical value, it seems that I am trying to print Micro QR Code, is the printer supported?
  • Some unknown value is specified for the module size, but EPSON is in the range of 1 to 16. The default is 3.
  • And since FUNC_182 is a function to notify the print size of the barcode, calling it after printing has no meaning.

Assuming the printer supports MicroQRCode printing, the command creation part would look like this:

byte[] FUNC_165 = new byte[]{Commands.GS, 0x28, 0x6b, 0x04, 0x00, 0x31, 0x41, 0x33, 0x00};
byte[] FUNC_167 = new byte[]{Commands.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, 0x03};
byte[] FUNC_169 = new byte[]{Commands.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x45, 0x30};
byte[] FUNC_180 = new byte[]{Commands.GS, 0x28, 0x6b, store_pL, store_pH, 0x31, 0x50, 0x30};
byte[] FUNC_181 = new byte[]{Commands.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30};
byte[] FUNC_182 = new byte[]{Commands.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x52, 0x30};
  • Although there is no problem with the current contents, actually specify the data length as the length of the byte array, not the length of the string.

So the first part would be:

String content = "Hello !!";
byte[] content_bytes = content.getBytes(StandardCharsets.US_ASCII)
int store_len = content_bytes.length + 3;
byte store_pL = (byte) (store_len % 256);
byte store_pH = (byte) (store_len / 256);

The actual writing will be like this?:

writer.write(INIT);
writer.write(FUNC_165);
writer.write(FUNC_167);
writer.write(FUNC_169);
writer.write(FUNC_180);
writer.write(content_bytes);
writer.write(FUNC_181);
writer.write(CUT);
writer.close();

Please try adjusting it to the parameter range that your Custom VKP printer actually supports.

How i can generete qrcode with ESC POS?

That's because it uses string variables.

Even if you specify the encoding, it is not always possible to convert character data with a value of 0x80 or higher to the correct byte value.

If you use only a byte array, you can use long data.


Not all can be treated as text encoded in a single code page.

This is because commands that include control codes such as barcode printing are very likely to contain data that cannot be handled as character string text.

However, text and barcode printing can be mixed. Text data can be written to a file as encoded binary data (not a string).

If there is another program that reads data from the file and writes it to the printer, that program must open the file as a binary data file.

Generate QRCode and Print in Printer Thermal using ESC POS - ZIJIANG 58mm - Delphi 10.2

Having quite similar issues on that kind of mini POS printers. When directly printing from Kotlin (Android Studio, native), I managed, somehow, to interpret partially their official manual and concluded that ESC Z works little different (actually it coresponds to the Java code you found)...

  1. ESC Z (27 90)
  2. first byte relates to table row ("version"), if 0 then it will "autoselect"
  3. at first, I thougth second byte must be 'M' (77) - 'L', 'Q', 'H' - didn't manage it to work?! (actually it has to be 0,1,2,3 based on error correction - as suggested in Java code you found and posted here)
  4. this byte relates to QR code size, 1-8
  5. lower byte of string size (for example, for your "dada" it would be 4)
  6. higher byte of string size (for your "dada" it would be 0... if longer than 256 characters, this shall be length div 256)
  7. string characters

In your Delphi code, I would change (step-by-step, you can binary mask the length...):

// start - qr-code //
ps := 'dada'; // your content string... detalji o računu ili štogod...
l1 := length(ps);
y := l1 div 256;
x := l1 - y * 256;
ostream.write(StringToJA(chr(27)+chr(90)+chr(7)+chr(1)+chr(6)+chr(x)+chr(y)+ps ,'iso8859-2'));

// please not that 7-1-6 is fixed combination - 7 relates to the table from documentation, 1 relates to error correction (use 0 for "smaller" QR with less redundany, or 2 and 3 for larger more complex QR), 6 relates to size of printed code (can be set lower)


Related Topics



Leave a reply



Submit