Go Down

Topic: Read data from parallel port (Read 23287 times) previous topic - next topic


Paul j. Have you made a version with SD card capture?


Jul 26, 2015, 12:41 am Last Edit: Jul 30, 2015, 12:53 am by Rhysun
Paul J - If you're running your PrinterCaptureInterrupt.ino code on an Uno you need to edit the following line:




The first parameter refers to the number of the interrupt rather than the Uno pin number.

Thanks for your code - I am currently using it to repurpose an old print server to do some IOT stuff and am having an enormous amount of fun with it!


Hello guys,
i tried several codes, with or without interrupts, but with little issue when i print from output printer with definied Epson LX-300 driver. When i capturing data from print output, everytime data are different. When i prolong delays in code, captured data are usually same. Did you connected some extra pullup rezistors betweeen arduino pins and +5V input?
Have you or can you recommend some tool to reverting the output back to pdf or text file? I have old MS DOS special computer which prints output only to LPT and i need to capture this output and save it to another machine. Have you some experiences with this reverting process?
Thanks in advance.


Guys i have been trying my best to read the data that the LPT send it to my epson lx-300 but i only get strange characters i think the code drops some of the received data i use the same code that Paul j shared can any one help please??


Oct 08, 2015, 03:15 pm Last Edit: Oct 08, 2015, 03:17 pm by ice-ty

i have continued this project with capturing epson printer code over centronics paralell port. I used an alternative arduino nano board and a cheap sd shield from ebay. The rest of the Hardware is simple and battery based.
The captured printer instructions (on the sd card) can be executed on pc with the tool DosPrinter.exe, this prints the printing job again with the standard windows printer.

Have fun with it.



Oct 18, 2015, 11:00 am Last Edit: Oct 18, 2015, 12:10 pm by umurri
I've read all the post in this discussion titled Reading Parallel Port but at the end, inside the last post, the Port it's read with sequential DigitalRead that appears to meaning that with Arduino, we can write a parallel port, but the reading is to do bit by bit and put them into a byte.

This is very strange for me, overall after to have read (and shared) the opinion and the arguments that suggest to use the complete port instead the single bit.
It's true, this is convenient overall for the output, for many reason.
For the input the reading of all 8 bit of the complete port is faster and clear than eight DigitalRead and the operation to load their value into a byte variable.
But it's to keep considered also that in many cases it's more convenient to work on a complete byte, overall if composed of the same kind of inputs.
I.E. to debounce 8 pushbutton we need roughly the same number of statements that we need to debounce a single pushbutton.
To detect some particular condition it's more quick to make some logical operation on the entire port instead of bit after bit.
I stop here with my silly examples, but you can imagine some of yours.

So please tell me any suggestion to gain the way to read an eight bit port with a single statement.
Can I do something using the assembler?
Thank you


You don't need to use assemby to get access to the PINx registers,
portValue = PINA; (or similar for other PIN registers) will work from C.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)


Oct 18, 2015, 12:07 pm Last Edit: Oct 18, 2015, 12:08 pm by umurri
You don't need to use assemby to get access to the PINx registers,
portValue = PINA; (or similar for other PIN registers) will work from C.
Thank you so much!

You means that there is the statements called "PINx" (that i believe means Port INput x) that read all the eight bit of the "x" port?
Great! (but as all the microcontrollers that I've saw until now)

Where can I read its description? Which is the source?
I thank you for this very useful information, never read until now.


There are different PIN Register, for Port A PINA, Port B PINB, .... depending on the processor you run.

Details can be found in the Atmel datasheet for your processor.

And there is no source, the processor registers (not only the PIN registers) can be accessed
like ordinary RAM locations, they are positioned before RAM in the memory map.

So the predefined PINA, PINB, ... are just names for the locations.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)


I tried the circuits proposed by ice-ty, and the others in this page. No matter what I do the printer status shows it  as "Off Line".

Are you connecting other pins beside pins 1-13 and 18-25?

(I changed the cables, arduinos, tested everything with the multimeter, etc, but I got the same result printer off-line).




I tried these above codes. But I am getting only garbage data output over my Arduino.

Do I need to read specific Data registers or something?

Do revert, as I am stuck for the last few days in the same.

Thanks in advance.


Hi guys,

I have same problem.. In my workshop I have one measurement device with LPT port (this is not PC, this is motorola uP based device) and on printer port I can pick only two printers Epson LQ1000 and HP dot matrix printer. (but I want to go paperless, all my documentation is in .pdf)

I wish to put arduino for capturing print data from LPT and send this to SD card or something like that. Any progress on that project?



Many thanks to Paul J for his work,

I just adapt some timing and it works perfectly for me, even if I'm using a "fake" Arduino nano with the conterfeit FTD232R... chip (but the CH341SER  add the USB2Serial fonctionalities I need...)

Below is the code I'm using with success.

Again many thanks to all..

