Jump to content


Photo

LPT port I/O control. 32 in, 12 out. LEDs ,Relays, Switches.


  • Please log in to reply
23 replies to this topic

#1 specter333

specter333
  • Members
  • 606 posts

Posted 02 April 2012 - 03:39 PM

Parallel Port Monitor and Controller.
LTP port two way communication.
Use buttons or switches for AHK script input and control LEDs or Relays from the outputs.

The LTP port I/O Library was re-upped on 8-21-12. All example scripts and photos were lost in the ahk.net crash.


I've seen many questions asked about this before and now I have a need for it so I've finally figured out how to use AHK for monitoring the parallel port inputs and controlling outputs. We'll I actually I found this link to the German forums where someone had figured it out already and Google Translate helped me figure out what they did.
Posted Image


Read This First!
First a word of warning. I know very little about electronics. Most resources I found suggest using a resistor to protect the LED and an isolator to protect your computer. I had neither of these and was lucky I didn't destroy anything.

It is my understanding that if your computer does not have protection built in to the parallel port a short circuit can fry the mother board. Use caution when using this script and get advice from an electronics tech before connecting anything to your parallel port.




The LPT I/O library.
The dll calls aren't difficult but I've made a library to make it as easy as possible.
LPTInOut.ahk

There are only 4 functions, In, Out, All On and All Off.
/*
Parallel Port Monitor and Controller.
LTP port two way communication.
Use buttons or switches for AHK script input and control LEDs or Relays from the outputs.

http://www.autohotkey.com/forum/viewtopic.php?p=525428

The DLL calls were found in the AHK German forumns.
http://de.autohotkey.com/forum/topic5559.html

[color=brown]LPTInOut_Out(num,port)[/color]  ; num is the value relating to the pins to activate.  port is the port address.
; This function must be called independently for the first eight and last four pins as they will be 
; on two different addresses.

[color=brown]LPTInOut_In(port)[/color] ; port is the port address.  Use a timer to constantly check the value present at this port.

[color=brown]LPTInOut_Off(LPTA,LPTB)[/color] ; LPTA is the port number of pins 1 thru 8 and LPTB 9 thru 16.
[color=brown]LPTInOut_On(LPTA,LPTB)[/color] ; These functions need only be called once to controls all 12 pins.

Detailed information can be found below the functions.
*/

; Out

LPTInOut_Out(num,port)
	{
	DllCall("INPOUT32\Out32",int,port,int,num)
	}


; In

LPTInOut_In(port)
	{
	LTPmon := DllCall("INPOUT32\Inp32",int,Port)
	Return, %LTPmon%
	}


; All Off

LPTInOut_Off(LPTA,LPTB)
	{
	DllCall("INPOUT32\Out32",int,LPTA,int,0)
	DllCall("INPOUT32\Out32",int,LPTB,int,11)
	}

	
; All On

LPTInOut_On(LPTA,LPTB)
	{
	DllCall("INPOUT32\Out32",int,LPTA,int,255)
	DllCall("INPOUT32\Out32",int,LPTB,int,20)
	}


/*
The parallel connector.  
This chart identifies the pin numbers as seen on the computer port. 

S4  S5  S7  S6  D7  D6  D5  D4  D3  D2  D1  D0  C0
  G7  G6  G5  G4  G3  G2  G1  G0  C3  C2  S3  C1
  
S = Status or input pins.
D = Data or output pins 1 thru 8.
C = Combo or output pins 9 thru 12, in some cases these can be used as inputs.
G = Ground pins.

Each LPT port will have three address, the first is for the first eight inputs, D0 thru D7.
The second for the last four inputs, C0 thru C3. The third for the inputs S3 thru S7.  
Note that S0 thru S2 are not included on the connecter.

The typical addresses for LPT1 are,
0x378 for output pins 1 thru 8 or D0 thru D7.
0x37A for output pins 9 thru 12 or C0 thru C3.
0x379 for input pins 1 thru 5 or S3 thru S7.
These may be different on some systems.
*/	
	
