====== Ptouch - Brother Label Printers - your own "driver" for Linux ======
Requirements: Ruby langugage interpreter and ImageMagic convert program to generate images.
For Debian based Linux system (Ubunutu) run as root
aptitude install ruby imagemagick
Tested printers PT-2420Pc, PT-18R and [[http://www.brother-usa.com/Ptouch/ModelDetail/7/PTP750W/Overview#.VZZr8kYpBGo|PT-P750W]]
Copy the following ruby sourcecode file and place it wherever. Name the file however you like. For example //ptprint.rb//
Add add the running privileges to the file
chmod +x ptprint.rb
Also see the instructions on the beginning of the source ruby file and edit the printer's name first.
And finally print the labels.
ptprint.rb "This is a text I want to be printed on a label"
If you want to print on more then one line do
ptprint.rb "This is a first line\nthis a second line\nthird line"
here is the source code of //ptprint.rb//.
#!/usr/bin/env ruby
# encoding: ASCII-8BIT
# Install the printer using CUPS as a raw printer - no driver will be used,
# The manufacture of Raw printer is Raw and the printer gets what is sent.
# If the CUPS can not find the printer, press the Plite button for few seconds to disable flash drive mode and enable printer mode.
# Set the printer name you have chosen
PRINTER_NAME="Brother_raw"
# See installed printers and its names by issuing command lpstat -p -d
if ARGV[0]==nil
puts "I expect one parameter which is text to be printed on a P-touch Label printer"
puts 'If you want to print a text over more then one line, use "\n" as new line marker.'
puts
puts "For more information about this simple script see http://www.odorik.cz/w/ptouch "
exit
end
# The width of the image (in pixels) should be divisible by eight to be a whole byte.
# The parameter -size x128 is suitable 24mm tape. If your use smaller tape lower the image width
# If you change the tape width, you may want to change the image width.
# For example 6mm tape may be best with 32,40 or 48 pixels (bits).
# The maximal width depends on printer model and for tape PT printers is usually 128 bits.
`convert +antialias -background white -fill black -size x128 -gravity South -rotate 90 label:"#{ARGV[0]}" image_to_be_printed.pbm`
# +antialias turns antialiasing off (not on as one would guess). The rendering is more smooth with certain versions of ImageMagick package.
# Of course you can create image with any program you wish. Or create a pdf or PostScript file and convert
# it with ghostcsript to image.
# gs -sOutputFile=label.pbm -sDEVICE=pbmraw -g720x$::LABELLENGTH -dNOPAUSE -dBATCH label.ps
def readImage(image_name)
# reads the width, lenght and pbm image data into memory
obrazek=File.open(image_name,"rb").read # we read the whole image content
# now we start to parse the content
puts "if the image is in pbm format, first two bytes of this binary file should by characters P4:#{obrazek[0..1]}"
# after P4 there should be at least one white space, so we can continue with char no 3
n=3
# If we create the pbm file with Ghostrcips, we may expect a note starting with #
# gs -sOutputFile=label.pbm -sDEVICE=pbmraw -g720x$::LABELLENGTH -dNOPAUSE -dBATCH label.ps
if obrazek[n]=="#"
puts "poznamka #{poznamka_zacatek=n}"
while obrazek[n]!="\n" do n=n+1; end
puts "poznamka konec#{poznamka_konec=n}"
puts "poznamka=#{obrazek[poznamka_zacatek..poznamka_konec]}"
n=n+1
end
puts "zacatek_sirky:#{zacatek_sirky=n}"
while ! /\s/.match(obrazek[n]) do n=n+1; end
puts "konc_sirky #{konec_sirky=n}"
puts "image width:#{sirka=obrazek[zacatek_sirky..konec_sirky].to_i}"
puts "sirka_v_bytech:#{sirka_v_bytech=sirka/8}"
while /\s/.match(obrazek[n]) do n=n+1; end
puts "zacatek_delky:#{zacatek_delky=n}"
while ! /\s/.match(obrazek[n]) do n=n+1; end
puts "konec_delky:#{konec_delky=n}"
puts "image length:#{delka=obrazek[zacatek_delky..konec_delky].to_i}"
while /\s/.match(obrazek[n]) do n=n+1; end
puts "image bitmap start #{zacatek_obrazku=n}"
return obrazek,sirka,sirka_v_bytech,delka,zacatek_obrazku
# orazek- picture, sirka- width, sirka_v_bytech - width in bytes, delke - length, zacatek_obrazku - the beggining of the picture
end
# Lets initialize the printer
data = "\x00"*100 # It seems that sending zeros before we start may help if the last printing operation did not finish correctly.
data << "\x1B@" # Initialize
#data << "\x1BiS" # 69H 53H the printer returns its state. We don't need this
data << "\x1BiM\x40" # auto cut
data << "\x1BiK\x08" # half cut off, no chain printing (cut at the end of printing).
data << "M\x02" # Compression? Don't understand this but the web checker at https://9cb21392cee7550e9d82f3f871ce806316582628.googledrive.com/host/0B7Vet6dn3-Gwd3BKVmwzR0pjU0E/index.html works better when I set the compression on.
obrazek,sirka,sirka_v_bytech,delka,zacatek_obrazku=readImage("image_to_be_printed.pbm")
radek=0 # we start sending the pixel data line by line, starting from top going down
while radek
The image to be printed is created using program "convert". However you can create your initial image by any program, for example inkscape or convert it from postcript using gs. Just change the code above a little.
There is also an [[http://www.openprinting.org/driver/ptouch/|opensource ptouch driver for cups]] , which is probably distributed with your Linux distribution. However the driver does not always work, is very difficult to troubleshoot and seems not to support continuous roll - varying page length. The driver was not updated since 2009 and did not work for me.
The Ruby script above is very easy to trouble shoot as anything which may be wrong is located only on few lines of code.
===== Trouble shooting =====
[[http://www.undocprint.org/formats/page_description_languages/brother_p-touch|See the unfilial short, but very transparent documentation.]]
Or see the official, not so transparent and not complete documentation of some models. (similar to other models where official documentation is missing)
[[http://download.brother.com/welcome/docp100064/cv_pte550wp750w_eng_raster_100.pdf|PT-E550w/P750w]]
[[http://download.brother.com/welcome/docp000678/cv_qlseries_eng_raster_600.pdf|QL series]]
[[http://etc.nkadesign.com/uploads/Printers/95CRRASE.pdf|PT-9500PC]]
[[http://etc.nkadesign.com/Printers/QL550LabelPrinterProtocol|See instructions for similar QL-500/QL-550 printers]]
[[http://etc.nkadesign.com/Printers/QL550LabelPrinterPerl|You can also see similar but more complex and complicated program in perl]], [[http://apz.fi/blabel/|blabel in perl (did not work for me)]]
To see a working example of what exactly can be send to your exact printer model, install the [[http://sourceforge.net/projects/usbsnoop/|SnoopyPro]] usb Sniffer for Windows. SnoopyPro is opensource.
{{:obrazky:snoopypro_usb_devices_brother.png|Choose the appropriate item to be monitored}}
{{:obrazky:snoopypro_usb_device_brother_capture_raw_send_data.png|}}
Also if you use option "print to file" under Windows you get the binary prn file you can examine.
However ptouch editor does not support printing to file and using a different program may not be optimal.
Therefore using the SnoopyPro may be your best choice. Print the empty small page or page with just one dot and see what has been send.
To examine binary files under Linux you can use GUI HEX editor //bless// or console alternative //dhex//.
===== Which printer is /dev/usb/lp0 ? =====
For USB printer may work:
aptitude install foo2zjs
usb_printerid /dev/usb/lp0
The command above returns for example:
GET_DEVICE_ID string:
MFG:Brother;CMD:PT-CBP;MDL:QL-500;CLS:PRINTER;
Some printers may not be detected.
===== CUPS does not detect my old printer =====
Brother USB printers do not have this problem, they are detected fine, you can skip this part if all your printers are detected fine.
If you have printer connected to "usb to parallel adapter", or your printer is very old, CUPS will not recognize your printer as the printer may not send any identification details.
To see connected USB devices issue
lsusb
To see which printers can be detected on your system, issue
lpinfo -v
If CUPS does not detect your printer, you can add it manually.
You have to enter the printer URI manually. The printer will be one of the /dev/usb/lpX files,
depending on the order as they got connected. See below how to create a special dev file for your special printer which des not depends on the turn on order. Then you can use this new file name instead.
For adding printer to CUPS manually you will use CUPS URI like : parallel:/dev/usb/lpX .
Go to http://localhost:631 CUPS add printer dialog: „Other Network Printers→LPD/LPR Host or Printer“ (weird or what?), pasted „parallel:/dev/usb/lp0“ into the „Connection“ (URI) field and followed the prompts.
**However if you do not need to use the CUPS driver, you can avoid using CUPS all together and send data to be printed directly to the printer's dev file.**
===== I want my printer to have always the same dev file name =====
If you have more then one printer, /dev/usb/lp0 will be the printer which was turned on as first.
So the name of the automatically created dev created for your special printer may be different each time.
To have always the same dev file for your special printer you need to add an udev rule.
Run.
udevadm info -a -p $(udevadm info -q path -n /dev/usb/lp0)>lp0_info.txt
udevadm info -a -p $(udevadm info -q path -n /dev/usb/lp1)>lp1_info.txt
vimdiff lp0_info.txt lp1_info.txt
See atributes which differs. Best are those which reminds you random hash.
ATTRS{serial}=="0000:00:1d.0" may not be enough as I have find out that two different devices may have this same serial number.
To make sure one dev file represents always the same printer, you can add udev rule using one of the
attribute.
For example:
vim /etc/udev/rules.d/99-printer.rules
Příklad obsahu souboru:
SUBSYSTEM=="usb", ATTRS{modalias}=="usb:v067Bp2305d0200dc00dsc00dp00ic07isc01ip02" , SYMLINK+="dot0"
SUBSYSTEM=="usbmisc", ATTRS{product}=="PT-2420PC" , SYMLINK+="labelprinter0"
SUBSYSTEM=="usbmisc", ATTRS{product}=="IEEE-1284 Controller" , SYMLINK+="dot0"
SUBSYSTEM=="usbmisc", ATTRS{product}=="EHCI Host Controller" , SYMLINK+="dot0"
SUBSYSTEM=="usbmisc", ATTRS{product}=="xHCI Host Controller" , SYMLINK+="dot0"
This creates file /dev/dot0 for our dotmatric printer connected to usb-parallel adapter.
[[http://www.reactivated.net/writing_udev_rules.html#example-printer|See other udev examples]]
To test new rules without rebooting
udevadm control --reload-rules && udevadm trigger
usbreset 1a86:7584
udevadm test /dev/usb/lp1
The printer which should have access to thouse special dev file needs to be added in the group lp.
Run
usermod -a -G lp user_name_to_use_this_printer
And relogin. (su su user) Check that new group is loaded by cammand //groups//
Now you can send the printing data directly to the /dev/dot0 file instead of to a raw printer using cups.
Other example of changing udev rules: http://unix.stackexchange.com/questions/60154/udev-rule-file-for-modem-not-working
ls /dev/serial/by-path/
udevadm trigger
udevadm info /dev/ttyUSB4|grep ID_PATH
http://superuser.com/questions/536478/how-to-lock-device-ids-to-port-addresses
udevadm test $(udevadm info -q path -n )
===== One click to print from your web page =====
If you want to be able to create links on your web page which will enable you to print just by clinking on them, create your special URL.
Your new URL, for example print:/ /text_to_be_printed will call your local script to the printing job.
[[https://translate.google.com/translate?sl=cs&tl=en&js=y&prev=_t&hl=cs&ie=UTF-8&u=http%3A%2F%2Fwww.odorik.cz%2Fw%2Fsiptapi%3Aregistrace_protokolu&edit-text=&act=url|See my working example how to create your own URL to run a script to activate Callback.]]
====== This simple driver is not enough? ======
Choose label printer manufacturer which fully supports Linux. [[http://var.dymo.com/UK/resources/sdk/linux/|Dymo printer seems to be fine.]]
====== Receipment thermal printer ======
http://www.aliexpress.com/item/freeshipping-black-USB-Port-58mm-thermal-Receipt-pirnter-POS-printer-low-noise-printer-thermal/32476628487.html
Manufacturer http://www.zjiang.com/support.asp?action=art&page=1