14

I'm printing some QR codes (from a Ruby script) writing ESC/POS commands to a Epson TM-T20 thermal printer.

BTW, I'm writing a simple ESC/POS commands printer "driver". The printer I'm using an Epson TM-T20 (USB interface) I'm doing some tests from a Windows 7 host, using serialport gem.

All fine about writing ESC/POS commands for print formatted texts and also linear barcodes, but I have problems uinderstanding the command protocol to print QR CODES, using the only available documentation supplyied by Epson (as far as I know), see: http://www.novopos.ch/client/EPSON/TM-T20/TM-T20_eng_qr.pdf

Now, he section concerning QRCodes commands is for me pretty obscure and I was unable to interpreter requested byte sequences; instead I found very helpfull the Nicolas' example I found here: https://code.google.com/p/python-escpos/wiki/Usage

Hacking that useful bytecodes example, I am able to successuffly print QR codes, see:
I https://twitter.com/solyarisoftware/status/464740233008132096

Nevertheless, in general, I'm confused on the ESC/POS message format, especially in case I would insert a long text message (> 400 chars) inside a QR code... It seem that printer reject (do not print) QR codes containing more than 400 chars using this code:

def test_qrcode (printer, text, print_also_text=false, qr_size=6.chr)

  s = text.size + 3
  lsb = (s % 256).chr
  msb = (s / 256).chr

  # https://code.google.com/p/python-escpos/wiki/Usage
  escpos = ""
  escpos << "\x1D\x28\x6B\x03\x00\x31\x43#{qr_size}"
  escpos << "\x1D\x28\x6B\x03\x00\x31\x45\x33"
  escpos << "\x1D\x28\x6B#{lsb}#{msb}\x31\x50\x30"
  escpos << text # 
  escpos << "\x1D\x28\x6B\x03\x00\x31\x51\x30"

  # writing byte streams directly to the serial port
  printer.write escpos

end

Does someone can suggest a CLEAR ESC/POS DOCUMENTATION concerning the ESC/POS commands (=bytecodes sequences) to print QRCodes (two-dimensional code ESC/POS commands) ?

2

4 Answers 4

24

The most complete documentation I've found for the ESC/POS command set is this one: http://content.epson.de/fileadmin/content/files/RSD/downloads/escpos.pdf

Recently, I added the QR code feature to a POS client. I've found it very useful to have a print out of this Code page 437 reference, especially for debugging a sequence that was printed.

My example is in Java, but you can get the idea:

