########################################################################################################################
# Happy Hare MMU Software
#
# EDIT THIS FILE BASED ON YOUR SETUP
#
# Copyright (C) 2022-2025  moggieuk#6538 (discord)
#                          moggieuk@hotmail.com
# This file may be distributed under the terms of the GNU GPLv3 license.
#
# Goal: Happy Hare MMU hardware config file with config for MMB11 MCU board
#
# (\_/)
# ( *,*)
# (")_(") Happy Hare Ready
#
#
# Notes about setup of common external MCUs can be found here:
#  https://github.com/moggieuk/Happy-Hare/blob/main/doc/mcu_notes.md
# 
# Note about "touch" endstops: Happy Hare provides extremely flexible homing options using both single steppers or
# synced steppers. The "touch" option leverages stallguard and thus requires the appropriate 'diag_pin' and stallguard
# parameters set on the TMC driver section. If you have the diag_pin exposed, it is harmless to define this because
# they will only be used when explicitly needed and configured.
#
# Touch option for each stepper provides these benefits / possibilities (experimental):
#  - on extruder stepper allows for the automatic detection of the nozzle!
#  - on selector stepper allows for the automatic detection of filament stuck in the gate and subsequent recovery
#  - on gear stepper allows for the automatic detection of the extruder entrance
#
# These sound wonderful right?  They are, but there are caveats:
#  - Some external MCUs are terrible at detecting stallguard and often result in an "undervoltage error"
#    It is generally possible to get selector touch (TMC2209) tuned especially if you set 'stealthchop_threshold'
#    to a value greater than homing speeds and less than move speed. I.e. the stepper runs in stealthchop mode when
#    homing. [klipper experts will know that it switches the chip mode automatically to stealthchop and then back for
#    Stallguard2 support, however the automatic switching back to spreadcycle at the end homing move seems to provoke
#    the error condition and setting 'stealthchop_threshold' appropriately avoids this condition. More than you wanted
#    to know I'm sure!
#  - I have not had much luck with touch (stallguard) on the gear stepper with EASY-BRD and ERB MCUs and you really
#    want the extra torque of spreadcycle so adjusting 'stealthchop_threshold' is not really an option
#  - Enabling on the extruder stepper is viable but you will likely have to change jumpers on your main mcu to expose
#    the DIAG pin for whichever driver the extruder stepper is connected to.
#
# In summary, "touch" homing with your MMU is an advanced option that requires patience and careful tuning. Everything
# works with regular endstops and there are workaround options for certain homing points (like extruder entry) in
# the absence of any endstop. I'm really interested in creative setups. Ping me on Discord (moggieuk#6538)
#
# See 'mmu.cfg' for serial definition and pins aliases
#
# HOMING CAPABLE EXTRUDER (VERY ADVANCED) -----------------------------------------------------------------------------
# With Happy Hare installed even the extruder can be homed. You will find the usual 'endstop' parameters can be added
# to your '[extruder]' section.  Useless you have some clever load cell attached to your nozzle it only really makes
# sense to configure stallguard style "touch" homing. To do this add lines similar to this to your existing
# '[extruder]' definition in printer.cfg.
#
#    [extruder]
#    endstop_pin: tmc2209_extruder:virtual_endstop
#
# Also be sure to add the appropriate stallguard config to the TMC section, e.g.
#
#    [tmc2209 extruder]
#    diag_pin: E_DIAG		# Set to MCU pin connected to TMC DIAG pin for extruder
#    driver_SGTHRS: 100		# 255 is most sensitive value, 0 is least sensitive
#
# Happy Hare will take care of the rest and add a 'mmu_ext_touch' endstop automatically
#


# MMU MACHINE / TYPE ---------------------------------------------------------------------------------------------------
# ███╗   ███╗███╗   ███╗██╗   ██╗    ███╗   ███╗ █████╗  ██████╗██╗  ██╗██╗███╗   ██╗███████╗
# ████╗ ████║████╗ ████║██║   ██║    ████╗ ████║██╔══██╗██╔════╝██║  ██║██║████╗  ██║██╔════╝
# ██╔████╔██║██╔████╔██║██║   ██║    ██╔████╔██║███████║██║     ███████║██║██╔██╗ ██║█████╗  
# ██║╚██╔╝██║██║╚██╔╝██║██║   ██║    ██║╚██╔╝██║██╔══██║██║     ██╔══██║██║██║╚██╗██║██╔══╝  
# ██║ ╚═╝ ██║██║ ╚═╝ ██║╚██████╔╝    ██║ ╚═╝ ██║██║  ██║╚██████╗██║  ██║██║██║ ╚████║███████╗
# ╚═╝     ╚═╝╚═╝     ╚═╝ ╚═════╝     ╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝╚══════╝
[mmu_machine]

