Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Parallel Port Trigger
#1
I need to trigger a program to run with a contact closure that will interface through a parallel port. I've never done anything like this before. I've found some C# program stuff, but I've never worked with anything outside of QM. Please help me through this.

Here are some things I've found so far:
http://jaspreetscodezone.blogspot.com/20...ntrol.html
http://logix4u.net/Legacy_Ports/Parallel...NT/XP.html
http://www.hytherion.com/beattidp/comput/pport.htm

From what I understand, parallel ports use a high and low voltage (0 and 5V) to send bits of data. So I am pretty sure, but not positive, that the contact closure will just send a high signal on just one of the pins. I'll just need to grab that as a trigger to fire a program that will play audio.

Is there anyway to do this with just QM or do I have to get into other languages.

Thanks for any help,
Jimmy Vig

**Work so far...
#2
Download from link 2 and register hwinterface.ocx in menu Tools -> Type Libraries.

Function dlg_parallel_port
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages

typelib HWINTERFACELib {BD6BB71B-5C9A-4FB3-877E-8B513D28B951} 1.0

str controls = "8 10"
str e8 e10
e8=255
e10="0x0378"
if(!ShowDialog("dlg_parallel_port" &dlg_parallel_port &controls)) ret

;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 223 135 "Parallel Port"
;1 Button 0x54030001 0x4 120 116 48 14 "OK"
;2 Button 0x54030000 0x4 170 116 48 14 "Cancel"
;3 ActiveX 0x54030000 0x0 206 4 12 10 "HWINTERFACELib.Hwinterface {B9022892-EA92-4F94-8101-B9CDE30E667D}"
;6 Button 0x54032000 0x0 44 34 62 14 "send to output"
;7 Static 0x54000000 0x0 8 18 98 12 ""
;8 Edit 0x54030080 0x200 8 34 32 14 ""
;9 Static 0x54000000 0x0 10 78 34 12 "Port"
;10 Edit 0x54030080 0x200 46 76 32 14 ""
;5 Button 0x54020007 0x0 4 62 108 36 "Config"
;4 Button 0x54020007 0x0 4 4 106 50 "Input and output"
;END DIALOG
;DIALOG EDITOR: "" 0x2030002 "*" "" ""

ret
;messages
HWINTERFACELib.Hwinterface x._getcontrol(id(3 hDlg))
int port=val(_s.getwintext(id(10 hDlg)))

sel message
,case WM_INITDIALOG
,SetTimer hDlg 1 50 0
,
,case WM_TIMER
,sel wParam
,,case 1
,,_s=x.InPort(port)
,,_s-"input is: "
,,_s.setwintext(id(7 hDlg))
,
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case 6
,_s.getwintext(id(8 hDlg))
,x.OutPort(port val(_s))
,
,case IDOK
,case IDCANCEL
ret 1
#3
Thanks a bunch for your help.

I am just trying to figure this out in advance, I don't have access to the Parallel port device I am going to be using, but when I load this up on my computer with nothing in the parallel port I get "Input is: 255" This 255, that's the what I should get in this instance? Then I should see that number change when a signal is received?

Also what are the four values received by SetTimer function.

Thanks again,
Jimmy Vig
#4
It should change when a signal received. I cannot test too.

SetTimer is documented in MSDN library.
#5
Another quick question or two:

When I export this as an .exe will the hwinterface.ocx file go with it or will I have to do something special. I just want to know little details like this in advance.

Also what exactly is "0x0378"
0x0376 jumps between 80 and 208
0x0377 is 255
0x0378 is 255
0x0379 is 120
others are 0
Most are 255
What do these number represent?

Ok...I see in Device Manager->Printer Port(LPT1)->Resources
there is I/O Range 0378-037F

When I change the value of the "send to output" the next time I open the dialog, the input reads as the new value. Is this what it is supposed to do?

I've been trying to skim stuff on parallel ports, but to be honest it is a bit above my head for now, any little extra information would be much appreciated!

Thanks again
#6
I tested a bit...I could not get the 255 of the input to change by closing contacts, but I could get a voltage reading to go down when I would send a number to the output.

I am going to test some more and see if I am just messing it up.

I would really like to know how to read each pin on the parallel port...I've been trying to make it through all the garble on parallel ports, but it is greek to me still.

Any light on this would be awesome. Thanks.
Jimmy Vig
#7
Maybe this relates to my problem...
From http://blogs.msdn.com/ericgu/archive/200...-port.aspx
"EPP ports aren't automatically configured for input. You need to set bit 5 in the control register (at the base address + 2) to turn it on."

How do I do this? Would this be 0x37a for the port address? What would be the correct value to send to output?

So is this talking about Pin 1 (nStrobe)? I think I remember somewhere else saying something about this toggling between read and writing data.

I don't know...still don't get this stuff, but I am on the edge of understanding.

