X-In/1-Out Non-Mixing Extruder Config

The following configuration is an example of an X-In/1-Out Hot-End such as:

Or a multi-in splitter such as:
2-in/1-Out: G1/8 "Y-piece" 1.75mm dual extusion upgrade (prometheus system) ( 1/8PT ) by SilasPfeifer - Thingiverse
4-in/1-Out: 4 in 1 out multi filament upgrade M5 by SilasPfeifer - Thingiverse

This configuration works with the following Klipper Version/Builds:
v0.10.0-312
v0.10.0-320
v0.10.0-333
v0.10.0-368
v0.10.0-377
v0.11.0-5
v0.11.0-6
v0.11.0-14
v0.11.0-30
v0.11.0-41
v0.11.0-173

For reference, the following configuration is a single v6 style hot-end and 2 extruder/steppers; BMG is the primary and a self-designed 4:1 ratio belted extruder is a secondary.
.

Klipper printer.cfg
Setup the [extruder] object with one stepper just as you would with a single stepper extruder:

Reference: Configuration reference - Klipper documentation

[extruder]  
step_pin: PC1
dir_pin: PC3
enable_pin: !PC7
microsteps: 16
rotation_distance: 22.024
full_steps_per_rotation: 200
gear_ratio: 50:17
nozzle_diameter: 0.400
filament_diameter: 1.750

The remaining configuration of the [extruder] module was not included here in order to save space.

Next, configure [extruder_stepper] objects, one per additional stepper.

Note that “extruder1”, “extruder2”, etc. are reserved for the [extruder] object.
Reference: Configuration reference - Klipper documentation

[extruder_stepper belted_extruder]
extruder: 
step_pin = PA4
dir_pin = PA6
enable_pin = !PA2
microsteps: 16
rotation_distance: 22.5
full_steps_per_rotation: 200
gear_ratio: 4:1

At this point, the printer has 2 steppers configured; one to one Hot End and one is not attached to any Hot End. There needs to be some gcode macro’s to un-sync and switch active steppers.

Here we will configure two macros making T0 = stepper on the [extruder] object and T1 the stepper on the [extruder_stepper] object. This will allow only one active stepper during extrude operations.

[gcode_macro T0]
gcode:
    # Deactivate stepper in my_extruder_stepper
    SYNC_EXTRUDER_MOTION EXTRUDER=belted_extruder MOTION_QUEUE=
    # Activate stepper in extruder
    SYNC_EXTRUDER_MOTION EXTRUDER=extruder MOTION_QUEUE=extruder

[gcode_macro T1]
gcode:
    SYNC_EXTRUDER_MOTION EXTRUDER=extruder MOTION_QUEUE=
    # Activate stepper in my_extruder_stepper
    SYNC_EXTRUDER_MOTION EXTRUDER=belted_extruder MOTION_QUEUE=extruder

Note: EXTRUDER is the stepper while MOTION_QUEUE is the hot-end

Next, remap the built-in ACTIVATE_EXTRUDER gcode macro so it can be used in your slicer:

[gcode_macro ACTIVATE_EXTRUDER]
description: Replaces built-in macro for a X-in, 1-out extruder configuration SuperSlicer fix
rename_existing: ACTIVATE_EXTRUDER_BASE
gcode:
    {% if 'EXTRUDER' in params %}
      {% set ext = params.EXTRUDER|default(EXTRUDER) %}
      {% if ext == "extruder"%}
        {action_respond_info("Switching to extruder.")}
        T0
      {% elif ext == "belted_extruder" %}
        {action_respond_info("Switching to belted_extruder.")}
        T1
      {% else %}
        {action_respond_info("EXTRUDER value being passed.")}
        ACTIVATE_EXTRUDER_BASE EXTRUDER={ext}
      {% endif %}
    {% endif %}

Finally, create a delayed gcode macro to set make one stepper active upon Klipper startup:

[delayed_gcode activate_default_extruder]
initial_duration: 1
gcode:
    ACTIVATE_EXTRUDER EXTRUDER=extruder

.

Printer Settings - SuperSlicer/PrusaSlicer/Slic3r

Note: As of the initial write-up of this document, I have not implemented tool-changing in a single print for either multi-color printing or multi-material printing (PETG print/PLA supports). This thread will be expanded to cover that in the future.

  • Printer Settings → General - Set the number of Extruders configured in Klipper and tick the Single Extruder Multi Material check-box

  • Printer Settings → Extruder 1 - modify the Tool name to be “extruder”, or the first stepper you have configured.

  • Printer Settings → Extruder 2 - modify the Tool name to match the [extruder_stepper] object configured in Klipper. In this image, it’s set to “belted_extruder”

  • Printer Settings → Custom G-code - Add in custom gcode to switch extruder stepper and pressure advance.

[tool_name] is linked to Printer Settings → Extruder1/2 values modified earlier

