This material is about the parallel port on MS-DOS / Windows
computers. It sometimes spills over into things of more general
nature when talking about devices you might attach to the parallel
port.
PLEASE NOTE: You CAN damage your computer if you make ill-advised
connections to it. Any use you make of anything you find here must be
AT YOUR OWN RISK
I have designed a parallel port protector that may be of interest. (Click on the link for information, and a way to obtain the circuit diagrams.)
I-Want-It-Now merchants: click here!.. a good site with essentials, minimal warnings, fewer details.
1) If you are going to use this page, you are probably not a computing novice. Ever set up a web server? It isn't hard! If you have an always- on broadband connection, FarWatch may be of interest. I have written pages for you explaining how to use an old Win98 box (or better) to give yourself a way to monitor the premises the old Win98 box is at from anywhere on the internet. Nothing to buy! And if you connect something to that PC via it's parallel port, you can "see" the state of the inputs to the parallel port from afar, too.
2) If you would be willing to help bring this information about the parallel port to a wider readership, please check out my plea for translators?
Don't want to tie up your printer port? No excuse!! You can get a cheap card to provide a second parallel port! Alternatively, for some projects needing input only consider using your joystick port... it can detect 4 switches and 4 resistances. (N.B.: Most joystick ports do not sense analogue voltages.) For how to program Delphi 2 and higher to read joysticks visit this page of my Delphi Tutorials.
Using your PC isn't the only way to have a lot of fun with controlling and sensing external devices. Control Plus sells a little computer ideally suited, and they offer a free simulator. At my Sheepdog Software (tm) site, I have done some tutorials. I've tried to make them accessible for novices, but also useful to experts.
Don't let the warning above worry you too much... I want to stress that there is a lot of fun to be
had with electronics projects. Find yourself an 'antique' PC. If you
can't rescue one from a dusty corner, you can buy one for almost
nothing. You can use the same monitor as you use on your main
machine. If you wreck the antique, it hasn't cost you much!
(I got one, with monitor, off a sidewalk once!)
I have a third generation inexpensive 'protect the PC' circuit in development. You interpose it between your PC and the home-made stuff you are attaching to
the parallel port, and any mistakes in the home-made things are blocked off from the computer by opto-isolators and relays. (Inputs to the computer are passed through an opto-isolator, outputs are fed to the coils of relays. Properly set up, the worst thing you can do is wreck an opto-isolator or a relay.... both relatively hard to do!) Email me if you are interested in that device. If you can design and etch your own PCBs I can send you some notes. (Send me a snailmail address, as they are not available in machine readable form.) If you are not making your own PCBs, I may still be able to help, but not so quickly and not for free.
If you can write your own programs, you can now connect multiple 8 bit input/ output ports to your PC using the Dallas Microlan, aka "1-wire". Look at the DS2408 if you are impatient. Or, give my introduction to 1-Wire a try. Extra cool: The ports would interface to your computer through your serial port, or your USB port!!
The bad news? You need to equip your PC with a pc-to-MicroLan adapter (about $25). The data rates wouldn't be as high as they would be via LPT1.
Quick guide... more thorough explanations appear further down the page...
Software...
For a simple program to turn bits on or off just by clicking a button, go to my shareware site. There are two free programs there... one for toggling bits, the other for using the computer as a timer via the parallel port.
- - - - - - - -
To send 123 to the parallel port....
(There are notes below about obtaining Delphi 1 or 3, or higher)
Once upon a time, sending 123 to the parallel port (or reading from the input bits there) was a pain. The way to do it depended on what Delphi you used and what OS the program had to run under. No longer, hurrah!
Some time ago, a kind reader sent me an email saying... "use inpout32.dll. It enables the sample programs in Jan Axelson's book Parallel Port Complete".
Click here for Jan Axelson's site, www.lvr.com (Link ok 2/05). It offers help with:
information and tools relating to parallel ports,
RS-232 and RS-485 serial communications, 8052-Basic,
microcontrollers, and making printed-circuit boards.)
It took me a while to get over my fear of DLLs, but am I glad I did! They are no big deal. Details are given in my tutorial on using inpout32.dll. That is written for Delphi programmers, but C or VB (yuck) programmers will find help there, too.
If you use inpout32.dll (freeware, dll and source code available from Logix4u), then one version of your program will run on many different operating systems... Win 3x to XP at last count, including NT.
=============
If you are determined to send 123 to the parallel port the hard way.....
----
In Delphi 1 or Turbo Pascal:
port[888]:=123;
(The code above won't work in Delphi 2 or with Win 9x)
----
In Delphi 2 (and probably higher), for Win95 and 98 (but not NT), add the following procedure....
procedure PortOut(IOport:word; Value:byte); assembler;
asm
xchg ax,dx
out dx,al
end;
.... and then you can send 123 to the parallel port with
PortOut(888,123);
The code above won't work in Delphi 1 or with Win 3x, or NT,
or 2000, or XP. Remember that there's a better way... see using inpout32.dll, above.
----
A newsgroup post said that in QuickBasic you do the following
Out &h378,123
The &h378 is just another way of saying 888. The &H part says "what follows is written in hexadecimal (aka "hex"). Hex 378 is the same as decimal (our "normal") 888. It's like the "difference" between "12", "twelve" and "dozen".
----
For NT, if you don't want to use the better way, using inpout32.dll, explained above, you first need to install a port driver. Here are a few URLs worth checking:
TVicHW32 http://www.entechtaiwan.com/tools.htm
DriverX http://www.tetradyne.com*)
Tinyport (NT only)
http://www.winsite.com/info/pc/winnt/programr/tinypo20.zip
(How to access the other lines of the parallel port is covered further down the page.)
Hardware
Imagine you are looking at the back of your PC, and that the parallel
port socket is horizontal, with the long row of socket on top. The numbers of the sockets at the ends of the rows are...
13 . . . . . . . . . . 1
25 . . . . . . 14
(See below for where things are to be found on the connector at the end of the cable normally plugged into a printer.)
The 'interesting' pins are:
Data bits 0-7: Pins 2 to 9, respectively. If you write to address 888
(decimal), you should see the outputs on those pins change. (The
address is different in some circumstances, but try 888. In Borland's
Pascal: port[888]:=254 would set all bits but the first one
high.)
Pins 18-25: Signal ground. (I.e. for a VERY simple experiment,
connect an LED to pin2, a 680ohm resistor to the LED, and then the
other end of the LED to pin 19. If it doesn't work... try turning the
LED around!)
Inputs: If you read address 889, you can discover the state of 5
pins. They determine the state of bits 3-7 of 889. bTmp:=port[889] is
the 'raw' Pascal you need. Obviously, you do clever things with the
result of that. The bits are mapped and named as follows:
Bit Pin Name
3 15 Error
4 13 Select In
5 12 Paper Empty
6 10 Acknowledge
7 11 Busy
(A trap for the unwary... 'Busy' is inverted 'just inside' the
computer. Thus if you apply a '1' to all of the pins, you'll see
01111xxx when you read 889! Isn't computing fun?)
Before turning to more generally useful things, I might as well
finish off the other pins....
Write to 890 to set the state of the following pins:
Bit Pin Name
0 1 Strobe
1 14 Auto Linefeed
2 16 Initialize
3 17 Select Out
The rest of this page is rough.... but ready.
The layout is a mess (sorry), and there's more editing to do (you're
welcome) but there's a lot of good info and links below and on the linked pages....
The following freeware runs in DOS and controls and monitors a parallel port (LPT1, LPT2, LPTM).
The 8 input and 8 output bits appear as large bright/ dim rectangles on the screen so you can see bits across the classroom. The input bits are all 'fixed' so that the two ports appear as one 8-bit input port using pins 10 through 17. F keys can be used to turn output bits on or off or blink them. I have a lot more to this but it'll be a while before I get the other parts of the package cleaned up (I have a graphical state-table sequencer etc. for sequencing and control). To learn more clicking here to visit Terry King's site. With a few LEDs and switches, you're set to have some fun. You can go a lot further, if you want to add other sensors. (More on sensors at Sheepdog's Sensing and Control site.)
Freeware from Terry King, Vermont, USA. Used with school kids, aged 10-13.
Click here for Boondog's site, where you'll find tutorials providing you with do-it-yourself-style articles. These articles show you how to interface devices to your PC. Devices like motors, relays, A/D and D/A converters, LCDs, keypads etc. The tutorials are complete with schematic wiring diagrams, parts lists, parts suppliers, etc.
For many projects, you need a source of 5v (or 12v) for the electronics outside your PC. I saw the following in a newsgroup. See my note at the end before attempting the test described.
"If you're getting the 5V from your PC, the ground from the PC will be fine. However, if you're trying to add 5V from somewhere else, be just a little wary. The PCs logic ground (and thus that of your one-wire bus) is probably tied to either line neutral or line ground. If you use a non-isolated switching power supply to get 5V from house wiring, it's possible to make smoke under certain conditions. If you're not sure, hook a cheap 1K resistor between the PCs ground and the ground of the power supply you intend to use (don't connect 5V yet for this test). If the resistor doesn't immediately go poof, then hook a voltmeter across it and check on both DC and AC settings; you shouldn't see more than a small fraction of a volt this way. If this test shows little or no voltage across the resistor, you're probably all set. Not all bad to put a very low-wattage 10 ohm resistor in both the ground and 5V lines, though - that's really cheap insurance, and most times the resistors will sacrifice themselves and protect the rest of the circuitry if something's badly amiss.
"As always, experiment at your own risk. Safety glasses are a minimum precaution when you think there's a chance of blowing up a resistor! Guard your eyesight carefully, and be prepared to turn off the power quickly if anything untoward develops."
I'm not sure why the writer suggests the 1k resistor. I would be inclined just to put the leads of my voltmeter on the two unconnected grounds, hoping to find no voltage (DC or AC!) between them. The 10 ohm idea puzzles me too.. why not just use a fuse?
In response to the previous paragraph, a test engineer in a Swedish firm kindly sent me the following....
"The first test with the 1k Ohm resistor tells you if there is a dangerous difference of voltage between the devices (i.e. dangerous to the equipment) If the two electronic devices have floating grounds, not connected to anything near earth potential, you will probably have a voltage between the devices that could be anything up to twice the top line voltage. But, since the coupling to earth or whatever is weak, it won't usually generate substantial current. It's just what leaks through capacitors and cables in the power supply.
"Using an old moving coil multi-meter with low resistance would probably tell you that there is no (dangerous) voltage between the devices. A modern digital multi-meter, however, has a very high impedance so the voltage you might see could alarm you. It's not necessarily a problem because it is likely that only a tiny current would flow. The 1k Ohm resistor (or 10k or even 50k or 100k...)
would provide the load needed to tell about the danger....
You might find the same "problem" if you measured the voltage between the metal frame-work of two lamps standing on your desk! (In the US. In the UK most electrical equipment is grounded.)
"The second resistor, the 10 Ohm between the "grounds", is used by
some people to minimize the problem with migrating ground currents (editor's "clarification": Ground loops? The author was contributing in his second language.... much more fluently than I could have in my second language!!) if the equipment have some kind of earth, ground or other common connection. A slowly changing voltage of let's say 1/2 Volt or so in zero Ohms is... It could damage a computer card if you were unlucky or at least jeopardize the signals within ICs on poorly designed PCBs.
"For "normal" desk top work I don't think this 10 Ohms is needed.
The resistance in the cables (if they are thin enough) will do, but as
you never know what "industrious" persons can came up with
in their workshops... Personally, if feeling uncertain, I would
use opto couplers. Most parallel ports can drive them directly trough
a resistor without extra electronics."
All of the above relates only (I hope) to situations where your circuit is in two or more separately powered parts... as will often be the case with parallel port interfacing. Unless you use opto-isolators (not a bad idea), you will have to connect the grounds of the separately powered parts, even though the power to the parts comes from different sources.
(An aside: The submission from Sweden put capital letters on Volt and Ohm. I started to "correct" them, but then realized that the general rule is to use capitals where a unit of measurement derives from a person's name, e.g. Hertz, Pascal. So why don't we usually capitalize "volt" and "ohm"? Boy, am I glad I didn't have to learn English as a second language!)
Much good information is available in the British magazine 'Everyday with Practical Electronics.' You can visit them at www.epemag.wimborne.co.uk
Robert Penfold's 'Interface' column has frequently had projects interfacing all sorts of things to the parallel port, but I don't think much of his material is in the website... yet. Agitate!
=== Someone asked: Why do we need to connect pull up/ down resistors or hex inverter buffers (open collector) to the control pins of a port? What is open collector actually? What are the states of the open collector port?
Someone answered:
Inputs do NOT *HAVE* an inherent state, and need NO pull-up or pull-down! But the input voltage to them must be definitely HI or LO. The open-collector outputs have internal pull-ups, and do NOT *NEED* external pull-ups, unless the internal pull-up is not sufficient. Rarely true!! See my FTP Gateway's TUTS/totmpole.tut file for explanations of how the three different kinds of outputs work. See the simplpt.faq and other *lpt.faq files for information about the parallel port. The simplpt.faq is below, Steve
ftp://ftp.armory.com/pub/user/rstevew
The filenames are: *lpt.faq;
ibmlpt.faq, tomlpt.faq, and krislpt.faq. each meets different skill levels and needs.
===
If you are very new to digital electronics, It may pay you to visit my tutorial on the subject of inputs and outputs. Bookmark this page, then
click here
===
If you put eight LEDs, one on each of pins 2-9, then you can get a pretty little light show very simply. The following is pseudo-code... you should be able to convert to the language of your choice....
REPEAT
Datum=0 ;Don't use a byte-type variable. Integer will do.
REPEAT
SEND Datum to parallel port
ADD 1 TO Datum
(If using Delphi, put application.processmessages here)
WAIT A BIT
UNTIL Datum>255
UNTIL 4=5 (i.e., forever!)
===
Someone wrote me with a question about using the "strobe" output. I sent the following in reply; maybe it clears something up for you....
The following is untested and may have silly mistakes, but should be a guide. Port 890 is read first, and then OR's or AND'd with the values given so that only the "strobe" bit is set or cleared.
procedure SendStrobeHi;
var b1:byte;
begin
b1:=port[890];
port[890]:=b1 OR 1;
end;
procedure SendStrobeLo;
var b1:byte;
begin
b1:=port[890];
port[890]:=b1 AND 254;
end;
Although the name 'strobe' implies a pulse, the output from the parallel port (pin 1) should stay high after a call of SendStrobeHi until you make a call of SendStrobeLo, after which it should stay low, etc.
Try sending the pin high and low with nothing but your voltmeter attached.... maybe the circuit you are trying to drive has flaws? (The strobe output from the parallel port shouldn't be expected to drive much.)
===
Some readers have reported problems when trying to drive a laptop's LPT with port[888]. I too have had the experience, though in my case, I did not explore the situation. I may just have had a situation where I was wanting too much current from the output.
If any reader knows how to determine the memory address used in a DOS or Windows 3.1 machine for the LPT port, if it isn't 888, I'd be glad to know. I'd even welcome information on addresses which might be right. (I'm particularly interested in driving the pins of an IBM Model 755, aka 9545.)
===
The pinout at the printer's end of a printer cable is as follows...
Look into the end of the cable that is normally plugged into your
printer. Turn it so that the long side of the connector is on top.
'Pin' 1 will be the one at the upper left.
The first in the lower row is 'pin' 19.
I won't persist in putting the word 'pin' in quotes (to acknowledge
the fact that the connections are not literally pins}... assume
them for the rest of this discussion of the printer end of
a Centronics cable.
Pin 2 is an output, the LSB of the data byte.
The next pins (3,4,5...9) carry the rest of the byte, in ascending order.
Pins 20-27 carry the corresponding 'data returns', i.e. are signal grounds.
In a perfect world, I think you are supposed to connect to each of them,
but I believe they are all connected inside the computer anyway, so
you can probably use just a few. (Using more than one takes care of
any current limitation issues, and provides insurance against bad
connections in the system.)
I can provide details of where the other signals are if you need them.
===
Remember 'the' PC is not always made exactly the same way... and, especially with old machines, a bit may be damaged or not implemented. Experiment! Be sure to test things as you go along, 'bottom up.'
The previous paragraph applies in particular to the issues of the power capabilities of the outputs, and the pull- up/ down needs of the inputs. I'm a novice on these issues myself... but I do have several
machines doing useful things for me. In general, I wouldn't be
reluctant to try to drive the base of a transistor with an output. I
try to design the external circuits to be fail-safe... e.g. if the
computer that controls my burglar alarm is off, or if it has booted
into MS-DOS but not my alarm software, the output of the parallel
port in those conditions was taken as the starting point for the
circuits that ring the alarm's bell. My program moves the output away
from the 'default' state to ring the bell. (There are also less
complex circuits also attached to the bell which can ring it if the
computer is dead!)
I have driven LEDs directly from the parallel port in my machine....
but I wouldn't assume that every machine has sufficiently strong
outputs.
(For the barely-started: Do be careful not to connect more than 5v to
any input, and NOT to connect 0 or 5v directly to any output. There
should be significant resistance between an output and either 0v or
5v, e.g. the resistor mentioned in my simple experiment with the LED,
above.)
I've had enormous fun with circuits driven off the parallel port. Getting started can be a little hard, but you'll soon be under way.
===
If you are ensconced in the brave new world of Windows, you're not supposed (gasp, horror) to access ports directly. There are good reasons for the rule... but there are also times to break it!
With the old Borland Turbo Pascal, making the pins of LPT1 all
5v was as simple as
port[888]:=255;
In Borland's superb Delphi, version 1, you could still do
port[888]:=255;
I'm told that was dropped in later versions of Delphi, BUT... fear not!...
Version 1 has been given away many times on cover discs of
magazines like Personal Computer World. It is also bundled
with later versions of Delphi. It is a superb tool for
creating Windows applications. Version 1 is for Windows
3.1, BUT NB: programs written with version 1 WILL run under
Windows 95 (to my personal knowledge, including the program
below), and I am confident that they would also run under
98. You would not have access to long filenames. (Big
deal!.. you can use the DOS alias names.) Version 3 has
also appeared on cover discs.
Just to check that the parallel port pins could be controlled
with a Delphi program, I wrote the following tiny program. The form it
relates to has only a button on it. When the program starts,
the button is marked '255' and all of the data lines are at
5v. Clicking the button toggles the system between that
state and one in which the button is marked '0' and all the
data lines are at 0v. The core of the program's
code is as follows:
procedure TForm1.FormCreate(Sender: TObject);
begin
(*initialize*)
button1.caption:='255';
port[888]:=255;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if button1.caption='255' then begin
button1.caption:='0';
port[888]:=0;
(*Makes outputs 0v*)
end(*no ; here*)
else begin
button1.caption:='255';
port[888]:=255;
(*Makes outputs 5v*)
end;
end;
===
Here is a version which will compile in Delphi 2, for Windows 95 and higher. The form has a Timer on it. The timer's interval property is set to 2000. The only other thing the form needs is a label called Label1. Below is EVERYTHING you need from 'implementation' through to the final 'end.'
implementation
{$R *.DFM}
{$R+} {nothing to do with previous $R}
(*The Delphi 2 on-line help has an entry for Mem[<seg>:<offset>], but
the compiler does not seem to recognize it, not does it appear in the
Reference Library Guide. Various postings in usergroups
seem to say that Win95 will not let programs access physical memory.
There was also an entry for something called ExtEscape which looked
promising for sending something to the port, but I haven't explored
that yet, and it didn't appear in Reference Library Guide either.
Peter Below (TeamB) provided the following port access routines
in a newsgroup post. He said push and pop were not needed, that
they were in fact bad ideas. He pointed out that the function uses
the normal Delphi 2/3 register calling convention and thus will get
the first parameter (e.g. IOPort) in eax, the second in edx.
In addition, he said...
This will not work on NT; it works on Win9x only because the OS has a
generic port driver. For NT you need to install such a driver first.
Here are a few URLs worth checking:
TVicHW32 http://www.entechtaiwan.com/tools.htm
DriverX http://www.tetradyne.com*)
Tinyport (NT only)
http://www.winsite.com/info/pc/winnt/programr/tinypo20.zip
procedure PortOut(IOport:word; Value:byte); assembler;
asm
xchg ax,dx
out dx,al
end;
(*More, similar, routines from Peter Blow. They are not needed
in this simple demo program...
function PortIn(IOport:word):byte; assembler;
asm
mov dx,ax
in al,dx
end;
function PortInW(IOport:word):word; assembler;
asm
mov dx,ax
in ax,dx
end;
procedure PortOutW(IOport:word; Value:word); assembler;
asm
xchg ax,dx
out dx,ax
end;
End of material from Peter Blow*)
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if bPoke<>0 then begin
Label1.caption:='0';
bPoke:=0;
PortOut(888,bPoke);
end(*no ; here*)
else begin
Label1.caption:='255';
bPoke:=255;
PortOut(888,bPoke);
end;(*else*)
end;
end.
===
In a newsgroup, I saw: "the TDLPort IO 'wrapper' can be installed as a Delphi component. This allows IO under Win95/98 and (using a different file) Win NT. I know the latter normally blocks attempts to Write to/Read from specific addresses but the
DLL (legally) get around the problem. I'm hoping that the Win95/98 version
will do the same rather than just re-duplicate inpout32. It comes with a
nice manual and is FREE!
Even though there was a lysdexic error in the above, Google found for me this, which leads to....
Name: TDLPortIO 1.3 Date: 12/7/99
Environment: Delphi 3.0, Delphi 4.0, C++ Builder 3.0, C++ Builder 4.0 Download
Type: Freeware with Source Size: 851 Kb
Description:
TDLPortIO is a wrapper for the free DriverLINX kernel mode driver (included).
It allows full port IO under Windows 95/98/NT.
Comes with a C++ Builder and Delphi components,
ActiveX control (for Visual BASIC) and DLL version.
Compatible with the shareware package TVicPort.
===
It is VERY ROUGH still, but I've started a collection of links and information about communicating via the serial port. It is at...
My Serial Port page
This isn't really the time or the place to tell you about the following, but until I can write it up properly....
If you are into making your own electronic devices, you might be interested in the USB modules from
www.ftdichip.com/FTEval.htm. For about $20, you can buy a little unit that plugs into a Win98 or higher machine via USB. On the "outside world" side, it has 8 bidirectional digital input / outputs, and a few handshake lines. The programming isn't trivial, but there is great material about accessing the device. Illustrations in Delphi are provided. You either install a TComPort component (a freeware one, with Delphi source code is available from Dejan Crnila and then access the 8 bits as if (to Win98) they were on a COM port, OR you use a DLL (supplied royalty free from FTDI). It is not exactly a parallel port via USB, but that's roughly the idea.
And, also perhaps in the wrong place, but maybe you'll find fun:
To control 8 lights from the parallel port is extremely easy. If you want to control more, you are going to have to design some external electronics with "latches". Three lines from the parallel port will go to something like a 74138 which selects one line of 8 outputs from the 74138 according to the pattern of ons and offs on the three inputs to the 74138. You will also use one line of the parallel port to say "latch now, data is valid", i.e., the signals you're seeing are the signals I want you to notice. This "latch now" signal is how you avoid problems while the signals are changing. The remaining 4 lines from the parallel port will be data lines. Thus, you will be able to change the state of four lights at a time, but you will have 8 banks of four lights, so the circuit, potentially, could have 40 lights (or other output devices) on it.
Apologies to those of you who've read all of this page carefully... you will have seen this item above... but many people just skip web pages, and I want everyone to know I have designed a parallel port protector that may be of interest. (That page opens in a new window, so you won;t lose this page... and it gives you access to the circuit diagrams.) It puts optoisolators on 4 lines, so you can connect (almost) anything as an input, and puts relays on the other 4 parallel port lines, so you can send outputs to control things easily.
Haven't found what you wanted? Click here to go to a further page consisting mainly of links to other resources.
Ad from page's editor: Yes.. I do enjoy compiling these things for you...
hope they are helpful. However.. this doesn't pay my bills!!! If you find
this stuff useful, (and you run an MS-DOS or Windows PC) please visit my
freeware and shareware page, download something, and circulate it for me?
At least (please) send an 'I liked the parallel port use page, and I'm
from (country / state)' email? (No... I don't do spam)
Links on your page to this page would also be appreciated!
Don't forget to check out the programs for controlling the state of the parallel port at my shareware site. There are two free programs there... one for toggling bits, the other for using the computer as a timer via the parallel port.
If you want to email page's
editor, Tom Boyd, please click here and read a short message. My eddress if given there.
Click here to go up to general 'electronic projects' page by editor of this page.
Why does this page have a script that loads a tiny graphic? I have my web traffic monitored for me by eXTReMe tracker. They offer a free tracker. If you want to try it, check out eXTReMe's site