====== 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