Thermal Printer driver for CUPS, Linux, and Raspberry Pi: zj-58

Update:build instructions have changed, 2019. If any manufacturer wants to see if their printer works, send me one (I’m easy to find) for free and I’ll check it out and add it here.

This might be my last post on mini-printers, as I’ve found a driver that just works with CUPS on Raspberry Pi. It also works on Ubuntu on my laptop, and should work (though untried) on Mac OS. You’ll have to build it from source, but it’s not too hard.

The hard part is working out if your thermal printer will work or not. There are many out there, and they’re all slightly different. If they support the ESC/POS bitmap command GS v 0 on 58 mm wide paper, they should work. The ones I’ve tested are:

  1. Catex POS5890U — USB, cheap, fast.
  2. “701” control board panel printer — fairly generic, decent quality printer with serial input. A bit slow for daily use at 9600 baud.
  3. Xiamen Embedded Printer DP-EH600 — as above.

The following should also work, but haven’t been tried:

  • Adafruit Mini Thermal Receipt Printer — again, serial, so not super fast.
  • Sparkfun thermal printer — which now appears to be identical to the Adafruit unit, and is referred to as the “A1 (or A2) micro panel printer” in the documentation.

Known not to work:

  • BTHT-V6 printer — which uses a completely different command set. (Roughly that of an Epson FX-80 for image commands, if you care.)

If you have a manual for your printer, check it to see if it prints bitmaps by sending a three byte header of 29 118 48 (or 1D 76 30 in hexadecimal). If you’re not sure, try it with a small test image, and be ready by the power switch …

Getting and building the driver

The driver is meant for a ZiJiang ZJ-58 printer, and lives here on Github: klirichek/zj-58.

Now read and follow the Building & Installing section of the README, and do what it says. I’ll wait …

Setting up the printer

This bit is much more graphical. You’ll need the system-config-printer package:

sudo apt install -y system-config-printer cups

Open up the printer settings window (Preferences → Print Settings):

2015-07-11-220946_452x281_scrotSelect the Add icon, and the New Printer window opens:

2015-07-11-221141_602x592_scrotThe POS5890U shows up as “Unknown” on my USB port, as Linux doesn’t know the name of this device from its USB ID.

Update (for the slightly desperate): In the land of “Things have changed!”, my Catex printer isn’t/wasn’t showing up at all. I had to resort to this in the Enter URI option:

thermal printer usb lp uri
(hey, this image doesn’t quite match the flow. Look only at the the “Device URI” bit please)

parallel:/dev/usb/lp0 seems to work. Another option might be looking at the output of

sudo /usr/lib/cups/backend/usb

which suggests that usb://Unknown/Printer might work too. (All of this might need to have been preceded by

sudo usermod -a -G lp pi

and a logout or reboot; I did say this was for the slightly desperate …)

If the above doesn’t apply, your printer might have an known ID, or show up as a serial port. Select the right one, and click Forward:

2015-07-11-221221_602x592_scrotHere, I’m really pleased that the driver is for a Zijiang unit, as it’s conveniently at the end of the list. Click Forward …

2015-07-11-221240_602x592_scrotNo options here, so again, Forward …

2015-07-11-221311_602x592_scrotI changed the name from the default ZJ-58 to the more unixly zj58. You don’t have to, but either way, Apply the changes.

2015-07-11-222030_452x281_scrotAnd there it is, registered as a printer!

Printer Options

Most printers expect paper wider than 58 mm, but mini-printers can’t do that. To tell the system about paper sizes, right click on the printer’s icon, and change the printer settings:

2015-07-11-222225_570x560_scrotA test page might print properly now, but you should probably go into Printer Options first:

2015-07-11-222239_570x560_scrotYou do want to set the media size to at least 58 × 210 mm. This is just the longest strip it will print in one ‘page’; if your print is shorter, it won’t waste extra paper. You can choose longer prints, but not wider. The default assume your local standard paper size which —be it A4, Letter, or whatever — will not be what you want here. Hit OK.

Printing something

You could print the self test page, but it’s long and boring. If you’re fairly sure your printer will be supported, try this scaled PDF version of the Raspberry Pi Logo: raspberry-pi-logo.  Printed and scanned, it came out like this:

raspberry-pi-logo-miniprinterNot the best rendition, but not bad for a $30 receipt printer. My test image came out like this (iffy scan, sorry):

zj58-driver-testI haven’t covered the intricacies of setting up serial port connections here; maybe another time. Also, there’s a short delay (maybe 10–20 s) between selecting Print and the printer coming to life. CUPS is pretty complex, and is doing things in the background while you wait.

