I have several old computers. It's fun to print something with them. But printers are getting old too, and old printers are more likely to be thrown away than old computers.

I would like to use an arduino (Uno) to emulate and capture computer-to-printer output, and send it to a modern computer (via USB) in any useful format. That could be plain text, formatted text, or a real printstream than can be redirected to a modern printer. Doesn't matter, that's interpreting the byte-stream and programming as good as you can.

The difficulty is the first step, the hardware: capturing a parallel signal over different wires, and turning that back again into byte-data.

Obviously, I'm not the first one to think about that. And I have done some looking around. I've seen several questions and several answers, but so far, I haven't seen a finished project. (I might have missed it) I have seen a commercial product, but +€200 seems to be over the top.


  • IS there a finished project, documented, that I can build ?
  • if not, I'm open to suggestions.

My knowledge of electronics is minimal, but I'm pretty good in breadboardin. :wink:

Greetings from the TyRannoSaurus

Be advised, there are THREE different versions of the old PC computer parallel ports. Each one is not compatible with the other.

I did made a short WWW request.
There are alot of solutions.

Oh, really? The Centronics I know as being the most commonly used. What other versions were there? RS232...?

Reading a Centronics parallel output is not very difficult. It can be done in several ways but calls for electronics knowledge.

Years ago I built a stepper motor coil winder. It was run from the parallel port on a Epson laptop, the very first lap top. When it died, I found a newer Epson laptop and the software would not run correctly. I gave up as the winder was no longer needed.
I had built a parallel port exerciser board with LEDs and switched in order to test the original software. The test software would not work correctly.
Recently, I pulled the file on the test board and began to Google search for information on the parallel ports on PC compatible computers, that is where I found there were three versions of the parallel printer port over several years. The explanation of differences provided the logic as to why software for version 1 would not work with version 2. They also wrote there was a later version 3.
The DOS software determined which port version was in use and provided the correct drivers. That is why no one noticed, unless they were accessing the port directly.

@ Paul_KD7HB

Thanks. Several versions of the parallel port handling in the computer then? I never faced any of that.
30 years ago I built an interface to read and write from/to a paper tape reader/punch. The project was to help SKF(!) restore old, worned out, bootloader tapes for a measuring machine.... All made in the home built Z80 hobby computer.

Centronics, in its basics, applies data to the data lines and then issues a clock pulse. Either 8 data I/O lines and an ISR reads the byte, and sends the acknowledge back, or use a shift register to pick up the printer port data.

@Railroader They are all essentially 8 bit parallel systems at heart though, right?
Given that and an understanding of the protocol a bit of port manipulation ought to do for capturing the data.

The issue I have is translation.

  • old program to old printer driver
  • odd printer driver to Arduino for transmission to new PC
  • New PC to new driver ??? There is a disconnect here

Unless the old PC used a special printer driver to convert the data to a universal raw format.

Instead of reinventing the wheel:
How to Buy The Retro-Printer Module |

"They are all essentially 8 bit parallel."
To get started use 8 GPIO lines for data and catch the clock pulse using an interrupt.
Data is setup on the data lines and when they are stable a clock pulse is launched.
Then read the 8 data lines in proper order and shift their value into a byte variable. When that is done, pulse the ACK line to tell the sending device that the port is ready for the next transfer.

I started digging and this page have information. Go down to pins, pinout. I've not checked the entire page yet.

Parallel port - Wikipedia

I think You worry too much. I suppose You have an old Pc that can perform printer output. Then there's no need to worry about the Pc drivers. Focus on the Arduino reading the printout.

Capture sounds easy, just a few lines of code.

I'm not trying to be persistent, I just don't understand the entire data path to the new printer beyond the capture and transmission; original file to paper, that is.

You're capturing/interfering with a thread started by jan-80

Start A new topic of Your own.

I was asking because the point was mentioned by OP and I did not see an response to this yet. Pardon me, but I thought you might know something about it.

I do have memories from my old work with parallel printer ports.
Just start a topic of Your own and I'll be answering.