/*
LPTInOut_In(port)
Use a timer to constantly monitor the input pins 1 thru 5 (S3 thru S7).  
A value will always be present when monitoring, if no pins are activated it will read 120.

-------------------------------------------------------------------------------------------
Here is a short monitoring example script.

^m::
SetTimer, Monitor, 250
Return

Monitor:
lptin := LPTInOut_In("0x379")  ; This is the typical address for LPT1.

If lptin = %LastRead%  ;  Keeps the script from running the associated subroutine everytime the timer runs.
	Return             ;  The subroutine only runs when a new input value is read.

LastRead = %lptin%  ;  Remembers the last input value for above.
	
If IsLabel(lptin)
	GoTo %lptin%
Return


112:
MsgBox, Pin 1(S3) has been activated.
Return

128:
MsgBox, All 5 input pins have been activated.
Return
-------------------------------------------------------------------------------------------


This chart shows the avallable input values and the combination of pins needed to set them.


		
		1		2		3		4		5
		S3		S4		S5		S6		S7
0 = 	x		x		x		x						S3 S4 S5 S6
8 = 			x		x		x						S4 S5 S6
16 = 	x				x		x						S3 S5 S6
24 =					x		x						S5 S6
32 = 	x		x				x						S3 S4 S6
40 = 			x				x						S4 S6
48 = 	x						x						S3 S6
56 = 							x						S6
64 = 	x		x		x								S3 S4 S5
72 = 			x		x								S4 S5
80 = 	x				x								S3 S5
88 = 					x								S5
96 = 	x		x										S3 S4
104 = 			x										S4
112 = 	x												S3
120 = 										All Open
128 = 	x		x		x		x		x	All Active	S3 S4 S5 S6 S7
136 = 			x		x		x		x				S4 S5 S6 S7
144 = 	x				x		x		x				S3 S5 S6 S7
152 = 					x		x		x				S5 S6 S7
160 = 	x		x				x		x				S3 S4 S6 S7
168 = 			x				x		x				S4 S6 S7
176 = 	x						x		x				S3 S6 S7
184 = 							x		x				S6 S7
192 = 	x		x		x				x				S3 S4 S5 S7
200 = 			x		x				x				S4 S5 S7
208 = 	x				x				x				S3 S5 S7
216 = 					x				x				S5 S7
224 = 	x		x						x				S3 S4 S7
232 = 			x						x				S4 S7
240 = 	x								x				S3 S7
248 = 									x				S7
*/


/*
LPTInOut_Out(num,port) Pins 1 thru 8 (D0 thru D7).

Each of the first eight ouput pins are assigned a value shown in this chart.
Pin 1(D0) = 1
Pin 2(D1) = 2
Pin 3(D2) = 4
Pin 4(D3) = 8
Pin 5(D4) = 16
Pin 6(D5) = 32
Pin 7(D6) = 64
Pin 8(D7) = 128

To activate any single pin simply call it's value and the LPT port address.
LPTInOut_Out(1,"0x378") This activates pin 1(D0) on LPT1. 

To activate multiple pins, add their values together.
LPTInOut_Out(3,"0x378")  This activates pins 1(D0) and 2(D1) on LPT1.

To deactivate all eight pins use the value O.
LPTInOut_Out(0,"0x378")
*/


/*
LPTInOut_Out(num,port) Pins 9 thru 12
These pins behave differently as some of them are normally hot meaning they are active until they receive a value
that deactivates them.  For this reason they can not be controled by adding their values.  Instead call a value
from this chart.

		C0		C1		C2		C3
		9		10		11		12
1				x				x		
2		x						x
3								x
5				x		x		x
6		x				x		x
7						x		x	
8 		x		x
9				x
10		x	
11 									All Off
12		x		x		x
13				x		x
14		x				x
15						x
16		x		x				x


20		x		x		x		x	All On


Example
LPTInOut_Out(8,"0x379")  This activates pins 9(C0) and 10(C1) on LPT1.


You should also use the ALL Off call in the autoexecute section of your scripts to have all pins
start in the off state.
LPTInOut_Out(11,"0x379")  Deactivates pins 9(C0) thru 12(C3) on LPT1.
or
LPTInOut_Off("0x378","0x37A")   Deactivates all output pins on LPT1.
*/

