Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VEVOR Y43BT label printer on Linux

Driver stack for a VEVOR Y43BT 4x6 thermal label printer (USB 5958:0041, vendor string Yxwl) on Arch Linux with CUPS. It renders PDFs and images to TSPL and prints them, both from the shell and from any application's Ctrl+P.

The VEVOR branding appears nowhere on the device - only in the Windows driver - so 5958:0041 / Yxwl is how you actually identify it.

What it is

The printer speaks TSPL at 203 dpi. A 4x6 label is 800 x 1200 dots of printable area (the full label is 812 x 1218). It has two USB interfaces: interface 0 is a small mass-storage "Driver" partition holding a link to VEVOR's download page, interface 1 is the actual printer.

file role
print-label.py renders a PDF/image to a 1-bit 800x1200 bitmap and wraps it in TSPL
cups/rastertoy43bt CUPS filter: PDF on stdin -> TSPL on stdout
cups/y43bt.ppd PPD declaring 4x6 media, 203 dpi, and the filter hookup
install.sh installs all of the above and creates the queues
shell/y43bt-aliases.zsh label, labeldark, labelpv, ...

Install

./install.sh

Requires cups, poppler (for pdftoppm) and a system-wide python-pillow. Pillow must not be a --user install: the filter runs as the cups user and will not see it.

Use

label shipping.pdf              # print, calibrated defaults
label shipping.pdf -d 13        # darker
label shipping.pdf -n 2         # two copies
labelpv shipping.pdf            # render a preview PNG, print nothing

Or just hit Ctrl+P in any application and pick Label_4x6, which the installer sets as the system default.

Calibration

Settled on DENSITY 11 / SPEED 2.

Density is the "heat" setting, DENSITY 0-15, higher = darker.

Judge a density change by the small return-address text rotated 90 degrees in the top-right corner, not by the barcode. Those strokes are 2-3 px in both directions and merge before anything else on the label does. The barcode's narrowest real gap is a forgiving 2 px - far wider than a synthetic Code128 test suggests.

setting result
DENSITY 10 read faint
DENSITY 11 / SPEED 3 over-corrected, thin and over-separated
DENSITY 12 / SPEED 2 still bled the rotated strokes shut
DENSITY 13 merged those strokes badly
DENSITY 11 / SPEED 2 settled here

Prefer lowering SPEED over raising DENSITY. The head fires a whole dot row at once, so vertical spacing comes from paper feed; rotated text is drawn by feed motion, where dwell time sharpens strokes while extra heat merely spreads them.

Change ONE of density / render-pipeline at a time. Dropping density and removing a resample step together compounded and overshot, costing a round of calibration.

Bleeding is a heat problem, not a rendering problem. The 1-bit bitmap keeps those strokes cleanly separated at thresholds 128, 110 and 90, and even 90 removes only ~13% of the black. Only DENSITY and SPEED move it. The 2D DataMatrix is fully threshold-independent - identical black-pixel count at every cutoff - so --threshold will never help it either.

PDFs are rasterised straight from their vectors at the final pixel size (pdftoppm -scale-to-x/-scale-to-y) rather than rendered at 203 dpi and resampled. Measured on a Code128 test, resampling fattened bars ~4% (134 vs 129 black px per scanline). Don't reintroduce a LANCZOS resize for PDFs.

Why two queues

install.sh creates two queues pointing at the same device:

queue type used by
VEVOR_Y43BT raw print-label.py, which sends TSPL with lp -o raw
Label_4x6 driver (PPD) system default; every GUI app

This is forced, not tidiness. CUPS 2.4 silently drops -o raw jobs sent to a queue that has a PPD attached. Attaching the PPD to the raw queue breaks print-label.py with no error anywhere: the job logs Job completed in the same second it was queued, no backend is ever started, and zero bytes reach the device. If label ever goes silent, check that nothing attached a PPD to the raw queue.

Gotchas

  • *cupsFilter2 is required in the PPD, not just *cupsFilter. With only the latter, cups-filters reads the PPD as a PostScript device and routes the job through pdftops, which fails.
  • The filter must re-suffix its input .pdf. As the last filter in the chain it receives data on stdin, or a spool file named like d00008-001 - either way with no extension. print-label.py picks its PDF path by extension, so without this Pillow tries to open a PDF as an image.
  • CUPS runs filters as the cups user (uid 209), not lp. sudo -u lp fails with "unknown user"; lp exists only as a group.
  • The renderer cannot live in a 0700 home directory - the cups user cannot traverse it. It installs to /usr/local/lib/y43bt/ with a symlink from ~/.local/bin/, so both paths share one file and the density defaults cannot drift apart.
  • --preview still prints. It saves the bitmap in addition to printing. Only -o suppresses the job; labelpv passes both.
  • This printer answers no status queries. Every TSPL status form tried (~!@, ~!T, ~!F, ~!I, and the ESC forms) returns nothing, despite the USB descriptor advertising bidirectional support. Infer state from the CUPS queue instead.

Testing without spending labels

Render only, no print:

print-label.py label.pdf --preview /tmp/out.png -o /dev/null

To exercise the whole CUPS chain, point a scratch queue at a file:

echo 'FileDevice Yes' | sudo tee -a /etc/cups/cups-files.conf
sudo systemctl restart cups
sudo touch /tmp/cap.out && sudo chmod 666 /tmp/cap.out   # backend won't create it
sudo lpadmin -p TEST -v file:///tmp/cap.out -P /usr/share/cups/model/y43bt.ppd -E
lp -d TEST label.pdf
head -c 60 /tmp/cap.out        # expect: SIZE 4.0,6.0 / DENSITY 11 / SPEED 2

Remember to remove the queue and the FileDevice line afterwards.

cupsfilter is not a valid test. It resolves PPD filters differently from the daemon and fails on a chain that works correctly under cupsd.

About

TSPL driver stack for the VEVOR Y43BT 4x6 thermal label printer on Linux: renderer, CUPS filter, PPD and installer

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages