Read data from parallel port

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.

Whandall: 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.

Hi, 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).

Thanks,

Gerard

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?

Regards, Raf

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…

/********************************************************************************
 * 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 {
  READY,
  BUSY,
  ACK
} 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;
  delay(100);
  Serial.println("Initialised");
}

void loop()
{
  switch (State) {
    case READY:
      digitalWrite(Busy, LOW);
      digitalWrite(nAck,HIGH);
      digitalWrite(led, HIGH);
      break;
      
  //    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:
      digitalWrite(nAck,LOW);
      delay(1); //milliseconds. Specification minimum = 5 us    ** Reduced to 1 is ok **
      State = READY;
      break;
  }   
}

void Interrupt()
{
    digitalWrite(Busy, HIGH);
    digitalWrite(led, LOW);
    ProcessChar();
    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);
         
  Serial.print((char)Char);
}

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?

Regards, Jeff

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?

Paul

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.