# Number of selectable gate on (each) MMU. Generally this is a single number, but with multi-mmu (type-B) setups
# it can be a comma separated list of the number of gates per unit.
# E.g. 'num_gates: 4,4,2' for a 2xBox Turtle and 1xNight Owl multiplexed setup
#
num_gates: 8

# MMU Vendor & Version is used to automatically configure some parameters and validate configuration
# If custom set to "Other" and uncomment the additional parameters below
#
# ERCF          1.1  add "s" suffix for Springy, "b" for Binky, "t" for Triple-Decky
#                    e.g. "1.1sb" for v1.1 with Springy mod and Binky encoder
# ERCF          2.0  community edition ERCFv2
# Tradrack      1.0  add "e" if encoder is fitted (assumed to be Binky)
# AngryBeaver   1.0
# BoxTurtle     1.0
# NightOwl      1.0
# 3MS           1.0
# 3D Chameleon  1.0
# Prusa         3.0  NOT YET SUPPORTED - COMING SOON
# Other              Generic setup that may require further customization of 'cad' parameters. See doc in mmu_parameters.cfg
#
mmu_vendor: ERCF			# MMU family
mmu_version: 2.0			# MMU hardware version number (add mod suffix documented above)

# The following attributes are set internally from vendor/version above. Only uncomment to customize the vendor
# default or for custom ("Other") designs
#
#selector_type: LinearSelector		# E.g. LinearSelector (type-A), VirtualSelector (type-B), MacroSelector, RotarySelector, ...
#variable_bowden_lengths: 0		# 1 = If MMU design has different bowden lengths per gate, 0 = bowden length is the same
#variable_rotation_distances: 1		# 1 = If MMU design has dissimilar drive/BMG gears, thus rotation distance, 0 = One drive gear (e.g. Tradrack)
#require_bowden_move: 1			# 1 = If MMU design has bowden move that is included in load/unload, 0 = zero length bowden (skip bowden move)
#filament_always_gripped: 0		# 1 = Filament is always trapped by MMU (most type-B designs), 0 = MMU can release filament
#has_bypass: 0				# 1 = Bypass gate available, 0 = No filament bypass possible

# Uncomment to change the display name in UI's.  Defaults to the vendor name
#display_name: My Precious

homing_extruder: 1			# CAUTION: Normally this should be 1. 0 will disable the homing extruder capability


# FILAMENT DRIVE GEAR STEPPER(S)  --------------------------------------------------------------------------------------
#  ██████╗ ███████╗ █████╗ ██████╗ 
# ██╔════╝ ██╔════╝██╔══██╗██╔══██╗
# ██║  ███╗█████╗  ███████║██████╔╝
# ██║   ██║██╔══╝  ██╔══██║██╔══██╗
# ╚██████╔╝███████╗██║  ██║██║  ██║
#  ╚═════╝ ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝
# Note that 'toolhead' & 'mmu_gear' endstops will automatically be added if a toolhead sensor or gate sensor is defined
#
# The default values are tested with the ERCF BOM NEMA14 motor. Please adapt these values to the motor you are using
# Example : for NEMA17 motors, you'll usually use higher current
#
[tmc2209 stepper_mmu_gear]
uart_pin: mmu:MMU_GEAR_UART
run_current: 1.1			# ERCF v2.5 BOM NEMA17 motor
hold_current: 0.1			# Recommend to be small if not using "touch" or move (TMC stallguard)
interpolate: True
sense_resistor: 0.110			# Usually 0.11, 0.15 for BTT TMC2226
stealthchop_threshold: 0		# Spreadcycle has more torque and better at speed
#
# Uncomment two lines below if you have TMC and want the ability to use filament "touch" homing with gear stepper
#diag_pin: ^mmu:MMU_GEAR_DIAG		# Set to MCU pin connected to TMC DIAG pin for gear stepper
#driver_SGTHRS: 60			# 255 is most sensitive value, 0 is least sensitive

[stepper_mmu_gear]
step_pin: mmu:MMU_GEAR_STEP
dir_pin: mmu:MMU_GEAR_DIR
enable_pin: !mmu:MMU_GEAR_ENABLE
rotation_distance: 22.7316868		# Bondtech 5mm Drive Gears. Overridden by 'mmu_gear_rotation_distance' in mmu_vars.cfg
#gear_ratio: 80:20			# ERCF v2.5 is direct drive
microsteps: 16 				# Recommend 16. Increase only if you "step compress" issues when syncing
full_steps_per_rotation: 200		# 200 for 1.8 degree, 400 for 0.9 degree
#
# Uncomment the two lines below to enable filament "touch" homing option with gear motor
#extra_endstop_pins: tmc2209_stepper_mmu_gear:virtual_endstop
#extra_endstop_names: mmu_gear_touch



