Sign in to follow this  
Followers 0
suthers

Parallel Port Control

11 posts in this topic

Hi All,

This is a simple script to demonstrate the capacity to interface AutoIT to the real world using the parallel port and the free inpout32.dll library. It allows you to set the data and control pins, and read the data, control and status pins. By using the functions in your own scripts (and building some electronics to connect to the port) you can use AutoIT to control something real, or have something real control AutoIT. The DLL works on any 32 bit windows from 9x to XP, but only on real (hardware) parallel ports (on the motherboard or a PCI card). It WILL NOT work on USB to parallel port adaptors. If your PC doesn't have a parallel port, you'll need to get a PCI parallel card to use this approach (which will count out most new laptops).

Download the DLL at

http://www.logix4u.net/inpout32.htm and place it in the same dir as the script

Instructions for electronics construction can be found at

http://www.epanorama.net/circuits/parallel_output.html

Have Fun! (I'm making IP controlled door openers...)

Shalom

Bill

#Include <Constants.au3>
Opt("TrayMenuMode", 1)

;set variables
$DLLFileAndPath = @ScriptDir & "/inpout32.dll"; remove the @ScriptDir & leading backslash if you prefer to keep the DLL in your system directory
$PortAddress = "0x378"; the default LPT1 on most machines
$OutputFileNameAndPath = @DesktopDir & "/LPT Port Status.txt"
;calculate register addresses
Dim $StatusRegisterAddress, $ControlRegisterAddress
CalculateRegisterAddresses($PortAddress)

;test for DLL
If FileExists($DLLFileAndPath) = 0 Then
    MsgBox(0, "Missing DLL File", "Parallel Port Control DLL Missing at '" & $DLLFileAndPath & "'. Cannot Continue." & @CRLF & @CRLF & "Download DLL from http://www.logix4u.net/inpout32.htm")
    Exit
EndIf

;create Tray Icon GUI
;Data Register Menu
$DataRegisterMenu = TrayCreateMenu("Set Data Bits")
$AllHighDataItem = TrayCreateItem("Set All Bits High", $DataRegisterMenu)
$SetCustomPinsDataItem = TrayCreateItem("Set Bits Custom", $DataRegisterMenu)
$AllLowDataItem = TrayCreateItem("Set All Bits Low", $DataRegisterMenu)
;Control register Menu
$ControlRegisterMenu = TrayCreateMenu("Set Control Bits")
$AllHighControlItem = TrayCreateItem("Set All Bits High", $ControlRegisterMenu)
$SetCustomPinsControlItem = TrayCreateItem("Set Bits Custom", $ControlRegisterMenu)
$AllLowControlItem = TrayCreateItem("Set All Bits Low", $ControlRegisterMenu)
;General
TrayCreateItem("")
$ReadPortItem = TrayCreateItem("Read Port Status")
TrayCreateItem("")
$ChangePortItem = TrayCreateItem("Change LPT Port")
TrayCreateItem("")
$exititem = TrayCreateItem("Exit")
;display tray icon
TraySetState()

While 1; loop waiting for tray messages
    $msg = TrayGetMsg()
    Select
        Case $msg = 0
            ContinueLoop
            
        Case $msg = $SetCustomPinsDataItem
            $CustomSettings = InputBox("Custom Bit Settings", "Enter data bit settings required" & @CRLF & @CRLF & "Bits are in order, Bit0 -> Bit 7" & @CRLF & @CRLF & "Enter values as 0 (Low) or 1 (High)", "0,0,0,0,0,0,0,0")
            $BitArray = StringSplit($CustomSettings, ",")
            SetLPTPortPins($PortAddress, $BitArray[1], $BitArray[2], $BitArray[3], $BitArray[4], $BitArray[5], $BitArray[6], $BitArray[7], $BitArray[8])
            
        Case $msg = $AllLowDataItem
            SetLPTPortPins($PortAddress, 0, 0, 0, 0, 0, 0, 0, 0)
            
        Case $msg = $AllHighDataItem
            SetLPTPortPins($PortAddress, 1, 1, 1, 1, 1, 1, 1, 1)
            
        Case $msg = $SetCustomPinsControlItem
            $CustomSettings = InputBox("Custom Bit Settings", "Enter control bit settings required" & @CRLF & @CRLF & "Bits are in order, Bit0 -> Bit 7" & @CRLF & @CRLF & "Enter values as 0 (Low) or 1 (High)", "0,0,0,0,0,0,0,0")
            $BitArray = StringSplit($CustomSettings, ",")
            SetLPTPortPins($ControlRegisterAddress, $BitArray[1], $BitArray[2], $BitArray[3], $BitArray[4], $BitArray[5], $BitArray[6], $BitArray[7], $BitArray[8])
            
        Case $msg = $AllLowControlItem
            SetLPTPortPins($ControlRegisterAddress, 0, 0, 0, 0, 0, 0, 0, 0)
            
        Case $msg = $AllHighControlItem
            SetLPTPortPins($ControlRegisterAddress, 1, 1, 1, 1, 1, 1, 1, 1)
            
        Case $msg = $ReadPortItem
        ;Read Status register
            $StatusRegisterArray = ReadPortStatus($StatusRegisterAddress)
            $StatusRegisterDisplayString = "Status Register @ " & $StatusRegisterAddress & @CRLF & " (BCD = " & $StatusRegisterArray[8] & ")" & @CRLF & "Bit0 = " & $StatusRegisterArray[0] & " (No pin)" & @CRLF & "Bit1 = " & $StatusRegisterArray[1] & " (No pin)" & @CRLF & "Bit2 = " & $StatusRegisterArray[2] & " (No pin)" & @CRLF & "Bit3 = " & $StatusRegisterArray[3] & " (Pin 15, nError)" & @CRLF & "Bit4 = " & $StatusRegisterArray[4] & " (Pin 13, Select)" & @CRLF & "Bit5 = " & $StatusRegisterArray[5] & " (Pin 12, Paper Out)" & @CRLF & "Bit6 = " & $StatusRegisterArray[6] & " (Pin 10, nAck)" & @CRLF & "Bit7 = " & $StatusRegisterArray[7] & " (Pin 11, Busy {inverted})"
        ;Read Control register
            $ControlRegisterArray = ReadPortStatus($ControlRegisterAddress)
            $ControlRegisterDisplayString = "Control Register @ " & $ControlRegisterAddress & @CRLF & " (BCD = " & $ControlRegisterArray[8] & ")" & @CRLF & "Bit0 = " & $ControlRegisterArray[0] & " (Pin 1, Strobe {Inverted})" & @CRLF & "Bit1 = " & $ControlRegisterArray[1] & " (Pin 14, Linefeed {Inverted})" & @CRLF & "Bit2 = " & $ControlRegisterArray[2] & " (Pin 16, nInitialise)" & @CRLF & "Bit3 = " & $ControlRegisterArray[3] & " (Pin 17, nSelectPrinter {Inverted})" & @CRLF & "Bit4 = " & $ControlRegisterArray[4] & " (No pin)" & @CRLF & "Bit5 = " & $ControlRegisterArray[5] & " (No pin, BiDirectional Mode)" & @CRLF & "Bit6 = " & $ControlRegisterArray[6] & " (No pin)" & @CRLF & "Bit7 = " & $ControlRegisterArray[7] & " (No pin)"
        ;set bidirectional flag
            if $ControlRegisterArray[5] = 0 Then
                $BiDirectionalCommunication = "Off"
            Else
                $BiDirectionalCommunication = "On"
            EndIf
        ;Read Data register
            $DataRegisterArray = ReadPortStatus($PortAddress)
            $DataRegisterDisplayString = "Data Register @ " & $PortAddress & @CRLF & " (BCD = " & $DataRegisterArray[8] & ", BiDirectional Mode is "&$BiDirectionalCommunication&")" & @CRLF & "Bit0 = " & $DataRegisterArray[0] & " (Pin 2)" & @CRLF & "Bit1 = " & $DataRegisterArray[1] & " (Pin 3)" & @CRLF & "Bit2 = " & $DataRegisterArray[2] & " (Pin 4)" & @CRLF & "Bit3 = " & $DataRegisterArray[3] & " (Pin 5)" & @CRLF & "Bit4 = " & $DataRegisterArray[4] & " (Pin 6)" & @CRLF & "Bit5 = " & $DataRegisterArray[5] & " (Pin 7)" & @CRLF & "Bit6 = " & $DataRegisterArray[6] & " (Pin 8)" & @CRLF & "Bit7 = " & $DataRegisterArray[7] & " (Pin 9)"
            
        ;Displaying
            $TextToDisplay = "Bit Status for LPT Port at " & $PortAddress & @CRLF & "(0 = Low, 1 = High)" & @CRLF & @CRLF & $DataRegisterDisplayString & @CRLF & @CRLF & $StatusRegisterDisplayString & @CRLF & @CRLF & $ControlRegisterDisplayString
            $SaveData = MsgBox(4, "Current Port Status", $TextToDisplay & @CRLF & @CRLF & "Would you like to save this output to Notepad?")
            If $SaveData = 6 Then
                FileDelete($OutputFileNameAndPath)
                FileWrite($OutputFileNameAndPath, $TextToDisplay)
                Run('notepad.exe "' & $OutputFileNameAndPath & '"')
            EndIf
            
        Case $msg = $ChangePortItem
            $NewPortAddress = InputBox("Change LPT Port", "Enter LPT Port Address"& @CRLF & @CRLF & "This can be found by looking at the first memory resource allocated to your LPT port in device manager.  Don't forget to add the '0x' prefix.", $PortAddress)
            If $NewPortAddress = "" Then
                MsgBox(0, "No Change", "Port not changed.  Still using address " & $PortAddress & @CRLF & @CRLF & "Data Register -> " & $PortAddress & @CRLF & "Status Register -> " & $StatusRegisterAddress & @CRLF & "Control Register -> " & $ControlRegisterAddress)
            Else
                $PortAddress = $NewPortAddress
                CalculateRegisterAddresses($PortAddress)
                MsgBox(0, "Port Changed", "Now using LPT Port at address " & $PortAddress & @CRLF & @CRLF & "Data Register -> " & $PortAddress & @CRLF & "Status Register -> " & $StatusRegisterAddress & @CRLF & "Control Register -> " & $ControlRegisterAddress)
            EndIf
            
        Case $msg = $exititem
            Exit
            
    EndSelect
WEnd

Exit


;Functions -> where the action happens!
Func SetLPTPortPins($WriteAddress, $Bit0, $Bit1, $Bit2, $Bit3, $Bit4, $Bit5, $Bit6, $Bit7)
;Convert bits to BCD
    $BCD = 0
    If $Bit0 = 1 Then $BCD = $BCD + 1
    If $Bit1 = 1 Then $BCD = $BCD + 2
    If $Bit2 = 1 Then $BCD = $BCD + 4
    If $Bit3 = 1 Then $BCD = $BCD + 8
    If $Bit4 = 1 Then $BCD = $BCD + 16
    If $Bit5 = 1 Then $BCD = $BCD + 32
    If $Bit6 = 1 Then $BCD = $BCD + 64
    If $Bit7 = 1 Then $BCD = $BCD + 128
;pass the call to inpout32.dll
    DllCall( $DLLFileAndPath, "int", "Out32", "int", $WriteAddress, "int", $BCD)
EndFunc  ;==>SetLPTPortPins

Func ReadPortStatus($ReadAddress)
;Read the port register (returns a BCD value)
    $CurrentPortStatusArray = DllCall($DLLFileAndPath, "int", "Inp32", "int", $ReadAddress)
    $StatusToDecode = $CurrentPortStatusArray[0]
;convert to bit status & store in array
    Dim $BitsReadArray[9]; [0] -> [7] the decoded bits, [8] the raw BCD value
    $BitsReadArray[8] = $CurrentPortStatusArray[0]
    $CurrentBitValue = 128
    For $BitCounter = 7 To 0 Step - 1
        If $StatusToDecode >= $CurrentBitValue Then
            $BitsReadArray[$BitCounter] = 1
            $StatusToDecode = $StatusToDecode - $CurrentBitValue
        Else
            $BitsReadArray[$BitCounter] = 0
        EndIf
        $CurrentBitValue = $CurrentBitValue / 2
    Next
;test if good decode obtained
    If $StatusToDecode <> 0 Then
        MsgBox(0, "Decoding error", "Error in decoding port '" & $PortAddress & "' register '" & $ReadAddress & " status '" & $CurrentPortStatusArray[0] & "' to bits.  Do not rely on the results.")
    EndIf
    
    Return $BitsReadArray
EndFunc  ;==>ReadPortStatus

Func CalculateRegisterAddresses($BaseAddress)
;check for correct hex prefix
    If Not (StringLeft($BaseAddress, 2) = "0x" Or StringLeft($BaseAddress, 2) = "0X") Then
        MsgBox(0, "Invalid Hex Notation", "The port address  " & $BaseAddress & "' entered was not in valid Hexadecimal notation.  It must start with '0x'")
        Exit
    EndIf
;check for valid hex characters in suffix
    If StringIsXDigit(StringTrimLeft($BaseAddress, 2)) = 0 Then
        MsgBox(0, "Invalid Hex Notation", "The port address  " & $BaseAddress & "' entered was not in valid Hexadecimal notation.  The characters after the '0x' must be only 0-9 and A-F")
        Exit
    EndIf
;calculate status register address
;Msgbox (0,"Debug","$BaseAddress = "& $BaseAddress & @CRLF & "StringTrimLeft($BaseAddress, 2) = " & StringTrimLeft($BaseAddress, 2) & @CRLF & "Dec(StringTrimLeft($BaseAddress, 2)) = " & Dec(StringTrimLeft($BaseAddress, 2)) & @CRLF & "Hex(Dec(StringTrimLeft($BaseAddress, 2)) + 1) = " & Hex(Dec(StringTrimLeft($BaseAddress, 2)) + 1))
    $RawHex = Hex(Dec(StringTrimLeft($BaseAddress, 2)) + 1)
;trim leading zeros
    While 1
        If StringLeft($RawHex, 1) = "0" Then
            $RawHex = StringTrimLeft($RawHex, 1)
        Else
            ExitLoop
        EndIf
    WEnd
    $StatusRegisterAddress = "0x" & $RawHex
;calculate control register address
    $RawHex = Hex(Dec(StringTrimLeft($BaseAddress, 2)) + 2)
;trim leading zeros
    While 1
        If StringLeft($RawHex, 1) = "0" Then
            $RawHex = StringTrimLeft($RawHex, 1)
        Else
            ExitLoop
        EndIf
    WEnd
    $ControlRegisterAddress = "0x" & $RawHex
    
EndFunc  ;==>CalculateRegisterAddresses

Share this post


Link to post
Share on other sites



nice find. i havent tried this yet but, you should check out the relayboard at electronickits.com

its great and has simple dos exe for controlling the parallel port.

thanks


[center]AutoIT + Finger Print Reader/Scanner = COOL STUFF -> Check Out Topic![/center][center][font=Arial Black]Check out ConsultingJoe.com[/font][/center][center]My Scripts~~~~~~~~~~~~~~Web Protocol Managing - Simple WiFi Scanner - AutoTunes - Remote PC Control V2 - Audio SpectrascopePie Chart UDF - At&t's TTS - Custom Progress Bar - Windows Media Player Embed[/center]

Share this post


Link to post
Share on other sites

Old topic but I finally tried this and it is amazing.

Nice menu, allows for fully controlling bits on the LPT port and it worked perfect for my relay board that you may all know about.

I can wait to use this on my new project.

Thanks


[center]AutoIT + Finger Print Reader/Scanner = COOL STUFF -> Check Out Topic![/center][center][font=Arial Black]Check out ConsultingJoe.com[/font][/center][center]My Scripts~~~~~~~~~~~~~~Web Protocol Managing - Simple WiFi Scanner - AutoTunes - Remote PC Control V2 - Audio SpectrascopePie Chart UDF - At&t's TTS - Custom Progress Bar - Windows Media Player Embed[/center]

Share this post


Link to post
Share on other sites

Old topic but I finally tried this and it is amazing.

Nice menu, allows for fully controlling bits on the LPT port and it worked perfect for my relay board that you may all know about.

I can wait to use this on my new project.

Thanks

i want autoit to make me a sandwhich eventually, but first do you have an example?


Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


Link to post
Share on other sites

i want autoit to make me a sandwhich eventually, but first do you have an example?

yeah, do you want pictures?

Currently I have a remote laptop that I'm going to use a plant grow monitor/timer. I have a CPU fan connected to the relay board and I just set the bit to 1 and the relay turns on.

it makes it very simple.


[center]AutoIT + Finger Print Reader/Scanner = COOL STUFF -> Check Out Topic![/center][center][font=Arial Black]Check out ConsultingJoe.com[/font][/center][center]My Scripts~~~~~~~~~~~~~~Web Protocol Managing - Simple WiFi Scanner - AutoTunes - Remote PC Control V2 - Audio SpectrascopePie Chart UDF - At&t's TTS - Custom Progress Bar - Windows Media Player Embed[/center]

Share this post


Link to post
Share on other sites

Currently I have a remote laptop that I'm going to use a plant grow monitor/timer. I have a CPU fan connected to the relay board and I just set the bit to 1 and the relay turns on.

What kind of plants are we talking about here? :shocked:


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

What kind of plants are we talking about here? :shocked:

nothing special...

...happy 420, lol


[center]AutoIT + Finger Print Reader/Scanner = COOL STUFF -> Check Out Topic![/center][center][font=Arial Black]Check out ConsultingJoe.com[/font][/center][center]My Scripts~~~~~~~~~~~~~~Web Protocol Managing - Simple WiFi Scanner - AutoTunes - Remote PC Control V2 - Audio SpectrascopePie Chart UDF - At&t's TTS - Custom Progress Bar - Windows Media Player Embed[/center]

Share this post


Link to post
Share on other sites

Not to bring up an old thread - but i have been looking for a program to control a remote control car via parallel port - seems like this is very close.

Have you ever thought of adding a simple GUI for the different (ON/OFF) states of the 8 bits?

My idea was to have 4 of the 8 for Left/Right/FWD/REV and a few simple on/off devices for the remaining 4

Just an idea - I am a autoit noob, but if its doable i may take a stab at it

thanks in advance

DocW...

Share this post


Link to post
Share on other sites

Just happened across this thread looking (as usual) for something else...There are a certain breed of person around the world, that get their jollies creating huge Christmas displays. To do this, some of these folks are using simple computer based controls. I was looking for (again...something else) when I happened across this site & project.

http://computerchristmas.com/index.phtml?l...o&HowToId=4

This is a project to control 320 ports! :whistle:

Have 320 or so things you need to control?. Ok...320 on/off things, but heck, that's a lot of ladder logic...

Rich


Good intentions will always be pleaded for every assumption of authority. It is hardly too strong to say that the Constitution was made to guard the people against the dangers of good intentions. There are men in all ages who mean to govern well, but they mean to govern. They promise to be good masters, but they mean to be masters.-Daniel Webster

Share this post


Link to post
Share on other sites

And how can I get data from parallel port using the above script. Is it the ReadPortStatus function, or I need to make my own.

If it IS ReadPortStatus, how will it export data (in which format)?

If it ISN'T ReadPortStatus, can anyone help me with this, please!!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0