Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    common toolchange macros (run "tpost.g" if "tpost#.g" not found)

    Scheduled Pinned Locked Moved
    Firmware wishlist
    6
    9
    466
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • marvineerundefined
      marvineer
      last edited by marvineer

      Hi together,

      I am in the process of refactoring all the macro files of my E3D ToolChanger - it got quite some conditional gcode happending.

      As for tool changing, each tool has its own tpre#.g, tpost#.g and tfree#.g, despite having almost the same content. To eliminate this redundancy I created a 'global' tpre.g, tpost.g and tfree.g for all tools. Now I call each of those macros with a parameter (param.T).

      With this change I can put together a common logic for all tools and call it in each specific file via 'M98 P"tpre.g" T#'.

      Example of the 'global' tfree.g:

      ; tfree.g
      ; can be called with param.T: tool number to be freed
      
      ; abort if axes are not homed: 0:X 1:Y 2:Z 4:C
      if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed || !move.axes[4].homed
      	M291 T5 P"Please home axes before a toolchange" R"Cannot change tool"
      	abort
      
      ; create vars
      var toolXpos = 0
      var toolYpos = 0
      ; set tool dock position (and check for valid num)
      if param.T == 0
      	set var.toolXpos = -157.7
      	set var.toolYpos = 115.5
      elif param.T == 1
      	set var.toolXpos = -67.5
      	set var.toolYpos = 115.7
      elif param.T == 2
      	set var.toolXpos = 61.3
      	set var.toolYpos = 115.3
      elif param.T == 3
      	set var.toolXpos = 170.0
      	set var.toolYpos = 115.2
      else
      	M291 "var.toolXpos or var.toolYpos was not set" R"error in tfree.g"
      	abort
      
      ; drop the bed
      G91
      G1 H4 Z5 F1200
      G90
      
      ; move to location
      G53 G1 X{var.toolXpos} Y55 F40000
      ; move in
      G53 G1 Y110 F4000
      ; move slowly to final position
      G53 G1 Y{var.toolYpos} F2500
      
       ; open coupler
      M98 P"/macros/Coupler/unlock.g"
      
      ; move out
      G53 G1 Y113 F2000					    
      G53 G1 Y110 F4000
      G53 G1 Y100 F6000
      
      

      Example of tfree1.g:

      ; tfree1.g
      ; called when tool 1 is freed
      M98 P"tfree.g" T1
      
      

      This works well so far, but I would like to get rid of the individual toolchange files.
      Therefore I would like to discuss the following ideas for calling tool change macros in RRF (changes are bold) :

      1. If another tool is already selected, run macro tfree#.g where # is the number of that tool. If tfree#.g is not found, run tfree.g (with parameter T = #) instead.

      2. If another tool is already selected, deselect it and set its heaters to their standby temperatures (as defined by the R parameter in the most recent G10/M568 command for that tool)

      3. Run macro tpre#.g where # is the number of the new tool. If tpre#.g is not found run tpre.g (with parameter T = #) instead.

      4. Set the new tool to its operating temperatures specified by the S parameter in the most recent G10/M568 command for that tool

      5. Run macro tpost#.g where # is the number of the new tool. If tpost#.g is not found run tpost.g (with parameter T = #) instead.

      6. Apply any X, Y, Z offset for the new tool specified by G10

      7. Use the new tool.


      What do you guys think? Is this a good idea or am I proposing a solution where no one has a problem?

      T3P3Tonyundefined chrishammundefined deckingmanundefined 3 Replies Last reply Reply Quote 2
      • T3P3Tonyundefined
        T3P3Tony administrators @marvineer
        last edited by T3P3Tony

        @marvineer thanks for the suggestion. I can see how it would be useful and would work. @dc42 may have a technical issue with this that I am not spotting but if not we would consider it for including in a future firmware version however that is unlikely to be before 3.6 as there are a lot of changes in (or due to be in) 3.5 already.

        www.duet3d.com

        1 Reply Last reply Reply Quote 0
        • chrishammundefined
          chrishamm administrators @marvineer
          last edited by

          @marvineer I like the idea of a fallback to tpre.g/tpost.g/tfree.g, but I am not sure if we actually need the T parameter. There is already state.nextTool for tpre.g, state.currentTool for tpost.g, and state.previousTool for tfree.g.

          It's quite straight-forward to add so I'll have a look. Btw the tool offsets can remain static, better to use G53 G1 for tool pickups and parking.

          Duet software engineer

          marvineerundefined 1 Reply Last reply Reply Quote 1
          • marvineerundefined
            marvineer @chrishamm
            last edited by

            @chrishamm I tried it with your suggestions, without the parameter it is even easier and more flexible.

            The best part: It's already on the way to being implemented 😄
            d583b48b-608e-4c87-9286-6ea1dc57ee82-image.png

            Thanks a lot!

            lparnell34undefined Exerqtorundefined 2 Replies Last reply Reply Quote 0
            • lparnell34undefined
              lparnell34 @marvineer
              last edited by

              @marvineer could you share your new global files for tool change?

              marvineerundefined 1 Reply Last reply Reply Quote 0
              • deckingmanundefined
                deckingman @marvineer
                last edited by

                @marvineer Getting rid of the individual tool change files when one has created "universal" files seems like a good idea. I did something similar to you but called my "universal" files "ToolFree.g" , "ToolPost.g" and "ToolPre.g". Then every individual tool change file just a has a simple M98 to call the appropriate "Toolxxx.g" file. It wasn't too bad too do. I simply created the first file than did repeat "save as" to create the rest but it's a bit of a pain having all those unnecessary file which do the same thing.

                Ian
                https://somei3deas.wordpress.com/
                https://www.youtube.com/@deckingman

                1 Reply Last reply Reply Quote 1
                • marvineerundefined
                  marvineer @lparnell34
                  last edited by

                  @lparnell34 shure, there you have it. Let me know if you have any questions.
                  It's not super well structured, but it'll do for now ...
                  I would recommend defining the dock positions globally so they are the same everywhere.

                  tpre.g:

                  ; tpre.g
                  ; called before a tool is selected
                  ; use state.nextTool to determine witch tool is selected
                  
                  ; abort if axes are not homed: 0:X 1:Y 2:Z 4:C
                  if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed || !move.axes[4].homed
                  	M291 T5 P"Please home axes before a toolchange" R"Cannot change tool"
                  	T-1 P0
                  	abort
                  
                  ; check if toolDetectSwitch is active, if so:abort
                  if sensors.gpIn[5] == null || sensors.gpIn[5].value == 1
                  	M291 T5 P"toolDetectSwitch is active, but should not" R"Cannot change tool"
                  	T-1 P0
                  	abort
                  
                  
                  if move.extruders[0].filament == "" && state.status == "processing"
                      M117 "No filament in extruder 0!"
                  
                  ; create vars
                  var dockXpos = 0
                  var dockYpos = 0
                  ; set tool dock position
                  if state.nextTool == 0
                  	set var.dockXpos = -157.7
                  	set var.dockYpos = 115.5
                  elif state.nextTool == 1
                  	set var.dockXpos = -67.5
                  	set var.dockYpos = 115.7
                  elif state.nextTool == 2
                  	set var.dockXpos = 61.3
                  	set var.dockYpos = 115.3
                  elif state.nextTool == 3
                  	set var.dockXpos = 170.0
                  	set var.dockYpos = 115.2
                  else
                  	M291 P"var.toolXpos or var.toolYpos was not set (unknown toolNum)" R"Cannot change tool"
                  	abort	
                  
                  G91
                  G1 H4 Z5 F1200					    	; drop the bed
                  G90
                  
                  set global.ZisLifted = false
                  
                  M98 P"/macros/Coupler/unlock.g"	                ; unlock Coupler
                  
                  M564 S0                                         ; allow movement outside the normal limits
                  
                  ; move to location
                  G1 X{var.dockXpos} Y100 F40000
                  ; move in faster
                  G1 Y110 F4000
                  ; move in slowly to final position
                  G1 Y{var.dockYpos} F2500
                  
                  M98 P"/macros/Coupler/lock.g"	                    ; close Coupler
                  
                  ;wait for all movement to stop
                  M400
                  
                  ; check if toolDetectSwitch is deactive, if so:abort
                  if sensors.gpIn[5] == null || sensors.gpIn[5].value == 0
                  	M291 T5 P"toolDetectSwitch is not active, but should" R"Cannot change tool"
                  	T-1 P0
                  	abort
                  
                  ; set speed and axes limits for this new tool
                  if state.nextTool == 0 || state.nextTool == 1
                  	M98 P"/macros/Speeds/set_speed.g" L"lightTool"  ; set speeds, jerk and accel. for light weight bowden tool
                  	M98 P"/macros/Boundaries/V6-and-Volcano.g"      ; set new limits for this tool
                  elif state.nextTool == 2
                  	M98 P"/macros/Speeds/set_speed.g" L"heavyTool" ; set speeds, jerk and accel. for heavy direct tool
                  	M98 P"/macros/Boundaries/Hemera-Direct.g"      ; set new limits for this tool
                  elif state.nextTool == 3
                  	M98 P"/macros/Speeds/set_speed.g" L"spindleTool" ; set speeds, jerk and accel. for very heavy spindle
                  	M98 P"/macros/Boundaries/Mill.g"      ; set new limits for this tool
                  else
                  	M291 P"speed and limits where not set (unknown toolNum)" R"Cannot change tool"
                  	abort
                  
                  ;WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
                  ;if you are using non-standard length hotends ensure the bed is lowered enough BEFORE undocking the tool!
                  G91
                  G1 H4 Z{-tools[state.nextTool].offsets[2]} F1200
                  G90
                  
                  G1 Y113 F2000					                ; move out a bit
                  
                  ; check if toolDetectSwitch is deactive, if so:abort
                  if sensors.gpIn[5] == null || sensors.gpIn[5].value == 0
                  	M291 T5 P"toolDetectSwitch is not active, but should be" R"Cannot change tool"
                  	T-1 P0
                  	abort
                  
                  G1 Y110 F4000					                ; move out a bit
                  
                  G1 Y55 F4000					                ; move out
                  
                  ; apply new min limit for z axis so we cannot crash into bed
                  M208 S1 Z{-tools[state.nextTool].offsets[2]}
                  
                  ; apply the normal limits again
                  M564 S1
                  

                  tpost.g:

                  ; tpost.g
                  ; called after a tool has been selected
                  ; use state.currentTool to determine witch tool was selected
                  
                  ; set filament parameters
                  ; this sets temps and other related settings for specific loaded filament
                  M703
                  ; wait for heat up on active tool only
                  M116 P{state.currentTool}
                  
                  ; unretract
                  G11
                  
                  ;prime nozzle
                  M98 P"/macros/Brush/setHeightToActiveTool.g"
                  
                  if state.status = "processing"
                  	M98 P"/macros/Brush/wipe_activeTool.g" S"ZisLifted"
                  
                  M106 R1	; restore print cooling fan speed
                  
                  

                  tfree.g:

                  ; tfree.g
                  ; called when a tool is freed
                  ; use state.previousTool to determine witch tool was freed
                  
                  ; abort if axes are not homed: 0:X 1:Y 2:Z 4:C
                  if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed || !move.axes[4].homed
                  	M291 T5 P"Please home axes before a toolchange" R"Cannot change tool"
                  	abort
                  
                  ; check if toolDetectSwitch is not active, if so:abort
                  if sensors.gpIn[5] == null || sensors.gpIn[5].value == 0
                  	M291 T5 P"toolDetectSwitch is not active, but should" R"Cannot change tool"
                  	abort
                  
                  ; create vars
                  var dockXpos = 0
                  var dockYpos = 0
                  ; set tool dock position
                  if state.previousTool == 0
                  	set var.dockXpos = -157.7
                  	set var.dockYpos = 115.5
                  elif state.previousTool == 1
                  	set var.dockXpos = -67.5
                  	set var.dockYpos = 115.7
                  elif state.previousTool == 2
                  	set var.dockXpos = 61.3
                  	set var.dockYpos = 115.3
                  elif state.previousTool == 3
                  	set var.dockXpos = 170.0
                  	set var.dockYpos = 115.2
                  else
                  	M291 "var.toolXpos or var.toolYpos was not set (unknown toolNum)" R"Cannot change tool"
                  	abort
                  	
                  ; free out of heat wait loop
                  M108
                  
                  G91
                  G1 H4 Z5 F1200					    	; drop the bed
                  G90
                  
                  M564 S0							    	; allow movement outside the normal limits
                  
                  G53 G1 X{var.dockXpos} Y55 F40000		; move to location
                  G53 G1 Y110 F4000					    ; move in
                  G53 G1 Y{var.dockYpos} F2500            ; move in slow
                  
                  M98 P"/macros/Coupler/unlock.g"		    ; open coupler
                  
                  M106 P2 S0							    ; fan off
                  
                  G53 G1 Y113 F2000					    ; move out a bit
                  
                  ;wait for all movements to stop and sync movement queues
                  M400
                  
                  ; check if toolDetectSwitch is active, if so:abort
                  if {sensors.gpIn[5] == null || sensors.gpIn[5].value == 1}
                  	M291 T5 P"toolDetectSwitch is active, but should not" R"Cannot change tool"
                  	T-1 P0
                  	abort
                  
                  G53 G1 Y110 F4000					    ; move out a bit
                  
                  G53 G1 Y100 F4000					    ; move Out
                  
                  ; set speeds, jerk and accel. for no active tool
                  M98 P"/macros/Speeds/set_speed.g"
                  
                  ; reset X and Y limits
                  M98 P"/macros/Boundaries/ToolHead.g"
                  ; reset Z min limit
                  M208 S1 Z0
                  
                  M564 S1								    ; apply the normal limits again
                  
                  
                  1 Reply Last reply Reply Quote 0
                  • Exerqtorundefined Exerqtor referenced this topic
                  • Exerqtorundefined
                    Exerqtor @marvineer
                    last edited by Exerqtor

                    @marvineer said in common toolchange macros (run "tpost.g" if "tpost#.g" not found):

                    @chrishamm I tried it with your suggestions, without the parameter it is even easier and more flexible.

                    The best part: It's already on the way to being implemented 😄
                    d583b48b-608e-4c87-9286-6ea1dc57ee82-image.png

                    Thanks a lot!

                    Not to go off on a tangent here, but I've skimmed through the last two months worth of commits on the 3.5dev branch without seeing that mentioned anywere, where did you find it? 🤔

                    marvineerundefined 1 Reply Last reply Reply Quote 0
                    • marvineerundefined
                      marvineer @Exerqtor
                      last edited by marvineer

                      @Exerqtor have a look at this:
                      Added support for tool macro fallbacks (commit)

                      It is already included in the latest version (3.5.0-beta.4).

                      1 Reply Last reply Reply Quote 1
                      • First post
                        Last post
                      Unless otherwise noted, all forum content is licensed under CC-BY-SA