# SELECTOR STEPPER  ----------------------------------------------------------------------------------------------------
# ███████╗███████╗██╗     ███████╗ ██████╗████████╗ ██████╗ ██████╗ 
# ██╔════╝██╔════╝██║     ██╔════╝██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗
# ███████╗█████╗  ██║     █████╗  ██║        ██║   ██║   ██║██████╔╝
# ╚════██║██╔══╝  ██║     ██╔══╝  ██║        ██║   ██║   ██║██╔══██╗
# ███████║███████╗███████╗███████╗╚██████╗   ██║   ╚██████╔╝██║  ██║
# ╚══════╝╚══════╝╚══════╝╚══════╝ ╚═════╝   ╚═╝    ╚═════╝ ╚═╝  ╚═╝
# Consult doc if you want to setup selector for "touch" homing instead or physical endstop
#
[tmc2209 stepper_mmu_selector]
uart_pin: mmu:MMU_SEL_UART
run_current: 0.6			# ERCF BOM NEMA17 motor
hold_current: 0.4			# Can be small if not using "touch" movement (TMC stallguard)
interpolate: True
sense_resistor: 0.110
stealthchop_threshold: 100		# Stallguard "touch" movement (slower speeds) best done with stealthchop
#
# Uncomment two lines below if you have TMC and want to use selector "touch" movement
#diag_pin: ^mmu:MMU_SEL_DIAG 		# Set to MCU pin connected to TMC DIAG pin for selector stepper
#driver_SGTHRS: 75			# 255 is most sensitive value, 0 is least sensitive

[stepper_mmu_selector]
step_pin: mmu:MMU_SEL_STEP
dir_pin: mmu:MMU_SEL_DIR
enable_pin: !mmu:MMU_SEL_ENABLE
rotation_distance: 40
microsteps: 16 				# Don't need high fidelity
full_steps_per_rotation: 200		# 200 for 1.8 degree, 400 for 0.9 degree
endstop_pin: ^mmu:MMU_SEL_ENDSTOP	# Selector microswitch
endstop_name: mmu_sel_home
# Uncomment this line only if default endstop above is using stallguard
#homing_retract_dist: 0
#
# Uncomment two lines below to give option of selector "touch" movement
#extra_endstop_pins: tmc2209_stepper_mmu_selector:virtual_endstop
#extra_endstop_names: mmu_sel_touch


# SERVOS ---------------------------------------------------------------------------------------------------------------
# ███████╗███████╗██████╗ ██╗   ██╗ ██████╗ ███████╗
# ██╔════╝██╔════╝██╔══██╗██║   ██║██╔═══██╗██╔════╝
# ███████╗█████╗  ██████╔╝██║   ██║██║   ██║███████╗
# ╚════██║██╔══╝  ██╔══██╗╚██╗ ██╔╝██║   ██║╚════██║
# ███████║███████╗██║  ██║ ╚████╔╝ ╚██████╔╝███████║
# ╚══════╝╚══════╝╚═╝  ╚═╝  ╚═══╝   ╚═════╝ ╚══════╝
# Basic servo PWM setup. If these values are changed then the angles defined for different positions will also change
#
# SELECTOR SERVO -------------------------------------------------------------------------------------------------------
#
[mmu_servo selector_servo]
pin: mmu:MMU_SEL_SERVO
maximum_servo_angle: 180
minimum_pulse_width: 0.00085
maximum_pulse_width: 0.00215
#
# OPTIONAL GANTRY SERVO FOR TOOLHEAD FILAMENT CUTTER ------------------------------------------------------------------
#
# (uncomment this section if you have a gantry servo for toolhead cutter pin)
#[mmu_servo mmu_gantry_servo]
#pin: 
#maximum_servo_angle:180
#minimum_pulse_width: 0.00075
#maximum_pulse_width: 0.00225
#initial_angle: 180


