I’ve always had a soft spot for Sinclair’s ZX Printer. Yes it was slow and the print was poorly rendered on its special aluminium-coated paper, which picked up greasy fingerprints like they were going out of fashion, but it was cute, compact and cheap.
A Sinclair ZX81 and the ZX Printer
Source: Carlos Pérez Ruiz
I never owned one—I didn’t have a Sinclair computer back then—but I’ve always liked the idea of having a small thermal printer for listings and such. I do have a Raspberry Pi, and it struck me that a cheap, compact thermal printer would be ideal for this mini microcomputer too. Being a Pi user, of course, hooking up a printer isn’t about plugging in a USB cable and running CUPS it’s about driving the device directly through code and the Pi’s GPIO ports.
I did a search for a suitably small and low-cost printer and quickly uncovered this little—111 x 65 x 57cm—fellow from SparkFun, available from various retailers in the UK for around £40, including Hobbytronics and Proto-Pic.
ZX Printer de nos jours: SparkFun's thermal printer and Pi
It’s basic and it only takes a narrow cash register paper, but it’s inexpensive. Designed to be integrated into some other hardware, doesn’t come with a convenient USB cable. Instead, there are two cables in the box—‘collections of wires’ would be a better description—each capped with a block connector for the printer and a block connector for the device you’ll be printing from. I’d say with a bit of wiring they could together support a single USB connector if you want to connect the printer that way.
I was forewarned of the printer’s wires-only approach by a Geek Gurl Diaries blog, which used the printer in a project. My original plan was to cut off one connector, clip the live and ground wires into a solder-less DC barrel connector and hook it up to a new AC adaptor. But to avoid a trip to Maplin, I thought I’d see if I anything at home I could use instead. There was: a spare USB extension cable and a USB AC adaptor with a 5.2V output.
The underside of the printer is home to the power connector—use the bundled red and black cable—and the data line, which takes the yellow, green and black cable, also bundled. No easy USB connection here
USB cables have a black ground wire and a red power line, so it was the matter of a moment to remove the female connector from the extension cable, cut away the shielding and the green and yellow data wires, and mate the cable’s red and black wires with the red and black power wires that come with the printer. The USB wires were particularly thin, but I used the DC barrel adaptor I’d already bought to connect the two cables securely together.
A botch, to be sure, but it worked. If you plan to put the printer inside another box, you can probably leave the cable as it is, but I think I’ll eventually pick up a pre-made USB-to-DC barrel cable, which will make for a tidier connection.
The solder-less DC barrel handily holds the USB cable and printer power wires together
For now, though, the printer has sufficient power to experiment with. You can start by pressing the printer’s line feed button down as you switch on the power: this forces the printer to churn out a test print.
The printer’s second cable is for data: the Pi uses the yellow (3.3V in) and black (ground) wires, but don’t attempt to connect the green (5V out) wire as it’ll blow your Raspberry. Since you don’t need the printer to talk to the Pi—we just want the Pi to talk to the printer—leaving the green wire disconnected is not a problem.
A pair of male-to-female prototyping wires can be used to hook the printer’s data cable connector to the Pi’s GPIO ports: pin 6 (GND) for the ground (black) connection and pin 8 (UART Tx) for the data (yellow).
The ground (black) and UART Rx (yellow) wires from the printer's data line go into the Pi's GPIO pins 6 and 8, respectively. Remember, DO NOT connect the green cable
To set the Pi to talk to the printer, you need to re-configure the Pi’s serial GPIO ports from the default settings. Edit /etc/inittab using your preferred text editor—I use nano, thus: sudo nano /etc/inittab—and find the following line:
| |
Add a # symbol at the start so the line is ignored when the OS reads the file at start-up—you turn the line from a command to a comment—then save the file.
Next edit /boot/cmdline.txt and find the line dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Duplicate this line, and then remove console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 from the copy. Now add a # to the first line. This way you can easily switch between default and custom version of the line simply by swapping the # from one line to the other.
Now reboot your Pi with the command:
| |
To use the printer in your Python programs, you need to install Python’s serial module, python-serial, using the following command:
| |
Now head over to Lauri Kainulainen’s page on the Github website: github.com/luopio/py-thermal-printer. Lauri has written a Python module, printer.py, that takes a lot of the work out of sending control codes and such to the printer. Download the code’s Zip file to your home folder and unpack it with
| |
I made a directory called Piprint first and put the printer.py and the file example-lammas.png into that. Wherever you save it, open up an LXTerminal window and navigate to the location and enter this command:
| |
This makes the script executable from the command line, and you can test this—and the printer—byentering and running:
| |
which will print out a test page.
Actually it won’t, at least not entirely, because it requires the python-imaging-tk module in order to output a sample bitmap image. You can install the module, if you wish, by entering:
| |
The SparkFun printer does a test print if you hold the linefeed button when powering it up
You don’t need python-imaging-tk just to print out text and graphical glyphs, only images. Whether you install it or not, you can add import printer to the start of your own Python programs to print from within them. The printer can only output 32 characters on each line using the standard font, ‘A’—40 with the smaller, alternative font, ‘B’—so it’s useful to import the textwrap module to make use of its text handing routines. For instance:
| |
You can use the sys to get characters entered by the user at the keyboard:
| |
Incidentally, if you don’t want to use printer.py, it’s not hard to control the printer using its own commands, each triggered with an ESC character—chr(27) in Python. You can download a full list of the printer’s commands here (PDF). However, Printer.py masks these codes with easy-to-remember command words.
So, if you’ve define a variable p as per the Python program above,
p.bold_on() turns on bold printingp.bold_off() turns it offp.font_b_on() activates the alternative, small fontp.font_b_off() brings back the main, large fontp.justify("R"), p.justify("C") and p.justify("L") aligns the text, respectively, right, centred and leftp.upsidedown_on() turns on upside down printingp.upsidedown_off() turns it offp.underline_on() starts underlining charactersp.underline_off() stops the underlinep.inverse_on() prints characters white on blackp.inverse_off() sets character printing back to black on whiteThose are the key text commands. Look through printer.py and you’ll see commands to format and output barcodes too, along with bitmap image printing. There are also routines to interpret text with markup commands and print it accordingly.
And here is the first draft of a simple Python program to replicate the Basic LPRINT command, or equivalent, to print out your programs:
| |
Save it as lprint.py. Run it with sudo lprint.py my_app.py
A printed listed, just like the old days. Well, kind of...