Whenever I have to control something I ssh into my desktop and work there, mostly because lately I turned a bit lazier (coding from the couch is really nice) and because I had to get rid of its screen for a while. Well, the hard disk is dying so I had to find a substitute till I buy a new one. Sometimes I don’t understand technology; that WD is at most three years old and smartd starts complaining. The Seagates in our router/print server/etc. have easily ten years spinning without a whine.
Enough ranting. Picked up a “Noganet” branded usb to parallel cable that was lurking in the basement. It appeared under Linux as /dev/usblp0 as expected (never saw one that really really implements a real parallel port). Trying to write to it resulted in a hang (the program was waiting for i/o) but pluggin a printer an cat’ing something resulted in a printed page. According to this page on BeyondLogic,
Centronics is an early standard for transferring data from a host to the printer. The majority of printers use this handshake. This handshake is normally implemented using a Standard Parallel Port under software control. Below is a simplified diagram of the `Centronics’ Protocol. […] Centronics Waveform Data is first applied on the Parallel Port pins 2 to 7. The host then checks to see if the printer is busy. i.e. the busy line should be low. The program then asserts the strobe, waits a minimum of 1uS, and then de-asserts the strobe. Data is normally read by the printer/peripheral on the rising edge of the strobe. The printer will indicate that it is busy processing data via the Busy line. Once the printer has accepted data, it will acknowledge the byte by a negative pulse about 5uS on the nAck line.
Quite often the host will ignore the nAck line to save time
So, I tied Busy(11) to ground and tried again. Success!!
From C everything is roses,
#include <fcntl.h> #include <stdlib.h> #include <stdio.h> /* not a single error check, will blow out very nice */ int main(int argc, char **argv) { int fd = open("/dev/usblp0", O_WRONLY); char d = (char) atoi(argv[1]); write(fd, &d, 1); close(fd); }
But not so with Python. I forgot to set the file to unbuffered, it wrote everything at once when exiting or flushing. The solution is to use something like
port = open('/dev/usblp0', 'wb', 0)
and you are all set to go.
It worked, somehow. The usb bus has a limit of 1000 packets per second, this means you can at most flip bits at that rate. It should work in other (faster) modes and allow me to read but haven’t figured yet how to do it, all I get now are non-working IOCTLS. Maybe the adapter is way cheaper than what I thought.