How to send ESC/POS commands to thermal printer in Linux
Asked Answered
G

3

9

I am trying to send ESC/POS commands on a thermal printer. But whenever i send them thermal printer prints them as a text instead of executing them as commands. I am writing these commands in a .prn file and whenever i executes lp command to print a file these .prn file also get printed but as a text.

I tried following method to write ESC/POS command in .prn file :

1) PRINT #1, CHR$(&H1D);"h";CHR$(80);
   PRINT #1, CHR$(&H1D);"k";CHR$(2);
   PRINT #1, "48508007";CHR$(0);
   PRINT #1, CHR$(&HA);
   PRINT #1, CHR$(&H1D);"k";CHR$(67);CHR$(12);
   PRINT #1, "48508007";

2) <ESC>(0x1B) <L>(0x4C)
   <GS>(0x1D) <k>(0x6B) 73 2 4 5 6 7 8 9 NUL
   <FF>(0x0c)

3) <ESC L>
   <GS k 73 2 4 5 6 7 8 9 NUL>

4) "ESC L" "GS k 73 2 4 5 6 7 8 9 NUL" "FF" I also tried sending ESC/POS command using C program as:

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>

int main() {
   int fd,ret;
   char buf[] = "HELLO"

   fd = open("/dev/bus/usb/003/007",O_WRONLY);
   if(fd < 3) {
      perror(open failed);
   }

   ret = write(fd,&buf,sizeof(buf));
   if(ret == -1) {
      perror("write failed");
   }
}

Upon execution the above code gives error as:

write failed: invalid arguments
Gherardo answered 5/6, 2015 at 8:40 Comment(0)
A
12

There are actually two issues here: data transport, and the data being transported.

Data transport: Use usblp

For getting the data to the printer, check that usblp is loaded. It allows you to expose the printer as a file in the lp group, so that you can open it as /dev/usb/lp0.

Once this works, as a regular user you can write:

echo "Hello" > /dev/usb/lp0

I wrote a blog post on the topic which covers the permissions side of this.

Data format

Secondly, the data itself needs to be sent in the correct binary format. A printer will not understand this human-readable .prn (print?) file directly, so it needs to be converted to the correct binary format.

To interpret a few things from your question:

  • ESC means \x1b, an ASCII escape
  • k means ``, the actual ASCII letter k
  • CHR$(80) means \x50, which is how the number 80 is sent to the printer.
  • CHR$(&H1D); means \x1d, an ASCII group separator (GS)

You can write some basic commands directly on the CLI using echo -e. Maybe the simplest non-text example is a CODE39 barcode that says '000'.

This same command in human-readable form, then hex, then as a terminal command would be:

  • GS k 4 0 0 0 NUL
  • 1d 6b 04 30 30 30 00
  • echo -e '\x1d\x6b\x04000\x00' > /dev/usb/lp0

Your best reference for this format is your printer's programming manual, but hopefully this helps you to interpret it.

Be aware that the commands you are trying to execute contain errors, and one of them will even will trap you in page mode.

Aside, the answers by @scruss and @abartek are completely accurate: Check that CUPS hasn't claimed the port by using the lsusb command, and use a hex editor to review your output, or a library to generate known-good commands.

Availability answered 27/5, 2017 at 3:15 Comment(0)
U
3

If the thermal printer is connected via USB, there's a good chance that CUPS will have claimed the port. Consequently, you won't be able to send data to it as a normal user.

To send the raw bytes via cups, use either lpr -l file or lp -o raw file. To inspect the bytes you're going to send, use the xxd hex viewer. These printers typically take CRLF at the end of line, so be sure to send \r\n.

I don't have a C library for you, but I've had success with python-escpos

Unbeaten answered 2/8, 2016 at 12:58 Comment(0)
G
0

If you sure about the hex codes, you can use your favourite hex editor to make a proper command prn file. Or you can pick one from here: Need a good hex editor for Linux
Why hex editor? Because all other way including some hidden content (like new line 0x0d) and the printer cannot understand the command sequency. Probably other problem is the program what you use to deliver a command - some program sometimes add other content or make some conversation when sending it to the printer (like extra page down). Be sure - your program cannot do this.
My way of problem solving this time:

  • be sure, the escape sequencies are correct. (Some printer use special escape sequency, to mark - the next bitstream will be command, not data)
  • be sure, the file what you would like to send to the printer is correct (no additional code in the file - easy way to check is mc viewer - hex mode view (F4))
  • be sure, the delivery to the printer is bitvise correct - the delivery program not manipulate the command file (use man to check it) - like convert non printable characters to hex code
Gertrudegertrudis answered 5/6, 2015 at 9:12 Comment(3)
Thank you @Gertrudegertrudis for your response. i tried this with no success.Gherardo
I send this file to the printer using lp command, which is to print a file. Is this a right way to send commands to the printer or there is any other method to do this. This thermal printer is connected to the system using USB port.Gherardo
Is there any library support in C language to do this.Gherardo

© 2022 - 2024 — McMap. All rights reserved.