Code: [Select]

 * PrinterCaptureInterrupt.ino
 * ------------------
 * Monitor a parallel port printer output and capture each character. Output the
 * character on the USB serial port so it can be captured in a terminal program.
 * By............: Paul Jewell
 * Date..........: 29th January 2015
 * Version.......: 0.1a
 * Modification : Change Interrupt Routine so Arduino respond "faster" to Printer
 *                Writing Busy Signal directly from interrupt routine
 *                Ecirbaf 12 Jan 2017
 *                Test on a PC with a "generic Printer Text only" printer
 *                Printing a test page OK
 *                Even if using somme accent characters
 *                Depend How your Terminal Software is handling that.
 * Wiring Layout
 * -------------
 * Parallel Port Output               Arduino Input
 * --------------------               -------------
 * Name      Dir.   Pin                Name    Pin
 * ----      ----   ---                ----    ---
 * nSTROBE    >       1................INT0      2 (as interupt)
 * DATA BYTE  >     2-9.......................3-10   
 * nACK       <      10.........................11
 * BUSY       <      11.........................12
 * OutofPaper <      12................GND
 * Selected   <      13.................5v
 * GND        <>  18-25................GND

int nStrobe = 2;
int Data0   = 3;
int Data1   = 4;
int Data2   = 5;
int Data3   = 6;
int Data4   = 7;
int Data5   = 8;
int Data6   = 9;
int Data7   = 10;
int nAck    = 11;
int Busy    = 12;
int led     = 13; // use as status led

enum States {
} State;


void setup()
  // Configure pins
  pinMode(nStrobe, INPUT_PULLUP);
  for (int n = Data0; n < (Data7+1); n++)
    pinMode(n, INPUT_PULLUP);
  pinMode(nAck, OUTPUT);
  pinMode(Busy, OUTPUT);
  pinMode(led, OUTPUT);
  Serial.begin(38400);    // ** Actual com port could at least go this speed  ** //
  while (!Serial) {

 attachInterrupt(0,Interrupt,FALLING);  // ** Name :Interrupt,  was clearer for me than DataReady  ** //

  State = READY;

void loop()
  switch (State) {
    case READY:
      digitalWrite(Busy, LOW);
      digitalWrite(led, HIGH);
  //    case BUSY: // nStrobe signal received by interrupt handler
  //      digitalWrite(Busy, HIGH);
  //      digitalWrite(led, LOW);
  //      ProcessChar();
  //      State = ACK;
  //      break;
  // ** All this case is made during Interrupt (Avoid some missed characters with "fast" printer) **
    case ACK:
      delay(1); //milliseconds. Specification minimum = 5 us    ** Reduced to 1 is ok **
      State = READY;

void Interrupt()
    digitalWrite(Busy, HIGH);
    digitalWrite(led, LOW);
    State = ACK;

void ProcessChar()
  byte Char;
  Char = digitalRead(Data0) +
         (digitalRead(Data1) << 1) +
         (digitalRead(Data2) << 2) +
         (digitalRead(Data3) << 3) +
         (digitalRead(Data4) << 4) +
         (digitalRead(Data5) << 5) +
         (digitalRead(Data6) << 6) +
         (digitalRead(Data7) << 7);


Hi All,

I didn't know if I should reply to this message or start a new one, so I'll try this first.

I'm using the code from Paul J and Ecirbaf to try and emulate an old printer. 

It was mostly working yesterday until I woke up today and it's now printing nonsense.  I'm using a DB-25 breakout with terminal blocks so I'm thinking it's a signal quality issue, waiting on a new centronics female connector to solder proper headers.

Anyway when it was running yesterday, it was mostly flawless with one small anomaly: one character in every few hundred would be duplicated, one character early.  E.g. instead of "The" it would print "hhe".

It seems the data on the bus is being changed to the next character before the Arduino reads and ACK's it, however it then prints twice and the total number of characters remains the same.  I tried messing with the timing, reducing the ACK pulse to near its minimum spec of 5 uS to no avail.

This is being tested on a "relatively" modern PC (Intel Core2 from about 2007) so perhaps it's just going too fast?  The machine I plan to hook it up to is circa 1995 and running DOS, so maybe that one will be slightly slower and easier to capture.

Or maybe this is another symptom of my ad hoc connection with the terminal blocks.

Has anybody else had any success running this code?  Any similar issues?



Jan 18, 2019, 10:40 pm Last Edit: Jan 19, 2019, 01:25 am by Paul_KD7HB
Never tried that code or needed to do anything with a parallel port in last 20 years. But yesterday I was looking at my parallel port exerciser and the documentation on the IBM version of the port.

Question: Are you responding "ACK  after processing all the pin reads for the data or are you doing it after  the strob, but before actually reading?


PS: After getting home and looking at documentation, I still have the same question for you. Also the SPEED of the computer has NO bearing on your problem. The control protocol for the parallel port takes care of that.

Go Up