# FILAMENT SENSORS -----------------------------------------------------------------------------------------------------
# ███████╗███████╗███╗   ██╗███████╗ ██████╗ ██████╗ ███████╗
# ██╔════╝██╔════╝████╗  ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝
# ███████╗█████╗  ██╔██╗ ██║███████╗██║   ██║██████╔╝███████╗
# ╚════██║██╔══╝  ██║╚██╗██║╚════██║██║   ██║██╔══██╗╚════██║
# ███████║███████╗██║ ╚████║███████║╚██████╔╝██║  ██║███████║
# ╚══════╝╚══════╝╚═╝  ╚═══╝╚══════╝ ╚═════╝ ╚═╝  ╚═╝╚══════╝
# Define the pins for optional sensors in the filament path. All but the pre-gate sensors will be automatically setup as
# both endstops (for homing) and sensors for visibility purposes.
#
# 'pre_gate_switch_pin_X'  .. 'mmu_pre_gate_X' sensor detects filament at entry to MMU. X=gate number (0..N)
# 'gate_switch_pin'        .. 'mmu_gate' shared sensor detects filament past the gate of the MMU
#     or
# 'post_gear_switch_pin_X' .. 'mmu_gear_X' post gear sensor for each filament
# 'extruder_switch_pin'    .. 'extruder' sensor detects filament just before the extruder entry
# 'toolhead_switch_pin'    .. 'toolhead' sensor detects filament after extruder entry
#
# Sync motor feedback will typically have a tension switch (most important for syncing) or both tension and compression.
# Note that compression switch is useful for use as a endstop to detect hitting the extruder entrance
# 'sync_feedback_tension_pin'     .. pin for switch activated when filament is under tension
# 'sync_feedback_compression_pin' .. pin for switch activated when filament is under compression
#
# Configuration is flexible: Simply define pins for any sensor you want to enable, if pin is not set (or the alias is empty)
# it will be ignored. You can also just comment out what you are not using.
#
[mmu_sensors]
pre_gate_switch_pin_0: ^mmu:MMU_PRE_GATE_0
pre_gate_switch_pin_1: ^mmu:MMU_PRE_GATE_1
pre_gate_switch_pin_2: ^mmu:MMU_PRE_GATE_2
pre_gate_switch_pin_3: ^mmu:MMU_PRE_GATE_3
pre_gate_switch_pin_4: ^mmu:MMU_PRE_GATE_4
pre_gate_switch_pin_5: ^mmu:MMU_PRE_GATE_5
pre_gate_switch_pin_6: ^mmu:MMU_PRE_GATE_6
pre_gate_switch_pin_7: ^mmu:MMU_PRE_GATE_7
pre_gate_switch_pin_8: ^mmu:MMU_PRE_GATE_8
pre_gate_switch_pin_9: ^mmu:MMU_PRE_GATE_9
pre_gate_switch_pin_10: ^mmu:MMU_PRE_GATE_10
pre_gate_switch_pin_11: ^mmu:MMU_PRE_GATE_11

post_gear_switch_pin_0: ^mmu:MMU_POST_GEAR_0
post_gear_switch_pin_1: ^mmu:MMU_POST_GEAR_1
post_gear_switch_pin_2: ^mmu:MMU_POST_GEAR_2
post_gear_switch_pin_3: ^mmu:MMU_POST_GEAR_3
post_gear_switch_pin_4: ^mmu:MMU_POST_GEAR_4
post_gear_switch_pin_5: ^mmu:MMU_POST_GEAR_5
post_gear_switch_pin_6: ^mmu:MMU_POST_GEAR_6
post_gear_switch_pin_7: ^mmu:MMU_POST_GEAR_7
post_gear_switch_pin_8: ^mmu:MMU_POST_GEAR_8
post_gear_switch_pin_9: ^mmu:MMU_POST_GEAR_9
post_gear_switch_pin_10: ^mmu:MMU_POST_GEAR_10
post_gear_switch_pin_11: ^mmu:MMU_POST_GEAR_11

# These sensors can be replicated in a multi-mmu, type-B setup (see num_gates comment).
# If so, then use a comma separated list of per-unit pins instead of single pin
gate_switch_pin: ^mmu:MMU_GATE_SENSOR
sync_feedback_tension_pin: 
sync_feedback_compression_pin: 

# These sensors are on the toolhead and often controlled by the main printer mcu
extruder_switch_pin: ^ebb36: PB6 
toolhead_switch_pin: ^ebb36: PB5


