Friday, February 13, 2015

Mobile Bluetooth Printing, Linux Command Line Edition

I recently picked up a DL58 mobile Bluetooth thermal printer and got it working with Android. I'm on a Linux kick, so I was curious if I could get the device to work from there.

The first step was to discover and pair the printer with my Linux box. There seem to be a number of different tools and methods for doing this. I found that the basic pairing process was easily accomplished using bluetoothctl. Though, it wasn't quite obvious where to go from there.

I made one leap forward when when I discovered that I could connect the rfcomm device to the printer, using something like this command:

  sudo rfcomm connect DL58 00:14:01:03:5A:26

When I did this, the printer chirped to life and printed out these lines of text:

Wait a second, those are AT commands--I recognize them from my old modem days. I read this as follows: the printer was reporting that I had a serial connection to it and it was awaiting the proper set of AT commands.

I went back to the eBay seller: did they have these AT commands documented? Alas, they didn't. Well that's too bad.

I put the printer down for a couple days and tried again. This time I happened to run an lsof and found that a program, ModemManager, had the rfcomm device open. Wait a second: I was reading the above conversation all wrong. The system saw rfcomm device come on line and ModemManager sent it some AT commands to try to get it configured. The printer, being a printer, printed the commands.

I disabled ModemManager by running sudo systemctl disable ModemManager. I then rebootd the system and ran the following commands:

sudo hciconfig hci0 up
sudo hcitool scan
sudo rfcomm bind DL58 00:14:01:03:5A:26
sudo chmod a+rw /dev/rfcomm0

I was then able to execute:

  echo Hello World > /dev/rfcomm0

And printer spat out Hello World. Success!

Because the printer follows one of the core principles of Linux (treat everything like a file), it's trivially to script. For example, I can enter the following to print a quippy statement:

 (fortune -n 50 ; echo ; echo ; echo) > /dev/refcomm0

The -n keeps fortune from generating an especially long message, and the extra echo's serve to advance the paper.

Here's a slightly more realistic example: Shira's headaches are often tied to changes in barometric pressure. I created the script below to capture the current pressure in our area. I can then kick off the following command line:

bpressure > /dev/rfcomm0 ; \
while sleep 20m ; do bpressure  > /dev/rfcomm0 ; done

The result is an old timey ticker tape of barometric pressure data. Here's one run:

I'm telling you, this Linux stuff is addictive. Could I have written the above code on Windows? Probably. Would it have taken me a matter of minutes, definitely not. I'm still not 100% sure I'll find a use for the DL58 printer attached to my Linux box, but I'm super impressed at how easy it is to leverage it.

My bpressure script which prints out the current barometric pressure:

#!/bin/bash

##
## Print out our barometric pressure
##

LAST_FILE=$HOME/.bpressure
touch $LAST_FILE

pressure=`curl -s 'http://api.openweathermap.org/data/2.5/weather?q=Arlington,VA,USA&units=imperial'| jq .main.pressure`
last=`cat ~/.bpressure`

scale() {
  echo "scale=0 ; $1 * 1000" | bc | sed 's/[.].*//'
}


if [ -z "$last" ] ; then
  sym='!'
else 
  now_value=`scale $pressure`
  last_value=`scale $last`
  if [ $now_value -eq $last_value ] ; then
    sym='='
  elif [ $now_value -gt $last_value ] ; then
    sym='^'
  else
    sym='v'
  fi
fi

echo $pressure > $LAST_FILE
echo "$sym $pressure" 

1 comment:

  1. Hi,
    thank you for nice how to. On your printer receipt I can see that there is time and date stamp and then pressure. I done everything it is working but on receipt show only pressure. No time and date. Can you help me setup date, time and pressure. Or maybe there is possibility to show temperature?
    Thank you in advance.

    ReplyDelete