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:
ESC i R 01— Raster-Mode-Switch. Der PT-1230PC ignoriert das komplett.- 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:
| Element | Bytes | Hex | Beschreibung |
|---|---|---|---|
| Init | 100 | 00 00 ... 00 | Buffer leeren |
| Init | 2 | 1B 40 | ESC @ — Drucker initialisieren |
| Rasterzeile Header | 3 | 47 0C 00 | G + 12 Datenbytes folgen |
| Padding | 4 | 00 00 00 00 | Pflicht-Nullen (Druckkopfschutz) |
| Druckdaten | 8 | variabel | 64 Pixel, MSB links |
| Leerzeile | 1 | 5A | Z — Kurzform fuer komplett weiss |
| 1 | 1A | Print + 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 usblpKernel-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
- cbdevnet/pt1230 — Protokoll-Dokumentation (Tool selbst funktioniert nicht korrekt)
- ptouch-print — Unterstuetzt PT-1230PC offiziell, funktioniert aber nicht
- Brother P-Touch on Linux Guide
- Brother ESC/P Command Reference