Click here to Skip to main content
Email Password   helpLost your password?

Screenshot - papic1.gif

Introduction

This is a wrapper for the inpout32.dll/inpout32.lib class which is available at Logix4u.net. For a little theory, please visit Logix4u.net.

This class is useful if you wish to control the 12 output pins of your computer's parallel port under Windows XP/NT (e.g., driving LEDs, motors and all). This means, the control pins are used as output. The LPT port has 8 data pins, 4 control pins, and 5 status pins (input), but unfortunately, the basic functions (Console and Port I/O Routines) do not support direct access to the control pins. For this reason, I have developed this project: to have more freedom and functionality using the LPT port.

Almost all functions have the same interface as PARAPIN functions, so this class is useful too if you are adapting your linux code included PARAPIN to Windows enviroment. Hopefully you will find CPaPiC useful.

Background

This C++ class was inspired by PARAPIN, A Parallel Port Pin Programming Library for Linux, which was developed by Jeremy Elson and Al Hooton.

The realization of this work can never been done without the inpout32.dll/inpout32.lib from Logix4u.net.

Using the code

Important!

If you are using WinXP, do the following steps:

  1. Execute regedit.exe:
  2. Find the following registry key:
  3. [HKEY_LOCAL_MACHINE\\\\SYSTEM\\\\CurrentControlSet\\\\Services\\\\Parport]
  4. Insert a new key named "Parameters" (if it does not exist).
  5. Insert a new double word named "DisableWarmPoll" into "Parameters" with value "1".
  6. Restart Windows.

After this. WinXP will not disturb the output if you are switching the status pins.

Before using CPaPiC:

  1. Copy the DLL file inpout32.dll and the lib file inpout32.lib to the project folder.
  2. From the Project menu, select Settings, go to the tab Link, in Object/ Library Modules, write inpout32.lib.

You may use CPaPiC in different ways. For example, you can:

  1. create a static or dynamic object, or
  2. derive your class from CPaPiC.

At first, I will show you how to create a static object and use its member functions and definitions. In this case, it is possible to use more then one object and control only the selected pins without the danger of disturbing the others. Let me declare a CPaPiC object like this:

CPaPiC papi;

The constructor sets the default port LPT1, and selects all the input and output port pins that are active:

Parallel port pins

Physically:

Parallel port

Two additional definitions that refer to all I/O pins are LP_INPUT_PINS and LP_OUTPUT_PINS. The LPT port can be changed by the lpt_init_user() function. For example:

papi.lp_init_user(LPT2); // papi will control port LPT2

Furthermore, you may give different memory addresses. (But only LPT1 and LPT2 are defined.) If you want to select the pins to control, you can do it this way:

papi.pin_input_mode( LP_PIN10 | LP_PIN11 | LP_PIN12 );
// Set input pins 10, 11 and 12 active

papi.pin_output_mode( LP_PIN01 | LP_PIN02 );
// Set output pins 1 and 2 active

// Equivalent code:

papi.pin_mode( LP_PIN10 | LP_PIN11 | LP_PIN12, LP_INPUT );
papi.pin_mode( LP_PIN01 | LP_PIN02, LP_OUTPUT );

Now, only the 10, 11, 12 input pins and the 1, 2 output pins will be available for the papi object. The port address and active pins are revisable any time. Controlling the selected pins is very simple. Just have a look at these (PARAPIN-like) functions:

Pin control functions

For example:

papi.clear_pin(LP_OUTPUT_PINS);
// Set all pins low (if not all have
// been selected, set only selected)

papi.set_pin( LP_PIN01 ); // Set pin 1 high

papi.invert_pin( LP_PIN01 | LP_PIN02 ); // Invert pins 1 and 2


// Loading the values of input pin registers:

lp_pin pins; // Creat a new lp_pin varible

pins = papi.pin_is_set( LP_PIN10 | LP_PIN11 | LP_PIN12 );
// ask the state of the registers of pins 10, 11 and 12

for( int i = 10; i < 13; i++)
    if( pins & LP_PIN[i] == 0 )
        printf( "pin %d is low\n", i );
        // the pin number i is low

    else
        printf( "pin %d is high\n", i ); // the pin number i is high

In the demo program, you can specify the pin parameters of a function using check boxes (parameter of pin_is_set(..) contains all input pins):

Giving parameters

I have derived the CPaPiCDlg class from CPaPiC, so my dialog has all the properties of CPaPiC. So, I can use all its functions instead of creating a separate CPaPiC object.

Points of interest

While writing the code, I learned how important the bit operations are.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generalkérdés
Lardino
3:10 10 Aug '09  
Szia gordius!

LPt portra szeretnék olyan érzékelőket rakni, amik Ohm-os ellenállás változást ad (egyfajta potméter), másodpercenként kb 10 érték.
ezeket az ellenállás adatokat szeretném én megjeleníteni (diagrammal, stb.).

Ha tudnál segíteni, azért nagyon hálás lennék, mivel látom, hogy te ebben a dologban otthon vagy... Smile

előre is köszönöm: Lardino
GeneralInput Using Data Pin
yuzizali
18:16 29 Apr '09  
Hi,

firstly, thanx for your great article and Parallel Interfacing library.
I read somewhere that Data Pin (PIN02-PIN09) are directional, which i assume can be used both to output voltage and read input.
Is that true? or it has another meaning by "supporting both IN/OUT mode"? if it is possible, does PaPiC can do that?
i'm trying to maximize the input number without adding parallel extension card.

thanx.
GeneralRe: Input Using Data Pin
gordius
11:09 2 May '09  
Hi,

thanks. I read that Data pins can be used for input but it is a bit more complicated and I didn't dealed with it. I think the direction can be controlled by Control pins. But this is all I know about it. Probably some forums can help..

B.r.
Zsolt
Questionim unable to find the proj menu
aisshu
20:21 25 Mar '09  
so do we need to use VC++ for PaPiC or can it done using c++ too?
if c++ then where to find the project folder/menu?
AnswerRe: im unable to find the proj menu
gordius
10:02 27 Mar '09  
Sorry, I never tried to use it without VC++.
GeneralPrecise timing using parallel port.
Roccivic
4:58 3 Oct '08  
Hi,
I'm about to write a program for accessing the parallel port.
But I wonder, if I use "Cpapic" will I be able to generate precise timing. For example, if I'd need a square wave at one of the output pins pulsing at 10Hz, how accurate will it actually be?

Many thanks in advance.

Rouslan
Questionsending data through parallel port
suncrest
7:14 10 Sep '08  
hi gordius
i have a few questions for you. right now i'm having my final project in my study where i should make a speech recognition program. to put in the voice to the computer,i have to connect my microphone hardware,which is involve an ADC in it,to parallel port. i'm having difficulty in sending data through parallel port.here's my problems:
1. how do i know if my parallel port support bi-directional system?
2. if my parallel port doesn't support bi-directional system,then if i want to send a data through it,i must use control and status ports,right? can control ports receive the data? i mean,their direction is "in/out",not just "in" like status ports or just "out" like data ports. so i'm a little bit confuse if i can use it or not.
3. i don't know how to receive data through parallel port using delphi 7.can you help me by make an example about it?
i hope you can help me.thank you!
AnswerRe: sending data through parallel port
gordius
11:02 10 Sep '08  
Hi, I focused in my project on sending a lot of data out in the easiest way. I have read about turning the control port direction but it was difficult for me and it needs a more complex hardware so I dropped the idea. So I can not help you in this case. But the speech recognition software is interesting. I hope you will successfully finish your project. Have a good work and never give up.
QuestionRe: sending data through parallel port
suncrest
19:44 10 Sep '08  
ow..i see.
mmm,do you have another alternative for me to send my data except using parallel port?the easiest and fastest way,if there's such a way...
btw,thx for the support,i really appreciate it^^
AnswerRe: sending data through parallel port
gordius
9:32 11 Sep '08  
Sorry, but the easiest way I know is sending data using the 5 input pin of the parallel port which is easy with this code.
GeneralFIle missing in source
Member 4568999
15:40 7 Sep '08  
Your source refers to a header file that isen't present in the rar file.
#include "PaPiC.h"

PaPiC.h isent included.
GeneralRe: FIle missing in source
gordius
11:53 9 Sep '08  
CPaPiC.h in not missing. Both of the zip files contain it. There is no PaPiC.h.
QuestionI need to "catch" the output for a printer in another computer
luixilva
12:47 9 Oct '07  
I have a problem: a program X send an output to the printer, but.... i need this output in a file in another computer. Then I need to "catch" this output trough the parallel port in another computer. I am using a cable DB25M - DB25M connected to the parallel port of both computers (this cable was used with a switch between two printers and worked properly), but.... i just can't:( do it, i don't know what happen, because i can read properly the ports: data, status and control.

I am using a visual C++ program to catch the output from the other computer trough the parallel port. The code i am using is something like this...

fin = 0;
count = 0;
data = _inp( dataport );
stat = _inp( statport );
ctrl = _inp( ctrlport );
do
{
ctrl = ctrl & 0x000000ff;
if( ctrl & 0x01 )
{
stat = stat | 0x80; // set the busy port on
retu = _outp( stat );
wait( (clock_t) 5 ); // wait for 5 micro-seconds
data = _inp( dataport );
printf( "Data read: 0x%2x\n", data );
stat = stat | 0x40; // set acknowledge on
retu = _outp( stat );
wait( (clock_t) 5 ); // wait for 5 micro-seconds
stat = stat & 0x7f; // set busy off
retu = _outp( stat );
stat = stat & 0xbf; // set ackn off
retu = _outp( stat );
++count;
}
if( _kbhit() != 0 )
{
c = getch();
if( c == 'c' || c == 'C' )
{
fin = 1;
printf("End of process\n");
}
}
} while( fin != 0 );