On most computers the parallel port will be LPT1 which is normally going to be at the addresses of 0x378 for outs 1 thru 8, 0x37A for 9 thru 12 and 0x379 for the inputs. The following picture shows the pin configuration.

Posted Image
Red = Out puts 1 thru 8. Orange = Outputs 9 thru 12. Blue = Inputs. Green = Grounds.

This photo and a large part of my education on the subject comes from the article I/O Ports Uncensored by Levent Saltuklaroglu.

Outputs, control up to 12 LEDs or Relays.

All other LPT examples I've seen only allow use of the first eight outputs, 9 thru 12 can be problematic as some but not all are normally powered. The numbers called to control these pins were found by trial and error. The values are listed in the LPT In/Out library.

The first eight pins work by simply adding the values to turn on the correct pins. Values are as follows.

D0 = 1
D1 = 2
D2 = 4
D3 = 8
D4 = 16
D5 = 32
D6 = 64
D7 = 128For example, to use pins D3 and D4 you would call 24. If any pins were already on they are turned off when the new call is made.

To use all 12 pins two calls must be made. The value of the first eight pins along with the address and the value and address of the last four.
LPTInOut_Out(255,"0x378") ; 1 thru 8 on
LPTInOut_Out(20,"0x37A") ; 9 thru 12 on

Using the LPT Control script takes care of finding the correct values to call. Just check the box by the pins to use, and set the port numbers in the boxes.
LTP Control.ahk
Posted Image



Inputs, 32 combinations of inputs from five buttons or switches.

The inputs, S3 thru S7 return a combination of thirty two values when activated. To activate I simply grounded the pins using toggle switches. READ THE WARNING ABOVE BEFORE TRYING THIS. The pin combinations are as follows.
0 = S3 S4 S5 S6
8 = S4 S5 S6
16 = S3 S5 S6
24 = S5 S6
32 = S3 S4 S6
40 = S4 S6
48 = S3 S6
56 = S6
64 = S3 S4 S5
72 = S4 S5
80 = S3 S5
88 = S5
96 = S3 S4
104 = S4
112 = S3
120 = All Open
128 = S3 S4 S5 S6 S7
136 = S4 S5 S6 S7
144 = S3 S5 S6 S7
152 = S5 S6 S7
160 = S3 S4 S6 S7
168 = S4 S6 S7
176 = S3 S6 S7
184 = S6 S7
192 = S3 S4 S5 S7
200 = S4 S5 S7
208 = S3 S5 S7
216 = S5 S7
224 = S3 S4 S7
232 = S4 S7
240 = S3 S7
248 = S7

When the port is being monitored the numbers being returned can be used as labels in your scripts. There will always be a number present, if no inputs are active "120" will be read from the port.

This input monitor script watches the port and if a label matching the input value is read it will execute the subroutine. Add subroutines directly to the script using the edit box on the bottom. Activate your switches to set the input value to the desired value. The value is entered into the edit box as a label. Fill in the subroutine and click "Add Subroutine". The new subroutine is added directly to the bottom of the script and the script reloads making it immediately active. Because the input value will still be the same, the new subroutine will run immediately when the script reloads, so beware.
LPT Monitor.ahk
Posted Image



Input Monitor and Output Sequencer.

This overly complex script not only monitors the input pins but allows you to build sequences to control LED lights. The first twelve input values control the outputs in real time making it easy to control the LEDs. Here is a animation demonstrating the five input pins controlling 12 LEDs.
LTP Monitor and Sequencer.
Posted Image

The sequencer;

