Receipt printer hacking (by alaric)
So, for Christmas, I got a receipt printer. It's a Jepod JP-5890K, the important specifications of which being:
- Mains powered
- USB connectivity (appears as a standard USB printer)
- 58mm wide thermal paper rolls (widely available, cheap)
- 384 dot horizontal resolution
- No automatic cutter, you need to tear the paper off yourself
- Costs less than £30
I asked for this thing because I noticed I was using a lot of Post-It notes to basically copy stuff down off the screen, and automating that seemed fun.
Getting it working
On NixOS, the USB lp driver isn't loaded by default, so I needed to add something to /etc/nixos/configuration.nix
:
boot.kernelModules = ["usblp"];
With that done, plugging it in produces a /dev/usb/lp0
device I can write to if I'm in the lp
group.
The language spoken by the printer is ESC/POS, which is a variant of the old Epson ESC/P, familiar to me from my childhood spent programming dot-matrix printers! The printer came with a poorly-translated programming manual on a CD-ROM, which largely agrees with online guides to ESC/POS, but it took a bunch of trial and error to get bitmap printing working and I never quite figured out how to make it print barcodes and QR codes. I'm not too worried about anything else if I can drive raw bitmaps into the device, though - once I can print bitmaps, I can make the printer do anything, by simply rendering everything to bitmaps on the computer.
My Driver
So I set about writing a driver for it in [https://www.call-cc.org/](Chicken Scheme). What I've written is tailored pretty tightly to my device so I've not released it, but if anyone else is interested in hacking ESC/POS devices, drop a comment and I'll gladly send you what I did.
The architecture of the driver is:
- Some procedures that correctly format and send ESC/POS control codes.
- Some code using the stb-image and stb-image-resize eggs to load images, scale them to 384 dots wide, and convert them to greyscale - then a quick and dirty dithering loop on top of that to turn it into one-bit-per-pixel data in the correct format for the ESC/POS bitmap commands. I didn't implement proper Floyd-Steinberg dithering, purely through laziness; it would be relatively easy to add. This lets me take arbitrary PNGs and JPEGs and print them, although photos look awful and it should be reserved for simple diagrams and logos!
- A bunch of high-level routines: Output a heading by enabling a big bold font and centering, output justified parapraphs, output TODO items by printing
[ ]
followed by a justified paragraph with a five-character margin, etc; all with the option of using either of the two fonts inside the printer, in any combination of double-wide and double-high. - A command line driver that invokes the high-level routines in order, so I can type:
receipt-printer -i mugshot.jpg -h TODOs -t "Take over world" \
-t "Buy milk" -tB "Eat lunch!" \
-p "A paragraph of normal text" \
-pN "A paragraph of text in the narrow font, which means we can fit a lot more in before it wraps"
... (N
denoting Narrow and B
denoting Big) and get the following:
(Excuse fingers, it was wanting to curl back up on me).
The command line can also include -F
followed by a filename to read commands from a file, as a sequence of Lisp s-expressions that could easily be generated from a Magic Pipes pipeline.
How I'm using it
A common source of reasons I was copying things from my screen to post-its was people saying "Oh can you give me the phone number of..." "...the URL of..." "...the login details to the shared family account on..." and so on. Now, when that happens, a quick receipt-printer -p "...paste stuff here..."
gives me a legible and correct copy in record time.
But the most common source was writing short-term TODO lists. You see, I have a massive and complicated life, which is documented in a massive and complicated set of Emacs Org Mode files, part of which is a list of things I need to do. For any given free day or weekend, however, I tend to assemble a shortlist of urgent things I plan to do in that time period, which previously I'd copy out onto a post-it and then cross items out as I did them.
Now, I have a file alongside my org files called current-projects.rp
which is in the correct format to be fed to receipt-printer -F <filename>
, listing my short-term TODO list. When I am in planning mode, I update it by referring to my org files, and when I'm about to start on my TODOs, I run a shell script called print-daily-planner
which looks like:
#!/bin/sh receipt-printer -h "`date +"%a %G-W%V-%w"`" \ -h "`date +"%Y-%m-%d"`" \ -F $HOME/.../current-tasks.rp
I'm considering having a directory of "favourite photos" and having it pick one at random to stick at the top, just because it'd be cute to get a random photo of one of the kids every time... although photos don't look too great on a single-bit printer, so it may not be worth it. Dunno.
Next steps
This is a bit of a hack, though. What I'd like to do when I get a moment is to have a CURRENT
tag I can add to headings in my org mode files, and make the print-daily-planner
command ask Emacs for all CURRENT
headings and print them out, rather than needing to maintain the current-projects.rp
file. Then I can just add and remove that tag and not need to copy things out of org mode!
I'd also like to include any scheduled appointments from my org files, any from the family shared Google Calendar, and maybe other stuff from public APIs - weather forecasts, news headlines, etc... I can rarely be bothered with integrating those kinds of things, though!
By andyjpb, Sun 24th Jan 2021 @ 11:41 pm
Now you can just press the "paper advance" button and you have a convenient (but non-sticky) piece of paper to scrawl on!!!
Ironically, this doesn't wrap properly!
PS: was this a self present?
For the past 15 years I've used the back of old business cards for impromptu TODO lists. A month or so ago I finally ran out of business cards with blank backs so I eagerly await hearing how you get on with this and how annoying the curly paper is!
By alaric, Mon 25th Jan 2021 @ 10:47 am
The curly paper isn't an issue, as once I've printed my TODO list, I pop it inside my phone case (a folding-open-like-a-book kind) which holds it flat, and it quickly loses its curl under the pressure!