Note: starting about Klipper version v0.10.0-312, and additional PA option was added; EXTRUDER, which allows PA to be used on [extruder_stepper] objects and it must be included when using SET_PRESSURE_ADVANCE.

ACTIVATE_EXTRUDER EXTRUDER=[tool_name]
SET_PRESSURE_ADVANCE ADVANCE=0 EXTRUDER=[tool_name]

I have this set at the top of the created gcode to make sure a tool is set. I also do not apply pressure advance at this point in printing.

Filament Settings - > Custom G-Code - Here, enter in custom code for PA and Tool on a per-filament basis

; Filament gcode
; PLA PA
{if tool_name == "belted_extruder"}
SET_PRESSURE_ADVANCE ADVANCE=0.4176 SMOOTH_TIME=0.040 EXTRUDER=[tool_name]
{endif}

You can add additional ‘if’ loops once you know the PA value for all your steppers, if they are not the same. If all your extruders are the same type/design, then you do no need an ‘if’ statement.

At this point, all the basics are supplied in order to start printing and switch extruders.

Klipper - TUNING_TOWER command -
To perform a PA test using the TUNING_TOWER command is slightly different. Just as with the SET_PRESSURE_ADVANCE command, a EXTRUDER needed to be specified to apply PA to, the same needs to be set in the TUNING_TOWER command:

TUNING_TOWER COMMAND="SET_PRESSURE_ADVANCE [EXTRUDER=<config_name>]" PARAMETER=<name> START=<value> FACTOR=<value>

Basically, putting SET_PRESSURE_ADVANCE [EXTRUDER=<config_name>] between double quotes so the COMMAND will be passed as one value.

Example using belted_extruder: TUNING_TOWER COMMAND="SET_PRESSURE_ADVANCE EXTRUDER=belted_extruder" PARAMETER=ADVANCE START=0 FACTOR=.020
.

Final Thoughts

Klipper has options/features that you can achieve the same thing different ways. This is just one way that works. If you have suggestions, recommendations, or Tool Change G-Code suggestions, please post them below.

I will do my best to keep a basic working example updated though future Klipper updates.

Slicer Setup:

Please reference this post for how to setup SuperSlicer/Prusa Slicer/Slic3r: X-In/1-Out Non-Mixing Extruder - Automate SuperSlicer Filament Swaps

2 Likes

Thanks.

FYI, it might be better to initially create the extruder_stepper object without assigning it to the extruder motion queue:

[extruder_stepper belted_extruder]
extruder:
step_pin = PA4
...

-Kevin

1 Like

Interesting approach, I was running the same hotend with just extruder and extruder1 defined. This was with extruder1 sharing the heater of extruder (shared_heater: extruder) and it just worked with Cura without the T0, T1 macros. Is there any advantage to doing it your way?

I was running similar as you, but the “shared_heater” option is being or is deprecated, so you will eventually need to migrate to this config, or something similar.

20220210: The SYNC_STEPPER_TO_EXTRUDER command is deprecated; the SET_EXTRUDER_STEP_DISTANCE command is deprecated; the extruder shared_heater config option is deprecated. These features will be removed in the near future. Replace SET_EXTRUDER_STEP_DISTANCE with SET_EXTRUDER_ROTATION_DISTANCE . Replace SYNC_STEPPER_TO_EXTRUDER with SYNC_EXTRUDER_MOTION . Replace extruder config sections using shared_heater with extruder_stepperconfig sections and update any activation macros to use SYNC_EXTRUDER_MOTION.

https://www.klipper3d.org/Config_Reference.html#extruder

Good to know. In my more recent incantation I was using duplicate pins and defining heart and thermo for multiple extruders and that seemed to work fine too. Though I would like to find the time to go back to the mixing extruder and see if I could come up with a solution for that. I guess I need to read the current docs and understand where things are now :wink:

Thanks for posting your work, this is much appreciated! With your instructions I was able to get this working on my custom setup.

1 Like

Thank you for the work. I have run into a problem, klipper changes to T1/extruderI with no problem but switching back to T0/extruder I get this error Unable to infer active extruder stepper I’ve added

{if tool_name == "extruderI"}
SET_PRESSURE_ADVANCE ADVANCE=0.8 SMOOTH_TIME=0.040 EXTRUDER=[tool_name]
{endif}

to the filament custom gcode (superslicer) which works fine for the 1st tool change to [extruder_stepper extruderI] however on the change back to [extruder] I get Unable to infer active extruder stepper I’ve tried changing the gcode to

{if tool_name == "extruder"}
SET_PRESSURE_ADVANCE ADVANCE=0.88 SMOOTH_TIME=0.040 EXTRUDER=[tool_name]
{endif}
{if tool_name == "extruderI"}
SET_PRESSURE_ADVANCE ADVANCE=0.88 SMOOTH_TIME=0.040 EXTR
UDER=[tool_name]
{endif}

This returns the same error

This didn’t work, terminal output

