Feature request: [active_extruder] variable in layer change G-code #2866

makertum opened this Issue May 30, 2015 · 9 comments


None yet

4 participants


It would be extremely useful to have a [current_extruder] or [active_extruder] variable in the custom layer change gcode field.

This variable is the missing puzzlepiece required for switching extruders within custom layer change procedures (such as cleaning nozzle tips on a brush or adding custom wipe/prime towers), because one would have to switch back to the currently active extruder afterwards by adding a T[active_extruder].

Anyway, I would be glad to hear some comments on this. Of course one can add all kinds of extras using post processing scripts, but I just think this would be an extremely useful variable that would open up many useful possibilities and an easy way to address scenarios where the current ooze prevention feature might not bring the desired results.

For illustration, I need this for improving my wipe tower script, which prints one hollow wipe tower for each extruder on each layer change, but there are probably many other cases, where this might come in handy, such as custom wiping hardware that needs to be approached by each extruder on every layer change or so. However, if I had the [active_extruder] variable in the layer change, my towers would look like this:


but since the variable is not there, I can only print the wipe towers with the active extruder, which looks like this:


So this is already nice, since the printer can wipe E0 on the wipe tower for E0, but the wipe tower might be of a different filament color, so there might be a little smear. And the extruder might have been out of operation for a long time, so one has to purge way more material on tool change, which can clog the tower.

So what this does is, on every layer change, it prints a pre-generated hollow wipe tower for every extruder. Then, on every tool change, it lets each extruder travel to the center of it's own hollow wipe tower, extrudes a little filament, travels out of the wipe tower to wipe away the string, and goes back to normal operation. That works, because the corresponding tower can be selected just by travelling to the first tower, then switching to relative positioning and using "G1 X[next_extruder]0" if the towers are spaced 10 mm center-to-center.


Here's the "After layer change G-code":

; next layer
M83 ; set extruder to relative mode
; T0 ; here one would have to switch to E0 for purging it every layer
; printing tower for E0
G1 X75.2 Y150.0 F9000.0
G1 X75.2 Y159.8 E0.3259 F3000.0
G1 X84.8 Y159.8 E0.3193
G1 X84.8 Y150.2 E0.3193
G1 X75.6 Y150.2 E0.306
G1 X75.6 Y159.4 E0.306 F3000.0
G1 X84.4 Y159.4 E0.2927
G1 X84.4 Y150.6 E0.2927
G1 X76.0 Y150.6 E0.2794
G1 X76.0 Y159.0 E0.2794 F3000.0
G1 X84.0 Y159.0 E0.2661
G1 X84.0 Y151.0 E0.2661
G1 X76.4 Y151.0 E0.2528
G1 X76.4 Y158.6 E0.2528 F3000.0
G1 X83.6 Y158.6 E0.2395
G1 X83.6 Y151.4 E0.2395
G1 X76.8 Y151.4 E0.2262
G1 X76.8 Y158.2 E0.2262 F3000.0
G1 X83.2 Y158.2 E0.2129
G1 X83.2 Y151.8 E0.2129
G1 X77.2 Y151.8 E0.1996
; T1 ; here one would have to switch to E1 for purging it every layer
; printing tower for E1
G1 X85.2 Y150.0 F9000.0
G1 X85.2 Y159.8 E0.3259 F3000.0
G1 X94.8 Y159.8 E0.3193
G1 X94.8 Y150.2 E0.3193
G1 X85.6 Y150.2 E0.306
G1 X85.6 Y159.4 E0.306 F3000.0
G1 X94.4 Y159.4 E0.2927
G1 X94.4 Y150.6 E0.2927
G1 X86.0 Y150.6 E0.2794
G1 X86.0 Y159.0 E0.2794 F3000.0
G1 X94.0 Y159.0 E0.2661
G1 X94.0 Y151.0 E0.2661
G1 X86.4 Y151.0 E0.2528
G1 X86.4 Y158.6 E0.2528 F3000.0
G1 X93.6 Y158.6 E0.2395
G1 X93.6 Y151.4 E0.2395
G1 X86.8 Y151.4 E0.2262
G1 X86.8 Y158.2 E0.2262 F3000.0
G1 X93.2 Y158.2 E0.2129
G1 X93.2 Y151.8 E0.2129
G1 X87.2 Y151.8 E0.1996
; T[active_extruder] ; here one would have to switch back to the actually active extruder
; continue

And this ist the "Tool change G-code":

