Reputation: 125
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
Upvotes: 9
Views: 33569
Reputation: 1688
There are actually two issues here: data transport, and the data being transported.
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.
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 escapek
means ``, the actual ASCII letter kCHR$(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.
Upvotes: 12
Reputation: 1160
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
Upvotes: 3
Reputation: 51
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:
Upvotes: 0