08:50:09
Unable to infer active extruder stepper
08:47:51
pressure_advance: 0.880000
pressure_advance_smooth_time: 0.040000
08:47:51
Extruder stepper now syncing with 'extruder'
08:47:51
Extruder stepper now syncing with ''
08:47:51
Switching to extruderI.
08:47:45
pressure_advance: 0.000000
pressure_advance_smooth_time: 0.040000
08:44:53
pressure_advance: 0.800000
pressure_advance_smooth_time: 0.040000
08:43:53
Retries: 1/20 Probed points range: 0.001591 tolerance: 0.005000

printer.cfg

[extruder]
max_extrude_cross_section: 50.0
max_extrude_only_distance: 1010.0
step_pin: PG12
dir_pin: !PG11
enable_pin: !PG13
microsteps: 16
rotation_distance: 7.64
nozzle_diameter: 0.600
filament_diameter: 1.750
heater_pin: PB1 # Heat0
sensor_pin:  PC1 # T0 Header
sensor_type: EPCOS 100K B57560G104F
min_temp: 0
max_temp: 290

[extruder_stepper extruderI]
extruder: extruder
step_pin: PD6
dir_pin: !PD5
enable_pin: !PD7
microsteps: 16
rotation_distance: 7.64

[gcode_macro ACTIVATE_EXTRUDER]
description: Replaces built-in macro for a X-in, 1-out extruder configuration SuperSlicer fix
rename_existing: ACTIVATE_EXTRUDER_BASE
gcode:
    {% if 'EXTRUDER' in params %}
      {% set ext = params.EXTRUDER|default(EXTRUDER) %}
      {% if ext == "extruder"%}
        {action_respond_info("Switching to extruder.")}
        T0
      {% elif ext == "extruderI" %}
        {action_respond_info("Switching to extruderI.")}
        T1
      {% else %}
        {action_respond_info("EXTRUDER value being passed.")}
        ACTIVATE_EXTRUDER_BASE EXTRUDER={ext}
      {% endif %}
    {% endif %}

[delayed_gcode activate_default_extruder]
initial_duration: 1
gcode:
    ACTIVATE_EXTRUDER EXTRUDER=extruder

SuperSlicer filament settings
pla1

; Filament gcode
; PLA PA
SET_PRESSURE_ADVANCE ADVANCE=0.8 SMOOTH_TIME=0.040 EXTRUDER=[tool_name]

pla2

; Filament gcode
; PLA PA
SET_PRESSURE_ADVANCE ADVANCE=0.88 SMOOTH_TIME=0.040 EXTRUDER=[tool_name]

both extruders are identical

It turns out the problem is in SuperSlicer. SS is adding a line in the gcode SET_PRESSURE_ADVANCE ADVANCE=0 but doesn’t specify which extruder which throws an error. Now I just have to figure out how to get SS to add this line instead SET_PRESSURE_ADVANCE ADVANCE=0 EXTRUDER=<tool name>

Check what you have for each Filament → Custom G-Code as well as Printer Settings → Custom C-Code for anything that has Pressure Advance.

I can no longer edit the original post, so here is an updated list of Klipper versions:

This configuration works with the following Klipper Version/Builds:
v0.10.0-312
v0.10.0-320
v0.10.0-333
v0.10.0-368
v0.10.0-377

First off, THANK YOU! You have gotten me quite fair along. However i am still running into the “Unable to infer active extruder stepper” error.

log

You are setting PA without explicitly defining the extruder.
Check every place, e.g. startup gcode, macros, filament switch gcodes etc., and make sure to use:

SET_PRESSURE_ADVANCE ADVANCE=... EXTRUDER=[tool_name]

where [tool_name] needs to be the name of your then active extruder and ... your desired PA value.

I have this all set up, although SuperSlicer, keeps adding set PA to 0 during the tool-change unload. Klipper throws an error when this happens. It seems to be associated with the wipe tower. If I discard the wipe tower, SS does not try to adjust the PA. Any experience with this?

Check your tool change custom gcode to see if you have any PA settings there. If you do, adjust as necessary

nothing in toolchange.

is my klipper, config, klippy.log, and gcode.

I continue to run into errors. I have started with brand new configs and programs but still run into the “unable to infer active extruder”.

I’m using Klipper v0.10.0-584. Trying to use both extruders in the same print but when one extruder is done for the print, it turns off the heater.

I’m having the exact same issue using klipper v0.10.0-608-g638303b3. Did you find a solution for this?

I did! After weeks of headaches and trial and error, I found the problem in my gcode! I slice with Cura and found that it likes to stick in an M104 S0. In the tutorial above, they use SuperSlicer. There is a setting in SuperSlicer for “Single Extruder Multi Material”. I assume that by checking this box it prevents the M104 from being issued mid print. There doesn’t appear to be a way to prevent it within Cura and I haven’t found a way to tell Klipper to ignore it, so I deal with it by implementing a post processing script to find and delete any instance of M104 S0.