O SUB ( see: http://www.linuxcnc.org/index.php/english/forum/10-advanced-configuration/5596-manual-tool-change--tool-lengh-touch-off?start=30#48235 ) ( Filename: tool-change.ngc ) ( LinuxCNC Manual Tool-Change Subroutines for Milling Machines version 1.1: subroutine 1/2 ) ( BEFORE USING CHANGE "CONFIGURATION PARAMETERS" BELOW FOR YOUR MACHINE! ) ( ) ( In the LinuxCNC .ini config file, under the [RS274NGC] section add: ) ( # change/add/use SUBROUTINE_PATH to point to the location where these tool-change subroutines are located: ) ( SUBROUTINE_PATH = macros ) ( REMAP=M6 modalgroup=6 ngc=tool-change ) ( REMAP=M600 modalgroup=6 ngc=tool-job-begin ) ( and under the [EMCIO] section add: ) ( TOOL_CHANGE_AT_G30 = 0 ) ( and ensure neither TOOL_CHANGE_POSITION nor TOOL_CHANGE_QUILL_UP is set. ) ( ) ( In the LinuxCNC .hal config file, map some input pin to be the probe input, e.g.: ) ( net probe-z parport.0.pin-12-in => motion.probe-input ) ( For multiple probe inputs, the following can be used, in this case a MESA 7i96 is controlling a NO probe, and a NC Toolsetter ) ( net probe-in <= hm2_7i96.0.gpio.005.in ) ( net length-in <= hm2_7i96.0.gpio.009.in_not ) ( net probe-in => or2.0.in0 ) ( net length-in => or2.0.in1 ) ( net probe-or-length <= or2.0.out => motion.probe-input ) ( The following tool change pins are required as well; ) ( loadusr -W hal_manualtoolchange ) ( net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change ) ( net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed ) ( net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number ) ( net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared ) ( In your Linuxcnc.var file, ensure you have the following variables #5061, #5062, #5063 ) ( They can be manually added and assigned a 0.000 to start ) ( In addition I have had to modify the post-processor for the following; ) ( Eliminate G43 call outs after tool changes ) ( Use G53 instead of G28, typically just a check box when post processing ) ( Set machine home for Z in F360 machine setup to be -.250, my machine Zero is at top of travel ) ( Usage: M6 in the g-code will invoke a manual tool change with automatic tool height adjustment. ) ( M600 is used at the beginning of the first g-code file of a job so that the next M6 will measure the tool for reference ) ( instead of caluculating a tool length offset. It can also be invoked manually through the MDI before a job starts. ) ( My sequence of Running; ) ( 1. Use a T99, a .250" Rod, to touch off X, Y, and Z of WCS as modeled in CAM ) ( 2. Manually input M600 ) ( 3. Manually call an M6 T99, tool will touch off on toolsetter and store tool height ) ( 4. Load program and run, M6 in program will prompt tool change, after changing, tool will touch off and Z will adjust ) ( 5. Run any and all code using the same desired Z height for the WCS as designed ) ( 6. For new WCS repeat from Step #1 ) ( ) ( General theory of operation: touches each tool off to the tool height sensor. The first tool is used as the reference, all ) ( subsequent tools adjust the tool offset. ) ( It is moved away by raising Z to _TravelZ before moving towards the switch, and when ) ( moving back from the switch again moves at height _TravelZ before going straight back down to the original position. Set ) ( all necessary modes to ensure correct operation no matter what state the program is in when this is called. We eliminate ) ( almost all side effects by saving and restoring the modal state. ) ( ) ( Side effects: sets G30, sets motion mode to G1. ) (------------------------------- CONFIGURATION PARAMETERS ----------------------------------------------) #<_UseInches> = 1.0 ( set to 1 to use inches here, or 0 to use millimeters; should match units on tool.tbl dimensions ) #<_TravelZ> = -.005 ( machine Z coordinate for travelling, typically near max Z to avoid ever hitting the work ) #<_TravelFeed> = 50.0 ( feedrate used for general Z moves when avoiding G0 ) #<_ProbeX> = 1.1 ( machine X coordinate of switch/touch-off plate ) #<_ProbeY> = 0 ( machine Y coordinate of switch/touch-off plate ) #<_ProbeFastZ> = -.005 ( machine Z coord to move to before starting probe, longest tool should not touch switch at this Z ) #<_ProbeMinZ> = -4.75 ( machine Z coord to stop probe, shortest tool must touch switch at this Z, must be > min Z ) #<_ProbeRetract> = 0.125 ( small distance to retract before approaching switch/touch-off plate second time ) #<_ProbeFastFeed> = 50.0 ( feed rate for moving to _ProbeFastZ ) #<_ProbeFeed1> = 20.0 ( feed rate for touching switch/touch-off plate first time ) #<_ProbeFeed2> = 4.0 ( feed rate for touching switch/touch-off plate second time ) #<_ToolChangeX> = 1.1 ( machine X coordinate to pause at for manual tool changing ) #<_ToolChangeY> = 0 ( machine Y coordinate to pause at for manual tool changing ) #<_MistOnDuringProbe> = 0 ( set to 1 for mist, or 2 for coolant, or 0 for nothing during probing, to clear switch of swarf ) (-------------------------------------------------------------------------------------------------------) O100 IF [ EXISTS[#<_ToolDidFirst>] EQ 0 ] #<_ToolDidFirst> = 0 #<_ToolZRef> = 0 ( Following were added to clear the memory as residual parameters ) #<_ToolZ> = 0 ( created incorrect settings ) # = 0 O100 ENDIF O105 IF [ #<_ToolDidFirst> EQ 0 ] G49 ( clear tool length compensation prior to saving state if this is first time ) #<_ToolZRef> = 0 ( Ensures values are cleared if M600 is not called ) #<_ToolZ> = 0 # = 0 O105 ENDIF G53 G1 F[#<_TravelFeed>] Z[#<_TravelZ>] G53 G1 F[#<_TravelFeed>] X[#<_ToolChangeX>] Y[#<_ToolChangeY>] ( Moves to desired potion for manual tool change ) M6 ( do the normal M6 stuff ) M70 ( save current modal state ) M9 ( turn off coolant, will be restored on return if it was on ) M5 ( turn off spindle, cannot be on during the probe ) G[21 - #<_UseInches>] ( use inches or millimeters as required here, units will be restored on return ) G30.1 ( save current position in #5181-#5183... ) G49 ( clear tool length compensation ) G90 ( use absolute positioning here ) G94 ( use feedrate in units/min ) G40 ( turn cutter radius compensation off here ) O200 IF [ #<_ToolDidFirst> EQ 0 ] G53 G1 F[#<_TravelFeed>] Z[#<_TravelZ>] ( go to high travel level on Z ) G53 G0 X[#<_ProbeX>] Y[#<_ProbeY>] ( to probe switch ) G53 G1 F[#<_ProbeFastFeed>] Z[#<_ProbeFastZ>]( move tool closer to switch -- we shouldn't hit it ) G54 G1 F[#<_ProbeFeed1>] G91 ( use relative positioning ) O101 IF [ #<_MistOnDuringProbe> EQ 1 OR #<_MistOnDuringProbe> EQ 2 ] M[7 + #<_MistOnDuringProbe> - 1] ( turn on mist/coolant ) O101 ENDIF G38.2 Z[#<_ProbeMinZ> - #<_ProbeFastZ>] F[#<_ProbeFeed1>] ( trip switch slowly ) G0 Z[#<_ProbeRetract>] ( go up slightly ) G38.2 Z[#<_ProbeRetract>*-1.25] F[#<_ProbeFeed2>] ( trip switch very slowly ) M9 ( turn off mist ) G90 ( use absolute positioning ) #<_ToolZRef> = #5063 ( save trip point ) #<_ToolZLast> = #<_ToolZRef> ( save last tool Z position ) G53 G1 F[#<_TravelFeed>] Z[#<_TravelZ>] ( return to safe level ) G53 G0 X[#5181] Y[#5182] ( return to where we were in X Y) G53 G1 F[#<_TravelFeed>] Z[#5183] ( return to where we were in Z ) M72 ( restore modal state ) #<_ToolDidFirst> = 1 ( we have been in this section to set reference value already ) O200 ELSE G53 G1 F[#<_TravelFeed>] Z[#<_TravelZ>] ( go to high travel level on Z ) O107 IF [#<_UseInches> EQ 1 ] # = #5410 # = [ # * 25.4 ] O107 ELSE # = #5410 # = [ # / 25.4 ] O107 ENDIF O102 IF [ #<_current_tool> EQ 0 AND # EQ 0 ] (MSG, Change tool then click Resume ) O102 ELSE # = [ # * 25.4 ] O102 ENDIF (M0) ( pause execution ) G53 G0 X[#<_ProbeX>] Y[#<_ProbeY>] ( to high place directly over switch ) G53 G1 F[#<_ProbeFastFeed>] Z[#<_ProbeFastZ>]( move tool closer to switch -- we shouldn't hit it ) G54 G1 F[#<_ProbeFeed1>] G91 ( use relative positioning ) O103 IF [ #<_MistOnDuringProbe> EQ 1 OR #<_MistOnDuringProbe> EQ 2 ] M[7 + #<_MistOnDuringProbe> - 1] ( turn on mist/coolant ) O103 ENDIF G38.2 Z[#<_ProbeMinZ> - #<_ProbeFastZ>] F[#<_ProbeFeed1>] ( trip switch slowly ) G0 Z[#<_ProbeRetract>] ( go up slightly ) G38.2 Z[#<_ProbeRetract>*-1.25] F[#<_ProbeFeed2>] ( trip switch very slowly ) M9 ( turn off mist ) G90 ( use absolute positioning ) #<_ToolZ> = #5063 ( save new tool length ) G43.1 Z[#<_ToolZ> - #<_ToolZRef>] ( set new tool length Z offset, we do this now to show operator even though it has to be set again after M72 ) G53 G1 F[#<_TravelFeed>] Z[#<_TravelZ>] ( return to high travel level ) G53 G0 X[#5181] Y[#5182] ( return to where we were in X Y) #<_ToolZLast> = #<_ToolZ> ( save last tool length ) M72 ( restore modal state ) G43.1 Z[#<_ToolZ> - #<_ToolZRef>] ( Apply offset to Z height after Modal reset ) O200 ENDIF O ENDSUB M2