Also, what's a quick way to convert a number into the 8 bit binary that I would see from the parallel port inputs....for example 255 is 11111111 which would be all high...right?

Thanks,
Jimmy Vig
#8
Figured out the 8-bit binary...it's not too hard really

Function Convert_to_Binary
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages

;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 90 65 "8-Bit Binary"
;2 Button 0x54030000 0x4 44 46 40 14 "Close"
;3 Edit 0x54030080 0x200 4 10 80 14 ""
;4 Edit 0x54030080 0x200 4 26 10 14 ""
;5 Edit 0x54030080 0x200 14 26 10 14 ""
;6 Edit 0x54030080 0x200 24 26 10 14 ""
;7 Edit 0x54030080 0x200 34 26 10 14 ""
;8 Edit 0x54030080 0x200 44 26 10 14 ""
;9 Edit 0x54030080 0x200 54 26 10 14 ""
;10 Edit 0x54030080 0x200 64 26 10 14 ""
;11 Edit 0x54030080 0x200 74 26 10 14 ""
;12 Button 0x54032000 0x0 4 46 40 14 "Convert"
;END DIALOG
;DIALOG EDITOR: "" 0x2030001 "" "" ""

str controls = "3 4 5 6 7 8 9 10 11"
str e3 e4 e5 e6 e7 e8 e9 e10 e11
e3=0
e4=0
e5=0
e6=0
e7=0
e8=0
e9=0
e10=0
e11=0
if(!ShowDialog("Convert_to_Binary" &Convert_to_Binary &controls)) ret

ret
;messages
sel message
,case WM_INITDIALOG
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case 12
,int Source=id(3 win("8-Bit Binary" "#32770"))
,int b1=id(4 win("8-Bit Binary" "#32770"))
,str s
,int b
,str ss.getwintext(Source)
,int S=val(ss)
,if S>255
,,mes "8-bit binary cannot excede 255" "8-bit Binary" "!"
,,ret
,CURRENCY i i0 i1 i2
,i=4
,i0=S
,rep 8
,,i0.div(i0 2)
,,i1.round(i0)
,,i2.sub(i0 i1)
,,if i2=0
,,,s=0
,,,out s
,,,s.setwintext(id(i win("8-Bit Binary" "#32770")))
,,,i=i+1
,,else
,,,i0.sub(i0 0.5)
,,,s=1
,,,out s
,,,s.setwintext(id(i win("8-Bit Binary" "#32770")))
,,,i=i+1
,case IDOK
,case IDCANCEL
ret 1
#9
Function DecToBin
Code:
Copy      Help
;/
function i str&sBin

;Converts from decimal (base-10) number to binary (base-2) number, eg 5 to "101".
;Although there are 32 bits, leading 0 bits are trimmed.

;EXAMPLE
;str s
;DecToBin 5 s
;out s


sBin.all(32)
itoa i sBin 2
sBin.fix

Function DecFromBin
Code:
Copy      Help
;/
function# $sBin

;Converts from binary (base-2) number to decimal (base-10) number, eg "101" to 5.

;EXAMPLE
;int i=DecFromBin("101")
;out i


if(!sBin) ret
ret strtoul(sBin 0 2)

-------------

I don't know how parallel port works more than i can read in http://logix4u.net/Legacy_Ports/Paralle ... acing.html
#10
http://www.beyondlogic.org/spp/parallel.htm

Ok...so the program you so kindly got me started on polls the changes on the data inputs. I really would like to use the IRQ for an interrupt instead. Do you see from the literature above how I would do this in QM. There is a program written in C given as an example, but I don't know how to recreate that in QM.

I see that I need to set Bit 5 on Base+1 port to high(1) to be able to input and to low(0) to be able to output. I think that is what will allow me to read contact closures, I can't test until I get back onto a PC, my laptop does not have a Parallel port.

Thanks again.
#11
x.OutPort(port+2 0x20) ;;set 5-th bit in the control register

------------

QM cannot receive hardware interrupts.
#12
Parallel Port reader works great. I am just putting the finishing touches on it and I will post the code.

How would I go about exporting the program to run on non-QM machine. I need to know what to do with the hwinterface control. Could you please give a detailed explanation how to register the osx without QM if that is possible.

Thanks.

So the Parallel Port is actually a pretty neat tool. I can wire any old button up to the parallel port and blammo...extra external control for the computer. So far I have figured out how to successfully read the 8 Data pins, I guess I am supposed to be able to use four control pins and maybe the five status pins too, but I haven't gotten that far yet. Basically I can add eight switches...any type of buttons, momentary, small, large, on/off and use them to fire off programs. If you really wanted you could have an on/off switch maximize a screen when on and minimize when off...so many possibilities!

Thanks for all your help Gintaras!

