Thursday, February 12, 2015

Thermal Nuclear Bluetooth Printing on Android (minus the nuclear part)

Inspired by this photography idea, I picked up a thermal Bluetooth printer from eBay. Specifically, a model DL58. I was impressed with the Chinese company that sold it to me; my request for access to the SDK was immediately and fully met. While I've got big plans for the printer, the first order of business was to get it printing basic text.

I don't really have any experiencing developing with Bluetooth devices, so I wasn't quite sure what I was in for. Thankfully, the device was discovered and paired with my phone without a hitch (pairing PIN: 1234). The first version of the SDK the eBay seller provided had the printing code wrapped up behind a shared native library. When I couldn't get this to work, the eBay seller provided an updated version of the code. This time, I could see that all the system was doing was making a Bluetooth socket connection to the device and sending text over the socket. Well that's easy enough. The printer does handle images too, and those are sent using some sort special binary header. That's something I'll be figuring out soon enough.

I then went to work taking my new found lessons in Bluetooth printing and turning them into a super simple app. I give you: DropPrint. DropPrint watches the directory /sdcard/DropPrint and when new files are discovered it prints them. Right now, DropPrint only understands two types of file: txt and scm files. I plan to also have it support image files, as well as bar code files (store "foo" in foo.qrc, and a qrcode with the contents "foo" get printed).

There's not much to DropPrint, but here's the requisite screenshot:

DropPrint's handling of txt files is obvious enough. But surely you're wondering what a scm file are all about. Well, it is what you think it is: Scheme file handling.

See, I implemented DropPrint in Kawa Scheme. That makes it trivial to read, eval and literally print scm files. For example, I can drop the following code in DropPrint/fib.scm:

 (define (dec x) (- x 1))
 (define (fib x) 
  (cond ((= x 0) 1)
        ((= x 1) 1)
         (+ (fib (dec x)) (fib (dec x))))))
  (let loop ((i 0))
   (cond ((= i 10) 'done)
          (display i)
          (display " = ")
          (display (fib i))
          (loop (+ i 1))))))

A few moments later, the printer spits out the following:

(Beware: it intentionally deletes the files after printing them)

In the bits-and-bytes world I live in, to actually have something physical generated is amazingly cool.

As implementation languages go, I'm very much warming up to Kawa. It's certainly far more satisfying to use for this sort of project than say PhoneGap, which has a huge number of layers to get to (HTML, JavaScript, PhoneGap code and core Java Code to name a few) before you can work with core Android APIs. I'm not yet sure I can make the case that Kawa is generally better for app development then Java itself, though, with time I'm sure I'll get there. I'm certainly finding it a heck of a lot of fun to program in.

Now that I've got basic printing working, it's time to turn my attention to images. Stay tuned...


  1. Anonymous7:31 AM

    I know exactly what you mean with the amazement of being able to generate something physical! Very nice indeed.

    PS: If your fib function is actually supposed to print the fibonacci numbers rather than powers of two, I believe you want "(+ (fib (dec x)) (fib (dec (dec x)))))))" in place of "(+ (fib (dec x)) (fib (dec x))))))"

  2. > I believe you want "(+ (fib (dec x)) (fib (dec (dec x)))))))" in place of "(+ (fib (dec x)) (fib (dec x))))))"

    D'oh -- good catch. I was just satisfied to see the printer generate a sequence...I should have paid closer attention to the exact sequence being generated.