(Seeing as I use their logo prominently up there, I should totes acknowledge that “Raspberry Pi is a trademark of the Raspberry Pi Foundation”. Also, I couldn’t have done all this without the support of Reed Zhao. Though Reed has moved on to bigger things and doesn’t sell printers any more, his help — not to mention the generous gift of a couple of printers — was very welcome.)

→ you might also be interested in my notes on mini-printers and Linux – it has some manuals too.


  1. Hello burak1489,
    Could you please upload the optimized 58mm ppd file?

  2. about ZJ-80 80mm, you said :

    “Not really sure; it’s not my code. Is the ZJ80 the same but wider?

    I see there’s a hard-coded reference to 384 dots wide in the driver code: and also the PPD appears to be hard-coded for 48 mm printing width. If you feel up to changing these (I don’t, unless someone wants to give me a ZJ-80 for testing) it might work.”

    Can you give me the values to replace on lines 260 to 262?

  3. I don’t know what the Zj-80 line width is in dots, sorry. You probably need to look at adafruit’s fork of the code, as they fix something in the imaging width.

  4. Hi Stewart,

    I am having trouble printing images with my Nano Thermal Printer from Adadfruit and wanted to ask if you could help.

    I have followed a tutorial on making an instant camera using a Raspberry Pi, can’t seem to get it to work and I’m thinking it may have something to do with the CUPS libraries or ZJ-58 Github folders you discussed above.

    I am running a Raspberry Pi Zero W with Raspbian Lite.
    When I initiate a print, using a lp command, the output I get is “request id is ZJ-58-## (1 files(s))” (where ## is the number of times I’ve attempted to print) and then nothing happens.

    I have been working on this project for several months now and can’t seem to figure it out.
    Please let me know if you could be of any help.

    Much appreciated,

    p.s. here is the tutorial link:

  5. Running DMESG on my POS-5890K labelled printer, it identifies itself as
    full-speed USB device number 9 using ehci-pci
    idVendor=0416, idProduct=5011
    New USB device strings: Mfr=1, Product=2, SerialNumber=3
    Product: POS58 USB Printer
    Manufacturer: GD32 Microelectronics
    SerialNumber: Printer

    What gives more clues is the small piece of thermal paper that came with the printer with a printout of its self-test (surely from Windows).
    It reads:
    58-IV-U Thermal Printer
    Version: 58.E-Z04-AA
    Revised date: 06-Jan-2017
    Command Standard: EPSON (ESC/POS)
    Print mode: Normal mode & Hex Mode
    Print method: Line Thermal
    Print width: 384 dots/line
    Print speed: 90 mm/s
    Chinese Mode: NO
    Print density: Level3
    Current Codepage:0
    Interface Type: USB
    Current Character: Chinese (GB18030)
    Code Page: 0: OEM437 (Std.Europe)
    1: Katakana
    2:OEM850 (Multilingual)

    I wonder why the CUPS folks have not released a generic “EPSON ESC/POS” printer driver where the above parameters can be tweaked and entered manually.

    The driver you linked was installed but didn’t work. A sample print gave gibberish. A second text-only printing (by clicking the CUPS “print self-test page” read “IF YOU CAN READ THIS YOU’RE USING THE WRONG DRIVER FOR YOUR PRINTER”.

    A crude bug-finding code it seems…

    Any ideas before I head over to the CUPS maling list and pull my hair?

  6. Hi,

    thanks for all your work. I came here in search of a way to get a ZJ-58 to work with the Raspberry Pi, not sure whether to buy one or another.

    I went carefully through all the steps and stopped on your comment of a 10…20 seconds delay. Did you happen to analyse this a little more? Do you see any way to tweak it?


  7. Hi Jan — the 10–20 second delay is an unavoidable side-effect of using CUPS. In order to support almost every bitmap printer ever, CUPS does a lot in the background:

    1. reads the input file
    2. guesses what format it is in
    3. converts that internally to PDF (I think)
    4. loads the driver for the particular printer
    5. runs the internally-generated PDF through the driver
    6. spools the result to the printer
    7. cleans up

    All of this is almost instantaneous on a modern laptop or desktop, but takes a few seconds on a Raspberry Pi.

    If you want quicker output and can accept a limited subset of input files, then feeding small bitmaps or plain text to the printer’s raw spool input is very fast. But this isn’t reliable in all cases, so I put up with CUPS’s delay.

  8. I’m using the TTL JP-701 printer (serial:/dev/serial0?baud=9600), and while following your guide, I only get as far as the last screen of the New Printer dialog. When I hit “Apply”, the Pi only thinks for a few seconds (hour glass cursor), then nothing. The dialog doesn’t close, the printer doesn’t get added, nothing happens. Any ideas?

    In case it’s relevant, I started from a headless Raspbian Lite, then added raspberrypi-ui-mods etc. in order to get a GUI to configure the printer. The rest works just fine.

    Is it maybe possible to add the printer only from the terminal?

    Any help or suggestions would be appreciated!

  9. Thank you for help! Your instruction worked without any problems.

  10. Hello,

    I could work my POS 80 printer with this driver. The weird thing is I can print but it is cutting from right side and there is really enough place on the paper. I can not see the right side of the my PDF. I selected already 80mm x 210 mm paper size but it is acting like 58 mm printer?
    Is there any way to fix this?

  11. This driver is only for the 58 mm printers. It can’t print the full width of the 80 mm printers. It would need to be rewritten to do that

  12. thanks a lot for this info 🙂
    still working on 2018 for a Zj-5890k on Ubuntu 16.04

  13. Hi Scruss
    I succesfully added the printer (Zijiang ZJ-58 -> serial:/dev/ttyAMA0?baud=19200).
    It prints fine,but instead “dot” or “spot” , I obtain small “+”. It’s frustrating because the picture(jpg or png) is visible but it will build with this characters and not with dots.

    I tested with the official Adaifruit installation and with yours.
    Voltage 8,4V- 2,3A

    Do you know maybe the cause ?



  14. Muchas Gracias! Me funciono con una impresora Thermal Receipt Printer 5890C en Raspbian (Debian)x86. Saludos cordiales desde Argentina

  15. Hi Steven, why I’m getting this error?
    Idle – Directory “/usr/lib/cups/filter” has insecure permissions (040733/uid=0/gid=0).
    Thanks alot.

  16. Hey, big fan of your work.
    I have a jpqr701 printer and i followed this tutorial but its just spuwing out chinese text. Do you know whats causing this (im using the specified baudrate).

  17. Salut,
    j’ai un PB avec mon imprimante Postek C168/200s, pilote d’impression, sous Raspberry Pi3.

  18. There are no manuals or control code tables available for the Postek, Bilel. It won’t work with this driver, and seems to be Windows only

  19. Hi, thank you so much for creating all this 🙂 Thats amazing. Just one thing. Is there an easy method to change the printing speed? I have the feeling that my ZJ-58 would print a bit better if he would do it slower.

    Thank you so much

  20. ESC7 is very specific. I’ve found it supported only for one(!) available printer; the rest majority just supports elementary set of commands.
    However, another thing I’ve found inside which directly influents to the print quality (especially when there are many black points a line) is hardware: on the cheap printers there is often too small capacitor for power buffering is soldered. I’ve changed 68uF to 1000uF (which perfectly fit in the place), and the problem with semi-black lines dissapeared.

    Btw, I’ve updated the repo with zj-58 filter; now it supports both 58 and 80mm printers (via different PPDs), still for generic POS printers, but also another method used in some epsons implemented (mine one zijiang doesn’t support it, so I just can’t test whether it works or not at all)

  21. Hey, I’ve followed this guide but it just won’t work. The only step I wasn’t able to do is execute “make”, because there’s no candidate specified.
    I’ve tried Raspbian Stretch, as well as Ubuntu Mate. The printer works fine on my Ubuntu desktop.
    I’m really at my wits’ end.
    cups_log shows that Ghostscript seems to have an issue.
    Has anyone got any tips?

  22. Thanks, Alexey. I knew that ESC 7 wasn’t universal. At least it’s better than one printer I have that will print faster and darker depending on how high the supply voltage is.

  23. IDK why I bother, I follow instructions to the letter, as soon as I type make and hit return, I get…

    $ cd zj-58/
    $ make
    make: *** No targets specified and no makefile found. Stop.
    $ dir
    CMakeLists.txt install LICENSE rastertozj.c zj58.ppd zj80.ppd zjdrv.drv

    as you can see, it did not like the make command as your post says…

    cd zj-58/

    and it clearly does not build…

  24. So the build instructions have changed.
    Did you read the README when things went sideways?
    Or did you come here to complain first?

    It’s not my job to give free documentation to someone else’s code. Please take some initiative of your own.

  25. @ Alexey, you’re perfectly right. I replaced two 47uF capacitors next to the ffc-cable
    heading to the printing unit with 1000uF. The result is so much better now. I tried this
    on a ZJ-589oK Model.

    Thanks a lot!

  26. Super. I bought a FUKUN receipt printer. Your above build instructions work fine, but I have a bad rep with printers and Linux 🙁

    The printer prints about 2 cm of image, whether it’s a test print or an image out of inkscape. Sometimes, it will restart with a few chinese characters, xxxx or the first 5mm of the image I tried to print.
    Any idea what gives?

  27. Hi scruss,

    can you help me to solve my problems. with Thermal printer PRJ-58U.
    i want to install the printer at linux – ubuntu 16.04

    i got the driver from my vendor, but looks like it’s didnt right.
    cause when i print a sample, its very smal (i use 55mm papersize)
    and the result print is so small.

    i dont know what the problem is.
    is me wrong the setting, or the driver not support..

    please kindly you can help me scruss

  28. The print width is 48 mm. You can’t go larger than that. Check your paper size again. Use zero margins. The printer has a fixed 5mm margin left and right that you can’t change.

  29. Hi scruss,

    Regarding PRJ-58u that i ask..
    when i print the test page. it works normal..

    but, i have a Queue Software that installed in my ubuntu. and looks like the software it not compatible with PRJ-58u. so, when the software do a execution for print..
    the result is so small.. i cant edit/setting it, because i’m no understand at all

    maybe some advice for me to setting scruss?

    btw. my vendor software advice me to use epson tm82. but its my very last option.

  30. If you have a commercial vendor, go to them for support. I’m not getting paid to fix this. You’re making money from this.

    I’m pretty sure I know exactly why they recommend a TM-82, and if they’re requiring you to use that, the smaller PRJ-58u won’t work the way you want.

  31. Hi! The driver works with all my thermal printers… but in all of them there is a top margin that shifts all the printed content down. The printer cuts the paper before the end (i think it cuts the paper at the calculated content height), then prints the remaining content and cuts again.

    Do you know how can I resolve this?

    Thanks and bye!

  32. CUPS doesn’t really handle continuous stationery very well. Can you pick one of the longer pages so that your entire content stays on the one ‘page’? It’s not too hard to modify the PPD to add longer pages. They’re a fairly horrible format to edit, though.

    There’s always a smallish hard margin at the top of the page. Make sure you print with zero margins, max page width 48 mm (ZJ-58) or 72 mm (ZJ-80)

  33. Thanks for this guide! I’m running into a weird issue trying to run this driver with the Adafruit mini serial printer on a Raspberry Pi, though. I can get text content printed reliable (both with the `lp` command and directly echoed over serial). But, when I try to print an image using your example command here, or when I try the “print test page” button, I get about one line correct and then random characters. I’m pretty sure it’s not the baud rate, since I’ve double checked that it matches the debug sheet that came with the printer and since I can get one line to print out, but I’m at a loss for what it could be. I’ve tried this now with two different Pis, but I only have one printer to test with.

  34. Hi Scruss, my name is Duvan, I am from Colombia in South America, I am writing to thank you for this work “Thermal Printer driver for CUPS, Linux, and Raspberry Pi: zj-58”, I had many problems with a reference POS printer ISH58 on an RPI3 and thanks to your tutorial I was able to do it easily and earn a little money. I wonder if you could send me your paypal account to share a bit of the earnings.
    Thank you very much for your help and I hope you are well in these difficult times for humanity.

    PS: Sorry for my bad English.

  35. just for a placeholder for the used Epson TM-T88III I bought:

    * nonstandard 38400 baud rate: stty -F /dev/ttyUSB0 38400 cs8 -cstopb -parenb crtscts

    * sorta print something with page cut: echo -e ‘****\nHello I am thermal printer\nGood day to you all\n**************\r\n************\r\n\r\n\r\n\r\n\r\n\r\n\x1dV\x00\x30’ > /dev/ttyUSB0

    * According to Paul Rickards, Citizen CBM-1000 driver works (mostly) –

  36. Hello, it has been passed much time but I would like to thank you for this article.
    I was almost giving up to use a pos58 cheap printer I had bought. But using this it worked.

  37. hello, can you help me to integrate the Black copper bc105 printer with raspberry pi 4b, I m facing a lot of issues like driver, command etc

  38. No, because I don’t have one. I can’t find a manual, but it claims ESC-POS compatibility. It does use a different print width from the typical printers mentioned here, so it might need a completely different driver.

Leave a comment

Your email address will not be published. Required fields are marked *