Jimmy Vig
#13
Will it have a setup program? For example, you can use Inno Setup to create setup programs. It can install the COM dll.

Or the macro can install it using RegisterComComponent function.

Note that if you move the dll to another folder, you must register it again.

-----------------

Or use the dll version (inpout32.dll). Then it just must be in the same folder as your exe or somewhere where Windows could find it. Also, then dialog is not necessary because it is not an ActiveX control.

Function dlg_parallel_port2
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages

;http://www.quickmacros.com/forum/viewtopic.php?p=13572
;http://logix4u.net/Legacy_Ports/Parallel_Port/Inpout32.dll_for_Windows_98/2000/NT/XP.html

dll inpout32.dll
,#Inp32 @PortAddress
,Out32 @PortAddress @data

str controls = "8 10"
str e8 e10
e8=255
e10="0x0378"
if(!ShowDialog("dlg_parallel_port2" &dlg_parallel_port2 &controls)) ret

;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 223 135 "Parallel Port"
;1 Button 0x54030001 0x4 120 116 48 14 "OK"
;2 Button 0x54030000 0x4 170 116 48 14 "Cancel"
;6 Button 0x54032000 0x0 44 34 62 14 "send to output"
;7 Static 0x54000000 0x0 8 18 98 12 ""
;8 Edit 0x54030080 0x200 8 34 32 14 ""
;9 Static 0x54000000 0x0 10 78 34 12 "Port"
;10 Edit 0x54030080 0x200 46 76 32 14 ""
;5 Button 0x54020007 0x0 4 62 108 36 "Config"
;4 Button 0x54020007 0x0 4 4 106 50 "Input and output"
;END DIALOG
;DIALOG EDITOR: "" 0x2030002 "*" "" ""

ret
;messages
int port=val(_s.getwintext(id(10 hDlg)))

sel message
,case WM_INITDIALOG
,SetTimer hDlg 1 50 0
,
,case WM_TIMER
,sel wParam
,,case 1
,,_s=Inp32(port)
,,_s-"input is: "
,,_s.setwintext(id(7 hDlg))
,
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case 6
,_s.getwintext(id(8 hDlg))
,Out32(port val(_s))
,
,case IDOK
,case IDCANCEL
ret 1
#14
Trying to get RegisterComComponent to work and not having the best of luck.

Say inpout32.dll is in dir "$program files$\Parallel_Port\"

What would I run as a command to register that from QM.

RegisterComComponent "C:\Program Files\Parallel_Port\inpout32.dll" 4|8

Returns an error message:
"C:\Program Files\Parallel_Port\inpout32.dll was loaded but the DllRegiterServer entry point was not found. This file can not be registered."

Please advise.
Jimmy Vig
#15
inpout32.dll does not need to be registered. Only the ocx, if you use it. But better use inpout32.dll.
#16
So I use RegisterComComponent to register the osx?

In dlg_parallel_port2 is that what you did?

"Or use the dll version (inpout32.dll). Then it just must be in the same folder as your exe or somewhere where Windows could find it. Also, then dialog is not necessary because it is not an ActiveX control."
Not quite sure what you mean here....

Sorry to be a bug about this.
#17
dlg_parallel_port2 does not use ocx. If you use dlg_parallel_port2, you don't need RegisterComComponent.

The ocx cannot be used not in a dialog. The dll can.
#18
I'm a little slow to the draw...where do I put the .dll to get it to work. When I try to make an .exe it won't let me because the .dll can't be found. So how can I put the .dll in the same folder. Where is somewhere windows can find it. I am pretty new to programming and .dll's are still to me those annoying things that get corrupted and make me scream!

Could I get a simplified step by step...starting with right after I download the dll...then I??
#19
Put the dll in the same folder as your exe.
Also copy it to the QM folder.
Or put it in Windows\System32.
Or put it in any folder and use full path with the dll statement.
#20
Cannot make exe. Error 4, failed to compile.

Highlights..."inpout32"

I am so sorry to tie you up like this...I know I am missing something really simple and it is driving me crazy...

Thank you for everything.
#21
The System32 folder was it...

I got it!

Awesome. Thank you so much...and again...sorry to tie you up.
#22
Ok, on your computer you can put the dll in system32, or in a folder specified by the PATH environment variable. Then you don't need to have 2 dlls - 1 in qm folder and 1 in exe folder.
On other computers, put the dll in the same folder as the exe. Or in system32.
#23
Ok...I think I have most of the kinks worked out for this. There is a long explanation in a Read Me function in the .qml

To date this is the most interesting project I have done...I'm still thinking of ways to use it, but the possibilities are pretty rad...well to me it's new...maybe to you guys out there this is an old trick.


Attached Files
.qml   Parallel Port Reader.qml (Size: 14.55 KB / Downloads: 533)


Forum Jump:


Users browsing this thread: 1 Guest(s)