:arrow: Select the LED lights to use.
:arrow: Enter the time in milliseconds to display the step.
:arrow: Click Record.
:arrow: Click Test to run the sequence.
:arrow: Check Loop to repeat the sequence. Uncheck to stop.
:arrow: Enter a name and save the sequence as it's own AHK script. Posted Image
Double click a row to delete it.
Right click the first column to adjust the time.
These edits can be made while the sequence is running.

Here is a small vid of a LED sequence. Lost in the ahk.net crash.


Don't forget, all these scripts need the LPT In/Out library.

#2 gwarble

gwarble
  • Members
  • 508 posts

Posted 02 April 2012 - 05:57 PM

Wow, very nice work, i cant wait to try this
Nice post too

#3 Drugwash

Drugwash
  • Members
  • 1048 posts

Posted 02 April 2012 - 07:01 PM

Your post reminds me why I built my first computer, many years ago: to automate things around the house. To the day, I never even got to control the light at the fish tank. Actually, I have no idea what I've done with my life until now. :( Thank you for reminding me why there's 13 computer units in my room and I'm still living in the stone age...

BTW, LEDs need current limitation through resistors, otherwise they may get fried. Requirements may go from ~15-20mA (regular LED) to Amperes for super-bright LEDs. Drop voltage also ranges from 2V to 3.5V according to LED color. More information here and here. Also, each relay (if any) would need a transistor buffer, for both safety and current draw limit; it would be best to use an external voltage source to power up the relays, to avoid computer's PSU failure if the external circuit gets damaged or requires too much power.

Also please note the LPT port(s) may have other addresses assigned. 03BC-03BF/07BC-07BF or 0278-027F/0678-067B are only two of the possibilities listed in my device manager on the XP machine.
Not to mention that LPT1 range may also be modified in certain BIOS versions (especially in older machines). So I believe a decent script should first read the currently assigned I/O range for the desired LPT port, before sending or receiving any commands.

#4 specter333

specter333
  • Members
  • 606 posts

Posted 03 April 2012 - 12:16 AM

Thanks guys, I appreciate the comments and Drugwash thanks for the info and links. The idea of finding it's own port range is a very good idea. I'll have to see if I can figure it out.

I had been up all night working on getting this ready to post and now I see quite a few mistakes and a lot of info I forgot to include. Mostly I think I should make the warning message stand out more. I'd hate to see anyone fry their computer because of this.

To control your fish tank light, or any other lights or appliances, you should check out the X10 Library. It's easy to control things around the house with this and no worries of frying your computer. I built a controller to raise and lower my video screen using two of their relays.

I actually was working on this for a massive project I'm in the middle of and I've now figured out this method is not going to work for the project. But I still wanted to get what I learned posted for others to use. This method only works for built in parallel ports. It will not work for added on ports by usb, pci card or any other type of add on. If anyone knows how to control add on parallel ports please post the information.

I was hoping to use several ports per computer but I can only control the built in one... and I need to control 64 displays.

I'm in the process of building sets for an upcoming Star Trek fan film called Starship Ajax. As you can see in this photo there are a lot of holes to fill in these consoles.
Posted Image

I was hoping to control LEDs directly from the LPT ports to avoid the cost of using external controllers. I've found some suitable USB cards I could use but they are $70 each. Multiply that by 64 displays and then the cost of the rest of the parts and the budget is shot. I've been shown some stand alone cards that would work but they are still $30 each.

At this point it looks as if our best option is to buy pallets of lcd monitors at auctions and use them instead. I hate that it won't be authentic but it will save us a huge amount of cash. Any suggestions for this project would also be appreciated.

#5 gwarble

gwarble
  • Members
  • 508 posts

Posted 03 April 2012 - 01:14 AM

How many LEDs total? Inputs? Other outputs...

You can use devices like u-hid, ledwiz, gpwiz, i-pac...

U-hid works great, 50 inputs less up to 16 as outputs, for $80...
Also you could get creative with wiring/combinations/banks of lights to the same output signal... think pinball machine

good luck, and thanks again for sharing this

