Using the Brother P-touch PT-2730 with Ubuntu 14.04 LTS

Sep 23, 2014 13:10


The Brother P-touch PT-2730 PC-Connectable Labeling System isn't supported on Linux. There's a CUPS driver for some P-touch models (via the printer-driver-ptouch package), but this isn't one of them, and trying to substitute a "similar" driver won't actually work - it will simply feed blank tape and frustrate you.

So, I looked at what their Windoze software generates, and it turns out to be incredibly simple, and quite easy to replicate.

Basically, the PT-2730 is a 180dpi monochrome raster printer that can output rows up to 128 pixels wide. It also has a cutting mechanism. That's all there is to it. None of the built-in fonts, label templates, etc. are accessible. You have to render your own bitmaps.

It connects to the host computer via USB; its ID is 04f9:2041. usb_printerid (included with printer-driver-foo2zjs) returns

GET_DEVICE_ID string:
MFG:Brother;CMD:PT-CBP;MDL:PT-2730;CLS:PRINTER;
Variables

The printer accepts TZ tapes in six of the seven standard widths: 24mm/.94", 18mm/.70", 12mm/.47", 9mm/.35", 6mm/.23", and 3.5mm/.13". (36mm/1.4" tape will not fit.) 3.5mm tape is relatively uncommon; it's used for things like the spines of CD jewel cases. These are continuous rolls, so labels don't have a fixed length.

There are four checkbox options:
Auto Cut Multiple labels are normally printed consecutively, with only a single cut at the end of the job. When auto cut is enabled, cuts are also made [before and] between each label. Chain Printing This option suppresses tape feed at the end of the job, reducing waste. Special tape (no cuts) Disables the cutting mechanism; overrides Auto Cut and Chain Printing settings. Mirror Printing Flips each row.
The above descriptions are unofficial, and possibly incorrect.

The manufacturer's driver also offers a "fake" option to "trim" labels; this only affects the raster generation, and works by cropping any blank rows at the very end.
Data Stream

You can send this directly to the device, which typically attaches as /dev/usb/lp0. (By default, only root and members of the "lp" group have access.) Bytes are given in hex; ## varies.
At the start of a print job (do this once)

1B 40 (Initialize)

Unlike some other P-touch models, you do not precede this with NUL bytes.
For each label within a job

Send these commands in this order:

1B 69 63 84 00 ## 00 00 (Print information command)

## is the target tape width in mm; valid choices are 04, 06, 09, 0C, 12, and 18. (04 is used for 3.5mm tape.)

1B 69 4D ## (Various mode settings)

## is bitmapped: 40 = auto cut, 80 = mirror

1B 69 4B ## (Advanced mode settings)

## is bitmapped: 08 = no chain printing, 10 = special tape

You read that right: the 08 bit is inverted.

1B 69 64 ## ## (Specify margin amount)

## ## is 16 bits, little endian: the permissible range is 0E 00 (.08") to 7D 03 (4.96").

This value is applied twice: once at the beginning of the label, and again at the end.

4D 02 (Select compression mode)

This specifies run length encoding.
The raster

Each row consists of:

47 ## ## {n bytes of compressed data}
-or- 5A

There are 128 pixels in each row, which means each one is represented as exactly 16 bytes. 24mm tape uses the full width; narrower tapes are centered in the print area. You still need to send 128 pixels regardless, but the unavailable left and right pixels must be zeroed to avoid damaging the mechanism.

24mm: use all 128 dots
18mm: 8-MBZ 112-dots 8-MBZ
12mm: 29-MBZ 70-dots 29-MBZ
8mm: 39-MBZ 50-dots 39-MBZ
6mm: 48-MBZ 32-dots 48-MBZ
3.5mm: 55-MBZ 18-dots 55-MBZ

The printhead is upside down, so the leftmost pixel in the raster prints the rightmost dot (and vice versa). Of course, if you set the mirror bit, it's the other way around.

Each 16-byte row is compressed using PackBits. ## ## is 16 bits, little endian. If a row is completely blank, 5A is substituted unless it's the very first row, which always uses the RLE representation (i.e. 47 02 00 F1 00). The worst-case encoding is 47 11 00 0F followed by 16 literal (i.e. uncompressed) bytes.

PackBits is easy to decode: 00-7F means 1-128 literal bytes follow; 81-FF subtract that from 257 decimal and repeat the next byte that many times; 80 you skip and do nothing. Optimal encoding is a little tricky: see the explanation in the TIFF 6.0 specification. What I ended up doing coalesces adjacent one- and two-byte runs, and then substitutes a series of repetitions if the resulting literal would consist entirely of matched pairs.

Rasters will typically have two blank rows at the end unless the user selected the "trim" option. However, the minimum length allowed for a label is 31 rows (the maximum is 7086). You may also want to insert additional blank rows at the beginning; you'll have to experiment with this to see what works best.
Trailer

0C (Print command)
-or- 1A (Print command with feeding)

Use the first command if another label immediately follows this one; use the second if there are no more in this job.
"But I just want it to behave like a normal printer!"

Next: What went wrong with printer-driver-ptouch, coping with CUPS, and why nothing is as simple as you think it should be.
Previous post
Up