Switching between extruders

I finished my modeling project did some test prints last night and found a few challenges and solutions in both Klipper and Slicers to the new configuration options.

Klipper - Stepper Main Config:

[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

[extruder_stepper belted_extruder]
extruder: extruder
#   The extruder this stepper is synchronized to. If this is set to an
#   empty string then the stepper will not be synchronized to an
#   extruder. The default is "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

[extruder] is NOT my full config, but there just for reference.
[extruder_stepper] is a full config for this stepper.

  1. extruder_stepper is synchronized with extruder. This is not what we want for a X-in/1-out extruder. Only one stepper should be rotating at a time. To get around this, use a gcode macro such as @koconnor posted to break the sync and activate/deactivate each stepper individually:
[gcode_macro T0]
gcode:
    # Deactivate stepper in my_extruder_stepper
    SYNC_STEPPER_TO_EXTRUDER STEPPER=belted_extruder EXTRUDER=
    # Activate stepper in extruder
    SYNC_STEPPER_TO_EXTRUDER STEPPER=extruder EXTRUDER=extruder

[gcode_macro T1]
gcode:
    # Deactivate stepper in extruder
    SYNC_STEPPER_TO_EXTRUDER STEPPER=extruder EXTRUDER=
    # Activate stepper in my_extruder_stepper
    SYNC_STEPPER_TO_EXTRUDER STEPPER=belted_extruder EXTRUDER=extruder

T0 will activate [stepper] and deactivate [extruder_stepper].
T1 will deactivate [stepper] and activate [extruder_stepper].

  1. Klipper built-in gcode_macro [ACTIVATE_EXTRUDER] no longer functions as previous. We only have one extrusion system with multiple extruder steppers. Also, SuperSlicer with Klipper G-Code flavor inserts a ACTIVATE_EXTRUDER method whenever there is a change in the extruder, so this is also broken. To get around this, gcode_macro to the rescue:
[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 extruder0.")}
        T0
      {% elif ext == "extruder1" %}
        {action_respond_info("Switching to extruder1.")}
        T1
      {% else %}
        {action_respond_info("EXTRUDER value being passed.")}
        ACTIVATE_EXTRUDER_BASE EXTRUDER={ext}
      {% endif %}
    {% endif %}

Expand this macro to cover additional [extruder_steppers] if you have a 3-in or 4-in hotend or a secondary hotend.

@koconnor can we skip extruder#? ie: [extruder], [extruder2], or do we need [extruder1] in the config? This would make a difference on how the macro is built and in a multi-hotend / tool changer printer, where the x-in/1-out or mixing extruder is placed in the system. (just thinking forward here).

  1. When Klipper starts, both steppers are sync’d. You need to remember to switch to a single stepper or you could get Klipper errors. I heated up my hotend to change filament and during the fast retract, I got a timer too close because BOTH steppers were reversing at an extreme rate the MCU could not keep up with. To help with this, I used a delayed_gcode_macro to deactivate [stepper_extruder] on start-up.
[delayed_gcode activate_default_extruder]
initial_duration: 1
gcode:
    ACTIVATE_EXTRUDER EXTRUDER=extruder
  1. M104 Temperature errors. This can be corrected in slicer or via gcode_macro. Basically, when a temp change is made, some slicers insert a tool# to the M104 command like: M104 S200 T1. The T1 or T0 in the temp would cause an issue with Klipper extruder motion control. gcode_macro to compensate:
[gcode_macro M104]
description: Replaces built-in gcode to not specify Tx due to single extruder
rename_existing: M104.1
gcode:
    {% set s = params.S|default(0)|float %}
    {% set t = params.T|default(0)|int %}
    {% if 'S' in params %}
      {%  if 'T' in params %}
        M104.1 S{s}
      {% else %}
        M104.1 S{s}
      {% endif %}
    {% endif %}

I’ll post my Slicer modifications next.

1 Like