Could you please help me?

Thank you in advance for your attentions.

Regards.
AnswerRe: I need to "catch" the output for a printer in another computer
gordius
4:40 10 Oct '07  
Hi!

By the old LPT-chips only the status and control pins of the port are readable. (More precisely only the status and control pin's state can be changed externally.) Of course you can read the state of data and control pins, but only what you have set internally before.

I have read somewhere, that the new LPT-chips allow to use data pins as input, working in bidirectional mode, but I could't find anything useful in this subject. Frown I visited some forums, but people in these found that only the status pins are useful for input data.

My simple solution is:
----------------------

Just connect the first 5 data pins (pin 2,3,4,5,6) of the 'A' comuter to the 'B' computer's 5 status pins (pin 10,11,12,13,15), and vice versa:

A B

2 - 10
3 - 11
4 - 12
5 - 13
6 - 15

10- 2
11- 3
12- 4
13- 5
15- 6

So you can trasmit 5 bits in a time unit bidirectional.
This is only I can advise.

Good luck!
g.


GeneralRe: I need to "catch" the output for a printer in another computer
luixilva
12:15 10 Oct '07  
First of all, thank you so much for answer me, but i have some doubts (i hope u can help me):

1.- how can a printer "read" the data and put over paper?
2.- if a printer can do it, don't u think a "C" program or an "Assembler" program can do the same thing, but instead of put the data on paper, put in a file?
3.- if u mean that i must change the data-cable, how can i read 8 bits of data instead of 5?, because with 5 bits i have no complete chars, or can I have them? how?
4.- if this stat lines are converted in data lines, how can i say to the sender that i have processed the actual char and I need the "next" char?

Thank you in advance for your answers. Smile

Regards my friend.

GeneralRe: I need to "catch" the output for a printer in another computer
gordius
3:25 11 Oct '07  
I think, my solution I have written to you is not good for catching data of printing.

1 - the printer has a special bus driver IC that can read adta, it is not the same that is in your computer's motherboard

2 - Unfortunately I don't know, how you can do it, I only know the very conservative usage of printer port, that is: status pins are only changeable, but it is enough:

3 - To read 8 bits instead of 5, it is possible to construct a relatively simlpy electronic, which reads the first 4 bit, puts it in a register then the last 4 bit and puts it together.

4 - It's a good question, I don't know..

But don't give it up! Try to find someone, who knows it.

Best regards.

GeneralSome trouble
gordius
4:08 24 Sep '07  
If I try to handle input pins, some of the output pin values suddenly change. How can I turn off this?

gordius
AnswerProblem solved
gordius
4:30 30 Sep '07  

If you are using WinXP, do the following steps:

(1) Execute regedit.exe
(2) Find the following registry key:
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Parport]
(3) Insert a new key named "Parameters" (if not exist)
(4) Insert a new double word into "Parameters" with value "00000001"
(5) Restart Windows

After this WinXP will not disturb the outputs if you are switching the status pins.

Generalhi i am unable to write any value on control pins where is the problem
rajbhansingh
4:10 11 Jul '07  
hi i am unable to write any value on control pins where is the problem my computer is pentium cerelon but my other computer p4 have no problem,how can i solve this problem

hi
GeneralRe: hi i am unable to write any value on control pins where is the problem
gordius
1:07 12 Jul '07  
Hi! I have an idea, where is the problem, probably your computer is Ok (I have a Celeron too.). Give me two or three days and I will try to fix it and return. Hi.

GeneralRe: hi i am unable to write any value on control pins where is the problem
gordius
9:52 12 Jul '07  
Hi! Into the constructor I inserted a line which sets the mode of the parallel port. I suppose it was the problem, but I'm not sure. Please download and test it (CPaPiC.cpp). If the control lines still doesn't work I have no idea what's wrong. Hi.
GeneralA little misleading ..
Garth J Lancaster
15:42 29 Jun '07  
I think you should modify your article just a little to indicate that what you've done is write a wrapper for the publically available inpout32.dll/inpout32.lib. There's nothing wrong with writing a wrapper and demonstrating its use, but people might get the impression you wrote the entire code - you didnt as far as I know (feel free to correct me and I'll apologize if required) ...

As far as I see, one source (which you fail to mention) for inpout32.dll/inpout32.lib is http://www.logix4u.net/inpout32.htm[^] with more notes on how it works http://www.logix4u.net/inpout_theory.htm[^], there may be other variants of it around .....

(modified) this link is also helpful if people are interested >> http://www.lvr.com/parport.htm[^]

Im trying not to put you down, but please acknowledge the work of others.

'g'
GeneralRe: A little misleading ..
gordius
11:08 1 Jul '07  
Hi 'g',

You are absolutely right, I should have indicated that this is a wrapper for inpout32.dll and inpout32.dll. I'm a beginner yet and I have made a mistake.
Thank you for your notice! I have corrected the article.

gordius


Last Updated 16 Nov 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010