Edit: ledwiz32 gives you 32 output signals for $45 bucks, claims up to 500 leds per board, and you can hook up 16 to one pc, also gives you pulse width modulation (any color with a RGB led using 3 output pins) or waveforms so your ahk script wont have to do all the blinking

Not affiliated, just have used u-hid and ipac for smaller projects with good success

#6 specter333

specter333
  • Members
  • 606 posts

Posted 03 April 2012 - 01:54 AM

How many LEDs total? Inputs? Other outputs...


There are not many inputs so that's no problem. I haven't counted the number of outputs but I don't think there are more than 12 per display even if the display has 60+ LEDs on it. I think that's all they had on their original controllers.

Here is a script I made for what looked like the simplest one. It has 11 LED lights.
Engineering 1.

Posted Image

The LPT1 outputs are working in conjunction with the graphics on the gui. Don't have anything connected to LPT1 other than LEDs when you run this.

Edit;

I forgot to mention you need to download the pic to use with the script.

#7 gwarble

gwarble
  • Members
  • 508 posts

Posted 03 April 2012 - 03:19 AM

If any are toggling one on and one off together, that can be accomplished with one output dont forget

64 displays? so 8 computers each driving 8 displays, or 96 outputs each at 12 per console, or three $45 32output boards totals to $135 x 8 is $1080? or so... what kind of budget are you thinking? 8 pcs to drive them should be cheap or free, talk to your local recycler i get working 3ghz p4s for 0-$10


Cool plan and interface

#8 Drugwash

Drugwash
  • Members
  • 1048 posts

Posted 03 April 2012 - 05:02 AM

i get working 3ghz p4s for 0-$10

This is one of the (rare) occasions when I wish I lived in the US. :roll: I mean... darn, I had to disassembly my Internet gateway computer three times and replace a total count of 19 gonflated/leaky capacitors on the motherboard to restore its functionality! When I look around and see myself surrounded by Pentium I - Pentium II machines, I feel like setting them all on fire and running away along the streets, howling. :(

Back to topic: why not build yourself a few mux/demux boards using old-school CMOS ICs, complete with latches and output buffers (I think they were called ULN 2003 or similar)? Or would that be too expensive and/or time consuming? I used to work with logic circuitry about ten years ago, but parts were quite expensive and/or hard to find so I finally gave up electronics altogether, although I still fix some gizmos every now and then for my friends in need.

#9 specter333

specter333
  • Members
  • 606 posts

Posted 03 April 2012 - 12:12 PM

Back to topic: why not build yourself a few mux/demux boards using old-school CMOS ICs, complete with latches and output buffers (I think they were called ULN 2003 or similar)?


The problem with this is I have been supplied very precise graphics from TOSGraphics.com which all exactly replicate the original displays. This means each graphic needs it's own controller as no two of them are the same or have the same pattern of flashing lights.

If any are toggling one on and one off together, that can be accomplished with one output dont forget

I'm not sure what you mean by this.

64 displays? so 8 computers each driving 8 displays, or 96 outputs each at 12 per console, or three $45 32output boards totals to $135 x 8 is $1080?

I'm going to check on these boards. 24 boards at $45 each is much better than 64 at $30 each. However I still have to consider the rest of the display, building the structure, buying the LEDs and resisters, printing the graphics, wiring and power supplies... Still a lot of expense.

The alternative is free computers, $10 LCD monitors, $10 graphics cards and $2 cables.

It's going to be a judgement call as to whether it's worth it. We intend to let anyone who wants to make their own fan film use this studio, so if there is enough interest then it will be. If it turns out to be only this one series then probably not.

#10 gwarble

gwarble
  • Members
  • 508 posts

Posted 03 April 2012 - 04:37 PM

Yeah leds, and your time wiring, will add up quick, lcds would probably look great...


As for the first "huh", if there are two outputs, that toggle together(ie one turns on the other turns off and vice versa) you can combine into one output with a relay or other to toggle them (normally open/ normally closed)

#11 Drugwash

Drugwash
  • Members
  • 1048 posts

Posted 03 April 2012 - 10:16 PM

The problem with this is I have been supplied very precise graphics from TOSGraphics.com which all exactly replicate the original displays. This means each graphic needs it's own controller as no two of them are the same or have the same pattern of flashing lights.

I was about to type all kind of old-school nonsense about CMOS circuits, but I realize that technology is far outdated. It is doable, but at a quite high expense in terms of both money and time. I guess you're better off using dedicated boards that were mentioned above. Even using PIC or Flash ROM would still require output buffers and other circuitry.

Guess there's a reason I quit electronics years ago...

#12 specter333

specter333
  • Members
  • 606 posts

Posted 03 April 2012 - 11:25 PM

I was about to type all kind of old-school nonsense about CMOS circuits, but I realize that technology is far outdated. It is doable, but at a quite high expense in terms of both money and time. I guess you're better off using dedicated boards that were mentioned above. Even using PIC or Flash ROM would still require output buffers and other circuitry.

Guess there's a reason I quit electronics years ago...


As I stated in the first post I'm not very knowledgeable about electronics. I goggled the part number, took a quick look and guessed that this was a type of relay that still only gave me 12 channels from the lpt port. Sorry if I was mistaken.

#13 Drugwash

Drugwash
  • Members
  • 1048 posts

Posted 04 April 2012 - 12:35 AM

It's more complicated than that. ULN2003 (2001/2002/2003/2004) is just a buffer with 7 input/outputs (I was wrong in assuming it had 8 in/out, so it's not suitable for our purpose, unless none of the displays requires more than 14 LEDs - details here and here). Full logic would include 4 demultiplexers (CD4067) with 16 outputs, and a CD4052 or CD4051 to command them on their INHIBIT input. On top of that, each display would need two 8-bit latches (CD4099 or CD4599, not sure which is more fit), which means 128 latch circuits. Each output from each latch needs a buffer that can take the maximum current required by its respective LED. The ULN integrated buffers mentioned above have a maximum of 500mA per channel (see the datasheets linked above); for more current, use transistors instead.

