Facebook
From Bulky Cheetah, 3 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 172
  1. ;
  2. ;   RosettaCNC (c) 2016-2020
  3. ;
  4. ; Name              : tool_change.ngc
  5. ; Sub UID           : 6
  6. ; Version           : 2
  7. ; Description       : Tool change macro
  8. ; Application       : Standard CNC cycles
  9. ; Note              : This macro is called by CNC with M06 or manually with G65 P"tool_change" for optional actions.
  10. ;                   : Check the #6000 parameter description for tool change supported types.
  11. ;
  12. ; DISCLAIMER        : This macro is provided 'AS IS', without WARRANTY of any kind, express or implied.
  13. ;                   : The macro is provided as an example only.
  14. ;                   : Use this macro at your own risk.
  15. ;
  16. ; TAKE CARE         : Don't use the CNC #5132..5135 because they are valid ONLY when the macro is called with a M06.
  17. ;
  18. ; Conventions of input parameters
  19. ;
  20. ;   Xx              compulsory parameter
  21. ;   [Xx]            optional parameter
  22. ;   (Xx|Yy|Zz)?     one of compulsory paramaters
  23. ;   [Xx|Yy|Zz]*     zero or more optionals parameters
  24. ;   [Xx|Yy|Zz]+     at least one or more optionals parameters
  25. ;   M!              compulsory parameter don't take care of passed value
  26. ;   [M!]            optional parameter don't take care of passed value
  27. ;   M[1|2]?         compulsory parameter with one of listed values (e.g. M1 or M2)
  28. ;   [M[1|2]?]       optional parameter with one of listed values (e.g. None or M1 or M2)
  29. ;
  30. ; Format
  31. ;
  32. ;   M06
  33. ;
  34. ;   G65 P"tool_change" Aa Bb Cc Ii [Jj] [K!]
  35. ;
  36. ; Arguments with M6 call
  37. ;
  38. ;   Aa  #1          tool id of the tool to be loaded
  39. ;   Bb  #2          slot of the tool to be loaded
  40. ;   Cc  #3          tool id of the tool in use
  41. ;   Ii  #4          slot of the tool in use
  42. ;
  43. ; Extra arguments with G65 call
  44. ;
  45. ;   Jj  #5          optional action:
  46. ;                       #0  = the option is disabled (is the normal condition when the macro is called by a M06)
  47. ;                        0  = do not change behavior of tool-setter after a pick in M06 or direct macro call
  48. ;                        1  = do not execute tool-setter after a pick
  49. ;                        2  = force execute tool-setter after pick
  50. ;                        3  = execute only tool-setter of loaded tool
  51. ;                        4  = execute only magazine open
  52. ;                        5  = execute only magazine close
  53. ;                        6  = return magazine state in #<tc.atc.magazine_state>
  54. ;                        7  = manually cone unload/load
  55. ;   Kk  #6          optional magazine argument:
  56. ;                       #0  = the option is disabled (is the normal condition when the macro is called by a M06)
  57. ;                       any = don't close magazine, is not the last operation (PICK/PLACE/TOOL-SETTER) to do yet
  58. ;
  59. ; Protected Parameters
  60. ;
  61. ;   Param           Description
  62. ;   =====           ===========
  63. ;   #6000           TOOL_CHANGE [GEN] : Type:
  64. ;                                       0   = Dummy tool change:
  65. ;                                             This mode only notice to the PLC about the loaded tool ID.
  66. ;                                             No other actions or movments will be done.
  67. ;                                       1   = Manual Tool Change (MTC) with tool length probing:
  68. ;                                             a] Moves to tool-setter position and measures the loaded tool length.
  69. ;                                             b] Moves to tool change position and show info about tool to manually change.
  70. ;                                             c] Waits for the manual tool change by the operator which confirm that change is done.
  71. ;                                             d] Moves to tool-setter position to measures the length of the new tool.
  72. ;                                             e] Calcs the difference and uses this value as tool length compensation.
  73. ;                                       2   = Manual Tool Change (MTC) with tool length from Tools Library info:
  74. ;                                             a] Moves to tool change position and show info about tool to manually change.
  75. ;                                             b] Waits for the manual tool change by the operator which confirm that change is done.
  76. ;                                             c] If enabled applies the tool length compensation from Tools Libary info.
  77. ;                                       10  = Automatic Tool Change (ATC)
  78. ;                                             This mode manages a rack of slots using place/side & pick/top approach.
  79. ;                                             If there is a loaded tool it will be placed.
  80. ;                                             If there is a requested tool it will be picked.
  81. ;                                             If the tool length measurement/compensation are enabled they are automaticallly performed.
  82. ;                                       11  = Automatic Tool Change (ATC)
  83. ;                                             This mode manages a rack of slots using place/top & pick/top approach.
  84. ;                                             If there is a loaded tool it will be placed.
  85. ;                                             If there is a requested tool it will be picked.
  86. ;                                             If the tool length measurement/compensation are enabled they are automaticallly performed.
  87. ;   #6001           TOOL_CHANGE [GEN] : Features:
  88. ;                                       0   = Back to work position is OFF.
  89. ;                                       1   = Back to work position is ON.
  90. ;   #6002           TOOL_CHANGE [MTC] : Change position X (MCS)
  91. ;   #6003           TOOL_CHANGE [MTC] : Change position Y (MCS)
  92. ;   #6004           TOOL_CHANGE [MTC] : Change position Z (MCS)
  93. ;   #6005           TOOL_CHANGE [TLS] : Sensor safe position Z (MCS)
  94. ;   #6006           TOOL_CHANGE [TLS] : Sensor top/center position X (MCS)
  95. ;   #6007           TOOL_CHANGE [TLS] : Sensor top/center position Y (MCS)
  96. ;   #6008           TOOL_CHANGE [TLS] : Sensor top/center position Z (MCS)
  97. ;   #6009           TOOL_CHANGE [GEN] : Feed during tool change procedure
  98. ;   #6010           TOOL_CHANGE [TLS] : Z approaching sensor position (MCS, reached with feed #6011)
  99. ;   #6011           TOOL_CHANGE [TLS] : Z feed to sensor approaching (FAST)
  100. ;   #6012           TOOL_CHANGE [TLS] : Z feed to 1st probe input capture (SLOW)
  101. ;   #6013           TOOL_CHANGE [TLS] : Z feed to 2nd probe input capture (VERY SLOW)
  102. ;   #6014           TOOL_CHANGE [TLS] : Z up movement after 1st touch capture (REL)
  103. ;   #6015           TOOL_CHANGE [TLS] : Minimum tool lenght accepted
  104. ;   #6016           TOOL_CHANGE [TLS] : Enable tool length compensation (only for tool change type 1)
  105. ;   #6017           TOOL_CHANGE [TLS] : Probe cleaning output
  106. ;   #6018           TOOL_CHANGE [TLS] : Probe cleaning time
  107. ;   #6019           TOOL_CHANGE [___] : !!! RESERVED FOR FUTURE USE !!!
  108. ;   #6020           TOOL_CHANGE [ATC] : Magazine type:
  109. ;                                       0 = none magazine
  110. ;                                       1 = magazine with 2 control outputs (open and close with individual pulse output)
  111. ;   #6021           TOOL_CHANGE [ATC] : Magazine input open
  112. ;   #6022           TOOL_CHANGE [ATC] : Magazine input closed
  113. ;   #6023           TOOL_CHANGE [ATC] : Magazine input timeout
  114. ;   #6024           TOOL_CHANGE [ATC] : Magazine output time
  115. ;   #6025           TOOL_CHANGE [ATC] : Magazine output open
  116. ;   #6026           TOOL_CHANGE [ATC] : Magazine output close
  117. ;   #6027..#6035    TOOL_CHANGE [___] : !!! RESERVED FOR FUTURE USE !!!
  118. ;   #6036           TOOL_CHANGE [ATC] : Fast unload tool holder distance
  119. ;   #6037           TOOL_CHANGE [ATC] : Slow unload tool holder distance
  120. ;   #6038           TOOL_CHANGE [ATC] : Slow unload tool holder feed
  121. ;   #6039           TOOL_CHANGE [ATC] : Fast load tool holder distance
  122. ;   #6040           TOOL_CHANGE [ATC] : Medium load tool holder distance
  123. ;   #6041           TOOL_CHANGE [ATC] : Medium load tool holder feed
  124. ;   #6042           TOOL_CHANGE [ATC] : Final load tool holder feed
  125. ;   #6043           TOOL_CHANGE [ATC] : Cone load unload time (used only if "Cone load unload input" is zero)
  126. ;   #6044           TOOL_CHANGE [ATC] : Cone load unload input (used only for a NO button and detect the release. You must have a macro that start procedure)
  127. ;   #6045           TOOL_CHANGE [ATC] : Cone cleaning blow output
  128. ;   #6046           TOOL_CHANGE [ATC] : Bearing cleaning blow output
  129. ;   #6047           TOOL_CHANGE [ATC] : Cone grip output
  130. ;   #6048           TOOL_CHANGE [ATC] : Cone grip output time
  131. ;   #6049           TOOL_CHANGE [ATC] : Slots positions parameters address
  132. ;                                       If undefined (#0) or set to 0 the default address is 6061 for maximum 13 slots
  133. ;   #6050           TOOL_CHANGE [ATC] : Safe Z
  134. ;   #6051           TOOL_CHANGE [ATC] : Unlock input
  135. ;   #6052           TOOL_CHANGE [ATC] : Unlock output
  136. ;   #6053           TOOL_CHANGE [ATC] : Unlock timeout
  137. ;   #6054           TOOL_CHANGE [ATC] : Clamp movement
  138. ;   #6055           TOOL_CHANGE [ATC] : Pick distance Z
  139. ;   #6056           TOOL_CHANGE [ATC] : Enable tool-setter
  140. ;   #6057           TOOL_CHANGE [ATC] : Spindle s1 (tool-holder attached correctly)
  141. ;   #6058           TOOL_CHANGE [ATC] : Spindle s2 (collet open)
  142. ;   #6059           TOOL_CHANGE [ATC] : Slot axis orientation (0 = along X | 1 = along Y)
  143. ;   #6060           TOOL_CHANGE [ATC] : Slots number
  144. ;   #6061..#6099    TOOL_CHANGE [ATC] : Slots positions parameters (default, with #6049 = #0 or 0, for 1 to 13 slots) (MCS)
  145. ;
  146. O6
  147.     ; === DISCLAIMER ===
  148.     ;
  149.     ; This macro is provided 'AS IS', without WARRANTY of any kind, express or implied.
  150.     ; The macro is provided as an example only.
  151.     ; Use this macro at your own risk.
  152.     ;
  153.     ; NOTE: You can comment line 157 or delete this ADVICE but anyway you will accept the macro DISCLAIMER of the original code.
  154.     ;
  155.     IF [EXISTS[#<tc.disclaimer.showed>] EQ 0] THEN10
  156.         #<tc.disclaimer.showed>=1
  157.         M109 P"<B>DISCLAIMER</B><BR><BR>This macro is provided 'AS IS'</B>,<BR>without WARRANTY of any kind, express or implied.<BR><BR>The macro is provided as an example only.<BR><BR>Use this macro at your own risk." Q2
  158.     END10
  159.  
  160.     ; store loaded/requested tool/slot ID
  161.     #<tc.requested.tool_id>=#1
  162.     #<tc.requested.slot_id>=#2
  163.     #<tc.loaded.tool_id>=#3
  164.     #<tc.loaded.slot_id>=#4
  165.  
  166.     ; recover macro optional action when macro is called with G65
  167.     IF [[#5 EQ #0] OR [#5 EQ 0]] THEN10
  168.         #<tc.macro.option>=0
  169.     ELSE10
  170.         #<tc.macro.option>=#5
  171.     END10
  172.  
  173.     ; recover macro optional magazine argument available when macro called with G65
  174.     IF [EXISTS[#<_args.K>]] THEN10
  175.         #<tc.do_not_close_magazine>=1
  176.     ELSE10
  177.         #<tc.do_not_close_magazine>=0
  178.     END10
  179.  
  180.     ; initialize ATC parameters
  181.     CALL P"TC_INIT"
  182.  
  183.     ; store actual PLC states in local variables
  184.     #<_saved.5001>=#5001        ; current TCP position X
  185.     #<_saved.5002>=#5002        ; current TCP position Y
  186.     #<_saved.5003>=#5003        ; current TCP position Z
  187.     #<_saved.5004>=#5004        ; current position A
  188.     #<_saved.5005>=#5005        ; current position B
  189.     #<_saved.5006>=#5006        ; current position C
  190.     #<_saved.5101>=#5101        ; active G-codes - group 01: G00, G01, ...
  191.     #<_saved.5130>=#5130        ; active feed rate (F)
  192.     #<_saved.5151>=#5151        ; active M-codes: M3, M4, M5
  193.     #<_saved.5153>=#5153        ; active M-codes: M7, M9
  194.     #<_saved.5154>=#5154        ; active M-codes: M8, M9
  195.     #<_saved.5103>=#5103        ; active G-codes - group 03: G90, G91
  196.  
  197.     ; store actual PLC states in global variables
  198.     #<saved.5136>=#5136         ; active feed override mode (P argument of M50)
  199.  
  200.     ; set absolute coordinate
  201.     G90
  202.  
  203.     ; check if last G-codes group 01 used instruction was a G00/G01 otherwise, to prevent
  204.     ; an error when setting G#<_saved.5101>, set it to G80 (cancel motion mode)
  205.     IF [[#<_saved.5101> NE 0] AND [#<_saved.5101> NE 1]] THEN #<_saved.5101>=80
  206.  
  207.     ; check if required only a tool-setter procedure by ATCM macro
  208.     IF [#<tc.macro.option> EQ 3] THEN10
  209.         CALL P"TC_TOUCH_PROBE_EXTERNAL_REQUEST"
  210.         ; enable tool length compensation if enabled
  211.         IF [#<tc.enable_tool_length_compensation> EQ 1] THEN G43 H#<tc.requested.tool_id>
  212.         GOTO10
  213.     ELIF [#<tc.macro.option> EQ 4] THEN10
  214.         CALL P"TC_MAGAZINE_OPEN"
  215.         GOTO10
  216.     ELIF [#<tc.macro.option> EQ 5] THEN10
  217.         #<tc.do_not_close_magazine>=0
  218.         CALL P"TC_MAGAZINE_CLOSE"
  219.         GOTO10
  220.     ELIF [#<tc.macro.option> EQ 6] THEN10
  221.         CALL P"TC_MAGAZINE_UPDATE_STATE"
  222.         GOTO10
  223.     ELIF [#<tc.macro.option> EQ 7] THEN10
  224.         CALL P"TC_TOGGLE_CONE_LOAD_UNLOAD"
  225.         GOTO10
  226.     END10
  227.  
  228.     ; check if tool change type = 0 then execute sub MANUAL_TOOL_CHANGE_0
  229.     IF [#<tc.type> EQ 0] THEN10
  230.         CALL P"MANUAL_TOOL_CHANGE_0"
  231.         GOTO10
  232.     END10
  233.  
  234.     ; avoid any activity if tool change type is 10 or 11 and requested tool is same of loaded tool
  235.     IF [[#<tc.type> EQ 10] OR [#<tc.type> EQ 11]] THEN10
  236.         IF [[#<tc.requested.tool_id> EQ 0] AND [#<tc.loaded.tool_id> EQ 0]] THEN M109 P"tool change require a PICK or PLACE or PLACE/PICK action" Q-1
  237.         IF [[#<tc.requested.tool_id> EQ #<tc.loaded.tool_id>]] THEN11
  238.             ; enable tool length compensation if enabled
  239.             IF [#<tc.enable_tool_length_compensation> EQ 1] THEN G43 H#<tc.requested.tool_id>
  240.             GOTO10
  241.         END11
  242.     END10
  243.  
  244.     ; notice start change procedure to PLC
  245.     M107
  246.  
  247.     ; show main procedure message for 1s
  248.     M109 P"Tool change procedure" Q4
  249.     G04 P1
  250.  
  251.     ; set position of axes type "rotary axes for head"
  252.     IF [[#<cnc.a.type>] EQ #<axis.type.rotary_head>] THEN10
  253.         G49
  254.         G53 G01 A0 F#<tc.feed>
  255.     END10
  256.     IF [[#<cnc.b.type>] EQ #<axis.type.rotary_head>] THEN10
  257.         G49
  258.         G53 G01 B0 F#<tc.feed>
  259.     END10
  260.     IF [[#<cnc.c.type>] EQ #<axis.type.rotary_head>] THEN10
  261.         G49
  262.         G53 G01 C0 F#<tc.feed>
  263.     END10
  264.  
  265.     ; check if Tool change type = 1 the execute sub MANUAL_TOOL_CHANGE_1
  266.     IF [#<tc.type> EQ 1] THEN CALL P"MANUAL_TOOL_CHANGE_1"
  267.  
  268.     ; check if Tool change type = 2 the execute sub MANUAL_TOOL_CHANGE_2
  269.     IF [#<tc.type> EQ 2] THEN CALL P"MANUAL_TOOL_CHANGE_2"
  270.  
  271.     ; check if Tool change type = 10 the execute sub AUTOMATIC_TOOL_CHANGE_10
  272.     IF [#<tc.type> EQ 10] THEN CALL P"AUTOMATIC_TOOL_CHANGE_10"
  273.  
  274.     ; check if Tool change type = 10 the execute sub AUTOMATIC_TOOL_CHANGE_10
  275.     IF [#<tc.type> EQ 11] THEN CALL P"AUTOMATIC_TOOL_CHANGE_11"
  276.  
  277.     ; move back to saved work position
  278.     IF [#<tc.features> EQ 1] THEN10
  279.         G01 X#<_saved.5001> Y#<_saved.5002>
  280.         G01 Z#<_saved.5003>
  281.         IF [[#<cnc.a.type>] EQ #<axis.type.rotary_head>] THEN G01 A#<_saved.5004>
  282.         IF [[#<cnc.b.type>] EQ #<axis.type.rotary_head>] THEN G01 B#<_saved.5005>
  283.         IF [[#<cnc.c.type>] EQ #<axis.type.rotary_head>] THEN G01 C#<_saved.5005>
  284.     END10
  285.  
  286.     ( restore saved states )
  287.    
  288. N10
  289.     ; restore spindle & coolants states
  290.     IF [#<_saved.5151> EQ 3] THEN M03
  291.     IF [#<_saved.5151> EQ 4] THEN M04
  292.     IF [#<_saved.5153> EQ 7] THEN M07
  293.     IF [#<_saved.5154> EQ 8] THEN M08
  294.  
  295.     ; restore save feed
  296.     F#<_saved.5130>
  297.  
  298.     ; restore g-code group 03 state
  299.     G#<_saved.5103>
  300.  
  301.     ; restore g-code group 01 state
  302.     G#<_saved.5101>
  303.  
  304.     ; reset HUD message
  305.     M109 P"" Q4
  306.  
  307.     ; notice end change procedure to PLC
  308.     M108
  309.  
  310. M99
  311.  
  312. ; TOOL CHANGE EXIT
  313. ;
  314. ; Inputs:
  315. ;
  316. ;   Ee  #8          Exit code
  317. ;   Aa  #1          Undefined compulsory protected parameter
  318. ;
  319. ; Exit codes:
  320. ;
  321. ;   0       NONE
  322. ;   1       Error : One or more compulsory protected parameters are undefined!
  323. ;   2       Error : Sensor was found already tripped before to start approach movements to probe!
  324. ;   3       Error : Sensor was tripped during approach movements to probe!
  325. ;   4       Error : Sensor was found already tripped before to start 1st touch movements!
  326. ;   5       Error : Sensor was not found during 1st touch movements!
  327. ;   6       Error : Sensor was found already tripped before to start 2nd touch movements!
  328. ;   7       Error : Sensor was not found during 2nd touch movements!
  329. ;   **      Error : Unknown error<number>!
  330. ;
  331. SUB "TC_EXIT"
  332.  
  333.     ; check for error code
  334.     IF [#<_args.e> EQ 0] THEN M99
  335.  
  336.     ; reset HUD message
  337.     IF [#<tc.enable_hud> EQ 1] THEN M109 P"" Q4
  338.  
  339.     ; notice end change procedure to PLC
  340.     M108
  341.  
  342.     IF [#<_args.e> EQ 1] THEN M109 P"compulsory protected parameter ##<_args.a> is undefined!"   Q-1
  343.     IF [#<_args.e> EQ 2] THEN M109 P"<B>Error during measure of tool length</B><BR><BR>Sensor was found already tripped before to start approach movements to probe!</B><BR>" Q1
  344.     IF [#<_args.e> EQ 3] THEN M109 P"<B>Error during measure of tool length</B><BR><BR>Sensor was tripped during approach movements to probe!</B><BR>" Q1
  345.     IF [#<_args.e> EQ 4] THEN M109 P"<B>Error during measure of tool length</B><BR><BR>Sensor was found already tripped before to start 1st touch movements!</B><BR>" Q1
  346.     IF [#<_args.e> EQ 5] THEN M109 P"<B>Error during measure of tool length</B><BR><BR>Sensor was not found during 1st touch movements!</B><BR>" Q1
  347.     IF [#<_args.e> EQ 6] THEN M109 P"<B>Error during measure of tool length</B><BR><BR>Sensor was found already tripped before to start 2nd touch movements!</B><BR>" Q1
  348.     IF [#<_args.e> EQ 7] THEN M109 P"<B>Error during measure of tool length</B><BR><BR>Sensor was not found during 2nd touch movements!</B><BR>" Q1
  349.     IF [#<_args.e> EQ 8] THEN M109 P"compulsory protected parameter ##<_args.a> has a wrong value!" Q-1
  350.  
  351.     M109 P"<B>Generic Error<BR><BR>Unknown error #<_args.e>!</B>" Q1
  352.  
  353. ENDSUB
  354.  
  355. ; MANUAL TOOL CHANGE TYPE 0
  356. ;
  357. ; This mode only notice to the PLC about the loaded tool ID.
  358. ; No other actions or movments will be done.
  359. ;
  360. SUB "MANUAL_TOOL_CHANGE_0"
  361.  
  362.     ; notice to PLC the loaded tool ID
  363.     M61 Q#<tc.requested.tool_id>
  364.  
  365. ENDSUB
  366.  
  367. ; MANUAL TOOL CHANGE TYPE 1
  368. ;
  369. ; Manual Tool Change (MTC) with tool length probing:
  370. ;   a] Moves to tool-setter position and measures the loaded tool length.
  371. ;   b] Moves to tool change position and show info about tool to manually change.
  372. ;   c] Waits for the manual tool change by the operator which confirm that change is done.
  373. ;   d] Moves to tool-setter position to measures the length of the new tool.
  374. ;   e] Calcs the difference and uses this value as tool length compensation.
  375. ;
  376. SUB "MANUAL_TOOL_CHANGE_1"
  377.  
  378.     ; disable spindle, flood & mist
  379.     M05 M09
  380.  
  381.     ; initialize local variabiles
  382.     #<_measure1_>=0     ; measured tool offset Z
  383.  
  384.     ; disable tool length compensation to avoid software limits error
  385.     G49
  386.  
  387.     ; measure of tool to unload : approaching to probe
  388.     IF [#<tc.enable_hud> EQ 1] THEN M109 P"Measure of tool to unload : approacing to probe..." Q4
  389.  
  390.     ; call touch probe procedure
  391.     CALL P"TC_TOUCH_PROBE" A#<tc.tls.top_center_position.z> B#<tc.tls.1st_capture_feed> C#<tc.tls.up_movement_after_1st_touch> D#<tc.tls.minimum_tool_lenght_accepted> E#<tc.tls.2nd_capture_feed>
  392.  
  393.     ; calculate the tool length offset as the difference between when the sensor was tripped and the sensor Z position.
  394.     #<_measure1_> = [#5713 - #<tc.tls.top_center_position.z>]
  395.  
  396.     ; move to sensor safe position Z
  397.     G53 G01 Z#<tc.tls.safe_position.z> F#<tc.feed>
  398.  
  399.     ; move to tool change position
  400.     G53 G01 Z#<tc.mtc.change_position.z> F#<tc.feed>
  401.     G53 G01 X#<tc.mtc.change_position.x> Y#<tc.mtc.change_position.y>
  402.  
  403.     ; a different tool should be inserted. Display the message to the user
  404.     M109 P"<BR>Insert tool <B>T#<tc.requested.tool_id></B><BR><@TI=#<tc.requested.tool_id>><BR>" Q2
  405.     G04 P1
  406.  
  407.     ; notice to PLC the loaded tool ID
  408.     M61 Q#<tc.requested.tool_id>
  409.  
  410.     ; measure of loaded tool : approaching to probe
  411.     IF [#<tc.enable_hud> EQ 1] THEN M109 P"Measure of loaded tool : approacing to probe..." Q4
  412.  
  413.     ; call touch probe procedure
  414.     CALL P"TC_TOUCH_PROBE" A#<tc.tls.top_center_position.z> B#<tc.tls.1st_capture_feed> C#<tc.tls.up_movement_after_1st_touch> D#<tc.tls.minimum_tool_lenght_accepted> E#<tc.tls.2nd_capture_feed>
  415.  
  416.     ; calculate the tool length offset as the difference between when the sensor was tripped and the sensor Z position.
  417.     #<_measure2_> = [#5713 - #<tc.tls.top_center_position.z>]
  418.  
  419.     ; move to sensor safe position Z
  420.     G53 G01 Z#<tc.tls.safe_position.z> F#<tc.feed>
  421.  
  422.     ; calc compensation to do
  423.     #<_toll_length_difference_>=[#<_measure2_>-#<_measure1_>+#5422]
  424.  
  425.     ; enable dynamic tool length compensation (without use of tools library)
  426.     G43.1 Z#<_toll_length_difference_>
  427.  
  428. ENDSUB
  429.  
  430. ; MANUAL TOOL CHANGE TYPE 2
  431. ;
  432. ; Manual Tool Change (MTC) with tool length from Tools Library info:
  433. ;   a] Moves to tool change position and show info about tool to manually change.
  434. ;   b] Waits for the manual tool change by the operator which confirm that change is done.
  435. ;   c] If enabled applies the tool length compensation from Tools Libary info.
  436. ;
  437. SUB "MANUAL_TOOL_CHANGE_2"
  438.  
  439.     ; check if a different tool should be inserted.
  440.     IF [#<tc.requested.tool_id> NE #<tc.loaded.tool_id>] THEN10
  441.  
  442.         ; disable spindle, flood & mist
  443.         M05 M09
  444.  
  445.         ; disable tool length compensation to avoid software limits error
  446.         G49
  447.  
  448.         ; move to tool change position
  449.         G53 G01 Z#<tc.mtc.change_position.z> F#<tc.feed>
  450.         G53 G01 X#<tc.mtc.change_position.x> Y#<tc.mtc.change_position.y>
  451.  
  452.         ; A different tool should be inserted. Display the message to the user.
  453.         M109 P"<BR>Insert tool <B>T#<tc.requested.tool_id></B><BR><@TI=#<tc.requested.tool_id>><BR>" Q2
  454.         G04 P1
  455.  
  456.         ; notice to PLC the loaded tool ID
  457.         M61 Q#<tc.requested.tool_id>
  458.  
  459.         ; enable tool length compensation if enabled
  460.         IF [#<tc.enable_tool_length_compensation> EQ 1] THEN G43 H#<tc.requested.tool_id>
  461.  
  462.     END10
  463.  
  464. ENDSUB
  465.  
  466. ; AUTOMATIC TOOL CHANGE TYPE 10
  467. ;
  468. ; This mode manages a rack of slots using place/side & pick/top approach.
  469. ; If there is a loaded tool it will be placed.
  470. ; If there is a requested tool it will be picked.
  471. ; If the tool length measurement/compensation are enabled they are automaticallly performed.
  472. ;
  473. SUB "AUTOMATIC_TOOL_CHANGE_10"
  474.  
  475.     ; checks if slots for the PICK and PLACE actions are valid
  476.     ;
  477.     ; this happen if G-code require a T with a slot higher than available slots to keep it
  478.     IF [[#<tc.loaded.slot_id> LT 0] OR [#<tc.loaded.slot_id> GT #<tc.atc.slots>]] THEN M109 P"tool change require a PLACE slot number not in range (1..#<tc.atc.slots>)" Q-1
  479.     IF [[#<tc.requested.slot_id> LT 0] OR [#<tc.requested.slot_id> GT #<tc.atc.slots>]] THEN M109 P"tool change require a PICK slot number not in range (1..#<tc.atc.slots>)" Q-1
  480.  
  481.     ; disable tool length compensation to avoid errors in software limits checking
  482.     G49
  483.  
  484.     ; check actions to do
  485.     #<_has.place>=[#<tc.loaded.tool_id> NE 0]       ; evaluate if tool change has place action
  486.     #<_has.pick>=[#<tc.requested.tool_id> NE 0]     ; evaluate if tool change has pick action
  487.  
  488.     ( loaded tool placing )
  489.  
  490.     ; check if necessary to place the loaded tool
  491.     IF [#<_has.place>] THEN10
  492.  
  493.         ; show place info
  494.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool Changing: PLACE of T#<tc.loaded.tool_id>" Q4
  495.  
  496.         ; move Z to safe position
  497.         G53 G00 Z#<tc.atc.safe.z>
  498.  
  499.         ; disable spindle, flood & mist
  500.         M05 M09
  501.  
  502.         ; open magazine
  503.         CALL P"TC_MAGAZINE_OPEN"
  504.  
  505.         ; move XY to clamp zone slot of loaded tool to place it
  506.         CALL P"TC_MOVE_XY_TO_CLAMP_ZONE_SLOT" M0
  507.  
  508.         ; move Z to tool drop position
  509.         G53 G00 Z#<tc.atc.slots[#<tc.loaded.slot_id>].z>
  510.  
  511.         ; move XY into tool place
  512.         G53 G01 X#<tc.atc.slots[#<tc.loaded.slot_id>].x> Y#<tc.atc.slots[#<tc.loaded.slot_id>].y> F#<tc.feed>
  513.  
  514.         ; unload tool-holder
  515.         CALL P"TC_TOOLHOLDER_UNLOAD"
  516.  
  517.         ; inform the PLC that the tool has been dropped
  518.         M61 Q0
  519.  
  520.         ; move Z to safe position
  521.         G53 G00 Z#<tc.atc.safe.z>
  522.  
  523.         ; turn OFF tool unlock output
  524.         M63 P#<tc.atc.unlock.output>
  525.  
  526.         ; check if there is not a pick action
  527.         IF [#<_has.pick> EQ 0] THEN11
  528.             ; move XY to clamp zone slot of just now unloaded tool
  529.             CALL P"TC_MOVE_XY_TO_CLAMP_ZONE_SLOT" M0
  530.         END11
  531.  
  532.     END10
  533.  
  534.     ( requested tool picking )
  535.  
  536.     ; check if necessary to pick the requested tool
  537.     IF [#<_has.pick>] THEN10
  538.  
  539.         ; show pick info
  540.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool Changing: PICK of T#<tc.requested.tool_id>" Q4
  541.  
  542.         ; check if place action is enabled
  543.         IF [#<_has.place> EQ 0] THEN11
  544.  
  545.             ; move Z to safe position
  546.             G53 G00 Z#<tc.atc.safe.z>
  547.  
  548.             ; disable spindle, flood & mist
  549.             M05 M09
  550.  
  551.             ; open magazine
  552.             CALL P"TC_MAGAZINE_OPEN"
  553.  
  554.             ; move XY to outer of tool place position
  555.             G53 G00 X#<tc.atc.slots[#<tc.requested.slot_id>].x> Y#<tc.atc.slots[#<tc.requested.slot_id>].y>
  556.  
  557.             ; enable bearing and cone cleaning blow
  558.             CALL P"TC_BEARING_CONE_CLEANING_BLOW" E1
  559.            
  560.         ELSE11
  561.             ; move Z to safe position
  562.             G53 G00 Z#<tc.atc.safe.z>
  563.  
  564.             ; move XY to outer of tool place position
  565.             G53 G00 X#<tc.atc.slots[#<tc.requested.slot_id>].x> Y#<tc.atc.slots[#<tc.requested.slot_id>].y>
  566.         END11
  567.  
  568.         ; turn ON tool unlock output and wait 1s
  569.         M62 P#<tc.atc.unlock.output>
  570.         G04 P1.0
  571.  
  572.         ; enable bearing and cone cleaning blow
  573.         CALL P"TC_BEARING_CONE_CLEANING_BLOW" E1
  574.  
  575.         ; move Z to tool pick position
  576.         #<change.pick.z>=[#<tc.atc.slots[#<tc.requested.slot_id>].z> + #<tc.atc.pick_distance.z>]
  577.         G53 G01 Z#<change.pick.z> F#<tc.feed>
  578.  
  579.         ; load tool-holder
  580.         CALL P"TC_TOOLHOLDER_LOAD"
  581.  
  582.         ; disable bearing and cone cleaning blow
  583.         CALL P"TC_BEARING_CONE_CLEANING_BLOW" E0
  584.  
  585.         ; inform PLC that requested tool has been picked
  586.         M61 Q#<tc.requested.tool_id>
  587.  
  588.         ; move X or Y to outer of tool place position depending by slot axis orientation
  589.         IF [#<tc.atc.slot.axis.orientation> EQ 0] THEN11
  590.             #<change.outer.y> = [#<tc.atc.slots[#<tc.requested.slot_id>].y> - #<tc.atc.clamp_movement>]
  591.             G53 G00 Y#<change.outer.y>
  592.         ELSE11
  593.             #<change.outer.x> = [#<tc.atc.slots[#<tc.requested.slot_id>].x> - #<tc.atc.clamp_movement>]
  594.             G53 G00 X#<change.outer.x>
  595.         END11
  596.  
  597.         ; move Z to safe position
  598.         G53 G00 Z#<tc.atc.safe.z>
  599.     END10
  600.  
  601.     ( new loaded tool measuring and compensation )
  602.  
  603.     ; check if there was a pick action so a new tool should be in the spindle
  604.     IF [#<_has.pick>] THEN10
  605.    
  606.         ; check if necessary to measure loaded tool
  607.         IF [[[#<tc.atc.enable_tool_setter> EQ 1] AND [#<tc.macro.option> EQ 0]] OR [#<tc.macro.option> EQ 2]] THEN11
  608.             CALL P"TC_TOUCH_PROBE"
  609.         END11
  610.  
  611.         ; enable tool length compensation if enabled
  612.         IF [#<tc.enable_tool_length_compensation> EQ 1] THEN G43 H#<tc.requested.tool_id>
  613.        
  614.     END10
  615.  
  616.     ; close magazine
  617.     CALL P"TC_MAGAZINE_CLOSE"
  618.  
  619. ENDSUB
  620.  
  621. ; AUTOMATIC TOOL CHANGE TYPE 11
  622. ;
  623. ; This mode manages a rack of slots using place/top & pick/top approach.
  624. ; If there is a loaded tool it will be placed.
  625. ; If there is a requested tool it will be picked.
  626. ; If the tool length measurement/compensation are enabled they are automaticallly performed.
  627. ;
  628. SUB "AUTOMATIC_TOOL_CHANGE_11"
  629.  
  630.     ; checks if slots for the PICK and PLACE actions are valid
  631.     ;
  632.     ; this happen if G-code require a T with a slot higher than available slots to keep it
  633.     IF [[#<tc.loaded.slot_id> LT 0] OR [#<tc.loaded.slot_id> GT #<tc.atc.slots>]] THEN M109 P"tool change require a PLACE slot number not in range (1..#<tc.atc.slots>)" Q-1
  634.     IF [[#<tc.requested.slot_id> LT 0] OR [#<tc.requested.slot_id> GT #<tc.atc.slots>]] THEN M109 P"tool change require a PICK slot number not in range (1..#<tc.atc.slots>)" Q-1
  635.  
  636.     ; disable tool length compensation to avoid errors in software limits checking
  637.     G49
  638.  
  639.     ; check actions to do
  640.     #<_has.place>=[#<tc.loaded.tool_id> NE 0]       ; evaluate if tool change has place action
  641.     #<_has.pick>=[#<tc.requested.tool_id> NE 0]     ; evaluate if tool change has pick action
  642.  
  643.     ( loaded tool placing )
  644.  
  645.     ; check if necessary to place the loaded tool
  646.     IF [#<_has.place>] THEN10
  647.  
  648.         ; show place info
  649.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool Changing: PLACE of T#<tc.loaded.tool_id>" Q4
  650.  
  651.         ; move Z to safe position
  652.         G53 G00 Z#<tc.atc.safe.z>
  653.  
  654.         ; disable spindle, flood & mist
  655.         M05 M09
  656.  
  657.         ; open magazine
  658.         CALL P"TC_MAGAZINE_OPEN"
  659.  
  660.         ; move XY to clamp zone slot of loaded tool to place it
  661.         CALL P"TC_MOVE_XY_TO_CLAMP_ZONE_SLOT" M0
  662.  
  663.         ; move XY into tool place
  664.         G53 G01 X#<tc.atc.slots[#<tc.loaded.slot_id>].x> Y#<tc.atc.slots[#<tc.loaded.slot_id>].y> F#<tc.feed>
  665.  
  666.         ; aproach to tool-holder drop zone
  667.         G53 G01 Z[#<tc.atc.slots[#<tc.loaded.slot_id>].z> + #<tc.atc.fast.unload.tool.holder.distance>] F#<tc.feed>
  668.         G53 G01 Z[#<tc.atc.slots[#<tc.loaded.slot_id>].z> + #<tc.atc.slow.unload.tool.holder.distance>] F#<tc.atc.slow.unload.tool.holder.feed>
  669.  
  670.         ; unload tool-holder
  671.         CALL P"TC_TOOLHOLDER_UNLOAD"
  672.  
  673.         ; inform the PLC that the tool has been dropped
  674.         M61 Q0
  675.  
  676.         ; move Z to safe position
  677.         G53 G00 Z#<tc.atc.safe.z>
  678.  
  679.         ; turn OFF tool unlock output
  680.         M63 P#<tc.atc.unlock.output>
  681.  
  682.         ; check if there is not a pick action
  683.         IF [#<_has.pick> EQ 0] THEN11
  684.             ; move XY to clamp zone slot of just now unloaded tool
  685.             CALL P"TC_MOVE_XY_TO_CLAMP_ZONE_SLOT" M0
  686.         END11
  687.  
  688.     END10
  689.  
  690.     ( requested tool picking )
  691.  
  692.     ; check if necessary to pick the requested tool
  693.     IF [#<_has.pick>] THEN10
  694.  
  695.         ; show pick info
  696.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool Changing: PICK of T#<tc.requested.tool_id>" Q4
  697.  
  698.         ; check if place action is enabled
  699.         IF [#<_has.place> EQ 0] THEN11
  700.  
  701.             ; move Z to safe position
  702.             G53 G00 Z#<tc.atc.safe.z>
  703.  
  704.             ; disable spindle, flood & mist
  705.             M05 M09
  706.  
  707.             ; open magazine
  708.             CALL P"TC_MAGAZINE_OPEN"
  709.  
  710.             ; move XY to clamp zone slot of requested tool to pick it
  711.             CALL P"TC_MOVE_XY_TO_CLAMP_ZONE_SLOT" M1
  712.  
  713.             ; move XY into tool place
  714.             G53 G01 X#<tc.atc.slots[#<tc.requested.slot_id>].x> Y#<tc.atc.slots[#<tc.requested.slot_id>].y> F#<tc.feed>
  715.         ELSE11
  716.             ; move XY to outer of tool place position
  717.             G53 G00 X#<tc.atc.slots[#<tc.requested.slot_id>].x> Y#<tc.atc.slots[#<tc.requested.slot_id>].y>
  718.         END11
  719.  
  720.         ( BEGIN UNLOAD TOOL-HOLDER )
  721.  
  722.         ; aproach to tool-holder drop zone
  723.         G53 G01 Z[#<tc.atc.slots[#<tc.requested.slot_id>].z> + #<tc.atc.fast.load.tool.holder.distance>] F#<tc.feed>
  724.  
  725.         ; turn ON tool unlock output
  726.         M62 P#<tc.atc.unlock.output>
  727.  
  728.         ; enable bearing and cone cleaning blow
  729.         CALL P"TC_BEARING_CONE_CLEANING_BLOW" E1
  730.  
  731.         ; check if required unlock output feedback
  732.         IF [#<tc.atc.unlock.input> GT 0] THEN11
  733.             ; wait and check for tool unlock input signal with timeout
  734.             M66 P#<tc.atc.unlock.input> L#<wait_input.high> Q#<tc.atc.unlock.timeout>
  735.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"<B>TOOL T#<tc.requested.tool_id> PICK ERROR</B><BR><BR>Collet Unlock Input is LOW<BR>" Q1
  736.         END11
  737.  
  738.         ; wait and check spindle S1/S2 for S1 HIGH & S2 LOW
  739.         CALL P"TC_WAIT_AND_CHECK_SPINDLE_S1_S2_FOR_HL"
  740.  
  741.         ; aproach to tool-holder drop zone
  742.         G53 G01 Z[#<tc.atc.slots[#<tc.requested.slot_id>].z> + #<tc.atc.medium.load.tool.holder.distance>] F#<tc.atc.medium.load.tool.holder.feed>
  743.  
  744.         ; disable bearing and cone cleaning blow
  745.         CALL P"TC_BEARING_CONE_CLEANING_BLOW" E0
  746.  
  747.         ; move Z to tool pick position
  748.         G53 G01 Z#<tc.atc.slots[#<tc.requested.slot_id>].z> F#<tc.atc.final.load.tool.holder.feed>
  749.  
  750.         ; turn OFF tool unlock output and wait 1s
  751.         M63 P#<tc.atc.unlock.output>
  752.  
  753.         ; check if required unlock output feedback
  754.         IF [#<tc.atc.unlock.input> GT 0] THEN11
  755.  
  756.             ; wait settle time for P5 input stabilizatin
  757.             G04 P1.0
  758.  
  759.             ; wait and check for tool unlock input signal with timeout
  760.             M66 P#<tc.atc.unlock.input> L#<wait_input.high> Q#<tc.atc.unlock.timeout>
  761.             IF [#5722 EQ #<wait_input.failure>] THEN12
  762.                 M109 P"<B>TOOL T#<tc.requested.tool_id> PICK ERROR</B><BR><BR>Cone present Input is LOW<BR>" Q1
  763.             END12
  764.         END11
  765.  
  766.         ; cone grip pulse management
  767.         CALL P"TC_CONE_GRIP_PULSE"
  768.  
  769.         ; inform PLC that requested tool has been picked
  770.         M61 Q#<tc.requested.tool_id>
  771.  
  772.         ; move Z to safe position
  773.         G53 G01 Z#<tc.atc.safe.z> F#<tc.feed>
  774.  
  775.         ; move XY to clamp zone slot of requested tool just now loaded
  776.         CALL P"TC_MOVE_XY_TO_CLAMP_ZONE_SLOT" M1
  777.  
  778.     END10
  779.  
  780.     ( new loaded tool measuring and compensation )
  781.  
  782.     ; check if there was a pick action so a new tool should be in the spindle
  783.     IF [#<_has.pick>] THEN10
  784.    
  785.         ; check if necessary to measure loaded tool
  786.         IF [[[#<tc.atc.enable_tool_setter> EQ 1] AND [#<tc.macro.option> EQ 0]] OR [#<tc.macro.option> EQ 2]] THEN11
  787.             CALL P"TC_TOUCH_PROBE"
  788.         END11
  789.  
  790.         ; enable tool length compensation if enabled
  791.         IF [#<tc.enable_tool_length_compensation> EQ 1] THEN G43 H#<tc.requested.tool_id>
  792.        
  793.     END10
  794.  
  795.     ; close magazine
  796.     CALL P"TC_MAGAZINE_CLOSE"
  797.  
  798. ENDSUB
  799.  
  800. ;   TOOL CHANGE CONE GRIP PULSE
  801. ;
  802. SUB "TC_CONE_GRIP_PULSE"
  803.  
  804.     ; check if required cone grip pulse
  805.     IF [#<tc.atc.cone.grip.output> GT 0] THEN10
  806.         G04 P#<tc.atc.cone.grip.output.time>
  807.         M62 P#<tc.atc.cone.grip.output>
  808.         G04 P#<tc.atc.cone.grip.output.time>
  809.         M63 P#<tc.atc.cone.grip.output>
  810.     END10
  811.  
  812. ENDSUB
  813.  
  814. ;   TOOL CHANGE BEARING/CONE CLEANING BLOW
  815. ;
  816. ;   Arguments
  817. ;       E0  #8      Enabled state: OFF
  818. ;       E1  #8      Enabled state: ON
  819. ;
  820. SUB "TC_BEARING_CONE_CLEANING_BLOW"
  821.  
  822.     ; evaluate enabled state
  823.     IF [#8 EQ 0] THEN10
  824.  
  825.         ; check if required cone clearing blow and put it OFF
  826.         IF [#<tc.atc.cone.cleaning.blow.output> GT 0] THEN11
  827.             M63 P#<tc.atc.cone.cleaning.blow.output>
  828.         END11
  829.        
  830.         ; check if required bearing cleaning blow and put it OFF
  831.         IF [#<tc.atc.bearing.cleaning.blow.output> GT 0] THEN11
  832.             M63 P#<tc.atc.bearing.cleaning.blow.output>
  833.         END11
  834.    
  835.     ELSE10
  836.  
  837.         ; check if required cone clearing blow and put it ON
  838.         IF [#<tc.atc.cone.cleaning.blow.output> GT 0] THEN11
  839.             M62 P#<tc.atc.cone.cleaning.blow.output>
  840.         END11
  841.  
  842.         ; check if required bearing cleaning blow and put it ON
  843.         IF [#<tc.atc.bearing.cleaning.blow.output> GT 0] THEN11
  844.             M62 P#<tc.atc.bearing.cleaning.blow.output>
  845.         END11
  846.    
  847.     END10
  848.  
  849. ENDSUB
  850.  
  851. ;   TOOL CHANGE WAIT AND CHECK SPINDLE S1/S2 FOR S1 LOW & S2 HIGH
  852. ;
  853. SUB "TC_WAIT_AND_CHECK_SPINDLE_S1_S2_FOR_LH"
  854.  
  855.     ; check if required spindle S1/S2 management
  856.     IF [[#<tc.atc.spindle.s1> GT 0] AND [#<tc.atc.spindle.s2> GT 0]] THEN10
  857.         ; wait and check for spindle S1/S2 management
  858.         M66 P#<tc.atc.spindle.s1> L#<wait_input.low> Q#<tc.atc.unlock.timeout>
  859.         IF [#5722 EQ #<wait_input.failure>] THEN M109 P"<B>TOOL T#<tc.loaded.tool_id> PLACE ERROR</B><BR><BR>Spindle S1 is HIGH<BR>" Q1
  860.         M66 P#<tc.atc.spindle.s2> L#<wait_input.high> Q#<tc.atc.unlock.timeout>
  861.         IF [#5722 EQ #<wait_input.failure>] THEN M109 P"<B>TOOL T#<tc.loaded.tool_id> PLACE ERROR</B><BR><BR>Spindle S2 is LOW<BR>" Q1
  862.     END10
  863.  
  864. ENDSUB
  865.  
  866. ;   TOOL CHANGE WAIT AND CHECK SPINDLE S1/S2 FOR S1 HIGH & S2 LOW
  867. ;
  868. SUB "TC_WAIT_AND_CHECK_SPINDLE_S1_S2_FOR_HL"
  869.  
  870.     ; check if required spindle S1/S2 management
  871.     IF [[#<tc.atc.spindle.s1> GT 0] AND [#<tc.atc.spindle.s2> GT 0]] THEN10
  872.         ; wait and check for spindle S1/S2 management
  873.         M66 P#<tc.atc.spindle.s1> L#<wait_input.high> Q#<tc.atc.unlock.timeout>
  874.         IF [#5722 EQ #<wait_input.failure>] THEN M109 P"<B>TOOL T#<tc.loaded.tool_id> PICK ERROR</B><BR><BR>Spindle S1 is LOW<BR>" Q1
  875.         M66 P#<tc.atc.spindle.s2> L#<wait_input.low> Q#<tc.atc.unlock.timeout>
  876.         IF [#5722 EQ #<wait_input.failure>] THEN M109 P"<B>TOOL T#<tc.loaded.tool_id> PICK ERROR</B><BR><BR>Spindle S2 is HIGH<BR>" Q1
  877.     END10
  878.  
  879. ENDSUB
  880.  
  881. ;   TOOL CHANGE MOVE XY TO CLAMP ZONE SLOT FOR LOADED OR SELECTED TOOL
  882. ;
  883. ;   Arguments
  884. ;       M0  #13     Required position: for the loaded tool
  885. ;       M1  #13     Required position: for the requested tool
  886. ;
  887. SUB "TC_MOVE_XY_TO_CLAMP_ZONE_SLOT"
  888.  
  889.     ; evaluate required position
  890.     IF [#13 EQ 0] THEN10
  891.    
  892.         ; move XY to outer of tool place position depending by slot axis orientation
  893.         IF [#<tc.atc.slot.axis.orientation> EQ 0] THEN11
  894.             G53 G00 Y[#<tc.atc.slots[#<tc.loaded.slot_id>].y> - #<tc.atc.clamp_movement>]
  895.             G53 G00 X#<tc.atc.slots[#<tc.loaded.slot_id>].x>
  896.         ELSE11
  897.             G53 G00 X[#<tc.atc.slots[#<tc.loaded.slot_id>].x> - #<tc.atc.clamp_movement>]
  898.             G53 G00 Y#<tc.atc.slots[#<tc.loaded.slot_id>].y>
  899.         END11
  900.    
  901.     ELSE10
  902.  
  903.         ; move XY to outer of tool place position depending by slot axis orientation
  904.         IF [#<tc.atc.slot.axis.orientation> EQ 0] THEN11
  905.             G53 G00 Y[#<tc.atc.slots[#<tc.requested.slot_id>].y> - #<tc.atc.clamp_movement>]
  906.             G53 G00 X#<tc.atc.slots[#<tc.requested.slot_id>].x>
  907.         ELSE11
  908.             G53 G00 X[#<tc.atc.slots[#<tc.requested.slot_id>].x> - #<tc.atc.clamp_movement>]
  909.             G53 G00 Y#<tc.atc.slots[#<tc.requested.slot_id>].y>
  910.         END11
  911.    
  912.     END10
  913.  
  914. ENDSUB
  915.  
  916. ;   TOOL CHANGE MOVE TO SAFE Z CLAMP ZONE TOOL-SETTER
  917. ;
  918. SUB "TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  919.  
  920.     ; move Z to safe position
  921.     G53 G00 Z#<tc.tls.safe_position.z>
  922.  
  923.     ; move XY to outer of tool-setter position depending by slot axis orientation
  924.     IF [#<tc.atc.slot.axis.orientation> EQ 0] THEN11
  925.         G53 G00 Y[#<tc.tls.top_center_position.y> - #<tc.atc.clamp_movement>]
  926.         G53 G00 X#<tc.tls.top_center_position.x>
  927.     ELSE11
  928.         G53 G00 X[#<tc.tls.top_center_position.x> - #<tc.atc.clamp_movement>]
  929.         G53 G00 Y#<tc.tls.top_center_position.y>
  930.     END11
  931.  
  932. ENDSUB
  933.  
  934. ;   TOOL CHANGE TOUCH PROBE EXTERNAL REQUEST
  935. ;
  936. SUB "TC_TOUCH_PROBE_EXTERNAL_REQUEST"
  937.  
  938.     ; disable tool length compensation to avoid software limits error
  939.     G49
  940.  
  941.     ; move to safe Z clamp zone tool-setter
  942.     CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  943.  
  944.     ; open magazine
  945.     CALL P"TC_MAGAZINE_OPEN"
  946.  
  947.     ; call touch probe procedure
  948.     CALL P"TC_TOUCH_PROBE"
  949.  
  950.     ; move to safe Z clamp zone tool-setter
  951.     CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  952.  
  953.     ; close magazine
  954.     CALL P"TC_MAGAZINE_CLOSE"
  955.  
  956. ENDSUB
  957.  
  958. ;   TOOL CHANGE TOUCH PROBE
  959. ;
  960. SUB "TC_TOUCH_PROBE"
  961.  
  962.     ; check mode type
  963.     IF [[#<tc.type> EQ 10] OR [#<tc.type> EQ 11]] THEN10
  964.         ; move to safe Z clamp zone tool-setter
  965.         CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  966.     ELSE10
  967.         ; move to safe Z zone tool-setter
  968.         G53 G01 Z#<tc.tls.safe_position.z> F#<tc.feed>
  969.     END10
  970.  
  971.     ; move XY to probe positions
  972.     G53 G00 X#<tc.tls.top_center_position.x> Y#<tc.tls.top_center_position.y>
  973.  
  974.     ; check if required cleaning probe pulse
  975.     IF [#<tc.tls.probe.cleaning.output> GT 0] THEN11
  976.         M62 P#<tc.tls.probe.cleaning.output>
  977.         G04 P#<tc.tls.probe.cleaning.output.time>
  978.         M63 P#<tc.tls.probe.cleaning.output>
  979.     END11
  980.  
  981.     ; move z to probe approaching position
  982.     G53 G38.3 Z#<tc.tls.approaching_position.z> X#<tc.tls.top_center_position.x> Y#<tc.tls.top_center_position.y> F#<tc.tls.approaching_feed>
  983.  
  984.     ; check if sensor was found already tripped before to start approach movements to probe
  985.     IF [#5700 EQ -2] THEN CALL P"TC_EXIT" E2
  986.  
  987.     ; check if sensor was tripped during approach movements to probe
  988.     IF [#5700 EQ 1] THEN CALL P"TC_EXIT" E3
  989.  
  990.     ; call tc touch probe managemnt
  991.     CALL P"TC_TOUCH_PROBE_MAIN" A#<tc.tls.top_center_position.z> B#<tc.tls.1st_capture_feed> C#<tc.tls.up_movement_after_1st_touch> D#<tc.tls.minimum_tool_lenght_accepted> E#<tc.tls.2nd_capture_feed>
  992.  
  993.     ; calc and set new tool length (offset Z)
  994.     #<_offset.z_>=[#5713 - #<tc.tls.top_center_position.z>]
  995.     G10 L1 P#<tc.requested.tool_id> V#<tc.requested.slot_id> X0 Y0 Z#<_offset.z_>
  996.  
  997.     ; show calculated tool length
  998.     IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool T#<tc.requested.tool_id> measured length = #<_offset.z_>mm" Q4
  999.  
  1000.     ; check mode type
  1001.     IF [[#<tc.type> EQ 10] OR [#<tc.type> EQ 11]] THEN10
  1002.         ; move to safe Z clamp zone tool-setter
  1003.         CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  1004.     ELSE10
  1005.         ; move to safe Z zone tool-setter
  1006.         G53 G01 Z#<tc.tls.safe_position.z> F#<tc.feed>
  1007.     END10
  1008.  
  1009. ENDSUB
  1010.  
  1011. ; TOOL CHANGE TOUCH PROBE MAIN
  1012. ;
  1013. ; Inputs:
  1014. ;
  1015. ;   Ee  #8          Exit code
  1016. ;   Aa  #1          Sensor top/center position Z (MCS)
  1017. ;   Bb  #2          Z feed to 1st probe input capture (SLOW)
  1018. ;   Cc  #3          Z up movement after 1st touch capture (REL)
  1019. ;   Dd  #7          Minimum tool lenght accepted
  1020. ;   Ee  #8          Z feed to 2nd probe input capture (VERY SLOW)
  1021. ;
  1022. SUB "TC_TOUCH_PROBE_MAIN"
  1023.  
  1024.     ; disable the feed rate override controls
  1025.     ;
  1026.     ; NOTE
  1027.     ; ====
  1028.     ; During debug movements, for safety, you can disable this code and use feed rate OVR
  1029.     M50 P0
  1030.  
  1031.     ; measure of tool : 1st touch
  1032.     IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool Measuring: Approach for 1st touch..." Q4
  1033.     G53 G38.3 Z[#<_args.a>+#<_args.d>] F#<_args.b>
  1034.  
  1035.     ; check if sensor was found already tripped before to start 1st touch movements
  1036.     IF [#5700 EQ -2] THEN10
  1037.         ; restore the feed rate override controls
  1038.         M50 P#<saved.5136>
  1039.  
  1040.         ; move to safe Z clamp zone tool-setter and notice error
  1041.         CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  1042.         CALL P"TC_EXIT" E4
  1043.     END10
  1044.  
  1045.     ; check if sensor was not found during 1st touch movements
  1046.     IF [#5700 NE 1] THEN10
  1047.         ; restore the feed rate override controls
  1048.         M50 P#<saved.5136>
  1049.  
  1050.         ; move to safe Z clamp zone tool-setter and notice error
  1051.         CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  1052.         CALL P"TC_EXIT" E5
  1053.     END10
  1054.  
  1055.     ; measure of tool : 2nd touch
  1056.     IF [#<tc.enable_hud> EQ 1] THEN M109 P"Tool Measuring: Approach for 2nd touch..." Q4
  1057.  
  1058.     G53 G00 Z[#5713+#<_args.c>]
  1059.     G53 G38.3 Z[#<_args.a>+#<_args.d>] F#<_args.e>
  1060.  
  1061.     ; check if sensor was found already tripped before to start 2nd touch movements
  1062.     IF [#5700 EQ -2] THEN10
  1063.         ; restore the feed rate override controls
  1064.         M50 P#<saved.5136>
  1065.  
  1066.         ; move to safe Z clamp zone tool-setter and notice error
  1067.         CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  1068.         CALL P"TC_EXIT" E6
  1069.     END10
  1070.  
  1071.     ; check if sensor was not found during 2nd touch movements
  1072.     IF [#5700 NE 1] THEN10
  1073.         ; restore the feed rate override controls
  1074.         M50 P#<saved.5136>
  1075.  
  1076.         ; move to safe Z clamp zone tool-setter and notice error
  1077.         CALL P"TC_MOVE_TO_SAFE_Z_CLAMP_ZONE_TOOLSETTER"
  1078.         CALL P"TC_EXIT" E7
  1079.     END10
  1080.  
  1081.     ; restore the feed rate override controls
  1082.     M50 P#<saved.5136>
  1083.  
  1084. ENDSUB
  1085.  
  1086. ;   TOOL CHANGE TOOLHOLDER LOAD (ATC)
  1087. ;
  1088. SUB "TC_TOOLHOLDER_LOAD"
  1089.  
  1090.     ; turn OFF tool unlock output and wait 1s
  1091.     M63 P#<tc.atc.unlock.output>
  1092.     G04 P1.0
  1093.  
  1094.     ; check if required unlock output feedback
  1095.     IF [#<tc.atc.unlock.input> GT 0] THEN10
  1096.         ; wait and check for tool unlock input signal with timeout
  1097.         M66 P#<tc.atc.unlock.input> L#<wait_input.high> Q#<tc.atc.unlock.timeout>
  1098.         IF [#5722 EQ #<wait_input.failure>] THEN M109 P"<B>TOOL T#<tc.requested.tool_id> PICK ERROR</B><BR><BR>Collet Unlock Input is LOW<BR>" Q1
  1099.     END10
  1100.  
  1101.     ; wait and check spindle S1/S2 for S1 HIGH & S2 LOW
  1102.     CALL P"TC_WAIT_AND_CHECK_SPINDLE_S1_S2_FOR_HL"
  1103.  
  1104. M99
  1105.  
  1106. ;   TOOL CHANGE TOOLHOLDER UNLOAD (ATC)
  1107. ;
  1108. SUB "TC_TOOLHOLDER_UNLOAD"
  1109.  
  1110.     ; turn ON tool unlock output and wait 1s
  1111.     M62 P#<tc.atc.unlock.output>
  1112.     G04 P1.0
  1113.  
  1114.     ; check if required unlock output feedback
  1115.     IF [#<tc.atc.unlock.input> GT 0] THEN10
  1116.         ; wait and check for tool unlock input signal with timeout
  1117.         M66 P#<tc.atc.unlock.input> L#<wait_input.low> Q#<tc.atc.unlock.timeout>
  1118.         IF [#5722 EQ #<wait_input.failure>] THEN11
  1119.             ; turn OFF tool unlock output
  1120.             M63 P#<tc.atc.unlock.output>
  1121.             ; notice error and stop
  1122.             M109 P"<B>TOOL T#<tc.requested.tool_id> PLACE ERROR</B><BR><BR>Collet Unlock Input is HIGH<BR>" Q1
  1123.         END11
  1124.     END10
  1125.  
  1126.     ; wait and check spindle S1/S2 for S1 LOW & S2 HIGH
  1127.     CALL P"TC_WAIT_AND_CHECK_SPINDLE_S1_S2_FOR_LH"
  1128.  
  1129. ENDSUB
  1130.  
  1131. ;   TOOL CHANGE MAGAZINE UPDATE STATE
  1132. ;
  1133. ;   #<tc.atc.magazine_state>
  1134. ;   0 = undefined
  1135. ;   1 = open
  1136. ;   2 = closed
  1137. ;
  1138. SUB "TC_MAGAZINE_UPDATE_STATE"
  1139.  
  1140.     ; set magazine state to UNDEFINED
  1141.     #<tc.atc.magazine_state>=0
  1142.  
  1143.     ; evaluate magazine type
  1144.     IF [#<tc.atc.magazine.type> EQ 1] THEN10
  1145.  
  1146.         IF [[#<tc.atc.magazine.input.open> GT 0] AND [#<tc.atc.magazine.input.closed> GT 0]] THEN11
  1147.  
  1148.             M66 P#<tc.atc.magazine.input.open> L#<wait_input.immediate>
  1149.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Error in magazine input recovering states" Q1
  1150.             #<_open_>=#5720
  1151.             M66 P#<tc.atc.magazine.input.closed> L#<wait_input.immediate>
  1152.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Error in magazine input recovering states" Q1
  1153.             #<_closed_>=#5720
  1154.             IF [[#<_open_> EQ 1] AND [#<_closed_> EQ 0]] THEN #<tc.atc.magazine_state>=1
  1155.             IF [[#<_open_> EQ 0] AND [#<_closed_> EQ 1]] THEN #<tc.atc.magazine_state>=2
  1156.  
  1157.         END11
  1158.  
  1159.     END10
  1160.  
  1161. ENDSUB
  1162.  
  1163. ;   TOOL CHANGE MAGAZINE OPEN
  1164. ;
  1165. SUB "TC_MAGAZINE_OPEN"
  1166.  
  1167.     ; get magazine state
  1168.     CALL P"TC_MAGAZINE_UPDATE_STATE"
  1169.  
  1170.     ; evaluate magazine type
  1171.     IF [#<tc.atc.magazine.type> EQ 1] THEN10
  1172.  
  1173.         ; if magazine is already OPEN nothing to do
  1174.         IF [#<tc.atc.magazine_state> EQ 1] THEN11
  1175.             M99
  1176.         END11
  1177.  
  1178.         ; open magazine
  1179.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"Opening Magazine" Q4
  1180.         #<tc.atc.magazine_state>=0
  1181.         M63 P#<tc.atc.magazine.output.close>
  1182.         M62 P#<tc.atc.magazine.output.open>
  1183.         IF [#<tc.atc.magazine.input.open> GT 0] THEN11
  1184.             M66 P#<tc.atc.magazine.input.open> L#<wait_input.high> Q#<tc.atc.magazine.input.timeout>
  1185.             M63 P#<tc.atc.magazine.output.open>
  1186.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Magazine not reached open state<BR>in the specified time" Q1
  1187.         ELSE11
  1188.             G4 P#<tc.atc.magazine.output.time>
  1189.             M63 P#<tc.atc.magazine.output.open>
  1190.         END11
  1191.         IF [#<tc.atc.magazine.input.closed> GT 0] THEN11
  1192.             M66 P#<tc.atc.magazine.input.closed> L#<wait_input.immediate>
  1193.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Error in magazine input recovering states" Q1
  1194.             IF [#5720 EQ 1] THEN M109 P"Magazine in wrong state<BR><BR>Opened/Closed inputs are HIGH" Q1
  1195.         END11
  1196.         #<tc.atc.magazine_state>=1
  1197.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"" Q4
  1198.  
  1199.     END10
  1200.  
  1201. ENDSUB
  1202.  
  1203. ;   TOOL CHANGE MAGAZINE CLOSE
  1204. ;
  1205. SUB "TC_MAGAZINE_CLOSE"
  1206.  
  1207.     ; check if magazine close is bypassed
  1208.     IF [#<tc.do_not_close_magazine> EQ 1] THEN M99
  1209.  
  1210.     ; get magazine state
  1211.     CALL P"TC_MAGAZINE_UPDATE_STATE"
  1212.  
  1213.     ; evaluate magazine type
  1214.     IF [#<tc.atc.magazine.type> EQ 1] THEN10
  1215.  
  1216.         ; if magazine is already CLOSED nothing to do
  1217.         IF [#<tc.atc.magazine_state> EQ 2] THEN11
  1218.             M99
  1219.         END11
  1220.  
  1221.         ; close magazine
  1222.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"Closing Magazine" Q4
  1223.         #<tc.atc.magazine_state>=0
  1224.         M63 P#<tc.atc.magazine.output.open>
  1225.         M62 P#<tc.atc.magazine.output.close>
  1226.         IF [#<tc.atc.magazine.input.closed> GT 0] THEN11
  1227.             M66 P#<tc.atc.magazine.input.closed> L#<wait_input.high> Q#<tc.atc.magazine.input.timeout>
  1228.             M63 P#<tc.atc.magazine.output.close>
  1229.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Magazine not reached closed state<BR>in the specified time" Q1
  1230.         ELSE11
  1231.             G4 P#<tc.atc.magazine.output.time>
  1232.             M63 P#<tc.atc.magazine.output.close>
  1233.         END11
  1234.         IF [#<tc.atc.magazine.input.open> GT 0] THEN11
  1235.             M66 P#<tc.atc.magazine.input.open> L#<wait_input.immediate>
  1236.             IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Error in magazine input recovering states" Q1
  1237.             IF [#5720 EQ 1] THEN M109 P"Magazine in wrong state<BR><BR>Opened/Closed inputs are HIGH" Q1
  1238.         END11
  1239.         #<tc.atc.magazine_state>=2
  1240.         IF [#<tc.enable_hud> EQ 1] THEN M109 P"" Q4
  1241.  
  1242.     END10
  1243.  
  1244. ENDSUB
  1245.  
  1246. ; TOOL CHANGE TOGGLE CONE LOAD/UNLOAD
  1247. ;
  1248. SUB "TC_TOGGLE_CONE_LOAD_UNLOAD"
  1249.  
  1250.     ; turn ON tool unlock output and wait 1s
  1251.     M62 P#<tc.atc.unlock.output>
  1252.     G04 P1.0
  1253.  
  1254.     ; wait cone load/unload input goes low
  1255.     IF [#<tc.atc.cone.load.unload.input> GT 0] THEN11
  1256.         M66 P#<tc.atc.cone.load.unload.input> L#<wait_input.low>
  1257.         IF [#5722 EQ #<wait_input.failure>] THEN M109 P"Unable to get cone load/unload input state" Q1
  1258.     ELSE11
  1259.         G04 P#<tc.atc.cone.load.unload.time>
  1260.     END11
  1261.  
  1262.     ; turn OFF tool unlock output
  1263.     M63 P#<tc.atc.unlock.output>
  1264.  
  1265.     ; check if required cone grip pulse
  1266.     IF [#<tc.atc.cone.grip.output> GT 0] THEN11
  1267.         G04 P#<tc.atc.cone.grip.output.time>
  1268.         M62 P#<tc.atc.cone.grip.output>
  1269.         G04 P#<tc.atc.cone.grip.output.time>
  1270.         M63 P#<tc.atc.cone.grip.output>
  1271.     END11
  1272.  
  1273. ENDSUB
  1274.  
  1275. ; TOOL CHANGE INITIALIZATION
  1276. ;
  1277. SUB "TC_INIT"
  1278.     ; if true enable all hud messages
  1279.     #<tc.enable_hud> = 0
  1280.  
  1281.     ; check if there are compulsory protected parameters undefined
  1282.  
  1283.     ; tool change generic parameters
  1284.     IF [#6000 EQ #0] THEN CALL P"TC_EXIT" E1 A6000
  1285.     IF [#6001 EQ #0] THEN CALL P"TC_EXIT" E1 A6001
  1286.     IF [#6009 EQ #0] THEN CALL P"TC_EXIT" E1 A6009
  1287.     IF [#6016 EQ #0] THEN CALL P"TC_EXIT" E1 A6016
  1288.     ; manual tool change parameters
  1289.     IF [#6002 EQ #0] THEN CALL P"TC_EXIT" E1 A6002
  1290.     IF [#6003 EQ #0] THEN CALL P"TC_EXIT" E1 A6003
  1291.     IF [#6004 EQ #0] THEN CALL P"TC_EXIT" E1 A6004
  1292.     ; tls (tool length presetter) parameters
  1293.     IF [#6005 EQ #0] THEN CALL P"TC_EXIT" E1 A6005
  1294.     IF [#6006 EQ #0] THEN CALL P"TC_EXIT" E1 A6006
  1295.     IF [#6007 EQ #0] THEN CALL P"TC_EXIT" E1 A6007
  1296.     IF [#6008 EQ #0] THEN CALL P"TC_EXIT" E1 A6008
  1297.     IF [#6010 EQ #0] THEN CALL P"TC_EXIT" E1 A6010
  1298.     IF [#6011 EQ #0] THEN CALL P"TC_EXIT" E1 A6011
  1299.     IF [#6012 EQ #0] THEN CALL P"TC_EXIT" E1 A6012
  1300.     IF [#6013 EQ #0] THEN CALL P"TC_EXIT" E1 A6013
  1301.     IF [#6014 EQ #0] THEN CALL P"TC_EXIT" E1 A6014
  1302.     IF [#6015 EQ #0] THEN CALL P"TC_EXIT" E1 A6015
  1303.     IF [#6017 EQ #0] THEN CALL P"TC_EXIT" E1 A6017
  1304.     IF [#6018 EQ #0] THEN CALL P"TC_EXIT" E1 A6018
  1305.     ; atc parameters
  1306.     IF [#6020 EQ #0] THEN CALL P"TC_EXIT" E1 A6020
  1307.     IF [#6021 EQ #0] THEN CALL P"TC_EXIT" E1 A6021
  1308.     IF [#6022 EQ #0] THEN CALL P"TC_EXIT" E1 A6022
  1309.     IF [#6023 EQ #0] THEN CALL P"TC_EXIT" E1 A6023
  1310.     IF [#6024 EQ #0] THEN CALL P"TC_EXIT" E1 A6024
  1311.     IF [#6025 EQ #0] THEN CALL P"TC_EXIT" E1 A6025
  1312.     IF [#6026 EQ #0] THEN CALL P"TC_EXIT" E1 A6026
  1313.     IF [#6036 EQ #0] THEN CALL P"TC_EXIT" E1 A6036
  1314.     IF [#6037 EQ #0] THEN CALL P"TC_EXIT" E1 A6037
  1315.     IF [#6038 EQ #0] THEN CALL P"TC_EXIT" E1 A6038
  1316.     IF [#6039 EQ #0] THEN CALL P"TC_EXIT" E1 A6039
  1317.     IF [#6040 EQ #0] THEN CALL P"TC_EXIT" E1 A6040
  1318.     IF [#6041 EQ #0] THEN CALL P"TC_EXIT" E1 A6041
  1319.     IF [#6042 EQ #0] THEN CALL P"TC_EXIT" E1 A6042
  1320.     IF [#6043 EQ #0] THEN CALL P"TC_EXIT" E1 A6043
  1321.     IF [#6044 EQ #0] THEN CALL P"TC_EXIT" E1 A6044
  1322.     IF [#6045 EQ #0] THEN CALL P"TC_EXIT" E1 A6045
  1323.     IF [#6046 EQ #0] THEN CALL P"TC_EXIT" E1 A6046
  1324.     IF [#6047 EQ #0] THEN CALL P"TC_EXIT" E1 A6047
  1325.     IF [#6048 EQ #0] THEN CALL P"TC_EXIT" E1 A6048
  1326.     IF [#6050 EQ #0] THEN CALL P"TC_EXIT" E1 A6050
  1327.     IF [#6051 EQ #0] THEN CALL P"TC_EXIT" E1 A6051
  1328.     IF [#6052 EQ #0] THEN CALL P"TC_EXIT" E1 A6052
  1329.     IF [#6053 EQ #0] THEN CALL P"TC_EXIT" E1 A6053
  1330.     IF [#6054 EQ #0] THEN CALL P"TC_EXIT" E1 A6054
  1331.     IF [#6055 EQ #0] THEN CALL P"TC_EXIT" E1 A6055
  1332.     IF [#6056 EQ #0] THEN CALL P"TC_EXIT" E1 A6056
  1333.     IF [#6057 EQ #0] THEN CALL P"TC_EXIT" E1 A6057
  1334.     IF [#6058 EQ #0] THEN CALL P"TC_EXIT" E1 A6058
  1335.     IF [#6059 EQ #0] THEN CALL P"TC_EXIT" E1 A6059
  1336.     IF [#6060 EQ #0] THEN CALL P"TC_EXIT" E1 A6060
  1337.  
  1338.     ; define tool change generic parameters
  1339.     #<tc.type>=#6000
  1340.     #<tc.features>=#6001
  1341.     #<tc.feed>=#6009
  1342.     #<tc.enable_tool_length_compensation>=#6016
  1343.  
  1344.     ; define manual tool change parameters
  1345.     #<tc.mtc.change_position.x>=#6002
  1346.     #<tc.mtc.change_position.y>=#6003
  1347.     #<tc.mtc.change_position.z>=#6004
  1348.  
  1349.     ; define tls (tool length presetter) parameters
  1350.     #<tc.tls.safe_position.z>=#6005
  1351.     #<tc.tls.top_center_position.x>=#6006
  1352.     #<tc.tls.top_center_position.y>=#6007
  1353.     #<tc.tls.top_center_position.z>=#6008
  1354.     #<tc.tls.approaching_position.z>=#6010
  1355.     #<tc.tls.approaching_feed>=#6011
  1356.     #<tc.tls.1st_capture_feed>=#6012
  1357.     #<tc.tls.2nd_capture_feed>=#6013
  1358.     #<tc.tls.up_movement_after_1st_touch>=#6014
  1359.     #<tc.tls.minimum_tool_lenght_accepted>=#6015
  1360.     #<tc.tls.probe.cleaning.output>=#6017
  1361.     #<tc.tls.probe.cleaning.output.time>=#6018
  1362.  
  1363.     ; define atc parameters
  1364.     #<tc.atc.magazine.type>=#6020
  1365.     #<tc.atc.magazine.input.open>=#6021
  1366.     #<tc.atc.magazine.input.closed>=#6022
  1367.     #<tc.atc.magazine.input.timeout>=#6023
  1368.     #<tc.atc.magazine.output.time>=#6024
  1369.     #<tc.atc.magazine.output.open>=#6025
  1370.     #<tc.atc.magazine.output.close>=#6026
  1371.  
  1372.     #<tc.atc.safe.z>=#6050
  1373.     #<tc.atc.unlock.input>=#6051
  1374.     #<tc.atc.unlock.output>=#6052
  1375.     #<tc.atc.unlock.timeout>=#6053
  1376.     #<tc.atc.clamp_movement>=#6054
  1377.     #<tc.atc.pick_distance.z>=#6055
  1378.     #<tc.atc.enable_tool_setter>=#6056
  1379.     #<tc.atc.spindle.s1>=#6057
  1380.     #<tc.atc.spindle.s2>=#6058
  1381.     #<tc.atc.slot.axis.orientation>=#6059
  1382.  
  1383.     #<tc.atc.fast.unload.tool.holder.distance>=#6036
  1384.     #<tc.atc.slow.unload.tool.holder.distance>=#6037
  1385.     #<tc.atc.slow.unload.tool.holder.feed>=#6038
  1386.     #<tc.atc.fast.load.tool.holder.distance>=#6039
  1387.     #<tc.atc.medium.load.tool.holder.distance>=#6040
  1388.     #<tc.atc.medium.load.tool.holder.feed>=#6041
  1389.     #<tc.atc.final.load.tool.holder.feed>=#6042
  1390.     #<tc.atc.cone.load.unload.time>=#6043
  1391.     #<tc.atc.cone.load.unload.input>=#6044
  1392.     #<tc.atc.cone.cleaning.blow.output>=#6045
  1393.     #<tc.atc.bearing.cleaning.blow.output>=#6046
  1394.     #<tc.atc.cone.grip.output>=#6047
  1395.     #<tc.atc.cone.grip.output.time>=#6048
  1396.  
  1397.     ; check slots number and get slots positions parameters address
  1398.     #<tc.atc.slots>=#6060
  1399.     IF [#<tc.atc.slots> LT 0] THEN CALL P"TC_EXIT" E8 A6060
  1400.     IF [[#6049 EQ #0] OR [#6049 EQ 0]] THEN10
  1401.         IF [#<tc.atc.slots> GT 13] THEN CALL P"TC_EXIT" E8 A6060
  1402.         #<tc.atc.slot.address>=6061
  1403.     ELSE10
  1404.         #<tc.atc.slot.address>=#6049
  1405.         IF [[#<tc.atc.slot.address> + [#<tc.atc.slots> * 3] GE 7000] THEN CALL P"TC_EXIT" E8 A6049
  1406.     END10
  1407.  
  1408.     ; recover atc slots positions (MCS)
  1409.     #<_i_>=1
  1410.     #<_j_>=#<tc.atc.slot.address>
  1411.     WHILE [#<_i_> LE #<tc.atc.slots>] DO10
  1412.         IF [##<_j_> EQ #0] THEN CALL P"TC_EXIT" E1 A#<_j_>
  1413.         #<tc.atc.slots[#<_i_>].x>=##<_j_>
  1414.         #<_j_>=[#<_j_> + 1]
  1415.         IF [##<_j_> EQ #0] THEN CALL P"TC_EXIT" E1 A#<_j_>
  1416.         #<tc.atc.slots[#<_i_>].y>=##<_j_>
  1417.         #<_j_>=[#<_j_> + 1]
  1418.         IF [##<_j_> EQ #0] THEN CALL P"TC_EXIT" E1 A#<_j_>
  1419.         #<tc.atc.slots[#<_i_>].z>=##<_j_>
  1420.         #<_j_>=[#<_j_> + 1]
  1421.         #<_i_>=[#<_i_> + 1]
  1422.     END10
  1423.  
  1424. ENDSUB