If you can’t tell I’m dumping a huge backlog of things I’ve wanted to document for a long time, don’t think I can keep up this post rate for long. Here’s a really easy one: talking to a parallel port based dot matrix printer. To be honest this can probably be used to talk to any parallel port device (especially printers), but we’ve tested it on a dot-matrix printer. We’ll start with the basics: what is a parallel port? A parallel port is a port popular on computers for the past couple decades that allows you to set an entire byte of data on the pins simultaneously and a bunch of control lines to exchange commands between devices. The best documentation I have ever found for the port is here, but the important pins are data[0-7], strobe, busy, and ack (although that last one turned out to not be used on this particular printer).
I built a cable that accommodated all the pins even though I knew we weren’t going to use them. The thing about “modern” serial protocols like RS232 or SPI is that they go one bit at a time, and this method does whole bytes at a time. The way we achieve this is by using what are called bit masks. Bit masks are where you essentially take an entire byte and do an bitwise AND with a mask to only leave whatever bits on and also on in the mask. The way we use bitmasks is to mask off all but one bit at a time so we know what value to set each bit on the parallel port to. Once we have one byte on the port we simply have to toggle the strobe pin to let the printer know when to read the byte. After the printer has started reading the byte we keep checking the busy pin to see if the printer is done yet. Once the printer is done reading the byte you are free to set up the next one. The printer is SUPPOSED to flip the ack line when it’s done, but this one didn’t.
The next important thing is to understand what the non-printable characters in the ASCII table are. The ASCII table is the definitions for all the bytes you can send down a standard ASCII compatible serial or parallel port. Most people focus on the printable characters because they can be seen, but when you’re talking to physical hardware the use of in-band signaling is important. The one non-printable character I will never forget is 7; bell. This character is supposed to tell the terminal to emit an audible sound, but frequently if you throw it at things like IRC, printers, or other things that are not serial terminals they try to implement the entire ASCII table including the non printable characters, which means they ding… every time the screen is rendered. This printer did not have a bell, unfortunately. The important characters are Carriage Return and Line Feed. These go back to the typewriter days where a CR puts the carriage at the beginning of the line and the LF moves the paper up one line. These are frequently used these days as signers of the end of a line (as they were when they actually incremented the paper) but sometimes they only use one or the other which saves one byte of space, but doesn’t make much sense from a technical standpoint (not that anyone really uses a CR without a LF these days). This printer was fairly smart; it only moved the carriage as far as it has to go to print the characters on that line (rather than moving all the way across the paper), but it wouldn’t move at all until the entire line truncated in a CR LF was sent.
This was implemented as an output for the future i3 Detroit rfid entry system, but can really be used anywhere 10 IO are free (or, if you want to be a little ironic, use a 74595 for the data). The entire entry on that system can be found here, but the code for the serial to printer test is here.