Das Problem

Du steckst einen Brother PT-1230PC per USB an deine Linux-Kiste. lsusb zeigt ihn brav:

Bus 003 Device 036: ID 04f9:202c Brother Industries, Ltd PT-1230PC P-touch Label Printer E mode

Und dann beginnt der Spass. Du installierst printer-driver-ptouch, richtest CUPS ein — und bekommst Hieroglyphen mit horizontalen Streifen. Du kompilierst ptouch-print — zwei vertikale Striche. Du baust pt1230 — Error 0x08. Du versuchst ESC/P Textmodus — Totenstille.

TL;DR

Der PT-1230PC unterstuetzt keinen ESC i R Raster-Mode-Switch, den alle gaengigen Tools senden. Ausserdem hat er nur einen 64-Pixel-Druckkopf (8 Bytes Daten + 4 Bytes Padding pro Rasterzeile), waehrend die Tools 128 Pixel (16 Bytes) annehmen. Die Loesung: ein Python-Script das direkt ueber /dev/usb/lp0 die Rasterdaten im korrekten Format sendet.

Warum die Standard-Tools scheitern

ptouch-print

Das weit verbreitete ptouch-print erkennt den PT-1230PC und listet ihn als unterstuetzt. Es sendet aber:

  1. ESC i R 01 — Raster-Mode-Switch. Der PT-1230PC ignoriert das komplett.
  2. 16 Bytes pro Rasterzeile (fuer 128px Druckkopf). Der PT-1230PC hat nur 64px.

Ergebnis: Zwei vertikale Striche auf einem kurzen Bandstreifen.

CUPS rastertoptch

Der CUPS-Filter rastertoptch aus dem Paket printer-driver-ptouch produziert tatsaechlich Output — aber mit brutalem Striping. Die PPD-Datei definiert 12mm Band als 34 PostScript-Punkte breit (= 85 Pixel bei 180 DPI). Der PT-1230PC erwartet aber nur 64 Pixel. Jede Rasterzeile hat also zu viele Bytes, und die Daten verschieben sich zeilenweise.

pt1230 (cbdevnet)

Das dedizierte pt1230-Tool kennt das korrekte 12-Byte-Rasterformat (4 Padding + 8 Daten). Es sendet aber ESC i R 01 vor den Rasterdaten. Der Drucker antwortet mit Status 0x02 (Error) und Error-Byte 0x08. Laut Brother-Dokumentation ist Bit 3 “not used” — der PT-1230PC sieht das offenbar anders.

ESC/P Textmodus

Der PT-1230PC meldet sich als “E mode” (Editor), was ESC/P-Befehle impliziert. Text mit ESC @ + Font-Auswahl + Zeichendaten + FF senden: nichts passiert. Der Drucker hat zwar eingebaute Fonts laut Brother-Doku, reagiert aber nicht auf die Befehle. Moeglicherweise ist die ESC/P-Implementation auf dem PT-1230PC nur fuer den Windows P-Touch Editor gedacht.

Die Loesung

Voraussetzungen

# Kernel-Modul fuer USB-Druckerzugriff
sudo modprobe usblp

# ImageMagick fuer Text-zu-Bitmap
sudo apt install imagemagick

Das Script

#!/usr/bin/env python3
"""PT-1230PC direct label printer for Linux"""
import subprocess, os, sys

text = sys.argv[1] if len(sys.argv) > 1 else "Hello"

# Text zu 64px monochrom Bitmap konvertieren
subprocess.run([
    'convert', '-size', 'x64', '-gravity', 'Center',
    '-font', 'DejaVu-Sans-Bold', '-pointsize', '52',
    f'label:{text}',
    '-monochrome', '-flop', '-rotate', '270',
    '-depth', '1', 'PBM:/tmp/_pt_img.pbm'
], check=True, capture_output=True)

# PBM einlesen
with open('/tmp/_pt_img.pbm', 'rb') as f:
    f.readline()  # P4
    while True:
        line = f.readline()
        if not line.startswith(b'#'):
            parts = line.strip().split()
            width, height = int(parts[0]), int(parts[1])
            break
    raw = f.read()

bytes_per_row = (width + 7) // 8
job = bytearray()

# Init: 100 Nullbytes + ESC @ (KEIN ESC i R!)
job += b'\x00' * 100 + b'\x1b\x40'

# Rasterzeilen senden
for row in range(height):
    row_start = row * bytes_per_row
    row_bytes = raw[row_start:row_start + bytes_per_row]
    if all(b == 0 for b in row_bytes):
        job += b'\x5a'  # Leerzeile
    else:
        job += b'\x47\x0c\x00'        # Header: G + 12 Bytes folgen
        job += b'\x00\x00\x00\x00'     # 4 Bytes Padding (Pflicht!)
        data = bytearray(8)            # 8 Bytes Druckdaten
        for i in range(min(len(row_bytes), 8)):
            data[i] = row_bytes[i]
        job += bytes(data)

job += b'\x1a'  # Print + Feed

fd = os.open('/dev/usb/lp0', os.O_WRONLY)
os.write(fd, bytes(job))
os.close(fd)
print(f"Printed: {text}")

Installation

sudo cp pt1230_print.py /usr/local/bin/pt1230-print
sudo chmod +x /usr/local/bin/pt1230-print

Nutzung

sudo pt1230-print "Dein Label-Text"

Das Protokoll im Detail

Der PT-1230PC erwartet fuer 12mm Band:

ElementBytesHexBeschreibung
Init10000 00 ... 00Buffer leeren
Init21B 40ESC @ — Drucker initialisieren
Rasterzeile Header347 0C 00G + 12 Datenbytes folgen
Padding400 00 00 00Pflicht-Nullen (Druckkopfschutz)
Druckdaten8variabel64 Pixel, MSB links
Leerzeile15AZ — Kurzform fuer komplett weiss
Drucken11APrint + Band vorschieben

Wichtig:

  • KEIN ESC i R 01 (Raster-Mode-Switch) senden!
  • KEIN ESC i a 01 (Command-Mode-Switch) senden!
  • Das Bild muss gespiegelt (-flop) und um 270 Grad rotiert werden
  • usblp Kernel-Modul muss geladen sein (nicht entladen wie manche Guides empfehlen!)

Fazit

Der PT-1230PC ist ein guenstiger, weit verbreiteter Labeldrucker — aber unter Linux ein Albtraum. Keines der gaengigen Open-Source-Tools funktioniert korrekt, weil sie alle ein Protokoll annehmen, das dieser Drucker nicht spricht. Die Loesung ist ein 40-Zeilen-Python-Script das die Rasterdaten direkt im richtigen Format an /dev/usb/lp0 sendet.

Falls du einen PT-1230PC hast und unter Linux Labels drucken willst: Spar dir die Stunden mit CUPS und ptouch-print. Nimm das Script oben.

Referenzen