Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communicate with and control a printer device via bluetooth or USB

The device is a label printer. It can be connected to via bluetooth and USB. I would imagine it is running some kind of linux, as it has a fairly complex interface/screen, but am not sure. In fact, this is something I would like to determine. But my goal is to get a shell, or some kind of 'meaningful' connection through which I can send commands/data which will trigger print events by the printer without using the manufacturer's software

Connecting to the device in ubuntu via USB creates /dev/usb/lp0. I tried connecting to this using python's serial module, but it couldn't connect to the serial port.

Via bluetooth I was also able to connect, using hcitool scan to get the device's MAC address and then rfcomm to connect (using this approach) . This created /dev/rfcomm0, which I was able to connect to and send data to using python.

Is it feasible to mimic the data normally sent over usb/bluetooth by the manufacturer's software to print without the software? I assume getting this would be possible by 'sniffing' data sent over bluetooth while a normal print command is sent by the manufacturer's software (although I suppose there's no reason it would look intelligible to a human).

If this kind of mimicry is possible, I am wondering whether simply sending the equivalent data over bluetooth, for example, would result in a print event. So far I have no reason to believe that data I send via the bluetooth connection is not being received, but I have yet to get any kind of response (data or physical) from the bluetooth connection.

Any advice/suggestions on how I might achieve my overall goal would be appreciated

like image 757
Ryan Avatar asked Oct 30 '22 13:10

Ryan


2 Answers

This is certainly possible (sorry for the answer 6 years later, but hopefully this will help anyone later in need). I have a similar problem and this is how I solved.

I have a MHT-P80F thermo printer. I figured out in settings that it supports a protocol called TSPL. These are the instructions you need to send to a printer and tell it to do either raw text printing, or even bitmaps.

All you need to do is to construct the correct bytestream (in mostly human-readable ASCII) and send it to /dev/usb/lp0. I have not tested it via bluetooth but I assume it should be similar.

For example, if you want to print out a "Hello World", these instructions will suffice:

CLS
SIZE 80mm,50mm
GAP 5mm,0mm
HOME
TEXT 0,0,"0",0,1,1,"Hello World"
PRINT 1

Each line is separated by a "\n".

Explanations (more could be found by searching TSPL):

  • CLS Tell the printer to clear all previous staged commands.
  • SIZE Tell the printer the size of each label (width, height).
  • GAP Between each label there's 5mm space without paper.
  • HOME (Re-)locate the paper roll for a new print.
  • PRINT Start printing of 1 copie(s).

Note these instructions are for the use of discrete labels. For a whole paper roll it might be different. TSPL implementations on different printers may differ, so you might to experiment a bit.

Generally, if you can print a bitmap, then you can print virtually any document (e.g. using PIL in Python or Jimp in Node.js to generate an image beforehand). So here's the most useful BITMAP command:

BITMAP 16,24,40,256,0,<BYTE STREAM>

where

  • 16: the starting (left most) X coordinate for your bitmap
  • 24: the starting (top most) Y coordinate for your bitmap
  • 40: the width of bitmap, in BYTES (see below)
  • 256: the height of bitmap, in DOTS
  • 0: mode of print, 0 being overwritting anything in that region

and <BYTESTREAM> being the binary data(black/white) of this image, from left to right and from top to bottom.

The bitmap width is given in bytes, so each byte represents 8 horizontal continous dots in the image. The highest bit 7 being most left, the lowest bit 0 most right. So if as in example we write 40 in this parameter, the image would be 40x8=320 dots in width.

The bitmap height, on the contray, is given in dots.

Most such thermal printer have a DPI of 203. This is an interesting start point to investigate into: 203/25.4 = 7.99, or rounded as 8. So for the printer, each 8 dots equals 1mm. In the above example, X=16 and Y=24 (both in dots) corresponds to starting location X=2mm and Y=3mm.

And finally, you generally do not need to inverse the color of this image. In BITMAP command, a 1 in a bit means correctly white or non-printed dot, and 0 means the black or heated dot.

like image 183
Chaobai Li Avatar answered Nov 09 '22 05:11

Chaobai Li


I am not sure about bluetooth but for USB printing you can use the cups library (licups) and use the APIs to do the priting. It uses IPP protocol. Usually cups uses a .ppd file specific to the printer (which contains the details about the printer) for installing it. For new language versions such as PCL5, 5e, 6 etc there are generic ppd files that can be used to install any printer that uses the respective language

like image 40
Ison Thomas Avatar answered Nov 09 '22 05:11

Ison Thomas