Macro Variables
Every variable_* tuning knob in mmu_macro_vars.cfg, for every core macro
Happy Hare ships - generated by reading the real shipped template and the
menuconfig help text behind each one, the same way as Parameters
and for the same reason: the wiki is treated here as too unreliable to
trust for facts that drift release to release. This page is the flat
lookup; each macro's own Feature page (where one exists) explains the
concept and workflow around it.
Every macro block below lives in its own [gcode_macro ..._VARS] section
in mmu_macro_vars.cfg, and every variable can be read live from a macro
as printer['gcode_macro _WHATEVER_VARS'].variable_name. Several sections
only appear in the shipped file at all once the matching feature is enabled
in menuconfig - noted per section.
mmu_macro_vars.cfg also generates one plain Tx macro (T0, T1, ...)
per gate, each just calling MMU_CHANGE_TOOL TOOL=x - not really a
"variable" to tune, but worth knowing these aren't hand-written: the count
tracks your gate total automatically, and interfaces like Mainsail need
these real macro definitions to show tool buttons at all.
Print start/end (_MMU_SOFTWARE_VARS)
Controls MMU_START_SETUP/MMU_START_LOAD_INITIAL_TOOL (print start) and
MMU_END (print end).
| Variable |
Default |
Description |
user_pre_initialize_extension |
(empty) |
Macro run at the start of MMU_START_SETUP - commonly G28 to home |
home_mmu |
False |
Home the MMU before the print starts |
check_gates |
True |
Check filament is actually loaded in every gate the print will use |
load_initial_tool |
True |
Automatically load the first tool needed |
automap_strategy |
none |
Automap strategy applied to the slicer tool map - none, filament_name, material, color, closest_color, or spool_id (future) - see Feature: Gate/TTG Maps |
user_print_end_extension |
(empty) |
Macro run at the start of MMU_END - a good place to move off the print |
unload_tool |
True |
Unload the current tool at print end |
reset_ttg |
False |
Reset the TTG map at print end |
dump_stats |
True |
Display print statistics at print end |
State change hooks (_MMU_STATE_VARS)
Extension points for every Happy Hare state-change/event macro, plus two
maintenance-warning limits.
| Variable |
Default |
Description |
user_action_changed_extension |
(empty) |
Run after default logic whenever printer.mmu.action changes (same params as the original call) |
user_print_state_changed_extension |
(empty) |
Same, for printer.mmu.print_state |
user_mmu_event_extension |
(empty) |
Same, for MMU events generally |
servo_down_limit |
5000 |
Maintenance-warning limit for a servo-down-cycle counter - -1 disables |
cutter_blade_limit |
3000 |
Same, for a cutter-blade-use counter |
Sequence/parking (_MMU_SEQUENCE_VARS)
Controls toolhead parking, z-hop, retraction, and the callback macros
around every load/unload - see Custom Load/Unload
Sequences for how these fit into the
bigger picture; this table is the full list that page deferred.
| Variable |
Default |
Description |
enable_park_printing |
toolchange,runout,load,unload,complete,pause,cancel |
Operations that park the toolhead while printing - empty string disables parking entirely |
enable_park_standalone |
toolchange,load,unload,pause,cancel |
Same, when not printing |
enable_park_disabled |
pause,cancel |
Same, while the MMU itself is disabled (MMU ENABLE=0) - only pause/cancel can actually occur in this mode |
min_toolchange_z |
1.0 mm |
Absolute minimum safety floor Z-height for every parking move |
park_toolchange |
-999, -999, 1, 5, 2 |
x, y, z-hop, z_hop_ramp, retract for toolchange/load/unload operations |
park_runout |
-999, -999, 1, 5, 2 |
Same, for a runout-forced toolchange |
park_pause |
50, 50, 5, 0, 2 |
Same, for a pause (also where the toolhead goes on an MMU error) |
park_cancel |
-999, -999, 10, 0, 5 |
Same, for CANCEL_PRINT |
park_complete |
50, 50, 10, 0, 5 |
Same, when the print completes |
pre_unload_position |
-999, -999, 0 |
Extra x, y, z-hop parking move just before unload starts |
post_form_tip_position |
-999, -999, 0 |
Same, right after tip forming/cutting on unload |
pre_load_position |
-999, -999, 0 |
Same, just before load starts |
restore_xy_pos |
last |
Where the toolhead returns to after a toolchange: last (original position), next (the next print position, toolchange only), or none |
park_travel_speed |
200 mm/s |
Speed for XY(Z) travel moves |
park_lift_speed |
15 mm/s |
Speed for Z-only travel |
retract_speed |
30 mm/s |
Speed of the retract move |
unretract_speed |
30 mm/s |
Speed of the unretract move |
user_park_move_macro |
(empty) |
Macro called instead of a plain G1 X Y move to park - receives X=/Y=/F=, and RESTORE=1 plus the restore coordinates when un-parking |
auto_home |
True |
Automatically home XYZ if needed before parking |
timelapse |
False |
Take a timelapse frame after a load |
user_mmu_error_extension |
(empty) |
Run after default logic when an MMU error occurs |
user_pre_unload_extension |
(empty) |
Run after default logic, before an unload starts |
user_post_form_tip_extension |
(empty) |
Run immediately after tip forming/cutting |
user_post_unload_extension |
(empty) |
Run after an unload completes |
user_pre_load_extension |
(empty) |
Run before a load starts |
user_post_load_extension |
(empty) |
Run after a load completes, before toolhead position is restored |
user_post_preload_extension |
(empty) |
Run after a successful gate preload |
Client macros (_MMU_CLIENT_VARS)
Only relevant if using the shipped PAUSE/RESUME/CANCEL_PRINT client
macros - most other tuning for these actually lives in
_MMU_SEQUENCE_VARS above, these three are supplemental.
| Variable |
Default |
Description |
reset_ttg_on_cancel |
False |
Reset the TTG map if the print is cancelled |
unload_tool_on_cancel |
False |
Unload the current tool on cancel |
user_pause_extension |
(empty) |
Run after Klipper's base pause |
user_resume_extension |
(empty) |
Run before Klipper's base resume |
user_cancel_extension |
(empty) |
Run before Klipper's base cancel_print |
Only present with a toolhead-mounted cutter enabled
(MMU_HAS_TOOLHEAD_CUTTER). Tunes _MMU_CUT_TIP - see Feature: Tip
Forming and Purging for the concept and
the mechanical routine; this is every knob involved.
| Variable |
Default |
Description |
restore_position |
False |
Return the toolhead to its position before the cut - leave off if using the parking logic above instead |
blade_pos |
37.5 mm |
Distance from the internal nozzle tip to the cutting blade - a toolhead dimension, not a tuning value |
retract_length |
32.5 mm |
Retract distance before the cut, measured from the nozzle tip - must be less than blade_pos; ~5mm less is a good starting point |
simple_tip_forming |
True |
Do a simple tip-forming move after the initial retraction, for extra cooling time |
cut_axis_steppers |
stepper_x, stepper_y |
Steppers to boost current on during the cut |
cut_stepper_current |
100% |
Current for those steppers during cutting - 100 disables the boost |
cutting_axis |
x |
Axis the cut motion happens on - x or y |
pin_loc_xy |
14, 250 |
X,Y of the depressor pin - where the cutter arm just touches it |
pin_park_dist |
5.0 mm |
Distance added to (or subtracted from) pin_loc_xy along cutting_axis, for a safe starting position with room to build momentum |
pin_loc_compressed_xy |
0.5, 250 |
X,Y when the cutter is fully compressed |
rip_length |
1.0 mm |
Retract distance after the cut, to free the blade before returning |
rip_speed |
3 mm/s |
Speed of that retract |
pushback_length |
15.0 mm |
How far the cut fragment is pushed back into the hotend, so it can't cause a future clog - can't exceed retract_length minus toolhead_ooze_reduction |
pushback_dwell_time |
0 ms |
Dwell time after the pushback |
travel_speed |
150 mm/s |
General travel speed for the cut sequence |
cut_fast_move_speed |
32 mm/s |
Fast approach speed, to build momentum before contact |
cut_slow_move_speed |
8 mm/s |
Slow speed for the actual cutting motion |
cut_fast_move_fraction |
1.0 |
Fraction of the move that runs at the fast speed |
evacuate_speed |
150 mm/s |
Speed moving away after the cut |
cut_dwell_time |
50 ms |
Dwell time at the cut point |
extruder_move_speed |
25 mm/s |
Speed for every extruder movement in the sequence |
cut_iterations |
1 |
Number of cuts to attempt - raise if your cutter struggles with a filament |
safe_margin_xy |
30, 30 |
Safety margin used when approaching the pin - roughly your toolhead's own width/height plus a little |
gantry_servo_enabled |
False |
Enable a gantry-mounted bumper servo, if fitted |
gantry_servo_down_angle |
55° |
Servo angle with the pin deployed |
gantry_servo_up_angle |
180° |
Servo angle with the pin retracted |
Tunes _MMU_FORM_TIP - see Feature: Tip Forming and
Purging for the
step-by-step tuning workflow; this is every variable involved, grouped by
that same step order.
| Variable |
Default |
Description |
ramming_volume |
0 mm³ |
Ramming volume during a print - 0 disables (e.g. to let the slicer ram instead) |
ramming_volume_standalone |
0 mm³ |
Same, outside a print |
toolchange_temp |
0°C |
Temperature to set during tip forming - 0 = don't change it |
toolchange_fan_assist |
False |
Use the part-cooling fan to speed up that temperature change |
toolchange_fan_name |
(empty) |
Fan name if not the default [fan], e.g. fan_generic fan0 |
toolchange_fan_speed |
50% |
Fan speed when fan assist is on |
unloading_speed_start |
80 mm/s |
Initial fast separation speed away from the melt zone |
unloading_speed |
18 mm/s |
Slower speed for the remaining move to the cooling zone |
cooling_tube_position |
35 mm |
Distance from the nozzle tip to the start of the cooling tube - hotend-specific, see Macro: Tip Forming for reference values |
cooling_tube_length |
10 mm |
Length of the cooling-move travel - also hotend-specific, see the same reference values |
initial_cooling_speed |
10 mm/s |
Initial slow cooling-move speed |
final_cooling_speed |
50 mm/s |
Final fast cooling-move speed - too fast deforms the tip on eject, too slow leaves a long string |
cooling_moves |
4 |
Number of back-and-forth cooling moves |
use_skinnydip |
False |
Enable the final skinnydip move (an advanced pass that can help burn off fine hairs on some materials) |
skinnydip_distance |
30 mm |
Reinsertion distance into the hotend for the skinnydip move |
dip_insertion_speed |
30 mm/s |
Skinnydip insertion speed |
dip_extraction_speed |
70 mm/s |
Skinnydip extraction speed - faster than insertion, to avoid forming new hairs |
melt_zone_pause |
0 ms |
Pause while in the melt zone |
cooling_zone_pause |
0 ms |
Pause after extraction, in the cooling zone |
use_fast_skinnydip |
False |
Skip the toolhead temperature-change wait during skinnydip |
parking_distance |
0 mm |
Where to park filament at the end of tip forming - 0 leaves it wherever it ends up |
extruder_eject_speed |
25 mm/s |
Speed used for that parking move (and final eject during testing) |
Servo cutter, MMU-mounted (_MMU_SERVO_CUTTER_VARS)
Only present with the MMU-mounted servo cutter enabled
(MMU_HAS_SERVO_CUTTER) - the EREC-style design. Tunes mmu_servo_cutter.cfg -
see Feature: Tip Forming and Purging
for the concept.
| Variable |
Default |
Description |
servo_closed_angle |
70° |
Angle with the bowden aligned to the MMU (closed) |
servo_open_angle |
10° |
Angle that opens the cutter and moves the bowden clear |
servo_duration |
1.5 s |
Duration of the PWM pulse train that activates the servo |
servo_idle_time |
1.8 s |
Time allowed for the servo to actually reach position |
feed_length |
48 mm |
Distance from the gate parking position to the blade - 58 for ERCF v1.1, 48 for ERCF v2/most others |
cut_length |
10 mm |
Amount of filament cut |
cut_attempts |
1 |
Attempts before reporting a cut failure |
Blobifier (_BLOBIFIER_VARS)
Only present with Blobifier enabled (MMU_HAS_BLOBIFIER) - see Macro:
Blobifier for what it is and the physical build. This
is genuinely Blobifier's own large,
third-party-maintained tuning surface, reproduced here in full rather than
left to its upstream README alone.
Hooks & extensions
| Variable |
Default |
Description |
user_pre_blobifier_extension |
(empty) |
Run at the very start, after state is saved - e.g. to park on a gantry-mounted nozzle leak stop |
clean_macro |
BLOBIFIER_CLEAN |
Macro that handles nozzle cleaning after purging but before lifting Z - the stock macro assumes a bed-mounted brush; clear this for a gantry-mounted one |
user_post_purge_extension |
(empty) |
Run after purging and cleaning, before Z is restored - e.g. to park on a gantry-mounted leak stop |
user_post_blobifier_extension |
(empty) |
Run after Z is restored - e.g. gantry-mounted brush cleaning |
Hardware & general
| Variable |
Default |
Description |
blobifier_type |
servo |
Tray actuator type: servo or stepper (manual_stepper) - set via menuconfig, not hand-edited |
firmware |
klipper |
klipper or kalico - Kalico uses integer STOP_ON_ENDSTOP values where mainline Klipper uses strings; only matters for a stepper tray |
toolhead_x |
(calibrate) |
Distance from the nozzle to the left edge of the toolhead - must calibrate |
toolhead_y |
(calibrate) |
Distance from the nozzle to the front edge of the toolhead - must calibrate |
travel_spd_xy |
10000 mm/min |
XY travel speed |
travel_spd_z |
1000 mm/min |
Z travel speed |
skew_correction |
0.1 |
Small XY nudge if skew correction causes an out-of-range error during Blobifier's own moves - adjust in 0.1-0.5mm steps only |
y_offset |
0 |
Offset subtracted from max Y during purging - calibrate by checking the toolhead is centred over the tray at max Y |
force_safe_descend_height_until |
1.0 |
Forces a "safe descend" (rather than skipping a downward move that might hit a print) below this height - useful at print start when no height estimate exists yet |
Tray positions
| Variable |
Default |
Description |
purge_x |
10 |
X location to purge at - roughly half way along the 15mm tray if mounted against the bed edge |
tray_top |
0.7 |
Z height of the tray top - must calibrate, the shipped default likely won't apply to your build |
tray_angle_out / tray_angle_in |
0° / 180° |
Servo tray: extended / retracted angle |
dwell_time |
200 ms |
Servo tray: time allowed to fully extend/retract |
tray_pos_out / tray_pos_in |
21 / 0 mm |
Stepper tray: extended / retracted position |
tray_stepper_speed |
110 mm/s |
Stepper tray movement speed |
Brush / nozzle cleaning
| Variable |
Default |
Description |
brush_start |
67 |
Start X of a bed-mounted brush - indicative defaults 34/67/84 for 250/300/350mm builds; for a gantry-mounted brush, set to your nozzle-stop position instead |
brush_width |
35 mm |
Brush width along X |
brush_top |
6 |
Z position of the brush top - start high and lower carefully; None for a gantry-mounted brush needing no Z move |
clearance_z |
2 mm |
Z clearance above the brush while travelling |
wipe_qty |
2 |
Number of full wipe passes |
wipe_spd_xy |
10000 mm/min |
Wipe speed |
brush_y_offset |
0 |
Offset subtracted from max Y for brushing |
brush_accel |
0 |
Acceleration while wiping - 0 uses the current printer acceleration |
Purge length tuning
| Variable |
Default |
Description |
purge_length_minimum |
30 mm |
Absolute minimum purged, even with no color change - primes the nozzle; roughly 2x your melt-zone length |
purge_length_maximum |
150 mm |
Maximum filament per single blob - Blobifier splits into multiple blobs above this |
purge_length |
150 mm |
Fallback purge length, if neither the tool map's purge volumes nor an explicit PURGE_LENGTH are set |
purge_length_modifier |
1.0 |
Multiplies the slicer-emitted purge value - prefer adjusting the slicer's own purge multiplier instead |
purge_length_addition |
0 mm |
Fixed length added on top of the calculated purge - leave at 0 and tune the slicer's purge volume/nozzle volume instead if possible |
include_extruder_residual |
0 |
Add extruder_filament_remaining to the purge length calculation - set 0 if your slicer's own purge matrix already accounts for nozzle residual |
Blob tuning
| Variable |
Default |
Description |
purge_spd |
400 mm/min |
Purge speed |
purge_temp_min |
200°C |
Minimum nozzle temperature to purge at |
purge_start |
0.2 |
Height to raise the nozzle above the tray before purging, letting built-up pressure escape |
z_raise |
12 |
Z raise amount per blob iteration |
z_raise_exp |
0.85 |
Exponent controlling how quickly the Z raise shrinks as the blob widens - 1 is linear, keep at or below 1 |
eject_hop |
6.0 |
Small lift after a blob, to release pressure on the tray |
pressure_release_time |
1000 ms |
Dwell after purging, before cleaning, to relieve nozzle pressure |
purge_pulse_size |
10 mm |
Filament extruded per pulse within a blob - close to half the melt-zone volume is the intent |
Retraction tuning
| Variable |
Default |
Description |
retract_between_blobs |
6 mm |
Retract distance between blobs - must stay under your hotend's heatbreak length |
retract_step |
2 mm |
Step size each retract/de-retract move is split into, so sync-feedback can keep up - leave at 2 unless you have a specific reason not to |
pulse_retract_length |
4 mm |
Length of a periodic mid-purge retract, to improve color transition - don't exceed 5-10mm |
pulse_retract_speed |
2400 mm/min |
Speed of that periodic retract |
pulse_deretract_speed |
800 mm/min |
Speed of the matching de-retract - slower, to let filament re-melt |
purge_retract_interval |
20 mm |
How often (by extrusion distance) the periodic retract fires - should be ≥ your melt-zone length |
Fan control
| Variable |
Default |
Description |
part_cooling_fan |
0.3 |
Part-cooling fan speed during purging - -1 leaves it unchanged, 0 off, 0.1-1.0 a fixed speed |
part_cooling_fan_blob_deposit |
1 |
Same, during the blob-deposit moment - full speed helps the blob freeze and release cleanly |
fan_name |
(empty) |
Fan name if not the default [fan], e.g. fan_generic fan0 |
Bucket
| Variable |
Default |
Description |
max_blobs |
400 |
Blobs the bucket holds before the print pauses |
enable_shaker |
1 (enabled) |
Whether a bucket shaker is fitted (needs the shaker STL installed) |
shaker_pos_x |
0 |
Shaker X offset |
bucket_shakes |
10 |
Back-and-forth motions per shake |
shake_accel |
10000 |
Acceleration during shaking - can run higher than print acceleration since quality doesn't matter here |
bucket_shake_frequency |
0.95 |
How often a completed blob triggers a shake, 0-1 - 0.75-0.95 is sensible |
shaker_arm_z |
2 |
Shaker arm height - raise if the hotend hits the tray while shaking |
Reference purge (_MMU_PURGE_VARS)
Tunes the simple built-in _MMU_PURGE macro - a basic reference purge you
can use as-is or as a starting point for your own; Blobifier is the more
capable alternative.
| Variable |
Default |
Description |
extruder_purge_speed |
2 mm/s |
Purge speed - as fast as possible without the extruder skipping steps (extruder current can also be raised in extruder_purge_current) |
Fan control (_MMU_FAN_VARS)
Only present with both fans and an environment sensor enabled
(MMU_HAS_FANS and MMU_HAS_ENVIRONMENT_SENSOR) - temperature-driven fan
automation for the MMU enclosure, distinct from the toolhead's own part
fan. See Feature: Fan Control for hardware
setup, commands, and troubleshooting.
| Variable |
Default |
Description |
fan_on_temp |
49.0°C |
Temperature threshold to turn fans on |
fan_off_temp |
47.0°C |
Temperature threshold to turn fans off |
fan_polling_time |
5.0 s |
Interval between temperature checks |
fan_control_enabled |
True |
Master on/off for the automatic temperature-based control |
fan_forced |
2 (AUTO) |
Force override: 0=all off, 1=all on, 2=automatic |
fan_sensors |
(see below) |
Comma-separated temperature_sensor names this control reads |
fans |
(see below) |
Comma-separated fan_generic names this control drives |
fan_sensors/fans are documented as auto-generated from your fan/sensor
pins, but confirmed (by rendering the real config template directly) not
to reliably work: fan_sensors picks up the single-sensor case correctly,
fans does not, and neither populates in the per-gate case. Check both
by hand - see Feature: Fan Control
for what to set them to.
See also