Mixing color support?

hello is it possible to have a 5 in 1 extruder for multi color CMYKW with klipper like in Marlin. a reference link here Set Mix | Marlin Firmware

It might be possible to use [extruder_stepper] config sections to control a mixing extruder. I don’t know if anyone has tried.

-Kevin

So I currently have a ZoneStar Z9V5Pro-MK4 with their hotend ZONESTAR M4V6 the 6th Version M4 4-IN-1-OUT color Mix

I want to be able to keep 16 color mixing



 * "Mixing Extruder"
 *   - Adds G-codes M163 and M164 to set and "commit" the current mix factors.
 *   - Extends the stepping routines to move multiple steppers in proportion to the mix.
 *   - Optional support for Repetier Firmware's 'M164 S<index>' supporting virtual tools.
 *   - This implementation supports up to two mixing extruders.
 *   - Enable DIRECT_MIXING_IN_G1 for M165 and mixing in G1 (from Pia Taubert's reference implementation).
 */
#define MIXING_EXTRUDER
#if ENABLED(MIXING_EXTRUDER)  
  #define MIXING_STEPPERS 	  4  		// Number of steppers in your mixing extruder
  #define MIXING_VIRTUAL_TOOLS 16  		// Use the Virtual Tool method with M163 and M164
  #define USE_PRECENT_MIXVALUE			// Use percent mix data on LCD setting and gcode command
  #define MIX_STATUS_SCREEN_IMAGE		// show mix rate ICON and data in LCD (only applied in LCD12864)
  #if ENABLED(MIX_STATUS_SCREEN_IMAGE) && DISABLED(CUSTOM_STATUS_SCREEN_IMAGE)
  #define CUSTOM_STATUS_SCREEN_IMAGE
  #endif  
  //#define DIRECT_MIXING_IN_G1    		// Allow ABCDHI mix factors in G1 movement commands
  #define GRADIENT_MIX           		// Support for gradient mixing with M166 and LCD
  #define RANDOM_MIX					// Support for random mixing with M167 and LCD
  #if ENABLED(GRADIENT_MIX)
    //#define GRADIENT_VTOOL       		// Add M166 T to use a V-tool index as a Gradient alias
  #endif
#endif

// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing).
// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder).
// For the other hotends it is their distance from the extruder 0 hotend.
//#define HOTEND_OFFSET_X { 0.0, 20.00 } // (mm) relative X-offset for each nozzle
//#define HOTEND_OFFSET_Y { 0.0, 5.00 }  // (mm) relative Y-offset for each nozzle
//#define HOTEND_OFFSET_Z { 0.0, 0.00 }  // (mm) relative Z-offset for each nozzle

// @section machine

/**
1 Like
4ColorMix16(1:White, 2:Yellow, 3:Red, 4:Blue)

{if next_extruder==0}
; White ok
M163 S0 P100 
M163 S1 P0 
M163 S2 P0 
M163 S3 P0 
M164 S0
{elsif next_extruder==1} 
; Red ok
M163 S0 P0 
M163 S1 P0 
M163 S2 P100 
M163 S3 P0 
M164 S1
{elsif next_extruder==2}
; Orange ok
M163 S0 P0 
M163 S1 P90 
M163 S2 P10 
M163 S3 P0 
M164 S2
{elsif next_extruder==3} 
; Yellow ok
M163 S0 P0 
M163 S1 P100 
M163 S2 P0 
M163 S3 P0 
M164 S3
{elsif next_extruder==4} 
; Green 
M163 S0 P0 
M163 S1 P30 
M163 S2 P20 
M163 S3 P50
M164 S4 
{elsif next_extruder==5} 
; Blue ok
M163 S0 P0 
M163 S1 P0 
M163 S2 P0 
M163 S3 P100 
M164 S5
{elsif next_extruder==6} 
;Navy
M163 S0 P0 
M163 S1 P0 
M163 S2 P20 
M163 S3 P80 
M164 S6
{elsif next_extruder==7} 
;Purple
M163 S0 P0 
M163 S1 P0 
M163 S2 P30 
M163 S3 P70 
M164 S7
{elsif next_extruder==8} 
;Blue green
M163 S0 P0 
M163 S1 P20 
M163 S2 P10 
M163 S3 P60 
M164 S8
{elsif next_extruder==9} 
;Pink ok
M163 S0 P90 
M163 S1 P0 
M163 S2 P10 
M163 S3 P0 
M164 S9
{elsif next_extruder==10} 
;Brown ok
M163 S0 P0 
M163 S1 P60 
M163 S2 P10 
M163 S3 P30 
M164 S10
{elsif next_extruder==11} 
;Apricot
M163 S0 P10
M163 S1 P75 
M163 S2 P15 
M163 S3 P0 
M164 S11
{elsif next_extruder==12} 
;Green Yellow
M163 S0 P0 
M163 S1 P60 
M163 S2 P0 
M163 S3 P40 
M164 S12
{elsif next_extruder==13} 
;Mint
M163 S0 P20 
M163 S1 P60 
M163 S2 P0 
M163 S3 P20  
M164 S13
{elsif next_extruder==14} 
;Sky Blue ok
M163 S0 P70 
M163 S1 P0 
M163 S2 P0 
M163 S3 P30 
M164 S14
{elsif next_extruder==15} 
;Silver
M163 S0 P50 
M163 S1 P20 
M163 S2 P5 
M163 S3 P25 
M164 S15
{endif}

Please post such code snippets using the preformatted text option:

1 Like

I’m a little confused, did you find a way to implement color-mixing with Klipper? I visited the github link, but I’m still confused on how to implement this. Is this compatible with Klipper? I can’t find a straightforward answer on how to add/use this feature.

Hello, I’m converting to klipper so was collecting info for me to work through once I get my board and start configuring. I’ll let you know what I can work out

1 Like

Do you had any success, I have a dual mixing extruder in the configuration 2in 1 out.
I can print just with one color with the extruder setup

[extruder]
step_pin: PL3 #PL6
dir_pin: PL5 #PL4
enable_pin: !PB6 #!PG0
microsteps: 16
rotation_distance: 6.98159 #7.7# 11.88736 #8.01504 #8.25549
nozzle_diameter: 0.4
filament_diameter: 1.750
heater_pin: PE5 #PE4
sensor_type: Generic 3950
sensor_pin: arduino:PC0 #PF1 #PF0
min_temp: 0 #0
max_temp: 250
#control: pid
#pid_kp: 23.770
#pid_ki: 0.938
#pid_kd: 150.631
min_extrude_temp: 180
max_extrude_only_distance: 150
pressure_advance = 0.6

[extruder_stepper extruder1]
extruder: 
step_pin: PL0
dir_pin: PL2
enable_pin: !PL1
microsteps: 16
rotation_distance: 6.98159 #7.7# 11.88736 #8.01504 #8.25549 #33.500
pressure_advance = 0.6

I then tried to implement M163 and M164,

[gcode_macro T0]
gcode:
	SYNC_EXTRUDER_MOTION EXTRUDER="extruder" MOTION_QUEUE="extruder"
	SYNC_EXTRUDER_MOTION EXTRUDER="extruder1" MOTION_QUEUE=""

[gcode_macro M163]  

# M163 [P<factor>] [S<index>] Set a single mix factor (in proportion to the sum total of all mix factors). The mix must be committed to a virtual tool by M164 before it takes effect.
gcode:
  {% if 'P' in params %}
     {% if 'S' in params %}
       {% if params.S == 0 %}
         M118 Set Mixing factor for tool {params.S|default(50)|float} to {params.P|default(50)|float}
         SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e0_percentage VALUE={params.P|default(50)|float}
       {% else %}
         SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e1_percentage VALUE={params.P|default(50)|float} 
         M118 Set Mixing factor for tool 1 to {params.P|default(50)|float}
       {% endif %}  
     {% else %}
       SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e0_percentage VALUE={params.P|default(50)|float}
       SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e1_percentage VALUE={100-params.P|default(50)|float}
       M118 Set Mixing factor to {params.P|default(50)|float} adnd {100-params.P|default(50)|float}
     {% endif %} 
  {% else %}   
     M118 No Mixing factor set, missing values for P and S
  {% endi

[gcode_macro M164]    
  variable_e0_percentage : 50 # default values
  variable_e1_percentage : 50
  
gcode:
  {% set e0 = e0_percentage / (e0_percentage + e1_percentage) | float %} # later treat the sum for all tools to 100% extrusion
  {% set e1 = e1_percentage / (e0_percentage + e1_percentage) | float %}
  M118 Got e0 { printer.configfile.settings.extruder.rotation_distance }
  M118 Got e1 { printer.configfile.settings['extruder_stepper extruder1'].rotation_distance  }
  M118 Mixing factor {e0} and {e1} 
  M118 e0 rot-dist { printer.configfile.settings.extruder.rotation_distance * e0|float }
  M118 e1 rot-dist { printer.configfile.settings['extruder_stepper extruder1'].rotation_distance * e1|float } 
  # activate stepper percentages
  SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder DISTANCE={ printer.configfile.settings.extruder.rotation_distance * e0 / 2 |float }
  SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder1 DISTANCE={ printer.configfile.settings['extruder_stepper extruder1'].rotation_distance * e1 / 2|float } 
  SYNC_EXTRUDER_MOTION EXTRUDER=extruder MOTION_QUEUE=extruder # Add e0
  SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder # Add e1
  M118 Mixing factor {e0} and {e1} activated

but every time I change the mixing I got the error

MCU 'mcu' shutdown: Rescheduled timer in the past
This generally occurs when the micro-controller has been
requested to step at a rate higher than it is capable of
obtaining.
Once the underlying issue is corrected, use the
"FIRMWARE_RESTART" command to reset the firmware, reload the
config, and restart the host software.
Printer is shutdown

it seams that the extruder positions get messed up by changing the rotation distance for the two steppers to implement the mixing.
Any ideas what I am missing and can change?

I solved my problem for mixing, their error had been that I multiplied the rotation distance by the percentage instead dividing it. I now have the following configs, that seam to work:

# Driver1 (Extruder 1 / T0)
[extruder]
step_pin: PL3 #PL6
dir_pin: PL5 #PL4
enable_pin: !PB6 #!PG0
microsteps: 16
rotation_distance: 6.98159 #7.7# 11.88736 #8.01504 #8.25549
nozzle_diameter: 0.4
filament_diameter: 1.750
heater_pin: PE5 #PE4
sensor_type: Generic 3950
sensor_pin: arduino:PC0 #PF1 #PF0
min_temp: 0 #0
max_temp: 250
min_extrude_temp: 180
max_extrude_only_distance: 150
pressure_advance = 0.6
max_extrude_cross_section: 2

# Driver42 (Extruder 2 / T1)
[extruder_stepper extruder1]
extruder: 
step_pin: PL0
dir_pin: PL2
enable_pin: !PL1
microsteps: 16
rotation_distance: 6.98159 #7.7# 11.88736 #8.01504 #8.25549 #33.500
pressure_advance = 0.6

[gcode_macro T0]
# Extruder 0 with a small amount from E1 to prevent clogging
gcode:
    M163 S0 P99
    M163 S1 P1
    M164
	
[gcode_macro T1]
# Extruder 1 with a small amount from E0 to prevent clogging
gcode:
    M163 S0 P1
    M163 S1 P99
    M164

[gcode_macro T2]
# only Extruder 0
gcode:
    M163 S1 P0
    M163 S0 P100
    M164 

[gcode_macro T3]
#only Extruder 1
gcode:
    M163 S1 P100
    M163 S0 P0
    M164 

[gcode_macro T4]
#only Extruder 1
gcode:
    M163 S1 P50
    M163 S0 P50
    M164 

[gcode_macro M163]  

# M163 [P<factor>] [S<index>] Set a single mix factor (in proportion to the sum total of all mix factors). The mix must be committed to a virtual tool by M164 before it takes effect.
gcode:
  {% if 'P' in params %}
     {% if 'S' in params %}
       {% set s = params.S|default(5)| int %}  
       {% if s == 1 %}
         M118 Set Mixing factor for extruder 1 to {params.P|default(50)|float}
         SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e0_percentage VALUE={params.P|default(50)|float}
       {% else %}
         SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e1_percentage VALUE={params.P|default(50)|float} 
         M118 Set Mixing factor for extruder 0 to {params.P|default(50)|float}
       {% endif %}  
     {% else %}
       SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e0_percentage VALUE={params.P|default(50)|float}
       SET_GCODE_VARIABLE MACRO=M164 VARIABLE=e1_percentage VALUE={100-params.P|default(50)|float}
       M118 Set Mixing factor to {params.P|default(50)|float} and {100-params.P|default(50)|float}
       M118 {e0_percentage} {e1_percentage} 
     {% endif %} 
  {% else %}   
     M118 No Mixing factor set, missing values for P and S
  {% endif %}
   
  
[gcode_macro M164]    
  variable_e0_percentage : 50 # default values
  variable_e1_percentage : 50
  
gcode:
  {% set e0 = e0_percentage / (e0_percentage + e1_percentage) | float %} # later treat the sum for all tools to 100% extrusion
  {% set e1 = e1_percentage / (e0_percentage + e1_percentage) | float %}
  M118 Got e0 { printer.configfile.settings.extruder.rotation_distance }
  M118 Got e1 { printer.configfile.settings['extruder_stepper extruder1'].rotation_distance  }
  #M118 Mixing factor {e0} and {e1} 
  M118 e0 rot-dist { printer.configfile.settings.extruder.rotation_distance * e0|float }
  M118 e1 rot-dist { printer.configfile.settings['extruder_stepper extruder1'].rotation_distance * e1|float } 
   {% if e0 == 0 %}
     # only e1
     SYNC_EXTRUDER_MOTION EXTRUDER=extruder MOTION_QUEUE= # e0 off
     SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder # Add e1
     SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder DISTANCE={ printer.configfile.settings.extruder.rotation_distance |float }
     SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder1 DISTANCE={ printer.configfile.settings['extruder_stepper extruder1'].rotation_distance |float } 
   {% elif e1 == 0 %}
     # only e0
     SYNC_EXTRUDER_MOTION EXTRUDER=extruder MOTION_QUEUE=extruder # add e0 
     SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE= # e1 off
     SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder DISTANCE={ printer.configfile.settings.extruder.rotation_distance |float }
     SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder1 DISTANCE={ printer.configfile.settings['extruder_stepper extruder1'].rotation_distance |float } 
   {% else %}
     # activate stepper percentages
     SYNC_EXTRUDER_MOTION EXTRUDER=extruder MOTION_QUEUE=extruder # Add e0
     SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder # Add e1
     SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder DISTANCE={ printer.configfile.settings.extruder.rotation_distance / e0|float }
     SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder1 DISTANCE={ printer.configfile.settings['extruder_stepper extruder1'].rotation_distance / e1|float } 
   {% endif %}
  M118 Mixing factor {e0} and {e1} activated

I now have multiple tools with predefined mixes, where T0 and T1 are the tow colors with one percantage of the other one mixed in to prevent clogging.
And In have macros M163 and M164 to set other mixes.

I had to raise the max_extrude_cross_section to two to not get errors and aborting of the print during the hard color change between T0 and T1 during printing the wipe tower.
I hear heavy moves from the extruder steppers during that change. Any ideas to fix that would be welcome