# ENCODER -------------------------------------------------------------------------------------------------------------
# ███████╗███╗   ██╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ 
# ██╔════╝████╗  ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗
# █████╗  ██╔██╗ ██║██║     ██║   ██║██║  ██║█████╗  ██████╔╝
# ██╔══╝  ██║╚██╗██║██║     ██║   ██║██║  ██║██╔══╝  ██╔══██╗
# ███████╗██║ ╚████║╚██████╗╚██████╔╝██████╔╝███████╗██║  ██║
# ╚══════╝╚═╝  ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝  ╚═╝
# Encoder measures distance, monitors for runout and clogging and constantly calculates % flow rate
# Note that the encoder_resolution set here is purely a default to get started. It will be correcly set after calibration
# with the value stored in mmu_vars.cfg
#
# The encoder resolution will be calibrated but it needs a default approximation 
# If BMG gear based:
#   resolution = bmg_circumfrance / (2 * teeth)
# 24 / (2 * 17) = 0.7059 for TRCT5000 based sensor
# 24 / (2 * 12) = 1.0 for Binky with 12 tooth disc
#
[mmu_encoder mmu_encoder]
encoder_pin: ^mmu:MMU_ENCODER
encoder_resolution: 1.0			# This is just a starter value. Overriden by calibrated 'mmu_encoder_resolution' in mmm_vars.cfg
desired_headroom: 5.0			# The clog/runout headroom that MMU attempts to maintain (closest point to triggering runout)
average_samples: 4			# The "damping" effect of last measurement (higher value means slower automatic clog_length reduction)
flowrate_samples: 20			# How many "movements" of the extruder to measure average flowrate over


# MMU OPTIONAL NEOPIXEL LED SUPPORT ------------------------------------------------------------------------------------
# ██╗     ███████╗██████╗ ███████╗
# ██║     ██╔════╝██╔══██╗██╔════╝
# ██║     █████╗  ██║  ██║███████╗
# ██║     ██╔══╝  ██║  ██║╚════██║
# ███████╗███████╗██████╔╝███████║
# ╚══════╝╚══════╝╚═════╝ ╚══════╝
# Define the led connection, type and length
#
# (comment out this section if you don't have leds or have them defined elsewhere)
[neopixel mmu_leds]
pin: mmu:MMU_NEOPIXEL
chain_count: 9			# Need number gates x1 or x2 + status leds
color_order: GRBW		# Set based on your particular neopixel specification (can be comma separated list)

# MMU LED EFFECT SEGMENTS ----------------------------------------------------------------------------------------------
# Define neopixel LEDs for your MMU. The chain_count must be large enough for your desired ranges:
#   exit   .. this set of LEDs, one for every gate, usually would be mounted at the exit point of the gate
#   entry  .. this set of LEDs, one for every gate, could be mounted at the entry point of filament into the MMU/buffer
#   status .. these LED. represents the status of the MMU (and selected filament). More than one status LED is possible
#   logo   .. these LEDs don't change during operation and are designed for driving a logo. More than one logo LED is possible
#
# Note that all sets are optional. You can opt to just have the 'exit' set for example. The advantage to having
# both entry and exit LEDs is, for example, so that 'entry' can display gate status while 'exit' displays the color
# 
# The animation effects requires the installation of Julian Schill's awesome LED effect module otherwise the LEDs
# will be static:
#   https://github.com/julianschill/klipper-led_effect
#
# LED's are indexed in the chain from 1..N. Thus to set up LED's on 'exit' and a single 'status' LED on a 4 gate MMU:
#
#    exit_leds:   neopixel:mmu_leds (1,2,3,4)
#    status_leds: neopixel:mmu_leds (5)
#
# In this example no 'entry' set is configured. Note that constructs like "mmu_leds (1-3,4)" are also valid
#
# The range is completely flexible and can be comprised of different led strips, individual LEDs, or combinations of
# both on different pins. In addition, the ordering is flexible based on your wiring, thus (1-4) and (4-1) both represent
# the same LED range but mapped to increasing or decreasing gates respectively. E.g if you have two Box Turtle MMUs, one
# with a chain of LEDs wired in reverse order and another with individual LEDs, to define 8 exit LEDs:
#
#   exit_leds: neopixel:bt_1 (4-1)
#              neopixel:bt_2a
#              neopixel:bt_2b
#              neopixel:bt_2c
#              neopixel:bt_2d
#
# Note the use of separate lines for each part of the definition,
#
# ADVANCED: Happy Hare provides a convenience wrapper [mmu_led_effect] that not only creates an effect on each of the
# [mmu_leds] specified segments as a whole but also each individual LED for atomic control. See mmu_leds.cfg for examples
#
# (comment out this whole section if you don't have/want leds; uncomment/edit LEDs fitted on your MMU)
[mmu_leds]
exit_leds:   neopixel:mmu_leds (1-8)
#entry_leds:  neopixel:mmu_leds (9-16)
#status_leds: neopixel:mmu_leds (17)
#logo_leds:   neopixel:mmu_leds (18)
frame_rate: 24