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

Update:build instructions have changed, 2019.

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

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 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 loan 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.

85 thoughts on “Thermal Printer driver for CUPS, Linux, and Raspberry Pi: zj-58”

  1. 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?

  2. 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.

  3. 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:

  4. 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?

  5. 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?


  6. 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.

  7. 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!

  8. 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?

  9. 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

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

  11. 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 ?



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

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

  14. 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).

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

  16. 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

  17. 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

  18. 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)

  19. 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?

  20. 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.

  21. 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…

  22. 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.

  23. @ 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!

  24. 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?

Leave a Reply

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