'**********************************************************************''   M6Start.mls   Tool Change Start                         01SEP2010''   Called during a Tool Change (M6 T1 .... )''**********************************************************************' User Interface SettingsConst userLable_atcDebug            = 1Const userLable_atcStatus           = 2Const userLable_atcChangeTime       = 3Const userDRO_atcCurrentPosition    = 1000Const userDRO_spindleToolNumber     = 1200Const userLED_atcInitialized        = 1000Const userLED_atcUnloading          = 1013Const userLED_atcLoading            = 1014Const OEMbutton_eStop               = 1021    ' ATC Carousel SettingsConst ATC_CarouselMotorEn           = Enable5Const ATC_CarouselMotorDir          = Enable6Const ATC_CarouselIndexSW           = Input3    Const ATC_CarouselHomeSW            = Input4' Draw Bar SettingsConst drawBarSolenoid               = Output18        Const drawBarHomeExtendSW           = OEMTrig1' Spindle Orientation SettingsConst SpindleOrientMotorEn          = Output6Const SpindleOrientMotorNumber      = 5    ' RAM Hardware SettingsConst RamHomeExtendSW               = Input1Const RamSolenoid                   = Output19' Mod Bus RegistersConst modbusReg_RPM                 = 64' Tool Changer Alignment ParameterConst toolChangeHeight              = -4.384'**********************************************************************''   M6 Tx Macro''   Called from Mach3 to Change to Tool''**********************************************************************Sub Main()    ' Timer Variables    Dim TimeStart As Single    Dim TimeEnd As Single    ' Get the Start Time    TimeStart = Timer    SetUserLabel( userLable_atcChangeTime, "Change Time: calculating" )        ' Make sure the ATC has been Initialized    If getUserLED( userLED_atcInitialized ) = 0 Then        SetUserLabel( userLable_atcDebug, "ATC must be INITIALIZED before changing a TOOL" )        Message "!!! ATC must be INITIALIZED before changing a TOOL !!!"        DoOEMButton( eStop )                Exit Sub    End If    ' Check for same tool case    currentTool = GetCurrentTool()    newTool = GetSelectedTool()    If ( currentTool = newTool ) Then        SetUserLabel( userLable_atcDebug, "Tools are the same, no tool change needed" )        Exit Sub    End If    ' Update our status that we changing tools    SetUserLabel( userLable_atcStatus, "Changing Tool: " & currentTool & " to Tool: " & newTool )    '    ' Unload the Current Tool    '        ' Only unload the tool if we have one.        If currentTool <> 0 Then                ' Get the ATC Carousel position of the current tool to unload            unloadTargetATCPos = GetATCPos( currentTool )                ' The tool to unload does NOT belong back into the ATC Carousel            If unloadTargetATCPos = 0 Then                     ' Provide User Support to Load the Tool ( Currently NOT Supported )                If manuallyUnloadToolFromSpindle( currentTool ) = 1 Then                    Exit Sub                                    End If                ' The tool to load belongs back into the carousel.            Else                            ' Attempt to unload Tool From Spindle                If unloadToolFromSpindle( unloadTargetATCPos ) = 1 Then                    Exit Sub                End If                        End If        ' If the Spindle does not have tool, then there is nothing to unload?        Else                    ' Prep the ATC for the loading of the new tool            If prepForLoad() = 1 Then                Exit Sub            End If                            End If    '    ' Load the new Selected Tool    '          ' We have a target tool to load        If newTool <> 0 Then                ' Get the ATC Carousel position of the new tool to Load            loadTargetATCPos = GetATCPos( newTool )                    ' The tool to load is NOT in the ATC Carousel, load it by hand.            If loadTargetATCPos = 0 Then                            ' Provide User Support to Load the Tool ( Currently NOT Supported )                If manuallyLoadToolIntoSpindle( newTool ) = 1 Then                    Exit Sub                                    End If                ' The new to load is in the ATC Carousel.            Else                            ' Load Tool into Spindle                If loadToolIntoSpindle( loadTargetATCPos ) = 1 Then                    Exit Sub                                    End If                        End If                ' There is no tool to load        Else                    ' There is no new tool to load, clean up machine state.            If postLoad() = 1 Then                Exit Sub            End If                            End If    ' Signal Mach3 that we have changed the tool    SetCurrentTool( newTool )    setOEMDRO( 824, newTool )   ' This is for the Tool Offsets    setUserDRO( userDRO_spindleToolNumber, newTool )        ' Update the Lables    SetUserLabel( userLable_atcStatus, "OK" )    SetUserLabel( 1, "" )    ' Update the Total Tool Change Time        TimeEnd = Timer    SetUserLabel( userLable_atcChangeTime, "Change Time: " & TimeEnd - TimeStart & " sec" )    End Sub  '**********************************************************************''   GetATCPos''   Given a tool number, this will search the table and return the ATC'   positon for the given tool.  '   1) If the tool is not found, 0 is returned''**********************************************************************Function GetATCPos( ByVal toolNumber As Integer) As Integer        Dim ATCpos As Integer        ' Look at each position for the given tool    ATCpos = 0    For x = 1 to 12        If getUserDro( 1200 + x ) = toolNumber Then            ATCpos = x        End If        Next x    ' The target tool was not found    If ATCpos > 0 Then        GetATCPos = ATCpos        Else         GetATCPos = 0    End If    End Function'**********************************************************************''   moveATC''   1) Calculates the fastest way to move (INC or DEC)'   2) Moves x times until the target slot is achieved''   Returns 0 Success, 1 Failure''**********************************************************************Function moveATC( ByVal targetPos As Integer ) As Integer    ' Set the default error code to FAILURE    moveATC = 1    ' Get the current Pos    currentPos = getUserDro( userDRO_atcCurrentPosition )    ' Check if we need to move at all (ie: are we already there?)    If currentPos = targetPos Then        moveATC = 0        Exit Sub    End If    ' Look for the targetPos in the posistive direction (INC)    posIndex = currentPos    posStep = 0    While posIndex <> targetPos         posStep = posStep + 1        posIndex = posIndex + 1        If posIndex > 12 Then            posIndex = 1                End If    Wend                    ' Look for the targetPos in the negative direction (DEC)    negIndex = currentPos    negStep = 0    While negIndex <> targetPos         negStep = negStep + 1        negIndex = negIndex - 1        If negIndex < 1 Then            negIndex = 12                End If    Wend          '           ' INC is the shortest direction    '    If posStep <= negStep Then            ' Set up the direction on Starter Capacitor (INC)        DeActivateSignal( ATC_CarouselMotorDir )        Sleep 100            ' Enable Motor        ActivateSignal( ATC_CarouselMotorEn )        ' Increment current position n Times            For x = 1 to posStep            ' Make sure we clear the Index Switch            Timeout = 0            While IsActive( ATC_CarouselIndexSW )                Sleep 10                                ' Check for TimeOut ( 3 Second )                Timeout = Timeout + 1                If Timeout = 300 Then                    EstopMessage( "ATC INC: Index Sw did not clear" )                    Exit Sub                                    End If            Wend                ' Make sure we see the Index Switch            Timeout = 0            While Not( IsActive( ATC_CarouselIndexSW ))                Sleep 10                                ' Check for TimeOut ( 3 Second )                Timeout = Timeout + 1                If Timeout = 300 Then                    EstopMessage( "ATC INC: Index Sw did was not detected" )                    Exit Sub                                    End If            Wend                                '            ' Update UI            '            currentPos = currentPos + 1            If currentPos = 13 Then                 currentPos = 1            End If                        ' Update ATC Carousel Number and LEDS            updateAtcPositionAndLEDs( currentPos )        Next x            '    ' DEC is the shortest direction    '    Else            ' Set up the direction on Starter Capacitor (DEC)        ActivateSignal( ATC_CarouselMotorDir )        Sleep 100            ' Enable Motor        ActivateSignal( ATC_CarouselMotorEn )                    ' Decrement current position n Times            For x = 1 to negStep                    ' Make sure we clear the Index Switch            Timeout = 0            While IsActive( ATC_CarouselIndexSW )                Sleep 10                                ' Check for TimeOut ( 3 Second )                Timeout = Timeout + 1                If Timeout = 300 Then                    EstopMessage( "ATC DEC: Index Sw did not clear" )                    Exit Sub                                    End If            Wend                ' Make sure we see the Index Switch            Timeout = 0            While Not( IsActive( ATC_CarouselIndexSW ))                Sleep 10                                ' Check for TimeOut ( 3 Second )                Timeout = Timeout + 1                If Timeout = 300 Then                    EstopMessage( "ATC DEC: Index Sw did was not detected" )                    Exit Sub                                    End If            Wend                        '            ' Update UI            '            currentPos = GetUserDRO( userDRO_atcCurrentPosition )            currentPos = currentPos - 1            If currentPos = 0 Then                 currentPos = 12            End If                        ' Update ATC Carousel Number and LEDS            updateAtcPositionAndLEDs( currentPos )        Next x    End If    ' Stop the Motor    DeActivateSignal( ATC_CarouselMotorEn )    DeActivateSignal( ATC_CarouselMotorDir )    '    ' If our new carousel position is 1(ie:HOME), then make sure the Home Sw is active      '     If getUserDRO( userDRO_debugModeEnable ) <> 1 Then                ' Get the current position        currentPos = getUserDro( userDRO_atcCurrentPosition )              ' Check if we should be homed        If currentPos = 1 Then            If Not( IsActive( ATC_CarouselHomeSW )) Then                EstopMessage( "ATC Home Sensor was not set when it should have been" )                Exit Sub                            End If                Else            ' Make sure we are NOT homed             If IsActive( ATC_CarouselHomeSW ) Then                EstopMessage( "ATC Home Sensor was SET when it shouldn't have been" )                Exit Sub                            End If        End If        End If            ' Success: Update the return code    moveATC = 0    End Function'**********************************************************************''   updateAtcPositionAndLEDs''   Sets the ATC Position Number and Updated the LEDs''**********************************************************************Sub updateAtcPositionAndLEDs( ByVal newAtcPosition As Integer )    ' Set the Main ATC DRO    setUserDro( userDRO_atcCurrentPosition, newAtcPosition )        ' Clear All LEDs    For x = 1 to 12        setUserLed( 1000 + x, 0 )    Next x        ' Set the Target LED    If newAtcPosition <> 0 Then        setUserLed( 1000 + newAtcPosition, 1 )    End If            End Sub '**********************************************************************''   manuallyUnloadToolFromSpindle''   Allows the user to Manually Unload Tools from the Spindle''   Returns 0 Success, 1 Failure''**********************************************************************Function manuallyUnloadToolFromSpindle( ByVal toolNumber As Integer) As Integer        ' No support for manual Unload    manuallyUnloadToolFromSpindle = 1        EstopMessage( "Tool: " & toolNumber & " is not definded in Tool Carousel Table" )    ' JOEL Make these message boxes    ' Message "Please Unload Tool: " & currentTool & ", from the Spindle and Press START"    ' Sleep 1000    ' Enable and Light Up the Tool Change Button on the Spindle    ' TODO    ' Wait for User to press the Start, this will signal that the tool has been loaded.        ' Disable and Tool Change Button on the Spindle.    ' TODO    End Function'**********************************************************************''   manuallyLoadToolIntoSpindle''   Allows the user to Manually Load Tools into the Spindle''   Returns 0 Success, 1 Failure''**********************************************************************Function manuallyLoadToolIntoSpindle( ByVal toolNumber As Integer) As Integer     ' No support for manual Unload    manuallyLoadToolIntoSpindle = 1    EstopMessage( "Tool: " & toolNumber & " is not definded in Tool Carousel Table" )           ' JOEL Make these message boxes    ' Message "Please Load Tool: " & newTool & ", into the Spindle and Press START"    ' Sleep 1000    ' Enable and Light Up the Tool Change Button on the Spindle    ' TODO        ' Disable and Tool Change Button on the Spindle.    ' TODOEnd Function'**********************************************************************''   postLoad''   Handles the Special case when there is NO tool to load.  Cleans up the '   status of the RAM and DrawBar''   Returns 0 Success, 1 Failure''**********************************************************************Function postLoad() As Integer    ' Set the default return code to FAILURE    postLoad = 1    ' Indicate we are loading    setUserLed( userLED_atcloading, 1 )    ' DeActivate the DrawBar Release and Verify    SetUserLabel( userLable_atcDebug, "Deactivating Drawbar" )    If deActivateDrawBar() = 1 Then        Exit Sub    End If    ' TODO: Home the RAM and Verify    SetUserLabel( userLable_atcDebug, "Homing the ATC RAM" )    If ramHome() = 1 Then        Exit Sub    End If    ' Indicate we are done loading the tool    setUserLed( userLED_atcloading, 0 )    ' Success     postLoad = 0 End Function'**********************************************************************''   loadToolIntoSpindle''   Loads a tool from the carousels current position into the spindle.''   1) Assumes the Spindle is EMPTY'   2) Assumes the Spindle Height is set to 'spindle clear height''   3) Assumes the RAM is extended'   4) Assumes the Tool Release is active'   5) Assumes Spindle Orintation is correct''   Returns 0 Success, 1 Failure''**********************************************************************Function loadToolIntoSpindle( ByVal loadTargetATCPos As Integer) As Integer    ' Set the default return code to FAILURE    loadToolIntoSpindle = 1    ' Indicate we are loading    setUserLed( userLED_atcloading, 1 )    ' Move ATC to the new tools position    SetUserLabel( userLable_atcDebug, "Rotating carousel to new tool posision" )    If moveATC( loadTargetATCPos ) = 1 Then        Exit Sub    End If            ' Move the Spindle to the 'carousel load/unload height'    SetUserLabel( userLable_atcDebug, "Moving Z Axis/Spindle to tool change height" )    Code "G53 G0 Z" & toolChangeHeight    While IsMoving()        Sleep 10    Wend    ' DeActivate the Draw Bar to load the new tool into the Spindle and Verify    SetUserLabel( userLable_atcDebug, "Loading tool into spindle" )    If deActivateDrawBar() = 1 Then        Exit Sub    End If    ' Home the RAM and Verify    SetUserLabel( userLable_atcDebug, "Home the ATC RAM" )    If ramHome() = 1 Then        Exit Sub    End If    ' Indicate we are done loading the tool    setUserLed( userLED_atcloading, 0 )    ' Success     loadToolIntoSpindle = 0End Function'**********************************************************************''   prepForLoad''   Handles the Special case when there is NO tool in the spindle and'   we want to load a new tool from the carousel''   Returns 0 Success, 1 Failure''**********************************************************************Function prepForLoad() As Integer    ' Set the default return code to FAILURE    prepForLoad = 1    ' Indicate we are unloading    setUserLed( userLED_atcUnloading, 1 )            ' Signal the Spindle to Stop    Code "M5"            ' Move Spindle up to 'spindle clear height'    SetUserLabel( userLable_atcDebug, "Moving Z Axis/Spindle to clear height" )    Code "G53 G0 Z0"        ' Wait for the Spindle to stop and Verify    Timeout = 0    While GetInput( modbusReg_RPM ) <> 0         Sleep 10                ' Check for TimeOut ( 7 Second )        Timeout = Timeout + 1        If Timeout = 700 Then            EstopMessage( "Spindle RPM was not ZERO during prepForLoad" )            Exit Sub        End If    Wend    ' Find Spindle Tool Orientation    SetUserLabel( userLable_atcDebug, "Finding spindle orientation" )    If orientSpindle() = 1 Then        Exit Sub    End If    ' Prepair the drawBar for loading and verify    SetUserLabel( userLable_atcDebug, "Prepairing drawBar for tool load" )    If activateDrawBar() = 1 Then        Exit Sub    End If            ' Extend the RAM and verify    SetUserLabel( userLable_atcDebug, "Extending ATC RAM" )    If ramExtend() = 1 Then        Exit Sub    End If                ' Indicate we are done unloading the tool    setUserLed( userLED_atcUnloading, 0 )    ' Success     prepForLoad = 0 End Function'**********************************************************************''   unloadToolFromSpindle''   1) Unloads the Current Tool from the Spindel into the ATC Caousel'   2) Leaves the RAM extended'   3) Leaves the DrawBar Active''   Returns 0 Success, 1 Failure''**********************************************************************Function unloadToolFromSpindle( ByVal unloadTargetATCPos As Integer) As Integer    ' Set the default return code to FAILURE    unloadToolFromSpindle = 1    ' Indicate we are unloading    setUserLed( userLED_atcUnloading, 1 )            ' Signal the Spindle to stop    Code "M5"                ' Move the Spindle up to 'carousel load/unload height'    SetUserLabel( userLable_atcDebug, "Moving Z Axis/Spindle to tool change height" )    Code "G53 G0 Z" & toolChangeHeight    ' Wait for the Spindle to stop    Timeout = 0    While GetInput( modbusReg_RPM ) <> 0         Sleep 10                ' Check for TimeOut ( 7 Second )        Timeout = Timeout + 1        If Timeout = 700 Then            EstopMessage( "Spindle RPM was not ZERO during unloadToolFromSpindle" )            Exit Sub        End If    Wend        ' Find Spindle Tool Orientation    SetUserLabel( userLable_atcDebug, "Finding spindle orientation" )    If orientSpindle() = 1 Then        Exit Sub    End If        ' Move Carousel to the unload Tool Index (we should be there anyway)    SetUserLabel( userLable_atcDebug, "Rotating carousel to unload posision" )    If moveATC( unloadTargetATCPos ) = 1 Then        Exit Sub    End If               ' Extend the RAM and verify    SetUserLabel( userLable_atcDebug, "Extending ATC RAM" )    If ramExtend() = 1 Then        Exit Sub    End If            ' Release the Tool from the Draw Bar and Verify    SetUserLabel( userLable_atcDebug, "Releasing tool from spindle" )    If activateDrawBar() = 1 Then        Exit Sub    End If            ' TODO: Air Blast ON    ' TODO: Air Blast OFF    ' Move Spindle up to 'spindle clear height'    SetUserLabel( userLable_atcDebug, "Moving Z Axis/Spindle to clear height" )    Code "G53 G0 Z0"    While IsMoving()        Sleep 10    Wend    ' There is No tool in the spindle, let Mach know    SetCurrentTool( 0 )    setUserDRO( userDRO_spindleToolNumber, 0 )    ' Indicate we are done unloading the tool from the spindle    setUserLed( userLED_atcUnloading, 0 )    ' Success     unloadToolFromSpindle = 0End Function'**********************************************************************''   orientSpindle''   1) Activates Motor Driver and Energizes Relays'   2) Attempts to find the Orientation Switch''   NOTE: Leaves the Motor Phases Active!''   Returns 0 Success, 1 Failure''**********************************************************************Function orientSpindle() As Integer        Dim Timeout As Integer        ' Set the default return code to FAILURE    orientSpindle = 1            ' Enable the Stepper Motor Driver and Connect the Motor to the Driver Outputs    ActivateSignal( SpindleOrientMotorEn )    Sleep( 100 )    '    ' Make sure the Home Sw is not Active, Mach cannot home if it is    '    If IsActive( CHome ) Then        ' Move Off the Home Sw        Code "G0 C0.5"         While IsMoving()            Sleep 10        Wend                ' Zero the Machine Cords so we don't move back to were we started when the G28.1         ' is called below        SetMachZero( SpindleOrientMotorNumber )               End If    '    ' Signal Mach to move until the Home Switch is found    '    Code "G28.1 C0"     Timeout = 0    While IsMoving()        Sleep 10                ' Check for TimeOut ( 2 Seconds )        Timeout = Timeout + 1        If Timeout = 200 Then            EstopMessage( "Spindle Orientation Failed to find Orientation Switch on FIRST pass" )            Exit Sub        End If    Wend    '    ' Signal Mach to move until the Home Switch is found again, this will fix any    ' acelleration/decelleration profile issues.    '    Code "G28.1 C0"     Timeout = 0    While IsMoving()        Sleep 10                ' Check for TimeOut ( 2 Seconds )        Timeout = Timeout + 1        If Timeout = 200 Then            EstopMessage( "Spindle Orientation Failed to find Orientation Switch on FINAL pass" )            Exit Sub        End If    Wend        ' Success    orientSpindle = 0        End Function'**********************************************************************''   ramExtend''   Returns 0 Success, 1 Failure''**********************************************************************Function ramExtend() As Integer        Dim Timeout As Integer        ' Set the default return code to FAILURE    ramExtend = 1        ' Make sure the Switch is set( homed before we start )    If Not( IsActive( RamHomeExtendSW )) Then        EstopMessage( "ATC RAM: Home/Extend Switch was NOT Active" )        Exit Sub    End If        ' Check if the Output is Active, it should NOT be        If IsOutputActive( RamSolenoid ) Then        Message "Can not Extend ATC RAM, the output is Currently Active"        Exit Sub    End If    ' Active the air solenoid for the Tool RAM    ActivateSignal( RamSolenoid )    '        ' Wait to clear the Home Switch    '    Timeout = 0        While IsActive( RamHomeExtendSW )        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "ATC RAM: Failed to clear Home Switch" )            Exit Sub        End If    Wend    '        ' Wait to Set the Extended Switch    '    Timeout = 0        While Not( IsActive( RamHomeExtendSW ))        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "ATC RAM: Failed to set Extended Switch" )            Exit Sub                    End If    Wend    ' Success    ramExtend = 0        End Function'**********************************************************************''   ramHome''   Returns 0 Success, 1 Failure''**********************************************************************Function ramHome() As Integer        Dim Timeout As Integer        ' Set the default return code to FAILURE    ramHome = 1        ' Make sure the Switch is set( extended before we start )    If Not( IsActive( RamHomeExtendSW )) Then        EstopMessage( "ATC RAM: Home/Extend Switch was NOT Active" )        Exit Sub    End If    ' Check if the Output is Active, it should be        If Not IsOutputActive( RamSolenoid ) Then        Message "Can not Home ATC RAM, the output is Not Active to DeActivate"        Exit Sub    End If    ' DeActive the air solenoid for the Tool RAM    DeActivateSignal( RamSolenoid )    '        ' Wait to clear the Extended Switch    '    Timeout = 0        While IsActive( RamHomeExtendSW )        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "ATC RAM: Failed to clear Extended Switch" )            Exit Sub        End If    Wend    '        ' Wait to Set the Home Switch    '    Timeout = 0        While Not( IsActive( RamHomeExtendSW ))        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "ATC RAM: Failed to set Home Switch" )            Exit Sub                    End If    Wend    ' Success    ramHome = 0        End Function'**********************************************************************''   activateDrawBar''   Returns 0 Success, 1 Failure''**********************************************************************Function activateDrawBar() As Integer        Dim Timeout As Integer        ' Set the default return code to FAILURE    activateDrawBar = 1        ' Make sure the Switch is set, we should be homed    If Not( IsActive( drawBarHomeExtendSW )) Then        EstopMessage( "Draw Bar (Home)Switch was NOT Active" )        Exit Sub    End If            ' Activate the Draw Bar    ActivateSignal( drawBarSolenoid )    '        ' Wait to clear the Home Switch    '    Timeout = 0        While IsActive( drawBarHomeExtendSW )        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "Draw Bar Failed to clear Home Switch" )            Exit Sub                    End If    Wend        '        ' Wait to Set the Extended Switch    '    Timeout = 0        While Not( IsActive( drawBarHomeExtendSW ))        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "Draw Bar Failed to set Extended Switch" )            Exit Sub                    End If    Wend    ' Now that the Draw Bar is Active, disable the orientation motor phases    DeActivateSignal( SpindleOrientMotorEn )    ' Success    activateDrawBar = 0        End Function'**********************************************************************''   deActivateDrawBar''   Returns 0 Success, 1 Failure''**********************************************************************Function deActivateDrawBar() As Integer        Dim Timeout As Integer        ' Set the default return code to FAILURE    deActivateDrawBar = 1        ' Make sure the Switch is set, we should be extended    If Not( IsActive( drawBarHomeExtendSW )) Then        EstopMessage( "Draw Bar (Extend)Switch was NOT Active" )        Exit Sub    End If            ' DeActivate the Draw Bar    DeActivateSignal( drawBarSolenoid )    '        ' Wait to clear the Extend Switch    '    Timeout = 0        While IsActive( drawBarHomeExtendSW )        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "Draw Bar Failed to clear Extend Switch" )            Exit Sub                    End If    Wend        '        ' Wait to Set the Home Switch    '    Timeout = 0        While Not( IsActive( drawBarHomeExtendSW ))        Sleep 10                ' Check for TimeOut ( 3 Second )        Timeout = Timeout + 1        If Timeout = 300 Then            EstopMessage( "Draw Bar Failed to set Home Switch" )            Exit Sub                    End If    Wend    ' Success    deActivateDrawBar = 0        End Function'**********************************************************************''   EstopMessage                                            Version 1.2''   1) Added support for lost tool''**********************************************************************Sub EstopMessage( ByVal errorMessage As String )    Const eStop                         = 1021                      Const userLED_atcInitialized        = 1000    ' Signal Mach3 that we have lost the tool    SetCurrentTool( 0 )    setUserDRO( userDRO_spindleToolNumber, 0 )        SetUserLabel( userLable_atcStatus, "Error" )    SetUserLED( userLED_atcInitialized, 0 )                    SetUserLabel( userLable_atcDebug, errorMessage )    Message "!!! " & errorMessage & " !!!"    Sleep 1000        DoOEMButton( eStop )    End Sub 