As I said in previous post, this is doable, but may not be feasible, especially considering the latches must be programmed serially. There can be alternatives to this circuit, using an EEPROM that can deliver 8 or 16 bits at a time (parallel latch), or PIC circuits that can contain the moving sequence stand-alone, with no computer control except for start/stop/pause. Unfortunately I cannot help in that area, as I quit the domain before getting to learn PIC programming and usage.

Anyway, the idea is, there are alternative solutions to one problem - it all depends on budget, time, parts availability, knowledge and of course, dedication. I could attempt to draw the schematic for the CMOS solution, if you want.

#14 specter333

specter333
  • Members
  • 606 posts

Posted 05 April 2012 - 07:00 PM

Thanks but I didn't understand much of what you said above. Plus, I'm sure buying that many parts will still add up to $30 or more for each control circuit which is what one of those stand alone processors cost. But I at this point it's still up in the air so I may be asking for more info later.

#15 Drugwash

Drugwash
  • Members
  • 1048 posts

Posted 06 April 2012 - 07:58 AM

Think binary. Four outputs of the LPT can control - through demultiplexing (2^4=16) - sixteen LEDs, which is what you need for one display at a time. A latch circuit will preserve the on/off state of its outputs no matter the input data, when WRITE is disabled. Only one display will have its LEDs "programmed" to turn on/off at a time. So all the LEDs can be turned on or off sequentially through the same common 16 inputs of the latches, driven by a single 16-bit demultiplexer.

That said, you'll still have eight LPT outputs to control the displays, through the same demux system. Six outputs will do (2^6=64 displays). One output will hold the data to be written to the latches (1 or 0, corresponding to On or Off). Last output will be used for the Write command.

All this is theory; here's the schematics, for analysis - there are software apps that can draw and analyze a schematic, so you may test it virtually. It may need some tweaking. Could be useful at least for a better understanding of logical circuitry.

Posted Image