public void print_qr_code(String qrdata)
{
    int store_len = qrdata.length() + 3;
    byte store_pL = (byte) (store_len % 256);
    byte store_pH = (byte) (store_len / 256);


    // QR Code: Select the model
    //              Hex     1D      28      6B      04      00      31      41      n1(x32)     n2(x00) - size of model
    // set n1 [49 x31, model 1] [50 x32, model 2] [51 x33, micro qr code]
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=140
    byte[] modelQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x04, (byte)0x00, (byte)0x31, (byte)0x41, (byte)0x32, (byte)0x00};

    // QR Code: Set the size of module
    // Hex      1D      28      6B      03      00      31      43      n
    // n depends on the printer
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=141
    byte[] sizeQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x43, (byte)0x03};


    //          Hex     1D      28      6B      03      00      31      45      n
    // Set n for error correction [48 x30 -> 7%] [49 x31-> 15%] [50 x32 -> 25%] [51 x33 -> 30%]
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=142
    byte[] errorQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x45, (byte)0x31};


    // QR Code: Store the data in the symbol storage area
    // Hex      1D      28      6B      pL      pH      31      50      30      d1...dk
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=143
    //                        1D          28          6B         pL          pH  cn(49->x31) fn(80->x50) m(48->x30) d1…dk
    byte[] storeQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, store_pL, store_pH, (byte)0x31, (byte)0x50, (byte)0x30};


    // QR Code: Print the symbol data in the symbol storage area
    // Hex      1D      28      6B      03      00      31      51      m
    // https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=144
    byte[] printQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x51, (byte)0x30};

    // flush() runs the print job and clears out the print buffer
    flush();

    // write() simply appends the data to the buffer
    write(modelQR);

    write(sizeQR);
    write(errorQR);
    write(storeQR);
    write(qrdata.getBytes());
    write(printQR);
    flush();
}
10
  • 1
    The link is now fixed! Commented Mar 24, 2016 at 7:30
  • @JosueIbarra This is not printing the QR-CODE, it's printing some weird letters and then the url in string format. Any reason why?
    – LeoColman
    Commented Dec 16, 2016 at 18:48
  • @Kerroker I had that when I used the wrong encoding, check that you are not casting to another encoding type (UTF for example) and properly using Code Page 437 with no padding. There is also the possibility that the printer driver you are using is doing this encoding transformation automatically. Commented Dec 16, 2016 at 19:27
  • 1
    @Tobia there are multiple QR commands, take a look at this page for the first one. The rest are in the documentation menu on the left. reference.epson-biz.com/modules/ref_escpos/… Commented Jan 11, 2020 at 16:15
  • 1
    @LeoColman the weird letters are the ESC/P codes and the string is... well, the string that would be rendered. This means that particular printer does not suport GS ( k QR code printing.
    – vesperto
    Commented Jun 8, 2021 at 9:30
1

I'm not familiar with ESC/POS but I do have some experience with QR codes.

If you're hitting an upper limit on the number of characters you can put in a QR code, there are four things inherent in the QR code design which might be causing it:

  1. You can control the amount of error correction data. More error correction means a bigger QR code but a more reliable scan.

  2. QR codes must be square so you might be bumping up against your printer firmware's "maximum width" and "minimum QR code pixel size" limits.

  3. QR codes are defined in "versions" with each version representing a range of sizes (the higher the version, the bigger the QR code). Your printer's firmware may just not support versions above a certain number.

  4. QR codes support four different encodings with different data limits on each (Numeric, Alphanumeric, Binary, and Kanji).

This means that you should:

  1. Check how much error correction you're putting in. (From most to least, the levels are H, Q, M, and L). You might find that a lower level of error correction still gives you enough reliability while allowing you to squeeze in more data.

  2. Check the spec to see if you can ask for smaller QR code pixels so a wider code will fit on the paper.

  3. Check what the highest supported QR code version for your printer is.

  4. Check which data encoding you're using.

If you're hitting a limit around 400 characters, the maximum version should be somewhere in the 8-13 range for numeric, 11-17 for alphanumeric, and 13-21 for binary, depending on the level of error correction used. (See the reference table I linked before)

1

This is in ESC/POS:

GS "(k"  4 0 49 65 50 0
GS "(k"  3 0 49 67  5
GS "(k"  3 0 49 69 48 
GS "(k" 28 0 49 80 48 "https://stackoverflow.com/"
GS "(k"  3 0 49 81 48
1

adding this VB6 function I use to print qrcodes.

REF: https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=140

Public Function qrcode(Msg As String) As String
    Dim Length As Integer
    Length = Len(Msg) + 3
    qrcode = Chr$(&H1D) & Chr$(&H28) & Chr$(&H6B) & Chr$(&H4) & Chr$(&H0) & Chr$(&H31) & Chr$(&H41) & Chr$(50) & Chr(0) 'function 165 select model
    qrcode = qrcode & Chr$(&H1D) & Chr$(&H28) & Chr$(&H6B) & Chr$(&H3) & Chr$(&H0) & Chr$(&H31) & Chr$(&H43) & Chr$(&H4) 'function 167 size of the module
    qrcode = qrcode & Chr$(&H1D) & Chr$(&H28) & Chr$(&H6B) & Chr$(&H3) & Chr$(&H0) & Chr$(&H31) & Chr$(&H45) & Chr(48) 'function 169 error correction level
    qrcode = qrcode & Chr$(&H1D) & Chr$(&H28) & Chr$(&H6B) & Chr$(Length Mod 256) & Chr$(Round(Length / 256, 0)) & Chr$(&H31) & Chr$(&H50) & Chr$(&H30) & Msg 'function 180 store data
    qrcode = qrcode & Chr$(&H1D) & Chr$(&H28) & Chr$(&H6B) & Chr$(&H3) & Chr$(&H0) & Chr$(&H31) & Chr$(&H51) & Chr(48) 'function 181 print
End Function

Usage is like:

Print #1, qrcode("https://mypage.com"); brake;

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.