Tool change macro



  • I would like a tool change script/macro that moves the tool to a known location, heats up the tool from idle, extrudes material, then moves across a wiper and continues printing.

    Should I make a script in my slicer (S3D) or can I write a macro that executes that code whenever the tool change is commanded from the slicer?


  • administrators



  • sorry to threadjack, but I don't want to start another thread if we are on the same topic. I am currently configuring a tool change function that uses 2 tool (and to be expanded to more in the future). I am confused on how to set tool offset for each extruder and then how to call them during print.

    After reading DC42's links, I have come to the conclusion that the G10 Pn Xn Yn Zn Rn Sn line is to be entered in the config.g file. I assume this tells the machine the offset for each tool based on the nozzle position. This will also define it's temperature when standby and active?

    https://duet3d.dozuki.com/Wiki/Multiple_tools_and_Tool_change_macros#Section_TODO
    "T1 P0 ; Select tool 1 to turn it on but don't execute tool change scripts

    T0 ; Select tool 0"

    Let's assume that the x carriage is currently unequipped (nothing attached) and all the tools are docked. if T0 selects tool 0, does that mean the machine just "equips" it in software but physically does nothing and at this point, and it will run the G10 command above to set the tooloffset and standby temperature? does it mean I would need to enter an additional command (a macro) for it to go physically pick up Tool 0?

    in the link above, "T-1 PO ; deselect all tools but don't run any tool change macro files":
    what exactly does the machine do with this code? I assume this is used when the xcarriage has no tool attached?

    I am also not sure what to put in the Tfree#, Tpre#, Tpost# files.

    please forgive me as I am very new at all this. Thank you.



  • Forget Tx P0 for the moment. Only think about T0 or T1 or T-1, for a few minutes.

    G10 does go in config.g. It can, with various arguments, set offsets, set temperatures or both.

    Later, when the machine encounter a T0, it will mount that tool (more about this in a second) and begin to use the offsets for Tool 0 that were specified in the G10. You don't have to do anything to make this happen.

    When a different tool is mounted, the offsets for that tool are automatically invoked. And, when T-1 is mounted (which is no tool) all offsets are removed.

    Now... back to how a tool is mounted. Your tpre0.g tfree0.g and tpost.g files contain the actual gcode to go get the tool, or put it away

    For example, if the machine has no tool currently mounted and it encounters a T0, it will invoke /sys/tpre0.g. Depending on the machine, this may do nothing at all. It will then invoke /sys/tpost0.g This file will contain G1 moves that place the carriage where it needs to be to pick up to tool, activate any locks, etc. etc.

    There's more to it than that... but stop and think about that for a few minutes.

    Here are my tpre/free/post files for a Tool Changing Jubilee printer:

    tfree1.g

    tpre1.g

    tpost1.g



  • Thanks Danal,

    Got it. I was looking at the "T: select tool" section (https://duet3d.dozuki.com/Wiki/Gcode#Section_T_Select_Tool) on the Gcode duet page and it did mention that upon a T# command, it will go down the list in order if things based on the condition. But how would it know if there is a tool mounted or not perhaps from a previous print or last time the machine was powered off? maybe using duex5 endstop as input (i have the duet2wifi + duex5)?

    May I ask when your printer has just turned on, by default, is the x carriage freed of all tools?

    I am thinking of doing something this:
    turn on printer. if T0 is not selected , then drop bed and select T0. This will then invoke Tpre0.g which will set the temperature (is this where I put my G10 command?). proceed with tpost0.g to pick up the tool. proceed with homing on all axis (my Z piezo probe is attached to the x carriage and uses the nozzle of the tool as Z=0.). after homing, run codes from the print file and until the first T# command and repeat the steps at the link above?

    I take it Tpost is a pick up tool code which will include the nozzle wipe and extrude? Tpre is to do all the preheating and apply tool offset, Tfree is only invoked when another tool is mounted?



  • @tekstyle said in Tool change macro:

    May I ask when your printer has just turned on, by default, is the x carriage freed of all tools?

    Yes, and this works on my printer because my Z probe is on the carriage, not on any particular tool.

    I am thinking of doing something this:
    turn on printer. if T0 is not selected , then drop bed and select T0. This will then invoke Tpre0.g which will set the temperature (is this where I put my G10 command?).

    You don't have to invoke G10. Put it in config.g and the firmware will activate/deactivate each different G10 statement as tools become mounted or dismounted.

    tpre is not a good place to set temperatures because the "to be mounted" tool is not considered active yet. You'd be setting temperatures for either the old tool, or system defaults.

    Quite often, tpre does nothing. I have it move the carriage "near" the "to be picked up" tool so that if the printer does wait (see below) for the tool to heat, a human looking at the printer can see the tool on which it is waiting.

    proceed with tpost0.g to pick up the tool.

    To be clear, the firmware "proceeds" to the next macro; you don't code anything.

    proceed with homing on all axis (my Z piezo probe is attached to the x carriage and uses the nozzle of the tool as Z=0.).

    Sort of. You don't want a G28 in tpre or tpost because it would happen at EVERY tool swap. You want a T0 G28 somewhere in your startup. Literally those two commands, on the same line if you wish.

    after homing, run codes from the print file and until the first T# command and repeat the steps at the link above?

    You don't do anything. Just run jobs. If they contain T0 and/or T1 and/or Tn commands, all the macros will happen as the firmware invokes them.

    I take it Tpost is a pick up tool code which will include the nozzle wipe and extrude?

    Tpre is to do all the preheating and apply tool offset

    As mentioned above, these need to be in Tpost so the the tool is "active" from the firmware's point of view. Also, you don't apply offsets, the firmware does.

    Tfree is only invoked when another tool is mounted?

    Correct. It will contain the G-Code to "park" a tool. Take a look at my tfree, and you will see it moves to a parking position (via several moves, so that it will never collide with another parked tool) and unlocks the tool. Also, my tfree0 and tfree1 are identical, except for the coordinates of the parking stall for each tool.



  • Implied in some of your questions above is the "How does the firmware 'know' what tool is mounted at power up (or after a reset)?".

    The fundamental answer is: It does not and/or cannot.

    (OK, a very few printers have a way to sense a tool and sometimes even which tool is mounted... this really requires conditional gcode for full advantage or similar, and that's why this is pretty uncommon, so far).

    Therefore... The human operator MUST do whatever actions are required to put the printer in a known state. And then continue startup procedures.

    "Known state" can mean anything you want... it generally means "no tools mounted, every tool in its proper parking stall" simply because most toolchanging printers have no way for the human to lock a tool. But, again, it could mean "Tool 0 mounted" or whatever you want (that the human can do).

    For these same reasons, it is very typical for toolchanging printers to home X and Y (and the tool lock axis, if there is that kind of lock), then pick up a tool or probe or etc, and use that to home Z.

    So power up for a toolchanging printer may involve:

    1. Manually remove any mounted tool and return it to its parking stall.
    2. Power up.
    3. Once printer is cleanly up, press the "Home" button... or press the "PowerUpPrep" macro button, or similar.


  • Also note that while you do NOT want a G28 (home) in a tpre/post/free file (because it would happen every time), it is perfectly OK to have T0 (or whichever) in the "homeall.g" file. If T0 is already mounted when the printer sees a T0 command, nothing happens.

    So the very first time the printer was homed after power up, it would mount T0. If it were homed again (and T0 is still mounted) the rest of the homing just proceeds.



  • Thank you again. good to know Tpre isn't really useful because I was pulling my hair trying to figure out what goes in it. I assume it is best used to start preheat before the current tool finishes doing whatever it is doing and before Tfree#.g is invoked.

    Here is my config.g:
    it isn't complete as I still have to setup the extruder, thermistor, etc. I have turned off the T0 command in config as I will need the firmware to home XY before it can select tool 0 to home Z.

    ; Configuration file for Duet WiFi (firmware version 3)
    ; executed by the firmware on start-up
    ;
    ; generated by RepRapFirmware Configuration Tool v2.1.8 on Mon Feb 24 2020 22:39:52 GMT-0800 (Pacific Standard Time)

    ; General preferences
    G90 ; send absolute coordinates...
    M83 ; ...but relative extruder moves
    M550 P"coreXY" ; set printer name

    M667 S1 ; select CoreXY mode

    ; Network
    M552 S1 ; enable network
    M586 P0 S1 ; enable HTTP
    M586 P1 S0 ; disable FTP
    M586 P2 S0 ; disable Telnet

    ; Drives
    M569 P0 S0 ; physical drive 0 goes backwards
    M569 P1 S0 ; physical drive 1 goes backwards
    M569 P2 S0 ; physical drive 2 goes forwards
    M569 P3 S1 ; physical drive 3 goes forwards
    M569 P4 S1 ; physical drive 4 goes forwards
    M584 X0 Y1 Z2 E3:4 ; set drive mapping
    M350 X16 Y16 Z16 E16:16 I1 ; configure microstepping with interpolation
    M92 X100.00 Y100.00 Z1600.00 E420.00:420.00 ; set steps per mm
    M566 X900.00 Y900.00 Z12.00 E120.00:120.00 ; set maximum instantaneous speed changes (mm/min)
    M203 X6000.00 Y6000.00 Z180.00 E1200.00:1200.00 ; set maximum speeds (mm/min)
    M201 X500.00 Y500.00 Z20.00 E250.00:250.00 ; set accelerations (mm/s^2)
    M906 X1700 Y1700 Z1700 E595:595 I30 ; set motor currents (mA) and motor idle factor in per cent
    M84 S30 ; Set idle timeout

    ; Axis Limits
    M208 X0 Y0 Z0 S1 ; set axis minima
    M208 X416 Y398 Z365 S0 ; set axis maxima

    ; Endstops
    M574 X1 S1 P"xstop" ; configure active-high endstop for low end on X via pin xstop
    M574 Y1 S1 P"ystop" ; configure active-high endstop for low end on Y via pin ystop
    M574 Z1 S2 ; configure Z-probe endstop for low end on Z

    ; Z-Probe
    M558 P5 I1 R0.4 C"zprobe.in+zprobe.mod" H5 F1200 T6000 ; set Z probe type to effector and the dive height + speeds
    G31 P500 X0 Y0 Z0 ; set Z probe trigger value, offset and trigger height
    M557 X46:416 Y0:340 S70 ; define mesh grid

    ; Heaters
    M308 S0 P"bedtemp" Y"thermistor" T100000 B4138 ; configure sensor 0 as thermistor on pin bedtemp
    M950 H0 C"bedheat" T0 ; create bed heater output on bedheat and map it to sensor 0
    M143 H0 S120 ; set temperature limit for heater 0 to 120C
    M307 H0 B0 S1.00 ; disable bang-bang mode for the bed heater and set PWM limit
    M140 H0 ; map heated bed to heater 0
    M308 S1 P"e0temp" Y"thermistor" T100000 B4138 ; configure sensor 1 as thermistor on pin e0temp
    M950 H1 C"e0heat" T1 ; create nozzle heater output on e0heat and map it to sensor 1
    M143 H1 S280 ; set temperature limit for heater 1 to 280C
    M307 H1 B0 S1.00 ; disable bang-bang mode for heater and set PWM limit
    M308 S2 P"e1temp" Y"thermistor" T100000 B4138 ; configure sensor 2 as thermistor on pin e1temp
    M950 H2 C"e1heat" T2 ; create nozzle heater output on e1heat and map it to sensor 2
    M143 H2 S280 ; set temperature limit for heater 2 to 280C
    M307 H2 B0 S1.00 ; disable bang-bang mode for heater and set PWM limit

    ; Fans
    M950 F0 C"fan0" Q500 ; create fan 0 on pin fan0 and set its frequency
    M106 P0 S1 H1 T45 ; set fan 0 value. Thermostatic control is turned on
    M950 F1 C"fan1" Q500 ; create fan 1 on pin fan1 and set its frequency
    M106 P1 S1 H2 T45 ; set fan 1 value. Thermostatic control is turned on

    ; Tools
    M563 P0 D0 H1 F0 ; define tool 0
    G10 P0 X0 Y0 Z0 ; set tool 0 axis offsets
    G10 P0 R0 S0 ; set initial tool 0 active and standby temperatures to 0C
    M563 P1 D1 H2 F0 ; define tool 1
    G10 P1 X0 Y0 Z0 ; set tool 1 axis offsets
    G10 P1 R0 S0 ; set initial tool 1 active and standby temperatures to 0C
    M563 P2 F0 ; define tool 2
    G10 P2 X0 Y0 Z0 ; set tool 2 axis offsets
    G10 P2 R0 S0 ; set initial tool 2 active and standby temperatures to 0C
    M563 P3 F0 ; define tool 3
    G10 P3 X0 Y0 Z0 ; set tool 3 axis offsets
    G10 P3 R0 S0 ; set initial tool 3 active and standby temperatures to 0C
    M563 P4 F0 ; define tool 4
    G10 P4 X0 Y0 Z0 ; set tool 4 axis offsets
    G10 P4 R0 S0 ; set initial tool 4 active and standby temperatures to 0C

    ; Custom settings are not defined

    ; Miscellaneous
    M501 ; load saved parameters from non-volatile memory
    ;T0 ; select first tool

    (made some changes based on your Tpost and pre files)
    home all.g
    ; Home XY prior to selecting the first tool and then home Z using tool 0

    ;X homing
    G91 ; relative positioning
    G53 G1 H2 Z25 F6000 ; lift Z relative to current position to avoid collision with bed clamps
    G53 G1 H1 Y-62 ; move -62mm in Y to avoid collision in X movement
    G53 G1 H1 X-436.8 F3600 ; move quickly to X axis endstop and stop there (first pass)
    G53 G1 X5 F6000 ; go back a few mm
    G53 G1 H1 X-436.8 F360 ; move slowly to X axis endstop once more (second pass)

    ;Y homing
    G53 G1 H1 Y-408.225 F3600 ; move quickly to Y axis endstop and stop there (first pass)
    G53 G1 Y5 F6000 ; go back a few mm
    G53 G1 H1 Y-408.225 F360 ; move slowly to Y axis endstop once more (second pass)

    ;pick up T0
    G91 ; relative positioning
    G53 G1 z3 ; lift Z a few mm to avoid collision during travel
    G90 ;absolute positioning
    G53 G1 x413 Y336 F6000 ;move into position in front of T0 dock
    G91 ;relative positioning
    G53 g1 z-3 ; drop Z few mm
    G53 G1 x0 y62 F1800 ;move in Y towards T0 dock
    G53 G1 x-8 y0 ;move in X towards T0 dock
    G53 G1 x2 y-62 ; move in X/Y away from T0 dock. now tool 0 is selected and out of the way of other parked tools.
    G90 ; absolute positioning

    ;M98 P"/sys/Tpost0"

    ;Z homing
    G91 ; relative positioning
    G53 G1 H2 Z5 F6000 ; lift Z relative to current position
    G90 ; absolute positioning
    G53 G1 X230 Y148 F6000 ; go to first probe point
    G30 ; home Z by probing the bed

    ; Uncomment the following lines to lift Z after probing
    G91 ; relative positioning
    G53 G1 Z5 F100 ; lift Z relative to current position
    G90 ; absolute positioning


    1. since G10 Rnnn Snnn are in config.g, if I need to changes these values, can I do it in the slicer?

    2. throughout a print, some of the parked extruders will not be used for some time depending on what is being printed. putting G10 Rnnn Snnn in config would mean it will heat to R upon power up correct? can G10 command or Tpre#.g command be invoked later in the print process but maybe a few minutes before the print actually needs to do a Tpost#.g to select it? I don't want all my tools to be at standby temperature for the entire duration of the print if they aren't needed.

    3. i turned off the M98 command in the homeall.g file because I can't get the firmware to call the macro. maybe I got the root directory path wrong.



  • my Tpost0.g:

    ; tpost0.g
    ; called after tool 0 has been selected
    ;
    ; generated by RepRapFirmware Configuration Tool v2.1.8 on Mon Feb 24 2020 22:39:52 GMT-0800 (Pacific Standard Time)
    ; Wait for set temperatures to be reached
    ;M116 P0

    ;pick up T0 macro
    G91 ; relative positioning
    G53 G1 z3 ; lift Z a few mm to avoid collision during travel
    G90 ;absolute positioning
    G53 G1 x413 Y336 F6000 ;move into position in front of T0 dock
    G91 ;relative positioning
    G53 g1 z-3 ; drop Z few mm
    G53 G1 x0 y62 F1800 ;move in Y towards T0 dock
    G53 G1 x-8 y0 ;move in X towards T0 dock
    G53 G1 x2 y-62 ; move in X/Y away from T0 dock. now tool 0 is selected and out of the way of other parked tools.
    G90 ; absolute positioning

    tfree0.g:
    ;Drop off T0 macro
    G91 ; relative positioning
    G53 G1 z3 ; lift Z a few mm for travel
    G90 ;absolute positioning
    G53 G1 x408 Y336 F6000 ;move in front of T0 dock
    G91 ;relative positioning
    G53 G1 x-3 y62 F1800 ;move 62mm in Y towards T0 dock
    G53 G1 x8 y0 ;move away 8mm in X from T0 dock
    G53 G1 x0 Y-62 ;move back 62mm in Y after drop off
    G53 G1 z-3 ; drop Z a few mm to resume
    G90 ;absolute positioning



  • Looks pretty good. I scanned it (did not read every coordinate in detail)

    Two thoughts:

    1. I'm just curious what locks and unlocks the tool when picking up or parking?

    2. I suggest "square" moves to avoid certain types of collision. That is, if you want to get to
      G53 G1 x413 Y336
      Just before picking up the tool, consider moving like this:
      G53 G1 Y336
      G53 G1 x413
      G53 G1 x413 Y336

    (last one not strictly necessary... but it helps make the macro "self documenting").

    This can avoid a tool-to-parked-tool collision that results from a diagonal move. For example, if the tool was at X0 Y300 when you initiated that move, it would be a long shallow diagonal across the backs of all the tools, quite likely to 'clip' the one nearest the tool we are putting away.

    Ask me how I know...



  • thanks for the suggesting in 2. I will impliment a square move instead of a linear move. I assume this would also be useful to avoid majority of the half printed workpiece by moving around its perimeter.

    I don't have a call to lock and unlock because I am using magnets.



  • In the Config.g file, T0 automatically commanded at the end. however, after reading the T section in the Gcode documentation, it will only get invoked when all axis are homed. I can home X and Y but I need to select Tool 0 before I can home Z. therefore, it does basically nothing. I check the tool status with "T" and it would say T0 is selected but there were indeed no action to select it. i would give me a popup "G0G/1: insufficient axis homed" something like that. How can I get this to work?

    interesting enough, my homeall.g which contains both home x and y macro has a G1 Z# component and it would still proceed. however, the (;pickup T0) macro won't run unless I deleted the G53 G1 z3 and G53 G1 Z-3 line.

    I do not know why the firmware won't let me proceed with Home x and y when there is also a Z movement command in them but not later in the macro.

    home all.g
    ; Home XY prior to selecting the first tool and then home Z using tool 0
    ;X homing
    G91 ; relative positioning
    G53 G1 H2 Z25 F6000 ; lift Z relative to current position to avoid collision with bed clamps this works
    G53 G1 H1 Y-62 ; move -62mm in Y to avoid collision in X movement
    G53 G1 H1 X-436.8 F3600 ; move quickly to X axis endstop and stop there (first pass)
    G53 G1 X5 F6000 ; go back a few mm
    G53 G1 H1 X-436.8 F360 ; move slowly to X axis endstop once more (second pass)
    ;Y homing
    G53 G1 H1 Y-408.225 F3600 ; move quickly to Y axis endstop and stop there (first pass)
    G53 G1 Y5 F6000 ; go back a few mm
    G53 G1 H1 Y-408.225 F360 ; move slowly to Y axis endstop once more (second pass)
    ;pick up T0
    G91 ; relative positioning
    G53 G1 z3 ; lift Z a few mm to avoid collision during travel had to semi-colon this line to work
    G90 ;absolute positioning
    G53 G1 x413 Y336 F6000 ;move into position in front of T0 dock
    G91 ;relative positioning
    G53 g1 z-3 ; drop Z few mm had to semi-colon this line to work
    G53 G1 x0 y62 F1800 ;move in Y towards T0 dock
    G53 G1 x-8 y0 ;move in X towards T0 dock
    G53 G1 x2 y-62 ; move in X/Y away from T0 dock. now tool 0 is selected and out of the way of other parked tools.
    G90 ; absolute positioning
    ;M98 P"/sys/Tpost0" ; just can't get this to work.
    ;Z homing
    G91 ; relative positioning
    G53 G1 H2 Z5 F6000 ; lift Z relative to current position
    G90 ; absolute positioning
    G53 G1 X230 Y148 F6000 ; go to first probe point
    G30 ; home Z by probing the bed
    ; Uncomment the following lines to lift Z after probing
    G91 ; relative positioning
    G53 G1 Z5 F100 ; lift Z relative to current position
    G90 ; absolute positioning


  • administrators

    @tekstyle said in Tool change macro:

    G53 g1 z-3 ; drop Z few mm had to semi-colon this line to work

    Z hasn't been homed at this point, so use:

    G53 G1 H2 Z-3



  • it works now! thank you. now I think I can use the Tpost0.g to pick up tool 0 before homing Z instead of all the extra instructions at the end instead of all the codes at the end of home Y.

    Thank you Danal and DC42.


Log in to reply