This topic belongs to the OP starting it.

You are probably referring to the 3 standards you can set in the BIOS: basic, PS/2 and EPP.

AFAIK, each one is an extension of the older one, and all based on the Centronics standard, wich precedes the IBM PC. Fundamentally, they are all the same, as long as you see the Parallel port as output only.

I've hooked up 40-year old printers - yes I have some - to modern computers (even via USB-2-parallel) and they worked. Just as I have hooked up modern printers to old computers. Never with problems.

My experience is that a printjob is a byte-stream. And a bytestream can be transferred by any means, including serial, USB or network. In essence, it's codes transferred. So I have good hopes if I capture e.g. ESC/P code from an old computer, capture that, file it, and send it via USB to an ESC/P-compatible printer, it will work. I might be wrong.

"interpreting the byte-stream" could also mean: stripping it of all control codes, so that all you're left with is raw text data. I might have to do that,

See also my reply about byte-stream: a printjob is a stack of commands, that's all.

If you capture a printjob, and you want to reproduce it, you should:

  • send it to a compatible printer
  • bypass the printer-driver of that printer

Where's the fun in that ?

  • I don't want to spend that amount of cash
  • I thought that Arduino was about building things yourself ?

The 25-pin parallel port has 8 data pins and a STROBE pin. I would connect the STROBE pin (1) to an interrupt pin (2 or 3 on UNO) and connect the data pins (2-9) to 8 input pins. If you connect them to 4-11 on the UNO you can read them all in a few cycles by reading the PIND (Pins 0-7) and PINB (Pins 8-13) registers. Connect any of the Ground pins (18-25) to Arduino Ground. Set the interrupt pin for FALLING. On an interrupt, grab four pins from each register and send that byte to the Serial buffer. If the serial port can keep up, you're done.

Something like this:

void StrobeInterrupt()
  uint8_t bits = PINB << 4;  // Pins 11-8 into bits 7-4
  bits |= PIND >> 4; // Pins 7-4 into bits 3-0
  // WARNING: If the Serial port can't keep up, this call
  // will block while the serial buffer is full and 
  // characters may be lost.

@ johnwasser
Yes, exactly. That is step one, to pick up the print port output.
Step 2, how/why try to send a printer stream into a Pc... How will that Pc handle it?

Here is the complete list of active pins on the parallel printer port for PC compatible machines.


Thanks for the comments and tips so far.
Thanks for the layout.

AFAIK, sending one byte goes as follows:

  • the computer sending, sets the bits on the data pins
  • the STROBE is set high once data is stable
  • printer reads data, sets BUSY signal high while reading & procesing
  • printer lowers BUSY signal, repeat cycle

Did I get that right ?

If so, I can 'slow down' the computer output, by using the BUSY signal, in order to adjust for serial processing and filtering & general program execution delay, on the Arduino side. Because using @johnwasser 's way of working, the Arduino has no way of slowing down the computer output and is at the merci of the computer's print speed. Wich might be too much for the Arduino to handle. Using the BUSY signal, I could give the Arduino more 'breathing' time.

If the answer to the question was 'No', the above reasoning is flawed, of course. Then I would need another way to slow down the computer's output speed.

Close. The STROBE signal is Active Low so it is the falling edge that tells the printer that data is ready.

You can turn on the BUSY line while the Serial.write() occurs to slow down the PC output. Even better would be to turn on the BUSY whenever Serial.availableToWrite() is below some threshold.

void StrobeInterrupt()
  uint8_t bits = PINB << 4;  // Pins 11-8 into bits 7-4
  bits |= PIND >> 4; // Pins 7-4 into bits 3-0

  boolean busy = Serial.availableToWrite() < 8;
  digitalWrite(BusyPin, busy ? HIGH : LOW);  // Swap HIGH and LOW if BUSY is Active Low

I don't remember what the ACKNOWLEDGE signal does. It may be necessary to strobe it to let the PC know that the data has been read and it is OK to change the data.