; tool change
G1 E-10 F4500 ; retraction
T[next_extruder] ; select extruder to wipe
G1 X80.0 Y145.0 ; go to first tower
G91 ; set relative positioning
G1 X[next_extruder]0 ; select tower
G1 X0.0 Y10.0 F9000.0 ; enter tower
G1 E10 F4500 ; inverse retraction
G1 E3.0 F3000.0 ; purge a little
G4 S1 ; wait a bit
G1 X10.0 Y-10.0 F9000.0 ; wipe
G90 ; set absolute positioning
; continue
@makertum makertum changed the title from [active_extruder] variable in layer change G-code to Feature request: [active_extruder] variable in layer change G-code May 30, 2015
@alexrj alexrj added this to the 1.2.8 milestone May 31, 2015
@alexrj alexrj added the Done label May 31, 2015
alexrj commented May 31, 2015

Done! [current_extruder] is waiting for you.

@alexrj alexrj closed this May 31, 2015
alexrj commented May 31, 2015

Also, thanks for the detailed discussion with usage cases - I really appreciate it.


Wow, that was quick, thanks a lot!

rsatue commented Jun 8, 2015


Will this work when you are using more than one extruder in the same layer?

Wouldn't make more sense to add some gcode lines to print the wipe-tower before every layer change and every change of tool?

makertum commented Jun 9, 2015

Hi rsatue,

my approach is printing one wipe tower for each extruder, which works for as many extruders as you like. This method ensures that an extruder is always wiped on a wipe tower of its own material, which is important for multi material prints with different print temps and contrasting colors. You just have to add a G-code snippet for printing all the towers on layer change, then add the G-Code snippet for wiping the next_extruder in the custom tool change G-Code.

But I think it does not make sense to print the wipe tower on tool change and on layer change, since the wipe tower has to be printed on each layer change, so that we can use it for the actual wiping move if a tool change occurs in a layer, and there might be layers where no tool change occurs, too.

In most reasonable scenarios, there's maximum 1 tool change per extruder per layer. Therefore it would, however make a lot of sense to look ahead in the G-Code, and if a tool change is about to happen in a particular layer, skip the printing of the wipe tower on that layer change and move it to that tool change instead. That way, one could save away the wiping moves entirely, which would save a little printing time.

However, it would be tedious to beef up custom G-Code fields for those kind of tasks (would require conditional statements like [if]/[else] and a bunch of new vars like [does_next_layer_contain_tool_change]), better use a post processing script. I also went on to generating my wiping towers with a little Perl script meanwhile.

@born2b born2b added a commit to born2b/Slic3r that referenced this issue Jun 10, 2015
@alexrj @born2b + born2b New [current_extruder] variable in custom G-code. #2866 57d2007
biskero commented Jul 27, 2015


just wanted to share my scenario and how to have an IF statement would help and simplify using g-code.
I am building a new extruder with 1 motor, 2 servos and 4 filaments materials.
Basically to switch from one filament to another I move the servos position.
So if I want to use Ext 0, I move Servo 0 to position 0 and Servo 1 to Rest position, this case filament 0 is engaged and all other 3 are not. Here is a design http://forums.reprap.org/read.php?4,518046,522292#msg-522292

So in the Tool Change G-code I would like to have an IF statement like this:
IF T[current_extruder] == T0 M280 P0 S80 ; this engage Ext 0 with servo 0 @80deg, Ext 1 is off
IF T[current_extruder] == T0 M280 P1 S90 ; this will make Servo 1 in rest position @90deg, Ext 2,3 off
here there are the other IF statements for T1 T2 T3

Does it make sense?


As far as I understand the matter, mapping tool changes to servo angles is more a "firmware-thing". So you might want to perform those actions in firmware, having the Tx G-code trigger the servo motion accordingly.

However, until Alessandro delivers a turing complete Custom G-code environment, which is bound to happen sooner or later, you could solve this quick and dirty using a Perl post processor script like this:

# make sure your custom tool change G-code is "; tool change [current_extruder]"
while (<>) {
    if(/^; tool change \d+/){
            print "M280 P0 S80 ; this engage Ext 0 with servo 0 @80deg, Ext 1 is off\n";
        }else if($1==1){
            print "M280 P1 S90 ; this will make Servo 1 in rest position @90deg, Ext 2,3 off\n";
biskero commented Jul 27, 2015

that was my next step, to have a script doing the trick.
Will have the new extruder assembled tomorrow so I can show more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment