Compare commits
	
		
			No commits in common. "main" and "eddy-ng" have entirely different histories.
		
	
	
		
	
		
					 25 changed files with 46 additions and 3032 deletions
				
			
		|  | @ -81,7 +81,7 @@ kick_start_time: 0.5 | |||
| heater: extruder | ||||
| heater_temp: 50.0 | ||||
| ##  If you are experiencing back flow, you can reduce fan_speed | ||||
| fan_speed: 0.6 | ||||
| #fan_speed: 1.0 | ||||
| 
 | ||||
| [neopixel sb_leds] | ||||
| pin: ebb36:PD3 | ||||
|  |  | |||
|  | @ -10,58 +10,41 @@ gcode: | |||
|       {% set CHAMBER_TEMP_MATERIAL = 25 %} | ||||
|     {% endif %} | ||||
|     {% set CHAMBER_TEMP = params.CHAMBER|default(CHAMBER_TEMP_MATERIAL)|float %} | ||||
|     {% set CLEAN_TEMP = params.CLEAN|default(150)|float %} | ||||
|     {% set CLEAN_TEMP = params.CLEAN|default(170)|float %} | ||||
|     G90 ; ensure absolute positioning | ||||
|     M117 Homing | ||||
|     STATUS_HOMING | ||||
|     G92 E0 ; Reset Extruder | ||||
|     BED_MESH_CLEAR | ||||
|     RESPOND PREFIX=DEBUG: MSG="G28" | ||||
|     G28 ; Home all axes | ||||
|     ;QUAD_GANTRY_LEVEL | ||||
|     STATUS_HEATING | ||||
|     ;TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={STANDBY_TEMP} ; Start heating up the nozzle most of the way | ||||
|     {% if "ABS" == MATERIAL_TYPE %} | ||||
|     RESPOND PREFIX=DEBUG: MSG="ABS, Preheating bed for heat-soak" | ||||
|     M117 Bed to 100{"\xf8"}C... | ||||
|     M190 S100 | ||||
|     {% endif %} | ||||
|     M117 Chamber to {CHAMBER_TEMP}C... | ||||
|     RESPOND PREFIX=DEBUG: MSG="Wait for chamber to {CHAMBER_TEMP}C" | ||||
|     M117 Chamber to {CHAMBER_TEMP}{"\xf8"}C... | ||||
|     TEMPERATURE_WAIT SENSOR="temperature_sensor chamber_temp" MINIMUM={CHAMBER_TEMP} ; Wait for chamber temp | ||||
|     M117 Bed to {BED_TEMP}C... | ||||
|     RESPOND PREFIX=DEBUG: MSG="Set Bed to {BED_TEMP}C" | ||||
|     M140 S{BED_TEMP} ; Set the bed temp to the original request (might be lower than preheat) | ||||
|     M117 Gantry Level | ||||
|     RESPOND PREFIX=DEBUG: MSG="QGL" | ||||
|     QUAD_GANTRY_LEVEL | ||||
|     M117 Cleaning nozzle | ||||
|     M109 S{CLEAN_TEMP} | ||||
|     CLEAN_NOZZLE | ||||
|     M117 Eddy Tap | ||||
|     G1 X175 Y175 Z2 | ||||
|     PROBE_EDDY_NG_TAP | ||||
|     M117 Bed mesh eddy scan | ||||
|     STATUS_MESHING | ||||
|     RESPOND PREFIX=DEBUG: MSG="Homing Z" | ||||
|     G28 Z | ||||
|     RESPOND PREFIX=DEBUG: MSG="Mesh scan" | ||||
|     BED_MESH_CALIBRATE ;Well, this is fine and dandy... | ||||
|     M117 Cleaning nozzle | ||||
|     RESPOND PREFIX=DEBUG: MSG="Preheating nozzle to clean (non-ooze) temp S{CLEAN_TEMP}C" | ||||
|     M109 S{CLEAN_TEMP} | ||||
|     RESPOND PREFIX=DEBUG: MSG="CLEAN_NOZZLE macro" | ||||
|     CLEAN_NOZZLE | ||||
|     M117 Carto Touch | ||||
|     RESPOND PREFIX=DEBUG: MSG="Homing Z" | ||||
|     G28 Z | ||||
|     RESPOND PREFIX=DEBUG: MSG="CARTOGRAPHER_TOUCH macro" | ||||
|     CARTOGRAPHER_TOUCH | ||||
|     RESPOND PREFIX=DEBUG: MSG="Lifting Z a little more" | ||||
|     G1 Z10 ; carto leaves it at Z=5 which is theoretically okay, but cleaning then might skip steps and cause problems. | ||||
|     M117 Final heat {EXTRUDER_TEMP}/{BED_TEMP} | ||||
|     RESPOND PREFIX=DEBUG: MSG="Final heat {EXTRUDER_TEMP}/{BED_TEMP}" | ||||
|     STATUS_HEATING | ||||
|     M190 S{BED_TEMP} ; Start heating the bed, wait until target temperature reached | ||||
|     M109 S{EXTRUDER_TEMP} ; Finish heating the nozzle | ||||
|     M117 Clean and prime | ||||
|     RESPOND PREFIX=DEBUG: MSG="CLEAN_NOZZLE macro (wipe ooze before prime line)" | ||||
|     CLEAN_NOZZLE | ||||
|     RESPOND PREFIX=DEBUG: MSG="PRIME LINE" | ||||
|     G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed | ||||
|     G1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position | ||||
|     G1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line | ||||
|  | @ -70,13 +53,9 @@ gcode: | |||
|     G92 E0 ; Reset Extruder | ||||
|     G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed | ||||
|     G1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish | ||||
|     RESPOND PREFIX=DEBUG: MSG="CLEAN_NOZZLE macro (wipe any retraction debris picked up during prime line)" | ||||
|     CLEAN_NOZZLE | ||||
|     RESPOND PREFIX=DEBUG: MSG="SKEW_PROFILE LOAD=calilantern_skew_profile" | ||||
|     SKEW_PROFILE LOAD=calilantern_skew_profile | ||||
|     M117 Print started | ||||
|     STATUS_PRINTING | ||||
|     RESPOND PREFIX=DEBUG: MSG="Handing to slicer GCODE" | ||||
| 
 | ||||
| #   Use PRINT_END for the slicer ending script - please customise for your slicer of choice | ||||
| [gcode_macro PRINT_END] | ||||
|  | @ -89,6 +68,7 @@ gcode: | |||
|     {% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %} | ||||
|     SET_SKEW CLEAR=1 | ||||
|     BED_MESH_CLEAR | ||||
|     PROBE_EDDY_NG_SET_TAP_OFFSET VALUE=0 | ||||
| 
 | ||||
|     SAVE_GCODE_STATE NAME=STATE_PRINT_END | ||||
|      | ||||
|  | @ -115,32 +95,15 @@ gcode: | |||
|     G92 E0 ; Reset Extruder | ||||
|     BED_MESH_CLEAR | ||||
|     G28 ; Home all axes | ||||
|     M117 Eddy Tap | ||||
|     G1 X175 Y175 Z2 | ||||
|     PROBE_EDDY_NG_TAP | ||||
|     M117 Bed mesh eddy scan | ||||
|     STATUS_MESHING | ||||
|     M117 Carto touch | ||||
|     G28 Z | ||||
|     CARTOGRAPHER_TOUCH | ||||
|     BED_MESH_CALIBRATE | ||||
|     SKEW_PROFILE LOAD=calilantern_skew_profile | ||||
|     M117 Ready.  Printing coordinates in place. | ||||
| 
 | ||||
| [gcode_macro OOPS_QUAD_LEVEL] | ||||
| description: gantry is so unlevel that 2mm is probably not good enough. | ||||
| gcode: | ||||
|     QUAD_GANTRY_LEVEL horizontal_move_z=10 | ||||
| 
 | ||||
| [gcode_macro MARTYN_CUT_TIP] | ||||
| description: Clears mesh and skew, cuts tip, then restores them.  The mesh may be unnecessary but we can, so why not :-) | ||||
| gcode: | ||||
|     SAVE_GCODE_STATE NAME=STATE_PRINT_END | ||||
|     BED_MESH_PROFILE SAVE=CUT_TIP_STATE | ||||
|     BED_MESH_CLEAR | ||||
|     SET_SKEW CLEAR=1 | ||||
|     _MMU_CUT_TIP | ||||
|     BED_MESH_PROFILE LOAD=CUT_TIP_STATE | ||||
|     SKEW_PROFILE LOAD=calilantern_skew_profile | ||||
|     RESTORE_GCODE_STATE NAME=STATE_PRINT_END | ||||
| 
 | ||||
| [gcode_macro CANCEL_PRINT] | ||||
| description: Cancel the actual running print | ||||
| rename_existing: CANCEL_PRINT_BASE | ||||
|  | @ -196,22 +159,19 @@ gcode: | |||
|   SET_PIN PIN=caselight VALUE={S} | ||||
| 
 | ||||
| [gcode_macro CLEAN_NOZZLE] | ||||
| variable_start_x: 124 | ||||
| variable_start_x: 101 | ||||
| variable_start_y: 354 | ||||
| variable_start_z: -0.6 | ||||
| variable_start_z: 5 | ||||
| variable_wipe_dist: -40 | ||||
| variable_wipe_qty: 5 | ||||
| variable_wipe_spd: 200 | ||||
| variable_raise_distance: 10 | ||||
| variable_raise_distance: 5 | ||||
| 
 | ||||
| gcode: | ||||
|  {% if "xyz" not in printer.toolhead.homed_axes %} | ||||
|    G28 | ||||
|  {% endif %} | ||||
|   | ||||
|  G91 ; relative | ||||
|  G1 Z10 ; just in case! | ||||
| 
 | ||||
|  G90                                            ; absolute positioning | ||||
|  ## Move nozzle to start position | ||||
|  G1 X{start_x} Y{start_y} F6000 | ||||
|  |  | |||
|  | @ -1,924 +0,0 @@ | |||
| # Include servo hardware definition separately to allow for automatic upgrade | ||||
| [include blobifier_hw.cfg] | ||||
| 
 | ||||
| ########################################################################################## | ||||
| 
 | ||||
| # Sample config to be used in conjunction with Blobifier Purge Tray, Bucket & Nozzle  | ||||
| # Scrubber mod. Created by Dendrowen (dendrowen on Discord). The Macro is based on a  | ||||
| # version, and Nozzle Scrubber is made by Hernsl (hernsl#8860 on Discord). The device is  | ||||
| # designed around a Voron V2.4 300mm, but should work for 250mm and 350mm too. This  | ||||
| # version only supports the assembly on the rear-left of the bed. If you decide to change  | ||||
| # that, please consider contributing to the project by creating a pull request with the  | ||||
| # needed changes. | ||||
| 
 | ||||
| # IMPORTANT: The rear-left part of your bed becomes unusable by this mod because the  | ||||
| #            toolhead needs to lower down to 0. Be sure not to use the left-rear 130x35mm. | ||||
| 
 | ||||
| # The goals of this combination of devices is to dispose of purged filament during a  | ||||
| # multicolored print without the need of a purge block and without the flurries of | ||||
| # filament poops consuming your entire 3D printer room. The Blobifier achieves that by | ||||
| # purging onto a retractable tray which causes the filament to turn into a tiny blob  | ||||
| # rather then a large spiral. This keeps the waste relatively small. The bucket should be | ||||
| # able to account for up to 200 filament swaps (for the 300mm V2). | ||||
| 
 | ||||
| # The Blobifier uses some room at the back-left side of your printer, depending on your | ||||
| # printer limits and positions. (usually max_pos.y - toolhead_y and brush_start +  | ||||
| # brush_width + toolhead_x). If you do place objects within this region, Blobifier will | ||||
| # skip purging automatically. It does this by extending the EXCLUDE_OBJECT_* macro's, so | ||||
| # make sure you have exclude objects enabled in your slicer. | ||||
| 
 | ||||
| # If your using Blobifier in conjunction with the filament cutter on the stealthburner | ||||
| # toolhead, you can place the pin at max_pos.y - 7 (e.g., max pos y is 307, place it at | ||||
| # 300). The pin will then poke through the cavity in your toolhead. (Be careful with  | ||||
| # manually moving the toolhead. I have broken many filament cutter pins) | ||||
| 
 | ||||
| # It is advised to use the start_gcode from Happy Hare. Then you will be able to fully  | ||||
| # and efficiently use this mod. Check the Happy Hare document at gcode_preprocessing.md  | ||||
| # in the Happy Hare github for more details. | ||||
| 
 | ||||
| ###################################### DISCLAIMER ######################################## | ||||
| 
 | ||||
| # You, and you alone, are responsible for the correct execution of these macros and  | ||||
| # gcodes. Any damage that may occur to your machine remains your responsibility.  | ||||
| # Especially when executing this macro for the first few times, keep an eye on your  | ||||
| # printer and the  | ||||
| # emergency stop. | ||||
| 
 | ||||
| ########################################################################################## | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Main macro. Usually you should only need to call this one or place it in the Happy Hare | ||||
| # _MMU_POST_LOAD macro using the variable_user_post_load_extension: | ||||
| # | ||||
| # variable_user_post_load_extension : `BLOBIFIER` | ||||
| # | ||||
| # Notes on parameters: | ||||
| # PURGE_LENGTH=[float] (optional) The length to purge. If omitted (default) it will check | ||||
| #                      the purge_volumes matrix or variable_purge_length. This can be used | ||||
| #                      to override and for testing. | ||||
| # | ||||
| [gcode_macro BLOBIFIER] | ||||
| # These parameters define your filament purging. | ||||
| # Note that the control of retraction is set in 'mmu_macro_vars.cfg' which can be increased | ||||
| # if you experience excessive oozing. | ||||
| variable_purge_spd: 400                 # Speed, in mm/min, of the purge. | ||||
| variable_purge_temp_min: 200            # Minimum nozzle purge temperature. | ||||
| variable_toolhead_x: 70                 # From the nozzle to the left of your toolhead | ||||
| variable_toolhead_y: 50                 # From the nozzle to the front of your toolhead | ||||
| 
 | ||||
| # This macro will prevent a gcode movement downward while 'blobbing' if there might be a | ||||
| # print in the way (e.g. You print something large and need the area where Blobifier does | ||||
| # its... 'business'). However, at low heights (or at print start) this might not be | ||||
| # desireable. You can force a 'safe descend' with this variable. Keep in mind that the  | ||||
| # height of the print is an estimation based on previous heights and certain assumptions | ||||
| # so it might be wise to include a safety margin of 0.2mm | ||||
| variable_force_safe_descend_height_until: 1.0 | ||||
| 
 | ||||
| # Adjust this so that your nozzle scrubs within the brush. Be careful not to go too low! | ||||
| # Start out with a high value (like, 6) and go | ||||
| # down from there. | ||||
| variable_brush_top: 6 | ||||
| 
 | ||||
| # These parameters define your scrubbing, travel speeds, safe z clearance and how many | ||||
| # times you want to wipe. Update as necessary. | ||||
| variable_clearance_z: 2          # When traveling, but not cleaning, the | ||||
|                                            #   clearance along the z-axis between nozzle | ||||
|                                            #   and brush. | ||||
| variable_wipe_qty: 2          # Number of complete (A complete wipe: left, | ||||
|                                            #   right, left OR right, left, right) wipes. | ||||
| variable_travel_spd_xy: 10000          # Travel (not cleaning) speed along x and | ||||
|                                            #   y-axis in mm/min. | ||||
| variable_travel_spd_z: 1000          # Travel (not cleaning) speed along z axis | ||||
|                                            #   in mm/min. | ||||
| variable_wipe_spd_xy: 10000          # Nozzle wipe speed in mm/min. | ||||
| 
 | ||||
| # The acceleration to use when using the brush action. If set to 0, it uses the already  | ||||
| # set acceleration. However, in some cases this is not desirable for the last motion  | ||||
| # could be an 'outer contour' acceleration which is usually lower. | ||||
| variable_brush_accel: 0 | ||||
| 
 | ||||
| # Blobifier sends the toolhead to the maximum y position during purge operations and | ||||
| # minimum x position during shake operations. This can cause issues when skew correction  | ||||
| # is set up. If you have skew correction enabled and get 'move out of range' errors  | ||||
| # regarding blobifier while skew is enabled, try increasing this value. Keep the  | ||||
| # adjustments small though! (0.1mm - 0.5mm) and increase it until it works. | ||||
| variable_skew_correction: 0.1 | ||||
| 
 | ||||
| # These parameters define the size of the brush. Update as necessary. A visual reference | ||||
| # is provided below. | ||||
| # | ||||
| #                  ←   brush_width   → | ||||
| #                   _________________ | ||||
| #                  |                 |  ↑                Y position is acquired from your | ||||
| #  brush_start (x) |                 | brush_depth       stepper_y position_max. Adjust | ||||
| #                  |_________________|  ↓                your brush physically in Y so | ||||
| #                          (y)                           that the nozzle scrubs within the | ||||
| #                      brush_front                       brush. | ||||
| # __________________________________________________________ | ||||
| #                     PRINTER FRONT | ||||
| # | ||||
| # | ||||
| # Start location of the brush. Defaults for 250, 300 and 350mm are provided below. | ||||
| # Uncomment as necessary | ||||
| #variable_brush_start:          34  # For 250mm build | ||||
| variable_brush_start: 67  # For 300mm build | ||||
| #variable_brush_start:          84  # for 350mm build | ||||
| 
 | ||||
| # width of the brush | ||||
| variable_brush_width: 35 | ||||
| 
 | ||||
| # Location of where to purge. The tray is 15mm in length, so if you assemble it against  | ||||
| # the side of the bed (default), 10mm is a good location | ||||
| variable_purge_x: 10 | ||||
| 
 | ||||
| # Height of the tray. If it's below your bed, give this a negative number equal to the  | ||||
| # difference. If it's above your bed, give it a positive number. You can find this number  | ||||
| # by homing, optional QGL or equivalent, and moving you toolhead above the tray, and  | ||||
| # lowering it with the paper method.  | ||||
| variable_tray_top: 0.7 | ||||
| 
 | ||||
| # Servo angles for tray positions | ||||
| variable_tray_angle_out: 0 | ||||
| variable_tray_angle_in: 180 | ||||
| 
 | ||||
| # Increase this value if the servo doesn't have enough time to fully retract or extend | ||||
| variable_dwell_time: 200 | ||||
| 
 | ||||
| # ======================================================================================== | ||||
| # ==================== BLOB TUNING ======================================================= | ||||
| # ======================================================================================== | ||||
| 
 | ||||
| # The following section defines how the purging sequence is executed. This is where you  | ||||
| # tune the purging to create pretty blobs. Refer to the visual reference for a better  | ||||
| # understanding. The visual is populated with example values. Below are some guides  | ||||
| # provided to help with tuning. | ||||
| # | ||||
| #                          \_____________/ | ||||
| #                             |___|___| | ||||
| #                                \_/            ______________  < End of third iteration. | ||||
| #                                / \                                  HEIGHT:   3 x iteration_z_raise - (2 + 1) x iteration_z_change  (3 x 5 - 2 x 1.2 = 11.4) | ||||
| #                               |   |                                 EXTRUDED: 3 x max_iteration_length                              (3 x 50 = 150) | ||||
| #                              /     \          ______________  < End of second iteration. | ||||
| #                             |       \                               HEIGHT:   2 x iteration_z_raise - 1 x iteration_z_change        (2 x 5 - 1 x 1.2 = 8.8) | ||||
| #                            /         |                              EXTRUDED: 2 x max_iteration_length                              (2 x 50 = 100) | ||||
| #                           |           \       ______________  < End of first iteration.  | ||||
| #                          /             \                            HEIGHT:   1 x iteration_z_raise                                 (1 x 5 = 5) | ||||
| #                         |               |                           EXTRUDED: 1 x max_iteration_length                              (1 x 50 = 50) | ||||
| #___________               \             /      ______________  < Start height of the nozzle. default value: 1.5mm | ||||
| #           |_______________\___________/_      ______________  < Bottom of the tray | ||||
| #           |_____________________________| | ||||
| #           | | ||||
| #  | ||||
| ########################### BLOB TUNING ############################## | ||||
| # +-------------------------------------+----------------------------+ | ||||
| # |  Filament sticks to the nozzle at   | Incr. purge start          | | ||||
| # |    initial purge (first few mm)     |                            | | ||||
| # +-------------------------------------+----------------------------+ | ||||
| # |  Filament scoots out from under     | Incr. temperature          | | ||||
| # |  the nozzle at the first iteration  | Decr. z_raise              | | ||||
| # |                                     | Incr. purge_length_maximum | | ||||
| # +-------------------------------------+----------------------------+ | ||||
| # |  Filament scoots out from under the | Decr. purge_spd            | | ||||
| # |  the nozzle at later iterations     | Decr. z_raise_exp          | | ||||
| # |                                     | Decr. z_raise              | | ||||
| # |                                     | Incr. purge_length_maximum | | ||||
| # +-------------------------------------+----------------------------+ | ||||
| # |  Filament sticks to the nozzle at   | Incr. z_raise_exp          | | ||||
| # |         later iterations            |     (Not above 1)          | | ||||
| # +-------------------------------------+----------------------------+ | ||||
| # | ||||
| 
 | ||||
| # The height to raise the nozzle above the tray before purging. This allows any built up  | ||||
| # pressure to escape before the purge. | ||||
| variable_purge_start: 0.2 | ||||
| 
 | ||||
| # The amount to raise Z | ||||
| variable_z_raise: 12 | ||||
| 
 | ||||
| # As the nozzle gets higher and the blob wider, the Z raise needs to be reduced, this | ||||
| # follows the following formula:  | ||||
| #            (extruded_amount/max_purge_length)^z_raise_exp * z_raise | ||||
| # 1 is linear, below 1 will cause z to raise less quickly over time, above 1 will make it | ||||
| # raise quicker over time. 0.85 is a good starting point and you should not have it above 1 | ||||
| variable_z_raise_exp: 0.85 | ||||
| 
 | ||||
| # Lift the nozzle slightly after creating the blob te release pressure on the tray. | ||||
| variable_eject_hop: 1.0 | ||||
| 
 | ||||
| # Dwell time (ms) after purging and before cleaning to relieve pressure from the nozzle. | ||||
| variable_pressure_release_time: 1000 | ||||
| 
 | ||||
| # Set the part cooling fan speed. Disabling can help prevent the nozzle from cooling down  | ||||
| # and stimulate flow, Enabling it can prevent blobs from sticking together. Values range  | ||||
| # from 0 .. 1, or -1 if you don't want it changed. | ||||
| #variable_part_cooling_fan: -1              # Leave it unchanged | ||||
| #variable_part_cooling_fan:  0              # Disable the fan | ||||
| variable_part_cooling_fan: 1               # Run it at full speed | ||||
| 
 | ||||
| # Define the part fan name if you are using a fan other than [fan] | ||||
| # Applies to [fan_generic] or other fan definitons | ||||
| # Example would be if you are using auxiliary fan control in Orcaslicer (https://github.com/SoftFever/OrcaSlicer/wiki/Auxiliary-fan) | ||||
| # If you are unsure if you need this, then probably just leave it commented out. | ||||
| 
 | ||||
| #variable_fan_name: "fan_generic fan0" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # ======================================================================================== | ||||
| # ==================== PURGE LENGTH TUNING =============================================== | ||||
| # ======================================================================================== | ||||
| 
 | ||||
| # The absolute minimum to purge, even if you don't changed tools. This is to prime the  | ||||
| # nozzle before printing | ||||
| variable_purge_length_minimum: 30 | ||||
| 
 | ||||
| # The maximum amount of filament (in mm¹) to purge in a single blob. Blobifier will  | ||||
| # automatically purge multiple blobs if the purge amount exceeds this. | ||||
| variable_purge_length_maximum: 150 | ||||
| 
 | ||||
| # Default purge length to fall back on when neither the tool map purge_volumes or  | ||||
| # parameter PURGE_LENGTH is set. | ||||
| variable_purge_length: 150 | ||||
| 
 | ||||
| # The slicer values often are a bit too wasteful. Tune it here to get optimal values.  | ||||
| # 0.6 (60%) is a good starting point. | ||||
| variable_purge_length_modifier: 0.6 | ||||
| 
 | ||||
| # Fixed length of filament to add after the purge volume calculation. Happy Hare already | ||||
| # shares info on the extra amount of filament to purge based on known residual filament, | ||||
| # tip cutting fragment and initial retraction setting. However this setting can add a fixed | ||||
| # amount on top on that if necessary although it is recommended to start with 0 and tune | ||||
| # slicer purge matrix first. | ||||
| # When should you alter this value: | ||||
| #   INCREASE: When the dark to light swaps are good, but light to dark aren't. | ||||
| #   DECREASE: When the light to dark swaps are good, but dark to light aren't. Don't  | ||||
| #     forget to increase the purge_length_modifier | ||||
| variable_purge_length_addition: 0 | ||||
| 
 | ||||
| # ======================================================================================== | ||||
| # ==================== BUCKET ============================================================ | ||||
| # ======================================================================================== | ||||
| 
 | ||||
| # Maximum number of blobs that fit in the bucket. Pauses the print if it exceeds this  | ||||
| # number. | ||||
| variable_max_blobs: 400 | ||||
| # Enable the bucket shaker. You need to have the shaker.stl installed | ||||
| variable_enable_shaker: 1 | ||||
| # The number of back-and-forth motions of one shake | ||||
| variable_bucket_shakes: 10 | ||||
| # During shaking acceleration can often be higher because you don't need to keep print  | ||||
| # quality in mind. Higher acceleration helps better with dispersing the blobs. | ||||
| variable_shake_accel: 10000 | ||||
| 
 | ||||
| # The frequency at which to shake the bucket. A decimal value ranging from 0 to 1, where 0  | ||||
| # is never, and 1 is every time. This way the shaking occurs more often as the bucket  | ||||
| # fills up. Sensible values range from 0.75 to 0.95 | ||||
| variable_bucket_shake_frequency: 0.95 | ||||
| 
 | ||||
| # Height of the shaker arm. If your hotend hits your tray during shaking, increase. | ||||
| variable_shaker_arm_z: 2 | ||||
| 
 | ||||
| gcode: | ||||
| 
 | ||||
|   # ====================================================================================== | ||||
|   # ==================== RECORD STATE (INCL. FANS, SPEEDS, ETC...) ======================= | ||||
|   # ====================================================================================== | ||||
| 
 | ||||
|   # General state | ||||
|   SAVE_GCODE_STATE NAME=BLOBIFIER_state | ||||
| 
 | ||||
|    | ||||
|   # ====================================================================================== | ||||
|   # ==================== CHECK HOMING STATUS ============================================= | ||||
|   # ====================================================================================== | ||||
|    | ||||
|   {% if "xyz" not in printer.toolhead.homed_axes %} | ||||
|     RESPOND MSG="BLOBIFIER: Not homed! Home xyz before blobbing" | ||||
|   {% elif printer.quad_gantry_level and printer.quad_gantry_level.applied == False %} | ||||
|     RESPOND MSG="BLOBIFIER: QGL not applied! run quad_gantry_level before blobbing" | ||||
|   {% else %} | ||||
|      | ||||
|     # Part cooling fan | ||||
|     {% if part_cooling_fan >= 0 %} | ||||
|       {% set fan = fan_name|string %} | ||||
|       # Save the part cooling fan speed to be enabled again later | ||||
|       {% set backup_fan_speed = (printer[fan].speed if printer[fan] is defined else printer.fan.speed) %} | ||||
|       # Set part cooling fan speed | ||||
|       M106 S{part_cooling_fan * 255} | ||||
|     {% endif %} | ||||
| 
 | ||||
|     # Set feedrate to 100% for correct speed purging | ||||
|     {% set backup_feedrate = printer.gcode_move.speed_factor %} | ||||
|     M220 S100 | ||||
| 
 | ||||
|     # ====================================================================================== | ||||
|     # ==================== DEFINE BASIC VARIABLES ========================================== | ||||
|     # ====================================================================================== | ||||
|      | ||||
|     {% set sequence_vars = printer['gcode_macro _MMU_SEQUENCE_VARS'] %} | ||||
|     {% set park_vars = printer['gcode_macro _MMU_PARK'] %} | ||||
|     {% set filament_diameter = printer.configfile.config.extruder.filament_diameter|float %} | ||||
|     {% set filament_cross_section = (filament_diameter/2) ** 2 * 3.1415 %} | ||||
|     {% set from_tool = printer.mmu.last_tool %} | ||||
|     {% set to_tool = printer.mmu.tool %} | ||||
|     {% set bl_count = printer['gcode_macro _BLOBIFIER_COUNT'] %} | ||||
|     {% set pos = printer.gcode_move.gcode_position %} | ||||
|     {% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %} | ||||
|     {% set ignore_safe = safe.print_height < force_safe_descend_height_until %} | ||||
|     {% set restore_z = [printer['gcode_macro BLOBIFIER_PARK'].restore_z,pos.z]|max %} | ||||
|     {% set pos_max = printer.toolhead.axis_maximum %} | ||||
|     {% set position_y = pos_max.y - skew_correction %} | ||||
| 
 | ||||
|     # Get purge volumes from the slicer (if set up right. see  | ||||
|     # https://github.com/moggieuk/Happy-Hare/wiki/Gcode-Preprocessing) | ||||
|     {% set pv = printer.mmu.slicer_tool_map.purge_volumes %} | ||||
|      | ||||
|     # ====================================================================================== | ||||
|     # ==================== DETERMINE PURGE LENGTH ========================================== | ||||
|     # ====================================================================================== | ||||
| 
 | ||||
|     {% if params.PURGE_LENGTH %} # =============== PARAM PURGE LENGTH ====================== | ||||
|       {action_respond_info("BLOBIFIER: param PURGE_LENGTH provided")} | ||||
|       {% set purge_len = params.PURGE_LENGTH|float %} | ||||
|     {% elif from_tool == to_tool and to_tool >= 0 %} # ==== TOOL DIDN'T CHANGE ============= | ||||
|       {action_respond_info("BLOBIFIER: Tool didn't change (T%s > T%s), %s" % (from_tool, to_tool, "priming" if purge_length_minimum else "skipping"))} | ||||
|       {% set purge_len = 0 %} | ||||
| 
 | ||||
|     {% elif pv %} # ============== FETCH FROM HAPPY HARE (LIKELY FROM SLICER) ============== | ||||
|       {% if from_tool < 0 and to_tool >= 0%} | ||||
|         {action_respond_info("BLOBIFIER: from tool unknown. Finding largest value for T? > T%d" % to_tool)} | ||||
|         {% set purge_vol = pv|map(attribute=to_tool)|max %} | ||||
|       {% elif to_tool < 0 %} | ||||
|         {action_respond_info("BLOBIFIER: tool(s) unknown. Finding largest value")} | ||||
|         {% set purge_vol = pv|map('max')|max %} | ||||
|       {% else %} | ||||
|         {% set purge_vol = pv[from_tool][to_tool]|float * purge_length_modifier %} | ||||
|         {action_respond_info("BLOBIFIER: Swapped T%s > T%s" % (from_tool, to_tool))} | ||||
|       {% endif %} | ||||
|       {% set purge_len = purge_vol / filament_cross_section %} | ||||
| 
 | ||||
|       {% set purge_len = purge_len + printer.mmu.extruder_filament_remaining + park_vars.retracted_length + purge_length_addition %} | ||||
| 
 | ||||
|     {% else %} # ========================= USE CONFIG VARIABLE ============================= | ||||
|       {action_respond_info("BLOBIFIER: No toolmap or PURGE_LENGTH. Using default")} | ||||
|       {% set purge_len = purge_length|float + printer.mmu.extruder_filament_remaining + park_vars.retracted_length %} | ||||
|     {% endif %} | ||||
| 
 | ||||
|     # ==================================== APPLY PURGE MINIMUM ============================= | ||||
|     {% set purge_len = [purge_len,purge_length_minimum]|max|round(0, 'ceil')|int %} | ||||
|     {action_respond_info("BLOBIFIER: Purging %dmm of filament" % (purge_len))} | ||||
| 
 | ||||
|     # ====================================================================================== | ||||
|     # ==================== PURGING SEQUENCE ================================================ | ||||
|     # ====================================================================================== | ||||
| 
 | ||||
|     # Set to absolute positioning. | ||||
|     G90 | ||||
| 
 | ||||
|     # Check for purge length and purge if necessary. | ||||
|     {% if purge_len|float > 0 %} | ||||
| 
 | ||||
|       # ==================================================================================== | ||||
|       # ==================== POSITIONING =================================================== | ||||
|       # ==================================================================================== | ||||
|        | ||||
|       # Retract the tray so it is not in the way | ||||
|       BLOBIFIER_SERVO POS=in | ||||
| 
 | ||||
|       # Move to the assembly, first a bit more to the right (brush_start) to avoid a  | ||||
|       # potential filametrix pin if it's not already on the same Y coordinate. | ||||
|       {% if printer.toolhead.position.y != position_y %} | ||||
|         G1 X{[brush_start - 20, 30]|max} Y{position_y} F{travel_spd_xy} | ||||
|       {% endif %} | ||||
| 
 | ||||
|       # ==================================================================================== | ||||
|       # ==================== BUCKET SHAKE ================================================== | ||||
|       # ==================================================================================== | ||||
|        | ||||
|       {% if enable_shaker and (safe.shake or ignore_safe) %} | ||||
|         {% if (bl_count.current_blobs + 1) >= bl_count.next_shake %} | ||||
|           BLOBIFIER_SHAKE_BUCKET SHAKES={bucket_shakes} | ||||
|           _BLOBIFIER_CALCULATE_NEXT_SHAKE | ||||
|         {% endif %} | ||||
|       {% endif %} | ||||
|        | ||||
|       # ==================================================================================== | ||||
|       # ==================== POSITIONING ON TRAY =========================================== | ||||
|       # ==================================================================================== | ||||
|       {% if safe.tray or ignore_safe %} | ||||
|         G1 Z{tray_top + purge_start} F{travel_spd_z} | ||||
|       {% endif %} | ||||
| 
 | ||||
|       # Move over to the tray after z change (For cases when the tool is lower than the tray) | ||||
|       G1 X{purge_x} F{travel_spd_xy} | ||||
| 
 | ||||
|       # Extend the tray | ||||
|       BLOBIFIER_SERVO POS=out | ||||
| 
 | ||||
|       # ==================================================================================== | ||||
|       # ==================== HEAT HOTEND =================================================== | ||||
|       # ==================================================================================== | ||||
|        | ||||
|       {% if printer.extruder.temperature < purge_temp_min %} | ||||
|         {% if printer.extruder.target < purge_temp_min %} | ||||
|           M109 S{purge_temp_min} | ||||
|         {% else %} | ||||
|           TEMPERATURE_WAIT SENSOR=extruder MINIMUM={purge_temp_min} | ||||
|         {% endif %} | ||||
|       {% endif %} | ||||
| 
 | ||||
|       # ==================================================================================== | ||||
|       # ==================== START ITERATING =============================================== | ||||
|       # ==================================================================================== | ||||
|        | ||||
|       # Calculate total number of iterations based on the purge length and the max_iteration  | ||||
|       # length. | ||||
|       {% set blobs = (purge_len / purge_length_maximum)|round(0, 'ceil')|int %} | ||||
|       {% set purge_per_blob = purge_len|float / blobs %} | ||||
|       {% set retracts_per_blob = (purge_per_blob / 40)|round(0, 'ceil')|int %} | ||||
|       {% set purge_per_retract = (purge_per_blob / retracts_per_blob)|int %} | ||||
|       {% set pulses_per_retract = (purge_per_blob / retracts_per_blob / 5)|round(0, 'ceil')|int %} | ||||
|       {% set pulses_per_blob = (purge_per_blob / 5)|round(0, 'ceil')|int %} | ||||
|       {% set purge_per_pulse = purge_per_blob / pulses_per_blob %} | ||||
|       {% set pulse_time_constant = purge_per_pulse * 0.95 / purge_spd / (purge_per_pulse * 0.95 / purge_spd + purge_per_pulse * 0.05 / 50) %} | ||||
|       {% set pulse_duration = purge_per_pulse / purge_spd %} | ||||
| 
 | ||||
|       # Repeat the process until purge_len is reached | ||||
|       {% for blob in range(blobs) %} | ||||
|         RESPOND MSG={"'BLOBIFIER: Blob %d of %d (%.1fmm)'" % (blob + 1, blobs, purge_per_blob)} | ||||
| 
 | ||||
|         {% if safe.tray or ignore_safe %} | ||||
|           G1 Z{tray_top + purge_start} F{travel_spd_z} | ||||
|         {% endif %} | ||||
| 
 | ||||
|         # relative positioning | ||||
|         G91  | ||||
|         # relative extrusion | ||||
|         M83 | ||||
| 
 | ||||
|         # Purge filament in a pulsating motion to purge the filament quicker and better | ||||
|         {% for pulse in range(pulses_per_blob) %} | ||||
|           # Calculations to determine z-speed | ||||
|           {% set purged_this_blob = pulse * purge_per_pulse %} | ||||
|           {% set z_last_pos = purge_start + ((purged_this_blob)/purge_length_maximum)**z_raise_exp * z_raise %} | ||||
|           {% set z_pos = purge_start + ((purged_this_blob + purge_per_pulse)/purge_length_maximum)**z_raise_exp * z_raise %} | ||||
|           {% set z_up = z_pos - z_last_pos %} | ||||
|           {% set speed = z_up / pulse_duration %} | ||||
| 
 | ||||
|           # Purge quickly | ||||
|           G1 Z{z_up * pulse_time_constant} E{purge_per_pulse * 0.95} F{speed} | ||||
|           # Purge a tiny bit slowly | ||||
|           G1 Z{z_up * (1 - pulse_time_constant)} E{purge_per_pulse * 0.05} F{speed} | ||||
| 
 | ||||
|           # retract and unretract filament every now and then for thorough cleaning | ||||
|           {% if pulse % pulses_per_retract == 0 and pulse > 0 %} | ||||
|             G1 E-2 F1800 | ||||
|             G1 E2 F800 | ||||
|           {% endif %} | ||||
|         {% endfor %} | ||||
| 
 | ||||
|         # ================================================================================== | ||||
|         # ==================== DEPOSIT BLOB ================================================ | ||||
|         # ================================================================================== | ||||
|         {% if safe.tray or ignore_safe %} | ||||
|           # Raise z a bit to relieve pressure on the blob preventing it to go sideways | ||||
|           G1 Z{eject_hop} F{travel_spd_z} | ||||
|           # Retract the tray | ||||
|           BLOBIFIER_SERVO POS=in | ||||
|           # Move the toolhead down to purge_start height lowering the blob below the tray | ||||
|           G90 # absolute positioning | ||||
|           G1 Z{tray_top} F{travel_spd_z} | ||||
|           # Extend the tray to 'cut off' the blob and prepare for the next blob | ||||
|           BLOBIFIER_SERVO POS=out | ||||
|           BLOBIFIER_SERVO POS=in | ||||
|           BLOBIFIER_SERVO POS=out | ||||
|           # Keep track of the # of blobs | ||||
|           _BLOBIFIER_COUNT | ||||
|         {% endif %} | ||||
|       {% endfor %} | ||||
|     {% endif %} | ||||
|     {% if safe.tray or ignore_safe %} | ||||
|       G1 Z{tray_top + 1} F{travel_spd_z} | ||||
|       G4 P{pressure_release_time} | ||||
|     {% endif %} | ||||
|     {% if safe.brush or ignore_safe %} | ||||
|       BLOBIFIER_CLEAN | ||||
|     {% else %} | ||||
|       G1 X{brush_start} F{travel_spd_xy} | ||||
|     {% endif %} | ||||
| 
 | ||||
|     # ====================================================================================== | ||||
|     # ==================== RESTORE STATE =================================================== | ||||
|     # ====================================================================================== | ||||
| 
 | ||||
|     # Retract to match what Happy Hare is expecting | ||||
|     G1 E-{park_vars.retracted_length} F{sequence_vars.retract_speed * 60} | ||||
|          | ||||
|     G90 # absolute positioning | ||||
|     G1 Z{restore_z} F{travel_spd_z} | ||||
|      | ||||
|     {% if part_cooling_fan >= 0 %} | ||||
|       # Reset part cooling fan if it was changed | ||||
|       M106 S{(backup_fan_speed * 255)|int} | ||||
|     {% endif %} | ||||
|      | ||||
|     M220 S{(backup_feedrate * 100)|int} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   # Retract the tray | ||||
|   BLOBIFIER_SERVO POS=in | ||||
|    | ||||
|   RESTORE_GCODE_STATE NAME=BLOBIFIER_state  | ||||
| 
 | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Wipes the nozzle on the brass brush | ||||
| # | ||||
| [gcode_macro BLOBIFIER_CLEAN] | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set pos_max = printer.toolhead.axis_maximum %} | ||||
|   {% set position_y = pos_max.y - bl.skew_correction %} | ||||
|   {% set original_accel = printer.toolhead.max_accel %} | ||||
|   {% set original_minimum_cruise_ratio = printer.toolhead.minimum_cruise_ratio %} | ||||
|   {% set pos = printer.gcode_move.gcode_position %} | ||||
|    | ||||
|   SAVE_GCODE_STATE NAME=BLOBIFIER_CLEAN_state | ||||
| 
 | ||||
|   G90 | ||||
|    | ||||
|   {% if bl.brush_accel > 0 %} | ||||
|     SET_VELOCITY_LIMIT ACCEL={bl.brush_accel} MINIMUM_CRUISE_RATIO=0.1 | ||||
|   {% endif %} | ||||
| 
 | ||||
|   {% if pos.z < bl.brush_top + bl.clearance_z %} | ||||
|     G1 Z{bl.brush_top + bl.clearance_z} F{bl.travel_spd_z} | ||||
|   {% endif %} | ||||
|   G1 X{bl.brush_start} F{bl.travel_spd_xy} | ||||
|   G1 Y{position_y} | ||||
|   G1 Z{bl.brush_top + bl.clearance_z} F{bl.travel_spd_z} | ||||
| 
 | ||||
|   # Move nozzle down into brush. | ||||
|   G1 Z{bl.brush_top} F{bl.travel_spd_z} | ||||
| 
 | ||||
|   SET_VELOCITY_LIMIT ACCEL={original_accel} MINIMUM_CRUISE_RATIO={original_minimum_cruise_ratio} | ||||
|    | ||||
|   # Perform wipe. Wipe direction based off bucket_pos for cool random scrubby routine. | ||||
|   {% for wipes in range(1, (bl.wipe_qty + 1)) %} | ||||
|      G1 X{bl.brush_start + bl.brush_width} F{bl.wipe_spd_xy} | ||||
|      G1 X{bl.brush_start} F{bl.wipe_spd_xy} | ||||
|   {% endfor %} | ||||
| 
 | ||||
|   # Move away from the brush, but not onto the tray or in front of the filametrix cutter pin | ||||
|   G1 X{[bl.brush_start - 20, 30]|max} F{bl.travel_spd_xy} | ||||
| 
 | ||||
|   RESTORE_GCODE_STATE NAME=BLOBIFIER_CLEAN_state | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Park the nozzle on the tray to prevent oozing during filament swaps. Place this  | ||||
| # extension in the post_form_tip extension in mmu_macro_vars.cfg: | ||||
| #   variable_user_post_form_tip_extension: "BLOBIFIER_PARK" | ||||
| # | ||||
| [gcode_macro BLOBIFIER_PARK] | ||||
| variable_restore_z: 0 | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set pos = printer.gcode_move.gcode_position %} | ||||
|   {% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %} | ||||
|   {% set pos_max = printer.toolhead.axis_maximum %} | ||||
|   {% set position_y = pos_max.y - bl.skew_correction %} | ||||
| 
 | ||||
|   SET_GCODE_VARIABLE MACRO=BLOBIFIER_PARK VARIABLE=restore_z VALUE={pos.z} | ||||
| 
 | ||||
|   SAVE_GCODE_STATE NAME=blobifier_park_state | ||||
|    | ||||
|   {% if "xyz" in printer.toolhead.homed_axes and printer.quad_gantry_level and printer.quad_gantry_level.applied %} | ||||
|     G90 | ||||
| 
 | ||||
|     # Retract the tray | ||||
|     BLOBIFIER_SERVO POS=in | ||||
| 
 | ||||
|     G1 X{[bl.brush_start - 20, 30]|max} Y{position_y} F{bl.travel_spd_xy} | ||||
|     {% if safe.tray or ignore_safe %} | ||||
|       G1 Z{bl.tray_top} F{bl.travel_spd_z} | ||||
|     {% endif %} | ||||
|     G1 X{bl.purge_x} F{bl.travel_spd_xy} | ||||
| 
 | ||||
|     # Extend the tray | ||||
|     BLOBIFIER_SERVO POS=out | ||||
| 
 | ||||
|   {% else %} | ||||
|     RESPOND MSG="Please home (and QGL) before parking" | ||||
|   {% endif %} | ||||
| 
 | ||||
|   RESTORE_GCODE_STATE NAME=blobifier_park_state | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Retract or extend the tray  | ||||
| # POS=[in|out] Retractor extend the tray | ||||
| # | ||||
| [gcode_macro BLOBIFIER_SERVO] | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set pos = params.POS %} | ||||
|   {% if pos == "in" %} | ||||
|     SET_SERVO SERVO=blobifier ANGLE={bl.tray_angle_in} | ||||
|     G4 P{bl.dwell_time} | ||||
|   {% elif pos == "out" %} | ||||
|     SET_SERVO SERVO=blobifier ANGLE={bl.tray_angle_out} | ||||
|     G4 P{bl.dwell_time} | ||||
|   {% else %} | ||||
|     {action_respond_info("BLOBIFIER: provide POS=[in|out]")} | ||||
|   {% endif %} | ||||
|   SET_SERVO SERVO=blobifier WIDTH=0 | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Define exclude objects for those who haven't already | ||||
| # | ||||
| [exclude_object] | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Overwrite the existing EXCLUDE_OBJECT_DEFINE to also check for safe descend. | ||||
| # | ||||
| [gcode_macro EXCLUDE_OBJECT_DEFINE] | ||||
| rename_existing: _EXCLUDE_OBJECT_DEFINE | ||||
| gcode: | ||||
|   # only reset on the first object at the beginning of a print | ||||
|   {% if printer.exclude_object.objects|length < 1 %} | ||||
|     _BLOBIFIER_RESET_SAFE_DESCEND | ||||
|   {% endif %} | ||||
|   _EXCLUDE_OBJECT_DEFINE {rawparams} | ||||
|   _BLOBIFIER_SAFE_DESCEND | ||||
|   UPDATE_DELAYED_GCODE ID=BLOBIFIER_SHOW_SAFE_DESCEND DURATION=1 | ||||
|    | ||||
| [delayed_gcode BLOBIFIER_SHOW_SAFE_DESCEND] | ||||
| gcode: | ||||
|   {% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %} | ||||
|   {action_respond_info( | ||||
|     "BLOBIFIER: Safe descend possible:\n - tray:  %s\n - brush: %s\n - shake: %s" %  | ||||
|     ( | ||||
|       "yes" if safe.tray else "no", | ||||
|       "yes" if safe.brush else "no", | ||||
|       "yes" if safe.shake else "no" | ||||
|     ) | ||||
|   )} | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Use the EXCLUDE_OBJECT_START gcode macro to record the current height | ||||
| # | ||||
| [gcode_macro EXCLUDE_OBJECT_START] | ||||
| rename_existing: _EXCLUDE_OBJECT_START | ||||
| gcode: | ||||
|   _EXCLUDE_OBJECT_START {rawparams} | ||||
|   {% if printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'].first_layer %} | ||||
|     SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=first_layer VALUE=False | ||||
|     SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_height VALUE={printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'].print_layer_height} | ||||
|   {% else %} | ||||
|     {% set pos = printer.gcode_move.gcode_position %} | ||||
|     {% set last_height = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'].print_previous_height|float %} | ||||
|     {% if pos.z > last_height %} | ||||
|       {% set last_layer = (pos.z - last_height)|round(2) %} | ||||
|       {% set print_height = (pos.z + last_layer)|round(2) %} | ||||
|       SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_previous_height VALUE={pos.z} | ||||
|       SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_height VALUE={print_height} | ||||
|     {% endif %} | ||||
|   {% endif %} | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Reset the safe descend variables. | ||||
| # | ||||
| [gcode_macro _BLOBIFIER_RESET_SAFE_DESCEND] | ||||
| gcode: | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=tray VALUE=True | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=brush VALUE=True | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=shake VALUE=True | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=first_layer VALUE=True | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_height VALUE=0 | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_previous_height VALUE=0 | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Determine if it is safe to drop the toolhead (e.g. not hit a print) | ||||
| # | ||||
| [gcode_macro _BLOBIFIER_SAFE_DESCEND] | ||||
| variable_tray: True # Assume it is safe | ||||
| variable_brush: True | ||||
| variable_shake: True | ||||
| variable_first_layer: True | ||||
| variable_print_height: 0 | ||||
| variable_print_previous_height: 0 | ||||
| variable_print_layer_height: 0.3 | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set pos_max = printer.toolhead.axis_maximum %} | ||||
|   {% set position_y = pos_max.y - bl.skew_correction %} | ||||
|   {% set tray = [bl.purge_x + bl.toolhead_x, position_y - bl.toolhead_y] %} | ||||
|   {% set brush = [bl.brush_start + bl.brush_width + bl.toolhead_x, position_y - bl.toolhead_y] %} | ||||
|   {% set shake = [bl.purge_x + bl.toolhead_x, position_y - bl.toolhead_y - 4] %} | ||||
|   {% set objects = printer.exclude_object.objects | map(attribute='polygon') %} | ||||
| 
 | ||||
|   {% for polygon in objects %} | ||||
|     {% for point in polygon %} | ||||
|       {% if point[0] < tray[0] and point[1] > tray[1] %} | ||||
|         SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=tray VALUE=False | ||||
|       {% endif %} | ||||
|       {% if point[0] < brush[0] and point[1] > brush[1] %} | ||||
|         SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=brush VALUE=False | ||||
|       {% endif %} | ||||
|       {% if point[0] < shake[0] and point[1] > shake[1] %} | ||||
|         SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=shake VALUE=False | ||||
|       {% endif %} | ||||
|     {% endfor %} | ||||
|   {% endfor %} | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Increment the blob count with 1 and check if the bucket is full. Pause  | ||||
| # the printer if it is. | ||||
| # | ||||
| [gcode_macro _BLOBIFIER_COUNT] | ||||
| # Don't change these variables | ||||
| variable_current_blobs: 0 | ||||
| variable_last_shake: 0 | ||||
| variable_next_shake: 0 | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} | ||||
|   {% if current_blobs >= bl.max_blobs %} | ||||
|     {action_respond_info("BLOBIFIER: Empty purge bucket!")} | ||||
|     M117 Empty purge bucket! | ||||
|     MMU_PAUSE MSG="Empty purge bucket!" | ||||
|   {% else %} | ||||
|     SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE={current_blobs + 1} | ||||
|     _BLOBIFIER_SAVE_STATE | ||||
|     {action_respond_info( | ||||
|       "BLOBIFIER: Blobs in bucket: %s/%s. Next shake @ %s"  | ||||
|       % (current_blobs + 1, bl.max_blobs, next_shake) | ||||
|     )} | ||||
|   {% endif %} | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Reset the blob count to 0 | ||||
| # | ||||
| [gcode_macro _BLOBIFIER_COUNT_RESET] | ||||
| gcode: | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE=0 | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=last_shake VALUE=0 | ||||
|   _BLOBIFIER_SAVE_STATE | ||||
|    | ||||
|   _BLOBIFIER_CALCULATE_NEXT_SHAKE | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Shake the blob bucket to disperse the blobs | ||||
| # | ||||
| [gcode_macro BLOBIFIER_SHAKE_BUCKET] | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} | ||||
|   {% set original_accel = printer.toolhead.max_accel %} | ||||
|   {% set original_minimum_cruise_ratio = printer.toolhead.minimum_cruise_ratio %} | ||||
|   {% set position_x = bl.skew_correction %} | ||||
| 
 | ||||
|   {% if "xyz" not in printer.toolhead.homed_axes %} | ||||
|     {action_raise_error("BLOBIFIER: Not homed. Home xyz first")} | ||||
|   {% endif %} | ||||
|    | ||||
|   SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=last_shake VALUE={count.current_blobs} | ||||
|   _BLOBIFIER_SAVE_STATE | ||||
|   SAVE_GCODE_STATE NAME=shake_bucket | ||||
|    | ||||
|   M400 | ||||
|   M117 (^_^) | ||||
| 
 | ||||
|   G90 | ||||
|   {% set shakes = params.SHAKES|default(10)|int %} | ||||
|   {% set pos_max = printer.toolhead.axis_maximum %} | ||||
|   {% set position_y = pos_max.y - bl.skew_correction %} | ||||
|    | ||||
|   # move to save y if not already there | ||||
|   {% if printer.toolhead.position.y != position_y %} | ||||
|     G1 X{bl.brush_start} Y{position_y} F{bl.travel_spd_xy} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   # Retract the tray | ||||
|   BLOBIFIER_SERVO POS=in | ||||
| 
 | ||||
|   # move up a bit to prevent oozing on base | ||||
|   G1 Z{bl.shaker_arm_z} F{bl.travel_spd_z} | ||||
|   # slide into the slot | ||||
|   G1 X{position_x} F{bl.travel_spd_xy} | ||||
| 
 | ||||
|   M400 | ||||
|   M117 (+(+_+)+) | ||||
| 
 | ||||
|   SET_VELOCITY_LIMIT ACCEL={bl.shake_accel} MINIMUM_CRUISE_RATIO=0.1 | ||||
|    | ||||
|   # Shake away! | ||||
|   {% for shake in range(1, shakes) %} | ||||
|      G1 Y{position_y - 4} | ||||
|      G1 Y{position_y} | ||||
|   {% endfor %} | ||||
| 
 | ||||
|   SET_VELOCITY_LIMIT ACCEL={original_accel} MINIMUM_CRUISE_RATIO={original_minimum_cruise_ratio} | ||||
|   # move out of slot | ||||
|   G1 X{bl.purge_x} | ||||
| 
 | ||||
|   M400 | ||||
|   M117 (X_x) | ||||
| 
 | ||||
|   RESTORE_GCODE_STATE NAME=shake_bucket   | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Calculate when the bucket should be shaken.  | ||||
| # | ||||
| [gcode_macro _BLOBIFIER_CALCULATE_NEXT_SHAKE] | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
|   {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} | ||||
| 
 | ||||
|   {% set remaining_blobs = bl.max_blobs - count.last_shake %} | ||||
|   {% set next_shake = (1 - bl.bucket_shake_frequency) * remaining_blobs + count.last_shake %} | ||||
|   _BLOBIFIER_SAVE_STATE | ||||
|   _BLOBIFIER_SET_NEXT_SHAKE VALUE={next_shake|int} | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Set when the bucket should be shaken next | ||||
| # VALUE=[int] At what amount of blobs should it be shaken | ||||
| # | ||||
| [gcode_macro _BLOBIFIER_SET_NEXT_SHAKE] | ||||
| gcode: | ||||
|   {% if params.VALUE %} | ||||
|     {% set next_shake = params.VALUE %} | ||||
|     SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=next_shake VALUE={next_shake} | ||||
|     _BLOBIFIER_SAVE_STATE | ||||
|   {% else %} | ||||
|     {action_respond_info("BLOBIFIER: Provide parameter VALUE=")} | ||||
|   {% endif %} | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # Some sanity checks | ||||
| # | ||||
| [delayed_gcode BLOBIFIER_INIT] | ||||
| initial_duration: 5.0 | ||||
| gcode: | ||||
|   _BLOBIFIER_INIT | ||||
|   # Extend and retract the tray to test | ||||
|   BLOBIFIER_SERVO POS=out | ||||
|   BLOBIFIER_SERVO POS=in | ||||
| 
 | ||||
| [gcode_macro _BLOBIFIER_INIT] | ||||
| gcode: | ||||
|   {% set bl = printer['gcode_macro BLOBIFIER'] %} | ||||
| 
 | ||||
|   # Valid part cooling fan setting | ||||
|   {% if bl.part_cooling_fan != -1 and (bl.part_cooling_fan < 0 or bl.part_cooling_fan > 1) %} | ||||
|     {action_emergency_stop("BLOBIFIER: Value %f is invalid for variable part_cooling_fan. Either -1 or a value from 0 .. 1 is valid." % (bl.part_cooling_fan))} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   # Valid bucket shake frequency | ||||
|   {% if bl.bucket_shake_frequency < 0 or bl.bucket_shake_frequency > 1 %} | ||||
|     {action_emergency_stop("BLOBIFIER: Value %f is invalid for variable bucket_shake_frequency. Change it to a value between 0 .. 1" % (bl.bucket_shake_frequency))} | ||||
|   {% endif %}   | ||||
| 
 | ||||
|   # Check if position is on 'next' | ||||
|   {% if printer.mmu %} | ||||
|     {% if printer['gcode_macro _MMU_SEQUENCE_VARS'].restore_xy_pos != 'next' %} | ||||
|       {action_respond_info("BLOBIFIER: If not using a wipe tower, consider setting restore_xy_pos: 'next' in mmu_macro_vars.cfg")} | ||||
|     {% endif %} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   # Check the z_raise variable for normal values | ||||
|   {% if bl.z_raise < 3 %} | ||||
|     {action_respond_info("BLOBIFIER: variable_z_raise: %f is very low. This is the value z raises in total on a single blob. Make sure the value is correct before continuing." % (bl.z_raise))} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   # Z raise exponent | ||||
|   {% if bl.z_raise_exp > 1 or bl.z_raise_exp < 0.5 %} | ||||
|     {action_respond_info("BLOBIFIER: variable_z_raise_exp has value: %f. This value is out of spec (0.5 ... 1.0)." % (bl.z_raise_exp))} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   # cap user defined accels at printer max_accel if greater | ||||
|   {% if bl.shake_accel >  printer.configfile.config.printer.max_accel|int %} | ||||
|      {action_respond_info("BLOBIFIER: variable_shake_accel has value: %d which is higher than your printer limit of %d. Reduce this if your printer skips steps." % (bl.shake_accel,printer.configfile.config.printer.max_accel|int))} | ||||
|   {% endif %} | ||||
|   {% if bl.brush_accel >  printer.configfile.config.printer.max_accel|int %} | ||||
|      {action_respond_info("BLOBIFIER: variable_brush_accel has value: %d which is higher than your printer limit of %d. Reduce this if your printer skips steps." % (bl.brush_accel,printer.configfile.config.printer.max_accel|int))} | ||||
|   {% endif %} | ||||
| 
 | ||||
| [delayed_gcode BLOBIFIER_LOAD_STATE] | ||||
| initial_duration: 2.0 # Give it some time to boot up | ||||
| gcode: | ||||
|   {% set sv = printer.save_variables.variables.blobifier %} | ||||
| 
 | ||||
|   {% if sv %} | ||||
|     # Restore state | ||||
|     SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=last_shake VALUE={sv.last_shake} | ||||
|     SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE={sv.current_blobs} | ||||
|   {% endif %} | ||||
|   _BLOBIFIER_CALCULATE_NEXT_SHAKE | ||||
| 
 | ||||
| [gcode_macro _BLOBIFIER_SAVE_STATE] | ||||
| gcode: | ||||
|   {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} | ||||
|   {% set sv = {'current_blobs': count.current_blobs, 'last_shake': count.last_shake} %} | ||||
|   SAVE_VARIABLE VARIABLE=blobifier VALUE="{sv}" | ||||
|  | @ -1,28 +0,0 @@ | |||
| 
 | ||||
| ########################################################################################## | ||||
| # The servo hardware configuration. Change the values to your needs. | ||||
| #  | ||||
| [mmu_servo blobifier] | ||||
| # Pin for the servo. | ||||
| pin: PG14 | ||||
| # Adjust this value until a 'BLOBIFIER_SERVO POS=out' extends the tray fully without a  | ||||
| # buzzing sound | ||||
| minimum_pulse_width: 0.00053 | ||||
| # Adjust this value until a 'BLOBIFIER_SERVO POS=in' retracts the tray fully without a  | ||||
| # buzzing sound | ||||
| maximum_pulse_width: 0.0023 | ||||
| # Leave this value at 180 | ||||
| maximum_servo_angle: 180 | ||||
| 
 | ||||
| 
 | ||||
| ########################################################################################## | ||||
| # The bucket hardware configuration. Change the pin to whatever pin you've connected the  | ||||
| # switch to. | ||||
| #  | ||||
| [gcode_button bucket] | ||||
| pin: ^PG15 # The pullup ( ^ ) is important here. | ||||
| press_gcode: | ||||
|   M117 bucket installed | ||||
| release_gcode: | ||||
|   M117 bucket removed | ||||
|   _BLOBIFIER_COUNT_RESET | ||||
|  | @ -1,31 +0,0 @@ | |||
| # Include servo hardware definition separately to allow for automatic upgrade | ||||
| [include mmu_eject_buttons_hw.cfg] | ||||
| 
 | ||||
| ########################################################################### | ||||
| # Optional hardware MMU eject buttons (e.g. QuattroBox) | ||||
| # | ||||
| # This is the supplementary macro to support dedicated per-gate eject | ||||
| # buttons for easy unloading. It is complimentary to the built-in auto | ||||
| # preload of filament | ||||
| # | ||||
| # To configure: | ||||
| # 1. Add this to your printer.cfg: | ||||
| # | ||||
| #   [include mmu/addons/mmu_eject_buttons.cfg] | ||||
| # | ||||
| 
 | ||||
| ########################################################################### | ||||
| # Macro to simply call MMU_EJECT for the specified gate | ||||
| # | ||||
| # This logic is separated from actual button h/w setup to facilitate upgrades | ||||
| # and to allow addition of logic (perhaps validation or warning logic) | ||||
| # | ||||
| [gcode_macro _MMU_EJECT_BUTTON] | ||||
| description: Wrapper around ejecting filament via dedicated hardware buttons | ||||
| gcode: | ||||
|     {% set gate = params.GATE|default(-1)|int %} | ||||
|     {% set mmu = printer['mmu'] %} | ||||
|     {% set current_gate = mmu.gate %} | ||||
| 
 | ||||
|     # TODO add validation and warning logic | ||||
|     MMU_EJECT GATE={gate} | ||||
|  | @ -1,21 +0,0 @@ | |||
| 
 | ||||
| ########################################################################################## | ||||
| # The eject button hardware configuration. Change the values to your needs and number | ||||
| # of gates | ||||
| #  | ||||
| 
 | ||||
| [gcode_button mmu_eject_button_0] | ||||
| pin: mmu:EJECT_BUTTON_0 | ||||
| press_gcode: _MMU_EJECT_BUTTON GATE=0 | ||||
| 
 | ||||
| [gcode_button mmu_eject_button_1] | ||||
| pin: mmu:EJECT_BUTTON_1 | ||||
| press_gcode: _MMU_EJECT_BUTTON GATE=1 | ||||
| 
 | ||||
| [gcode_button mmu_eject_button_2] | ||||
| pin: mmu:EJECT_BUTTON_2 | ||||
| press_gcode: _MMU_EJECT_BUTTON GATE=2 | ||||
| 
 | ||||
| [gcode_button mmu_eject_button_3] | ||||
| pin: mmu:EJECT_BUTTON_3 | ||||
| press_gcode: _MMU_EJECT_BUTTON GATE=3 | ||||
|  | @ -1,91 +0,0 @@ | |||
| # Include servo hardware definition separately to allow for automatic upgrade | ||||
| [include mmu_erec_cutter_hw.cfg] | ||||
| 
 | ||||
| ########################################################################### | ||||
| # Optional EREC Filament Cutter Support | ||||
| # | ||||
| # https://github.com/kevinakasam/ERCF_Filament_Cutter | ||||
| #  | ||||
| # This is the supplementary macro to support filament cutting at the MMU | ||||
| # on a ERCF design. | ||||
| # | ||||
| # To configure: | ||||
| # 1. Add this to your printer.cfg: | ||||
| # | ||||
| #   [include mmu/addons/mmu_erec_cutter.cfg] | ||||
| # | ||||
| # 2. In mmu_macro_vars.cfg, change this line: | ||||
| # | ||||
| #   variable_user_post_unload_extension : "EREC_CUTTER_ACTION" | ||||
| # | ||||
| # 3. Tune the servo configuration and macro "variables" below | ||||
| # | ||||
| 
 | ||||
| # EREC CUTTER CONFIGURATION ----------------------------------------------- | ||||
| #   (addons/mmu_erec_cutter.cfg) | ||||
| # | ||||
| [gcode_macro _EREC_VARS] | ||||
| description: Empty macro to store the variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # These variables control the servo movement | ||||
| variable_servo_closed_angle   : 70	; Servo angle for closed position with bowden aligned MMU | ||||
| variable_servo_open_angle     : 10	; Servo angle to open up the cutter and move bowden away from MMU | ||||
| variable_servo_duration       : 1.5	; Time (s) of PWM pulse train to activate servo | ||||
| variable_servo_idle_time      : 1.8	; Time (s) to let the servo to reach it's position | ||||
| 
 | ||||
| # Controls for feed and cut lengths | ||||
| variable_feed_length          : 48	; Distance in mm from gate parking position to blade (ERCFv1.1: 58, v2/other: 48) | ||||
| variable_cut_length           : 10	; Amount in mm of filament to cut | ||||
| variable_cut_attempts         : 1	; Number of times the cutter tries to cut the filament | ||||
| 
 | ||||
| 
 | ||||
| ########################################################################### | ||||
| # Macro to perform the cutting step. Designed to be included to the | ||||
| # _MMU_POST_UNLOAD step | ||||
| # | ||||
| [gcode_macro EREC_CUTTER_ACTION] | ||||
| description: Cut off the filament tip at the MMU after the unload sequence is complete | ||||
| gcode: | ||||
|     {% set vars = printer["gcode_macro _EREC_VARS"] %} | ||||
|      | ||||
|     MMU_LOG MSG="Cutting filament tip..." | ||||
| 
 | ||||
|     _CUTTER_OPEN | ||||
|     _MMU_STEP_MOVE MOVE={vars.feed_length + vars.cut_length} | ||||
|     {% for i in range(vars.cut_attempts - 1) %} | ||||
|         _CUTTER_CLOSE | ||||
|         _CUTTER_OPEN | ||||
|     {% endfor %} | ||||
|     _MMU_STEP_MOVE MOVE=-1 | ||||
|     _CUTTER_CLOSE | ||||
|     _MMU_EVENT EVENT="filament_cut"	# Count as one cut for consumption counter | ||||
|      | ||||
|     _MMU_STEP_SET_FILAMENT STATE=2	# FILAMENT_POS_START_BOWDEN | ||||
|     _MMU_STEP_UNLOAD_GATE		# Repeat gate parking move | ||||
|     _MMU_M400				# Wait on both move queues | ||||
| 
 | ||||
| [gcode_macro _CUTTER_ANGLE] | ||||
| description: Helper macro to set cutter servo angle | ||||
| gcode: | ||||
|     {% set angle = params.ANGLE|default(0)|int %} | ||||
|     SET_SERVO SERVO=cut_servo ANGLE={angle} | ||||
|      | ||||
| [gcode_macro _CUTTER_CLOSE] | ||||
| description: Helper macro to set cutting servo the closed position | ||||
| gcode: | ||||
|     {% set vars = printer["gcode_macro _EREC_VARS"] %} | ||||
|     SET_SERVO SERVO=cut_servo ANGLE={vars.servo_closed_angle} DURATION={vars.servo_duration} | ||||
|     G4 P{vars.servo_idle_time * 1000} | ||||
|     RESPOND MSG="EREC Cutter closed" | ||||
|     M400 | ||||
| 
 | ||||
| [gcode_macro _CUTTER_OPEN] | ||||
| description: Helper macro to set cutting servo the open position | ||||
| gcode: | ||||
|     {% set vars = printer["gcode_macro _EREC_VARS"] %} | ||||
|     SET_SERVO SERVO=cut_servo ANGLE={vars.servo_open_angle} DURATION={vars.servo_duration} | ||||
|     G4 P{vars.servo_idle_time * 1000} | ||||
|     RESPOND MSG="EREC Cutter open" | ||||
|     M400 | ||||
| 
 | ||||
|  | @ -1,10 +0,0 @@ | |||
| 
 | ||||
| ########################################################################################## | ||||
| # The servo hardware configuration. Change the values to your needs. | ||||
| #  | ||||
| [mmu_servo cut_servo] | ||||
| pin: mmu:PA7			# Extra Pin on the ERCF easy Board | ||||
| maximum_servo_angle: 180	# Set this to 60 for a 60° Servo | ||||
| minimum_pulse_width: 0.0005	# Adapt these for your servo | ||||
| maximum_pulse_width: 0.0025	# Adapt these for your servo | ||||
| 
 | ||||
|  | @ -1,154 +0,0 @@ | |||
| ######################################################################################################################## | ||||
| # 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 pin config | ||||
| # | ||||
| # (\_/) | ||||
| # ( *,*) | ||||
| # (")_(") Happy Hare Ready | ||||
| # | ||||
| # | ||||
| # This contains aliases for pins for MCU type MMB11 | ||||
| # | ||||
| #[mcu oldmmu] | ||||
| #canbus_uuid: 214adf7db8eb	# Change to `canbus_uuid: 1234567890` for CANbus setups | ||||
| 
 | ||||
| [mcu mmu] | ||||
| canbus_uuid: 029f6dc0d75b | ||||
| 
 | ||||
| # PIN ALIASES FOR MMU MCU BOARD ---------------------------------------------------------------------------------------- | ||||
| # ██████╗ ██╗███╗   ██╗     █████╗ ██╗     ██╗ █████╗ ███████╗ | ||||
| # ██╔══██╗██║████╗  ██║    ██╔══██╗██║     ██║██╔══██╗██╔════╝ | ||||
| # ██████╔╝██║██╔██╗ ██║    ███████║██║     ██║███████║███████╗ | ||||
| # ██╔═══╝ ██║██║╚██╗██║    ██╔══██║██║     ██║██╔══██║╚════██║ | ||||
| # ██║     ██║██║ ╚████║    ██║  ██║███████╗██║██║  ██║███████║ | ||||
| # ╚═╝     ╚═╝╚═╝  ╚═══╝    ╚═╝  ╚═╝╚══════╝╚═╝╚═╝  ╚═╝╚══════╝ | ||||
| # Section to create alias for pins used by MMU for easier integration into Klippain and RatOS. The names match those | ||||
| # referenced in the mmu_hardware.cfg file. If you get into difficulty you can also comment out this aliases definition | ||||
| # completely and configure the pin names directly into mmu_hardware.cfg. However, use of aliases is encouraged. | ||||
| 
 | ||||
| # Note: that aliases are not created for TOOLHEAD_SENSOR, EXTRUDER_SENSOR or SYNC_FEEDBACK_SENSORS because those are | ||||
| # most likely on the printer's main mcu. These should be set directly in mmu_hardware.cfg | ||||
| # | ||||
| # [board_pins oldmmu] | ||||
| # mcu: mmu # Assumes using an external / extra mcu dedicated to MMU | ||||
| # aliases: | ||||
| #     MMU_GEAR_UART=PA10, | ||||
| #     MMU_GEAR_STEP=PB15, | ||||
| #     MMU_GEAR_DIR=PB14, | ||||
| #     MMU_GEAR_ENABLE=PB8, | ||||
| #     MMU_GEAR_DIAG=PA3, | ||||
| 
 | ||||
| #     MMU_GEAR_UART_1=, | ||||
| #     MMU_GEAR_STEP_1=, | ||||
| #     MMU_GEAR_DIR_1=, | ||||
| #     MMU_GEAR_ENABLE_1=, | ||||
| #     MMU_GEAR_DIAG_1=, | ||||
| 
 | ||||
| #     MMU_GEAR_UART_2=, | ||||
| #     MMU_GEAR_STEP_2=, | ||||
| #     MMU_GEAR_DIR_2=, | ||||
| #     MMU_GEAR_ENABLE_2=, | ||||
| #     MMU_GEAR_DIAG_2=, | ||||
| 
 | ||||
| #     MMU_GEAR_UART_3=, | ||||
| #     MMU_GEAR_STEP_3=, | ||||
| #     MMU_GEAR_DIR_3=, | ||||
| #     MMU_GEAR_ENABLE_3=, | ||||
| #     MMU_GEAR_DIAG_3=, | ||||
| 
 | ||||
| #     MMU_SEL_UART=PC7, | ||||
| #     MMU_SEL_STEP=PD2, | ||||
| #     MMU_SEL_DIR=PB13, | ||||
| #     MMU_SEL_ENABLE=PD1, | ||||
| #     MMU_SEL_DIAG=PA4, | ||||
| #     MMU_SEL_ENDSTOP=PB2, | ||||
| #     MMU_SEL_SERVO=PA0, | ||||
| 
 | ||||
| #     MMU_ENCODER=PA1, | ||||
| #     MMU_GATE_SENSOR=, | ||||
| #     MMU_NEOPIXEL=PA2, | ||||
| 
 | ||||
| #     MMU_PRE_GATE_0=, | ||||
| #     MMU_PRE_GATE_1=PA3, | ||||
| #     MMU_PRE_GATE_2=, | ||||
| #     MMU_PRE_GATE_3=, | ||||
| #     MMU_PRE_GATE_4=, | ||||
| #     MMU_PRE_GATE_5=, | ||||
| #     MMU_PRE_GATE_6=, | ||||
| #     MMU_PRE_GATE_7=, | ||||
| #     MMU_PRE_GATE_8=, | ||||
| #     MMU_PRE_GATE_9=, | ||||
| #     MMU_PRE_GATE_10=, | ||||
| #     MMU_PRE_GATE_11=, | ||||
| 
 | ||||
| #     MMU_POST_GEAR_0=, | ||||
| #     MMU_POST_GEAR_1=, | ||||
| #     MMU_POST_GEAR_2=, | ||||
| #     MMU_POST_GEAR_3=, | ||||
| #     MMU_POST_GEAR_4=, | ||||
| #     MMU_POST_GEAR_5=, | ||||
| #     MMU_POST_GEAR_6=, | ||||
| #     MMU_POST_GEAR_7=, | ||||
| #     MMU_POST_GEAR_8=, | ||||
| #     MMU_POST_GEAR_9=, | ||||
| #     MMU_POST_GEAR_10=, | ||||
| #     MMU_POST_GEAR_11=, | ||||
| 
 | ||||
| [board_pins mmu] | ||||
| mcu: mmu # Assumes using an external / extra mcu dedicated to MMU | ||||
| aliases: | ||||
|     MMU_GEAR_UART=gpio9, | ||||
|     MMU_GEAR_STEP=gpio7, | ||||
|     MMU_GEAR_DIR=gpio8, | ||||
|     MMU_GEAR_ENABLE=gpio6, | ||||
|     MMU_GEAR_DIAG=gpio23, | ||||
| 
 | ||||
|     MMU_SEL_UART=gpio0, | ||||
|     MMU_SEL_STEP=gpio2, | ||||
|     MMU_SEL_DIR=gpio1, | ||||
|     MMU_SEL_ENABLE=gpio3, | ||||
|     MMU_SEL_DIAG=gpio22, | ||||
| 
 | ||||
|     MMU_SEL_ENDSTOP=gpio20, | ||||
|     MMU_SEL_SERVO=gpio21, | ||||
| 
 | ||||
|     MMU_ENCODER=gpio15, | ||||
|     MMU_NEOPIXEL=gpio14, | ||||
|     MMU_GATE_SENSOR=, | ||||
| 
 | ||||
|     MMU_PRE_GATE_0=gpio10, | ||||
|     MMU_PRE_GATE_1=gpio11, | ||||
|     MMU_PRE_GATE_2=gpio12, | ||||
|     MMU_PRE_GATE_3=gpio24, | ||||
|     MMU_PRE_GATE_4=gpio13, | ||||
|     MMU_PRE_GATE_5=gpio26, | ||||
|     MMU_PRE_GATE_6=gpio27, | ||||
|     MMU_PRE_GATE_7=gpio28, | ||||
|     MMU_PRE_GATE_8=, | ||||
|     MMU_PRE_GATE_9=, | ||||
|     MMU_PRE_GATE_10=, | ||||
|     MMU_PRE_GATE_11=, | ||||
| 
 | ||||
|     MMU_POST_GEAR_0=, | ||||
|     MMU_POST_GEAR_1=, | ||||
|     MMU_POST_GEAR_2=, | ||||
|     MMU_POST_GEAR_3=, | ||||
|     MMU_POST_GEAR_4=, | ||||
|     MMU_POST_GEAR_5=, | ||||
|     MMU_POST_GEAR_6=, | ||||
|     MMU_POST_GEAR_7=, | ||||
|     MMU_POST_GEAR_8=, | ||||
|     MMU_POST_GEAR_9=, | ||||
|     MMU_POST_GEAR_10=, | ||||
|     MMU_POST_GEAR_11=, | ||||
| 
 | ||||
| [temperature_sensor MMB] | ||||
| sensor_type: temperature_mcu | ||||
| sensor_mcu: mmu | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_cut_tip.cfg | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_form_tip.cfg | ||||
|  | @ -1,368 +0,0 @@ | |||
| ######################################################################################################################## | ||||
| # 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.8			# ERCF BOM NEMA17 motor | ||||
| hold_current: 0.6			# 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 (8-1) | ||||
| #entry_leds:  neopixel:mmu_leds (9-16) | ||||
| #status_leds: neopixel:mmu_leds (17) | ||||
| #logo_leds:   neopixel:mmu_leds (18) | ||||
| frame_rate: 24 | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_leds.cfg | ||||
|  | @ -1,536 +0,0 @@ | |||
| ######################################################################################################################## | ||||
| # 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 supporting MACRO configuration | ||||
| # | ||||
| # (\_/) | ||||
| # ( *,*) | ||||
| # (")_(") Happy Hare Ready | ||||
| # | ||||
| # | ||||
| # Supporting set of macros supplied with Happy Hare can be customized by editing the macro "variables" declared here. | ||||
| # | ||||
| # This configuration will automatically retained and upgraded between releases (a backup of previous config files will | ||||
| # always be made for your reference). If you want to customize macros beyond what is possible through these variables | ||||
| # it is highly recommended you copy the macro to a new name and change the callback macro name in 'mmu_parameters.cfg' | ||||
| # That way the default macros can still be upgraded but your customization will be left intact | ||||
| # | ||||
| 
 | ||||
| 
 | ||||
| # PERSISTED STATE --------------------------------------------------------- | ||||
| # Happy Hare stores configuration and state in the klipper variables file. | ||||
| # Since klipper can only be a single 'save_variables' file, if you already | ||||
| # have one you will need to merge the two and point this appropriately. | ||||
| # | ||||
| [save_variables] | ||||
| filename: ~/printer_data/config/mmu/mmu_vars.cfg | ||||
| 
 | ||||
| 
 | ||||
| # NECESSARY KLIPPER OVERRIDES --------------------------------------------- | ||||
| # ██╗  ██╗██╗     ██╗██████╗ ██████╗ ███████╗██████╗  | ||||
| # ██║ ██╔╝██║     ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗ | ||||
| # █████╔╝ ██║     ██║██████╔╝██████╔╝█████╗  ██████╔╝ | ||||
| # ██╔═██╗ ██║     ██║██╔═══╝ ██╔═══╝ ██╔══╝  ██╔══██╗ | ||||
| # ██║  ██╗███████╗██║██║     ██║     ███████╗██║  ██║ | ||||
| # ╚═╝  ╚═╝╚══════╝╚═╝╚═╝     ╚═╝     ╚══════╝╚═╝  ╚═╝ | ||||
| # | ||||
| # These supplemental settings essentially disable klipper's built in | ||||
| # extrusion limits and is necessary when using an MMU | ||||
| [extruder] | ||||
| max_extrude_only_distance: 200 | ||||
| max_extrude_cross_section: 50 | ||||
| 
 | ||||
| # For dialog prompts and progress in Mainsail. Requires Mainsail version >= v2.9.0 | ||||
| [respond] | ||||
| 
 | ||||
| # Other Happy Hare prerequisites. Harmless if already defined elsewhere in user config | ||||
| [display_status] | ||||
| [pause_resume] | ||||
| [virtual_sdcard] | ||||
| path: ~/printer_data/gcodes | ||||
| #on_error_gcode: CANCEL_PRINT | ||||
| 
 | ||||
| 
 | ||||
| # PRINT START/END --------------------------------------------------------- | ||||
| # ██████╗ ██████╗ ██╗███╗   ██╗████████╗    ███████╗████████╗ █████╗ ██████╗ ████████╗ | ||||
| # ██╔══██╗██╔══██╗██║████╗  ██║╚══██╔══╝    ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | ||||
| # ██████╔╝██████╔╝██║██╔██╗ ██║   ██║       ███████╗   ██║   ███████║██████╔╝   ██║    | ||||
| # ██╔═══╝ ██╔══██╗██║██║╚██╗██║   ██║       ╚════██║   ██║   ██╔══██║██╔══██╗   ██║    | ||||
| # ██║     ██║  ██║██║██║ ╚████║   ██║       ███████║   ██║   ██║  ██║██║  ██║   ██║    | ||||
| # ╚═╝     ╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝   ╚═╝       ╚══════╝   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝    | ||||
| #   (base/mmu_software.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_SOFTWARE_VARS] | ||||
| description: Happy Hare optional configuration for print start/end checks | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # These variables control the behavior of the MMU_START_SETUP and MMU_START_LOAD_INITIAL_TOOL macros | ||||
| variable_user_pre_initialize_extension      : ''	; Executed at start of MMU_START_SETUP. Commonly G28 to home | ||||
| variable_home_mmu                           : False	; True/False, Whether to home mmu before print starts | ||||
| variable_check_gates                        : True	; True/False, Whether to check filament is loaded in all gates used | ||||
| variable_load_initial_tool                  : True	; True/False, Whether to automatically load initial tool | ||||
| # | ||||
| # Automapping strategy to apply slicer tool map to find matching MMU gate (will adjust tool-to-gate map). Options are: | ||||
| #   'none'           - don't automap (i.e. don't update tool-to-gate map) | ||||
| #   'filament_name'  - exactly match on case insensitive filament name | ||||
| #   'material'       - exactly match on material | ||||
| #   'color'          - exactly match on color (with same material) | ||||
| #   'closest_color'  - match to closest available filament color (with same material) | ||||
| #   'spool_id'       - exactly match on spool_id  [FUTURE] | ||||
| variable_automap_strategy                   : "none"	; none|filament_name|material|color|closest_color|spool_id | ||||
| 
 | ||||
| # These variables control the behavior of the MMU_END macro | ||||
| variable_user_print_end_extension           : ''	; Executed at start of MMU_END. Good place to move off print | ||||
| variable_unload_tool                        : True	; True/False, Whether to unload the tool at the end of the print | ||||
| variable_reset_ttg                          : False	; True/False, Whether reset TTG map at end of print | ||||
| variable_dump_stats                         : True	; True/False, Whether to display print stats at end of print | ||||
| 
 | ||||
| 
 | ||||
| # STATE MACHINE CHANGES --------------------------------------------------- | ||||
| # ███████╗████████╗ █████╗ ████████╗███████╗     ██████╗██╗  ██╗ █████╗ ███╗   ██╗ ██████╗ ███████╗ | ||||
| # ██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝    ██╔════╝██║  ██║██╔══██╗████╗  ██║██╔════╝ ██╔════╝ | ||||
| # ███████╗   ██║   ███████║   ██║   █████╗      ██║     ███████║███████║██╔██╗ ██║██║  ███╗█████╗   | ||||
| # ╚════██║   ██║   ██╔══██║   ██║   ██╔══╝      ██║     ██╔══██║██╔══██║██║╚██╗██║██║   ██║██╔══╝   | ||||
| # ███████║   ██║   ██║  ██║   ██║   ███████╗    ╚██████╗██║  ██║██║  ██║██║ ╚████║╚██████╔╝███████╗ | ||||
| # ╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝   ╚══════╝     ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚══════╝ | ||||
| #   (base/mmu_state.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_STATE_VARS] | ||||
| description: Happy Hare configuration for state change hooks | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # You can extend functionality to all Happy Hare state change or event | ||||
| # macros by adding a command (or call to your gcode macro). | ||||
| # E.g for additional LED logic or consumption counters | ||||
| variable_user_action_changed_extension      : ''	; Executed after default logic with duplicate params | ||||
| variable_user_print_state_changed_extension : ''	; Executed after default logic with duplicate params | ||||
| variable_user_mmu_event_extension           : ''	; Executed after default logic with duplicate params | ||||
| 
 | ||||
| # Maintenance warning limits (consumption counters) | ||||
| variable_servo_down_limit                   : 5000      ; Set to -1 for no limit / disable warning | ||||
| variable_cutter_blade_limit                 : 3000      ; Set to -1 for no limit / disable warning | ||||
| 
 | ||||
| 
 | ||||
| # LED CONTROL ------------------------------------------------------------- | ||||
| # ██╗     ███████╗██████╗ ███████╗ | ||||
| # ██║     ██╔════╝██╔══██╗██╔════╝ | ||||
| # ██║     █████╗  ██║  ██║███████╗ | ||||
| # ██║     ██╔══╝  ██║  ██║╚════██║ | ||||
| # ███████╗███████╗██████╔╝███████║ | ||||
| # ╚══════╝╚══════╝╚═════╝ ╚══════╝ | ||||
| # Only configure if you have LEDs installed. The led_effects option is | ||||
| # automatically ignored if led-effects klipper module is not installed | ||||
| #   (base/mmu_led.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_LED_VARS] | ||||
| description: Happy Hare led macro configuration variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # Default effects for LED segments when not providing action status | ||||
| #   'off'             - LED's off | ||||
| #   'on'              - LED's white | ||||
| #   'gate_status'     - indicate gate availability / status            (printer.mmu.gate_status) | ||||
| #   'filament_color'  - display filament color defined in gate map     (printer.mmu.gate_color_rgb) | ||||
| #   'slicer_color'    - display slicer defined set color for each gate (printer.mmu.slicer_color_rgb) | ||||
| #   'r,g,b'           - display static r,g,b color e.g. "0,0,0.3" for dim blue | ||||
| #   '_effect_'        - display the named led effect | ||||
| # | ||||
| variable_led_enable             : True			; True = LEDs are enabled at startup (MMU_LED can control), False = Disabled | ||||
| variable_led_animation          : True			; True = Use led-animation-effects, False = Static LEDs | ||||
| variable_default_exit_effect    : "gate_status"		;    off|gate_status|filament_color|slicer_color|r,g,b|_effect_ | ||||
| variable_default_entry_effect   : "filament_color"	;    off|gate_status|filament_color|slicer_color|r,g,b|_effect_ | ||||
| variable_default_status_effect  : "filament_color"	; on|off|gate_status|filament_color|slicer_color|r,g,b|_effect_ | ||||
| variable_default_logo_effect    : "0,0,.3"		;    off                                        |r,g,b|_effect_ | ||||
| variable_white_light            : (1, 1, 1)		; RGB color for static white light | ||||
| variable_black_light            : (.01, 0, .02)		; RGB color used to represent "black" (filament) | ||||
| variable_empty_light            : (0, 0, 0)		; RGB color used to represent empty gate | ||||
| 
 | ||||
| 
 | ||||
| # SEQUENCE MACRO - PARKING MOVEMENT AND TOOLCHANGE CONTROL ---------------- | ||||
| # ███╗   ███╗ ██████╗ ██╗   ██╗███████╗███╗   ███╗███████╗███╗   ██╗████████╗ | ||||
| # ████╗ ████║██╔═══██╗██║   ██║██╔════╝████╗ ████║██╔════╝████╗  ██║╚══██╔══╝ | ||||
| # ██╔████╔██║██║   ██║██║   ██║█████╗  ██╔████╔██║█████╗  ██╔██╗ ██║   ██║    | ||||
| # ██║╚██╔╝██║██║   ██║╚██╗ ██╔╝██╔══╝  ██║╚██╔╝██║██╔══╝  ██║╚██╗██║   ██║    | ||||
| # ██║ ╚═╝ ██║╚██████╔╝ ╚████╔╝ ███████╗██║ ╚═╝ ██║███████╗██║ ╚████║   ██║    | ||||
| # ╚═╝     ╚═╝ ╚═════╝   ╚═══╝  ╚══════╝╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝   ╚═╝    | ||||
| # Configure carefully if you 'enable_park: True' | ||||
| #   (base/mmu_sequence.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_SEQUENCE_VARS] | ||||
| description: Happy Hare sequence macro configuration variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # Parking and movement controls: | ||||
| # Happy Hare defines 7 operations that may require parking. You can specify | ||||
| # whether to park for each of those operations both during a print and | ||||
| # standalone (not printing) with Happy Hare or when HH is disabled: | ||||
| # | ||||
| # enable_park_printing | ||||
| #    This is a list of the operations that should result in toolhead parking | ||||
| #    while in a print. There are really two main starting points from which | ||||
| #    you can customize. If using the slicer to form tips (and toolchange is | ||||
| #    over the wipetower) you don't want to park on "toolchange" but you would | ||||
| #    want to on "runout" which is a forced toolchange unknown by the slicer. | ||||
| #    Typically you would also want to park at least on pause, cancel and | ||||
| #    complete if not done elsewhere | ||||
| # | ||||
| # enabled_park_standalone | ||||
| #    List of the operations that should result in toolhead parking when not | ||||
| #    printing, for example, just manipulating the MMU manually or via | ||||
| #    Klipperscreen. Really it is up to you to choose based on personal | ||||
| #    workflow preferences but this defaults to just 'pause,cancel' | ||||
| #    (i.e. disabled for toolchange) | ||||
| # | ||||
| # enabled_park_disabled | ||||
| #    List of the operations that should result in toolhead parking when MMU is | ||||
| #    disabled (MMU ENABLE=0) and using Happy Hare client macros. Note that only | ||||
| #    pause and cancel can occur in this mode and would typically be enabled | ||||
| # | ||||
| # The operations are as follows: | ||||
| #   toolchange - normal toolchange initiated with Tx or MMU_CHANGE_TOOL command | ||||
| #   runout     - when a forced toolchange occurs as a result of runout | ||||
| #   load       - individual MMU_LOAD operation | ||||
| #   unload     - individual MMU_UNLOAD/MMU_EJECT operation | ||||
| #   complete   - when print is complete (Happy Hare enabled) | ||||
| #   pause      - a regular klipper PAUSE | ||||
| #   cancel     - a regular klipper CANCEL_PRINT | ||||
| # | ||||
| # It is possible to call the parking macro manually in this form should you wish | ||||
| # to include in your macros. | ||||
| # | ||||
| #    _MMU_PARK FORCE_PARK=1 X=10 Y=10 Z_HOP=5 | ||||
| # | ||||
| # restore_xy_pos | ||||
| #    Controls where the toolhead (x,y) is returned to after an operation that | ||||
| #    invokes a parking move: | ||||
| #   last - return to original position before park (frequently the default) | ||||
| #   next - return to next print position if possible else last logic will be applied. | ||||
| #          In print this reduces dwell time at the last position reducing blobbing | ||||
| #          and unnecessary movement. Only applied to "toolchange" operation | ||||
| #   none - the toolhead is left wherever it ends up after change. In a print the | ||||
| #          next gcode command will restore toolhead x,y position | ||||
| # | ||||
| # Notes: | ||||
| # - The starting z-height will always be restored, thus the different between 'next' | ||||
| #   and 'none' is the z-height at which the (x,y) move occurs and the location of | ||||
| #   of any un-retract | ||||
| # - The default parking logic is a straight line move to the 'park_*' position. | ||||
| #   To implement fancy movement and control you can specify your own | ||||
| #   'user_park_move_macro' to use instead of default straight line move | ||||
| # - x,y parking coordinates can be negative if your printer can handle it | ||||
| # | ||||
| # Retraction can be used to optimize stringing and blobs that can occur when | ||||
| # changing tools and are active only during a print. | ||||
| # IMPORTANT: For toolchanging the config order would be: | ||||
| #   1. In mmu_parameters.cfg configure extruder dimensions like | ||||
| #      'toolhead_extruder_to_nozzle',etc. These are based on geometry. | ||||
| #   2. In mmu_parameters.cfg tweak 'toolhead_ooze_reduction' only if necessary | ||||
| #      so that filament _just_ appears at the nozzle on load | ||||
| #   3. Only then, adjust retraction to control stringing and blobs when | ||||
| #      changing tool in a print | ||||
| variable_enable_park_printing   : 'toolchange,runout,load,unload,complete,pause,cancel'	; Empty '' to disable parking | ||||
| variable_enable_park_standalone : 'toolchange,load,unload,pause,cancel'			; Empty '' to disable parking | ||||
| variable_enable_park_disabled   : 'pause,cancel'					; Empty '' to disable parking | ||||
| 
 | ||||
| variable_min_toolchange_z       : 1.0		; The absolute minimum safety floor (z-height) for ALL parking moves | ||||
| 
 | ||||
| # These specify the parking location, z_hop and retraction for all enabled operation | ||||
| # types. Each must be 5 values: | ||||
| #   x_coord, y_coord, z_hop(delta), z_hop_ramp, retraction length | ||||
| # Use -999,-999 for no x,y move (you can just have z_hop). Use 0 for no z_hop | ||||
| # The z_hop ramp is the horizontal distance in mm to travel during the lift. The | ||||
| # direction is automatic and only applied if lifting the first time from print. | ||||
| # This move is useful to help break the filament "string" | ||||
| variable_park_toolchange        : -999, -999, 1, 5, 2	; x,y,z-hop,z_hop_ramp,retract for "toolchange" operations (toolchange,load,unload) | ||||
| variable_park_runout            : -999, -999, 1, 5, 2	; x,y,z-hop,z_hop_ramp,retract | ||||
| variable_park_pause             : 50, 50, 5, 0, 2	; x,y,z-hop,z_hop_ramp,retract (park position when mmu error occurs) | ||||
| variable_park_cancel            : -999, -999, 10, 0, 5	; x,y,z-hop,z_hop_ramp,retract | ||||
| variable_park_complete          : 50, 50, 10, 0, 5	; x,y,z-hop,z_hop_ramp,retract | ||||
| 
 | ||||
| # For toolchange operations, this allows to you to specify additional parking moves | ||||
| # at various stages of the toolchange. Each must have 3 values: | ||||
| #   x_coord, y_coord, z_hop(delta) | ||||
| # Use -999,-999,0 for no movement at that stage (no-op). | ||||
| # All movement will be at the established movement plane (z-height) | ||||
| variable_pre_unload_position    : -999, -999, 0	; x,y,z-hop position before unloading starts | ||||
| variable_post_form_tip_position : -999, -999, 0	; x,y,z-hop position after form/cut tip on unload | ||||
| variable_pre_load_position      : -999, -999, 0	; x,y,z-hop position before loading starts | ||||
| 
 | ||||
| variable_restore_xy_pos         : "last"	; last|next|none - What x,y position the toolhead should travel to after a "toolchange" | ||||
| 
 | ||||
| variable_park_travel_speed      : 200		; Speed for any travel movement XY(Z) in mm/s | ||||
| variable_park_lift_speed        : 15		; Z-only travel speed in mm/s | ||||
| variable_retract_speed          : 30		; Speed of the retract move in mm/s | ||||
| variable_unretract_speed        : 30		; Speed of the unretract move in mm/s | ||||
| 
 | ||||
| # ADVANCED: Normally x,y moves default to 'G1 X Y' to park position. This allows | ||||
| # you to create exotic movements. Macro will be provided the following parameters: | ||||
| #    YOUR_MOVE_MACRO X=<x_coord> Y=<y_coord> F=<speed> | ||||
| # when restoring the from parked postion the same macro is called but passed a RESTORE=1 parameter, along with co-ordinates to restore to | ||||
| #    YOUR_MOVE_MACRO RESTORE=1 X=<x_coord> Y=<y_coord> F=<speed> | ||||
| variable_user_park_move_macro   : ''		; Executed instead of default 'G1 X Y move' to park position | ||||
| 
 | ||||
| variable_auto_home              : True          ; True = automatically home if necessary, False = disable | ||||
| variable_timelapse              : False		; True = take frame snapshot after load, False = disable | ||||
| 
 | ||||
| # Instead of completely defining your your own macros you can can extend functionality | ||||
| # of default sequence macros by adding a command (or call to your gcode macro) | ||||
| variable_user_mmu_error_extension     : ''	; Executed after default logic when mmu error condition occurs | ||||
| variable_user_pre_unload_extension    : ''	; Executed after default logic | ||||
| variable_user_post_form_tip_extension : ''	; Executed after default logic | ||||
| variable_user_post_unload_extension   : ''	; Executed after default logic | ||||
| variable_user_pre_load_extension      : ''	; Executed after default logic | ||||
| variable_user_post_load_extension     : 'CLEAN_NOZZLE'	; Executed after default logic but before restoring toolhead position | ||||
| 
 | ||||
| 
 | ||||
| # CUT_TIP ----------------------------------------------------------------- | ||||
| #  ██████╗██╗   ██╗████████╗    ████████╗██╗██████╗  | ||||
| # ██╔════╝██║   ██║╚══██╔══╝    ╚══██╔══╝██║██╔══██╗ | ||||
| # ██║     ██║   ██║   ██║          ██║   ██║██████╔╝ | ||||
| # ██║     ██║   ██║   ██║          ██║   ██║██╔═══╝  | ||||
| # ╚██████╗╚██████╔╝   ██║          ██║   ██║██║      | ||||
| #  ╚═════╝ ╚═════╝    ╚═╝          ╚═╝   ╚═╝╚═╝      | ||||
| # Don't need to configure if using tip forming | ||||
| #   (base/mmu_cut_tip.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_CUT_TIP_VARS] | ||||
| description: Happy Hare toolhead tip cutting macro configuration variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # Whether the toolhead tip cutting macro will return toolhead to initial position | ||||
| # after the cut is complete. If using parking logic it is better to disable this | ||||
| variable_restore_position       : False		; True = return to initial position, False = don't return | ||||
| 
 | ||||
| # Distance from the internal nozzle tip to the cutting blade. This dimension | ||||
| # is based on your toolhead and should not be used for tuning | ||||
| # Note: If you have a toolhead sensor this variable can be automatically determined! | ||||
| # Read https://github.com/moggieuk/Happy-Hare/wiki/Blobing-and-Stringing | ||||
| variable_blade_pos              : 37.5		; TUNE ME: Distance in mm from internal nozzle tip | ||||
| 
 | ||||
| # Distance to retract prior to making the cut, measured from the internal nozzle | ||||
| # tip. This reduces wasted filament (left behind in extruder) but might cause a | ||||
| # clog if set too large. This must be less than 'blade_pos' | ||||
| # Note: the residual filament left in nozzle ('toolhead_ooze_reduction') is | ||||
| # subtracted from this value so make sure toolhead is calibrated | ||||
| variable_retract_length         : 32.5		; TUNE ME: 5mm less than 'blade_pos' is a good starting point | ||||
| 
 | ||||
| # Whether to perform a simple tip forming move after the initial retraction | ||||
| # Enabling this adds gives some additional cooling time of molten filament and | ||||
| # may help avoid potential clogging on some hotends | ||||
| variable_simple_tip_forming     : False		; True = Perform simple tip forming, False = skip | ||||
| 
 | ||||
| # Change to X and Y stepper current during the cut operation. Technically any stepper | ||||
| # current can be modified by adding the stepper name to the list. Be careful not to | ||||
| # overload your steppers but generally up to 150% is safe | ||||
| variable_cut_axis_steppers      : 'stepper_x, stepper_y'	; Comma separated list of stepper names to increase current for cutting | ||||
| variable_cut_stepper_current    : 100				; % of stepper current to use for cutting motion (100 to disable) | ||||
| 
 | ||||
| # This should be the position of the toolhead where the cutter arm just | ||||
| # lightly touches the depressor pin | ||||
| # NOTE: this is with skew correction ON | ||||
| variable_cutting_axis           : "x"		; "x" or "y". Determines cut direction (axis) during cut motion, used for park distance | ||||
| variable_pin_loc_xy             : 19.54, 353	; x,y coordinates of depressor pin | ||||
| 
 | ||||
| # This distance is added to "pin_loc_x" or "pin_loc_y" depending on the 'cutting_axis' | ||||
| # to determine the starting position and to create a small safety distance that aids | ||||
| # in generating momentum | ||||
| variable_pin_park_dist          : 5.0		; Distance in mm | ||||
| 
 | ||||
| # Position of the toolhead when the cutter is fully compressed. Should leave a small headroom from the | ||||
| # extremes of your printer edges (e.g. it should be a bit larger than 0, or whatever Xmin is) to avoid | ||||
| # banging the toolhead or gantry. Typically x position will match x in pin_loc_xy if cutting in y direction | ||||
| # or y position will match y in pin_loc_xy if cutting in x direction, but diagonal cuts are possible | ||||
| variable_pin_loc_compressed_xy  : 3.54, 353	; x,y coordinates of fully depressed location | ||||
| 
 | ||||
| # Retract length and speed after the cut so that the cutter blade doesn't | ||||
| # get stuck on return to origin position | ||||
| variable_rip_length             : 1.0		; Distance in mm to retract to aid lever decompression (>= 0) | ||||
| variable_rip_speed              : 3		; Speed mm/s | ||||
| 
 | ||||
| # Pushback of the remaining tip from the cold end into the hotend. This does | ||||
| # not have to push back all the way, just sufficient to ensure filament fragment | ||||
| # stays in hot end and the "nail head" of the cut is pushed back past the | ||||
| # PTFE/metal junction so it cannot cause clogging problems on future loads. | ||||
| # Cannot be larger than 'retract_length' - `toolhead_ooze_reduction` | ||||
| variable_pushback_length        : 15.0		; TUNE ME: PTFE tube length + 3mm is good starting point | ||||
| variable_pushback_dwell_time    : 0		; Time in ms to dwell after the pushback | ||||
| 
 | ||||
| # Speed related settings for tip cutting | ||||
| # Note that if the cut speed is too fast, the steppers can lose steps. | ||||
| # Therefore, for a cut: | ||||
| # - We first make a fast move to accumulate some momentum and get the cut | ||||
| #   blade to the initial contact with the filament | ||||
| # - We then make a slow move for the actual cut to happen | ||||
| variable_travel_speed           : 150		; Speed mm/s | ||||
| variable_cut_fast_move_speed    : 32		; Speed mm/s | ||||
| variable_cut_slow_move_speed    : 8		; Speed mm/s | ||||
| variable_evacuate_speed         : 150		; Speed mm/s | ||||
| variable_cut_dwell_time         : 50		; Time in ms to dwell at the cut point | ||||
| variable_cut_fast_move_fraction : 1.0		; Fraction of the move that uses fast move | ||||
| variable_extruder_move_speed    : 25		; Speed mm/s for all extruder movement | ||||
| 
 | ||||
| # Safety margin for fast vs slow travel. When traveling to the pin location | ||||
| # we make a safer but longer move if we are closer to the pin than this | ||||
| # specified margin. Usually setting these to the size of the toolhead | ||||
| # (plus a small margin) should be good enough | ||||
| variable_safe_margin_xy         : 30, 30	; Approx toolhead width +5mm, height +5mm) | ||||
| 
 | ||||
| # If gantry servo option is installed, enable the servo and set up and down | ||||
| # angle positions | ||||
| variable_gantry_servo_enabled   : False		; True = enabled, False = disabled | ||||
| variable_gantry_servo_down_angle: 55		; Angle for when pin is deployed | ||||
| variable_gantry_servo_up_angle  : 180		; Angle for when pin is retracted | ||||
| 
 | ||||
| 
 | ||||
| # FORM_TIP ---------------------------------------------------------------- | ||||
| # ███████╗ ██████╗ ██████╗ ███╗   ███╗    ████████╗██╗██████╗  | ||||
| # ██╔════╝██╔═══██╗██╔══██╗████╗ ████║    ╚══██╔══╝██║██╔══██╗ | ||||
| # █████╗  ██║   ██║██████╔╝██╔████╔██║       ██║   ██║██████╔╝ | ||||
| # ██╔══╝  ██║   ██║██╔══██╗██║╚██╔╝██║       ██║   ██║██╔═══╝  | ||||
| # ██║     ╚██████╔╝██║  ██║██║ ╚═╝ ██║       ██║   ██║██║      | ||||
| # ╚═╝      ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝       ╚═╝   ╚═╝╚═╝      | ||||
| # Don't need to configure if using tip cutting | ||||
| #   (base/mmu_form_tip.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_FORM_TIP_VARS] | ||||
| description: Happy Hare tip forming macro configuration variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # Step 1 - Ramming | ||||
| # Ramming is the initial squeeze of filament prior to cooling moves and is | ||||
| # described in terms of total volume and progression of squeeze intensity | ||||
| # printing/standalone. This can be separately controlled when printing or | ||||
| # standalone | ||||
| variable_ramming_volume            : 0		; Volume in mm^3, 0 = disabled (optionally let slicer do it) | ||||
| variable_ramming_volume_standalone : 0		; Volume in mm^3, 0 = disabled | ||||
| 
 | ||||
| # Optionally set for temperature change (reduction). The wait will occur | ||||
| # before nozzle separation if 'use_fast_skinnydip: False' else after cooling | ||||
| # moves. Temperature will be restored after tip creation is complete | ||||
| variable_toolchange_temp        : 0		; 0 = don't change temp, else temp to set | ||||
| variable_toolchange_fan_assist  : False		; Whether to use part cooling fan for quicker temp change | ||||
| variable_toolchange_fan_name    : ''		; Define the part fan name if not default [fan] e.g "fan_generic fan0" | ||||
| variable_toolchange_fan_speed   : 50		; Fan speed % if using fan_assist enabled | ||||
| 
 | ||||
| # Step 2 - Nozzle Separation | ||||
| # The filament is then quickly separated from the meltzone by a fast movement | ||||
| # before then slowing to travel the remaining distance to cooling tube. The | ||||
| # initial fast movement should be as fast as extruder can comfortably perform. | ||||
| # A good starting point# for slower move is unloading_speed_start/cooling_moves. | ||||
| # Too fast a slower movement can lead to excessively long tips or hairs | ||||
| variable_unloading_speed_start  : 80		; Speed in mm/s for initial fast movement | ||||
| variable_unloading_speed        : 18		; Speed in mm/s for slow move to cooling zone | ||||
| 
 | ||||
| # Step 3 - Cooling Moves | ||||
| # The cooling move allows the filament to harden while constantly moving back | ||||
| # and forth in the cooling tube portion of the extruder to prevent a bulbous | ||||
| # tip forming. The cooling tube position is measured from the internal nozzle | ||||
| # to just past the top of the heater block (often it is beneficial to add a | ||||
| # couple of mm to ensure the tip is in the cooling section. The cooling tube | ||||
| # length is then the distance from here to top of heatsink (this is the length | ||||
| # length of the cooling moves). The final cooling move is a fast movement to | ||||
| # break the string formed. | ||||
| variable_cooling_tube_position  : 35		; Start of cooling tube. DragonST:35, DragonHF:30, Mosquito:30, Revo:35, RapidoHF:27 | ||||
| variable_cooling_tube_length    : 10		; Movement length. DragonST:15, DragonHF:10, Mosquito:20, Revo:10, RapidoHF:10 | ||||
| variable_initial_cooling_speed  : 10		; Initial slow movement (mm/s) to solidify tip and cool string if formed | ||||
| variable_final_cooling_speed    : 50		; Fast movement (mm/s) Too fast: tip deformation on eject, Too Slow: long string/no separation | ||||
| variable_cooling_moves          : 4		; Number of back and forth cooling moves to make (2-4 is a good start) | ||||
| 
 | ||||
| # Step 4 - Skinnydip | ||||
| # Skinnydip is an advanced final move that may have benefit with some | ||||
| # material like PLA to burn off persistent very fine hairs. To work the | ||||
| # depth of insertion is critical (start with it disabled and tune last) | ||||
| # For reference the internal nozzle would be at a distance of | ||||
| # cooling_tube_position + cooling_tube_length, the top of the heater | ||||
| # block would be cooling_tube_length away. | ||||
| variable_use_skinnydip          : False		; True = enable skinnydip, False = skinnydip move disabled | ||||
| variable_skinnydip_distance     : 30		; Distance to reinsert filament into hotend starting from end of cooling tube | ||||
| variable_dip_insertion_speed    : 30		; Medium/Slow insertion speed mm/s - Just long enough to melt the fine hairs, too slow will pull up molten filament | ||||
| variable_dip_extraction_speed   : 70		; Speed mm/s - Around 2x Insertion speed to prevents forming new hairs | ||||
| variable_melt_zone_pause        : 0		; Pause if melt zone in ms. Default 0 | ||||
| variable_cooling_zone_pause     : 0		; Pause if cooling zone after dip in ms. Default 0 | ||||
| variable_use_fast_skinnydip     : False		; False = Skip the toolhead temp change wait during skinnydip move | ||||
| 
 | ||||
| # Step 5 - Parking | ||||
| # Park filament ready to eject | ||||
| variable_parking_distance       : 0		; Position mm to park the filament at end of tip forming, 0 = leave where filament ends up after tip forming | ||||
| variable_extruder_eject_speed   : 25		; Speed mm/s used for parking_distance (and final_eject when testing) | ||||
| 
 | ||||
| 
 | ||||
| # PURGE ------------------------------------------------------------------- | ||||
| # ██████╗ ██╗   ██╗██████╗  ██████╗ ███████╗ | ||||
| # ██╔══██╗██║   ██║██╔══██╗██╔════╝ ██╔════╝ | ||||
| # ██████╔╝██║   ██║██████╔╝██║  ███╗█████╗   | ||||
| # ██╔═══╝ ██║   ██║██╔══██╗██║   ██║██╔══╝   | ||||
| # ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗ | ||||
| # ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝ | ||||
| #                                           | ||||
| # Optional reference (bucket) purge. Blobifier if far better but this can be | ||||
| # used as a basis for custom purge | ||||
| #   (base/mmu_purge.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_PURGE_VARS] | ||||
| description: Happy Hare reference purging macro configuration variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| # Set speed as fast as you can without the extruder skipping steps. Note that | ||||
| # you can increase the extruder current for purging in mmu_parameters.cfg | ||||
| variable_extruder_purge_speed   : 2		; Speed in mm/s for purging | ||||
| 
 | ||||
| 
 | ||||
| # CLIENT MACROS ----------------------------------------------------------- | ||||
| # ██████╗  █████╗ ██╗   ██╗███████╗███████╗    ██████╗ ███████╗███████╗██╗   ██╗███╗   ███╗███████╗ | ||||
| # ██╔══██╗██╔══██╗██║   ██║██╔════╝██╔════╝    ██╔══██╗██╔════╝██╔════╝██║   ██║████╗ ████║██╔════╝ | ||||
| # ██████╔╝███████║██║   ██║███████╗█████╗      ██████╔╝█████╗  ███████╗██║   ██║██╔████╔██║█████╗   | ||||
| # ██╔═══╝ ██╔══██║██║   ██║╚════██║██╔══╝      ██╔══██╗██╔══╝  ╚════██║██║   ██║██║╚██╔╝██║██╔══╝   | ||||
| # ██║     ██║  ██║╚██████╔╝███████║███████╗    ██║  ██║███████╗███████║╚██████╔╝██║ ╚═╝ ██║███████╗ | ||||
| # ╚═╝     ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚══════╝    ╚═╝  ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═╝     ╚═╝╚══════╝ | ||||
| # If using the recommended PAUSE/RESUME/CANCEL_PRINT macros shipped with | ||||
| # Happy Hare these variables allow for customization and basic extension | ||||
| # Note that most parameters are pulled from the "movement" (sequence) | ||||
| # macro above and thus these are supplemental a | ||||
| #   (optional/client_macros.cfg) | ||||
| # | ||||
| [gcode_macro _MMU_CLIENT_VARS] | ||||
| description: Happy Hare client macro configuration variables | ||||
| gcode: # Leave empty | ||||
| 
 | ||||
| variable_reset_ttg_on_cancel    : False		; True/False, Whether reset TTG map if print is canceled | ||||
| variable_unload_tool_on_cancel  : False		; True/False, Whether to unload the tool on cancel | ||||
| 
 | ||||
| # You can extend functionality by adding a command (or call to your gcode macro) | ||||
| variable_user_pause_extension   : ''		; Executed after the klipper base pause | ||||
| variable_user_resume_extension  : ''		; Executed before the klipper base resume | ||||
| variable_user_cancel_extension  : ''		; Executed before the klipper base cancel_print | ||||
| 
 | ||||
| 
 | ||||
| ########################################################################### | ||||
| # Tool change macros | ||||
| # This is automatically created on installation but you can increase or | ||||
| # reduce this list to match your number of tools in operation | ||||
| # Note: it is annoying to have to do this but interfaces like Mainsail rely | ||||
| # on real macro definitions for tools to be visible in the UI | ||||
| # | ||||
| [gcode_macro T0] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=0 | ||||
| [gcode_macro T1] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=1 | ||||
| [gcode_macro T2] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=2 | ||||
| [gcode_macro T3] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=3 | ||||
| [gcode_macro T4] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=4 | ||||
| [gcode_macro T5] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=5 | ||||
| [gcode_macro T6] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=6 | ||||
| [gcode_macro T7] | ||||
| gcode: MMU_CHANGE_TOOL TOOL=7 | ||||
| 
 | ||||
|  | @ -1,685 +0,0 @@ | |||
| ######################################################################################################################## | ||||
| # 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: Main configuration parameters for the klipper module | ||||
| # | ||||
| # (\_/) | ||||
| # ( *,*) | ||||
| # (")_(") Happy Hare Ready | ||||
| # | ||||
| # Notes: | ||||
| #   Macro configuration is specified separately in 'mmu_macro_vars.cfg'. | ||||
| #   Full details in https://github.com/moggieuk/Happy-Hare/tree/main/doc/configuration.md | ||||
| # | ||||
| [mmu] | ||||
| happy_hare_version: 3.2			# Don't mess, used for upgrade detection | ||||
| 
 | ||||
| # MMU Hardware Limits -------------------------------------------------------------------------------------------------- | ||||
| # ██╗     ██╗███╗   ███╗██╗████████╗███████╗ | ||||
| # ██║     ██║████╗ ████║██║╚══██╔══╝██╔════╝ | ||||
| # ██║     ██║██╔████╔██║██║   ██║   ███████╗ | ||||
| # ██║     ██║██║╚██╔╝██║██║   ██║   ╚════██║ | ||||
| # ███████╗██║██║ ╚═╝ ██║██║   ██║   ███████║ | ||||
| # ╚══════╝╚═╝╚═╝     ╚═╝╚═╝   ╚═╝   ╚══════╝ | ||||
| # | ||||
| # Define the physical limits of your MMU. These settings will be respected regardless of individual speed settings. | ||||
| # | ||||
| gear_max_velocity: 300			# Never to be exceeded gear velocity regardless of specific parameters | ||||
| gear_max_accel: 1500			# Never to be exceeded gear acceleration regardless of specific parameters | ||||
| selector_max_velocity: 250		# Never to be exceeded selector velocity regardless of specific parameters | ||||
| selector_max_accel: 1200		# Never to be exceeded selector acceleration regardless of specific parameters | ||||
| 
 | ||||
| 
 | ||||
| # Servo configuration  ------------------------------------------------------------------------------------------------- | ||||
| # ███████╗███████╗██████╗ ██╗   ██╗ ██████╗  | ||||
| # ██╔════╝██╔════╝██╔══██╗██║   ██║██╔═══██╗ | ||||
| # ███████╗█████╗  ██████╔╝██║   ██║██║   ██║ | ||||
| # ╚════██║██╔══╝  ██╔══██╗╚██╗ ██╔╝██║   ██║ | ||||
| # ███████║███████╗██║  ██║ ╚████╔╝ ╚██████╔╝ | ||||
| # ╚══════╝╚══════╝╚═╝  ╚═╝  ╚═══╝   ╚═════╝  | ||||
| # | ||||
| # Angle of the servo in three named positions | ||||
| #   up   = tool is selected and filament is allowed to freely move through gate | ||||
| #   down = to grip filament | ||||
| #   move = ready the servo for selector move (optional - defaults to up) | ||||
| # V2.4.0 on: These positions are only for initial config they are replaced with calibrated servo positions in `mmu_vars.cfg` | ||||
| # | ||||
| # Note that leaving the servo active when down can stress the electronics and is not recommended with EASY-BRD or ERB board | ||||
| # unless the 5v power supply has been improved and it is not necessary with standard ERCF builds | ||||
| # Make sure your hardware is suitable for the job! | ||||
| # | ||||
| servo_up_angle: 140			# ERCF: MG90S: 30  ; SAVOX SH0255MG: 140 ; Tradrack: 145 | ||||
| servo_down_angle: 30			# ERCF: MG90S: 140 ; SAVOX SH0255MG: 30  ; Tradrack: 1 | ||||
| servo_move_angle: 109			# Optional angle used when selector is moved (defaults to up position) | ||||
| servo_duration: 0.4			# Duration of PWM burst sent to servo (default non-active mode, automatically turns off) | ||||
| servo_dwell: 0.5			# Minimum time given to servo to complete movement prior to next move | ||||
| servo_always_active: 0 			# CAUTION - WILL DAMAGE COMMON SERVOS, PLEASE USE AT YOUR OWN RISK: 1=Force servo to always stay active, 0=Release after movement | ||||
| servo_active_down: 0			# CAUTION - WILL DAMAGE COMMON SERVOS, PLEASE USE AT YOUR OWN RISK: 1=Force servo to stay active when down only, 0=Release after movement | ||||
| servo_buzz_gear_on_down: 1		# Whether to "buzz" the gear stepper on down to aid engagement | ||||
| 
 | ||||
| 
 | ||||
| # Logging -------------------------------------------------------------------------------------------------------------- | ||||
| # ██╗      ██████╗  ██████╗  ██████╗ ██╗███╗   ██╗ ██████╗  | ||||
| # ██║     ██╔═══██╗██╔════╝ ██╔════╝ ██║████╗  ██║██╔════╝  | ||||
| # ██║     ██║   ██║██║  ███╗██║  ███╗██║██╔██╗ ██║██║  ███╗ | ||||
| # ██║     ██║   ██║██║   ██║██║   ██║██║██║╚██╗██║██║   ██║ | ||||
| # ███████╗╚██████╔╝╚██████╔╝╚██████╔╝██║██║ ╚████║╚██████╔╝ | ||||
| # ╚══════╝ ╚═════╝  ╚═════╝  ╚═════╝ ╚═╝╚═╝  ╚═══╝ ╚═════╝  | ||||
| # | ||||
| # log_level & logfile_level can be set to one of (0 = essential, 1 = info, 2 = debug, 3 = trace, 4 = stepper moves) | ||||
| # Generally you can keep console logging to a minimal whilst still sending debug output to the mmu.log file | ||||
| # Increasing the console log level is only really useful during initial setup to save having to constantly open the log file | ||||
| # Note: that it is not recommended to keep logging at level greater that 2 (debug) if not debugging an issue because | ||||
| # of the additional overhead | ||||
| # | ||||
| log_level: 1 | ||||
| log_file_level: 2			# Can also be set to -1 to disable log file completely | ||||
| log_statistics: 1 			# 1 to log statistics on every toolchange (default), 0 to disable (but still recorded) | ||||
| log_visual: 1				# 1 log visual representation of filament, 0 = disable | ||||
| log_startup_status: 1			# Whether to log tool to gate status on startup, 1 = summary (default), 0 = disable | ||||
| log_m117_messages: 1			# Whether send toolchange message via M117 to screen | ||||
| 
 | ||||
| 
 | ||||
| # Movement speeds ------------------------------------------------------------------------------------------------------ | ||||
| # ███████╗██████╗ ███████╗███████╗██████╗ ███████╗ | ||||
| # ██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝ | ||||
| # ███████╗██████╔╝█████╗  █████╗  ██║  ██║███████╗ | ||||
| # ╚════██║██╔═══╝ ██╔══╝  ██╔══╝  ██║  ██║╚════██║ | ||||
| # ███████║██║     ███████╗███████╗██████╔╝███████║ | ||||
| # ╚══════╝╚═╝     ╚══════╝╚══════╝╚═════╝ ╚══════╝ | ||||
| # | ||||
| # Long moves are faster than the small ones and used for the bulk of the bowden movement. You can set two fast load speeds | ||||
| # depending on whether pulling from the spool or filament buffer (if fitted and not the first time load). This can be helpful | ||||
| # in allowing faster loading from buffer and slower when pulling from the spool because of the additional friction (prevents | ||||
| # loosing steps). Unloading speed can be tuning if you have a rewinder system that imposes additional limits. | ||||
| # NOTE: Encoder cannot keep up much above 450mm/s so make sure 'bowden_apply_correction' is off at very high speeds! | ||||
| # | ||||
| gear_from_spool_speed: 80		# mm/s Speed when loading from the spool (for the first time if has_filament_buffer: 1) | ||||
| gear_from_spool_accel: 100		# Acceleration when loading from spool | ||||
| gear_from_buffer_speed: 150		# mm/s Speed when loading filament from buffer. Conservative is 100mm/s, Max around 400mm/s | ||||
| gear_from_buffer_accel: 400		# Normal acceleration when loading filament | ||||
| gear_unload_speed: 80			# mm/s Use (lower) speed when unloading filament (defaults to "from spool" speed) | ||||
| gear_unload_accel: 100			# Acceleration when unloading filament (defaults to "from spool" accel) | ||||
| # | ||||
| gear_short_move_speed: 80		# mm/s Speed when making short moves (like incremental retracts with encoder) | ||||
| gear_short_move_accel: 600		# Usually the same as gear_from_buffer_accel (for short movements) | ||||
| gear_short_move_threshold: 70		# Move distance that controls application of 'short_move' speed/accel | ||||
| gear_homing_speed: 50			# mm/s Speed of gear stepper only homing moves (e.g. homing to gate or extruder) | ||||
| 
 | ||||
| # Speeds of extruder movement. The 'sync' speeds will be used when gear and extruder steppers are moving in sync | ||||
| # | ||||
| extruder_load_speed: 16			# mm/s speed of load move inside extruder from homing position to meltzone | ||||
| extruder_unload_speed: 16		# mm/s speed of unload moves inside of extruder (very initial move from meltzone is 50% of this) | ||||
| extruder_sync_load_speed: 18		# mm/s speed of synchronized extruder load moves | ||||
| extruder_sync_unload_speed: 18		# mm/s speed of synchronized extruder unload moves | ||||
| extruder_homing_speed: 18		# mm/s speed of extruder only homing moves (e.g. to toolhead sensor) | ||||
| 
 | ||||
| # Selector movement speeds. (Acceleration is defined by physical MMU limits set above and passed to selector stepper driver) | ||||
| # | ||||
| selector_move_speed: 200		# mm/s speed of selector movement (not touch) | ||||
| selector_homing_speed: 60		# mm/s speed of initial selector homing move (not touch) | ||||
| selector_touch_speed: 80		# mm/s speed of all touch selector moves (if stallguard configured) | ||||
| 
 | ||||
| # Selector touch (stallguard) operation. If stallguard is configured, then this can be used to switch on touch movement which | ||||
| # can detect blocked filament path and try to recover automatically but it is more difficult to set up | ||||
| # | ||||
| selector_touch_enable: 0		# If selector touch operation configured this can be used to disable it 1=enabled, 0=disabled | ||||
| 
 | ||||
| # When Happy Hare calls out to a macro for user customization and for parking moves these settings are applied and the previous | ||||
| # values automatically restored afterwards. This allows for deterministic movement speed regardless of the starting state. | ||||
| # | ||||
| macro_toolhead_max_accel: 0		# Default printer toolhead acceleration applied when macros are run. 0 = use printer max | ||||
| macro_toolhead_min_cruise_ratio: 0.5	# Default printer cruise ratio applied when macros are run | ||||
| 
 | ||||
| 
 | ||||
| # Gate loading/unloading ----------------------------------------------------------------------------------------------- | ||||
| #  ██████╗  █████╗ ████████╗███████╗    ██╗      ██████╗  █████╗ ██████╗  | ||||
| # ██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝    ██║     ██╔═══██╗██╔══██╗██╔══██╗ | ||||
| # ██║  ███╗███████║   ██║   █████╗      ██║     ██║   ██║███████║██║  ██║ | ||||
| # ██║   ██║██╔══██║   ██║   ██╔══╝      ██║     ██║   ██║██╔══██║██║  ██║ | ||||
| # ╚██████╔╝██║  ██║   ██║   ███████╗    ███████╗╚██████╔╝██║  ██║██████╔╝ | ||||
| #  ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ╚══════╝    ╚══════╝ ╚═════╝ ╚═╝  ╚═╝╚═════╝  | ||||
| # | ||||
| # These settings control the loading and unloading filament at the gate which is the parking position inside the MMU. | ||||
| # Typically this would be switch sensor but you can also use an encoder. Even with encoder the endstop can be a switch | ||||
| # and the encoder used for move verifcation (see advanced 'gate_endstop_to_encoder' option). Note that the `encoder` | ||||
| # method, due to the nature of its operation will overshoot a little. This is not a problem in practice because the | ||||
| # overshoot will simply be compensated for in the subsequent move. A +ve parking distance moves towards the MMU, -ve | ||||
| # moves back through the endstop towards the toolhead. If the MMU has multiple bowden tubes then it is possible to home | ||||
| # at the extruder sensor and avoid long bowden moves! | ||||
| # | ||||
| # Possible gate_homing_endstop names: | ||||
| #   encoder       - Detect filament position using movement of the encoder | ||||
| #   mmu_gate      - Use gate endstop | ||||
| #   mmu_gear      - Use individual per-gate endstop (type-B MMU's) | ||||
| #   extruder      - Use extruder entry sensor (Only for some type-B designs, see [mmu_machine] require_bowden_move setting) | ||||
| # | ||||
| gate_homing_endstop: encoder		# Name of gate endstop, "encoder" forces use of encoder for parking | ||||
| gate_homing_max: 70			# Maximum move distance to home to the gate (or actual move distance for encoder parking) | ||||
| gate_preload_homing_max: 70		# Maximum homing distance to the mmu_gear endstop (if MMU is fitted with one) | ||||
| gate_unload_buffer: 50			# Amount to reduce the fast unload so that filament doesn't overshoot when parking | ||||
| gate_load_retries: 2			# Number of times MMU will attempt to grab the filament on initial load (type-A designs) | ||||
| gate_parking_distance: 13 		# Parking position in the gate (distance back from homing point, -ve value means move forward) | ||||
| gate_endstop_to_encoder: 10		# Distance between gate endstop and encoder (IF both fitted. +ve if encoder after endstop) | ||||
| gate_autoload: 1			# If pre-gate sensor fitted this controls the automatic loading of the gate | ||||
| gate_final_eject_distance: 0		# Distance to eject filament on MMU_EJECT (Ignored by MMU_UNLOAD) | ||||
| 
 | ||||
| 
 | ||||
| # Bowden tube loading/unloading ---------------------------------------------------------------------------------------- | ||||
| # ██████╗  ██████╗ ██╗    ██╗██████╗ ███████╗███╗   ██╗    ██╗      ██████╗  █████╗ ██████╗  | ||||
| # ██╔══██╗██╔═══██╗██║    ██║██╔══██╗██╔════╝████╗  ██║    ██║     ██╔═══██╗██╔══██╗██╔══██╗ | ||||
| # ██████╔╝██║   ██║██║ █╗ ██║██║  ██║█████╗  ██╔██╗ ██║    ██║     ██║   ██║███████║██║  ██║ | ||||
| # ██╔══██╗██║   ██║██║███╗██║██║  ██║██╔══╝  ██║╚██╗██║    ██║     ██║   ██║██╔══██║██║  ██║ | ||||
| # ██████╔╝╚██████╔╝╚███╔███╔╝██████╔╝███████╗██║ ╚████║    ███████╗╚██████╔╝██║  ██║██████╔╝ | ||||
| # ╚═════╝  ╚═════╝  ╚══╝╚══╝ ╚═════╝ ╚══════╝╚═╝  ╚═══╝    ╚══════╝ ╚═════╝ ╚═╝  ╚═╝╚═════╝  | ||||
| # | ||||
| # In addition to different bowden loading speeds for buffer and non-buffered filament it is possible to detect missed | ||||
| # steps caused by "jerking" on a heavy spool. If bowden correction is enabled the driver with "believe" the encoder | ||||
| # reading and make correction moves to bring the filament to within the 'bowden_allowable_load_delta' of the end of | ||||
| # bowden position (this does require a reliable encoder and is not recommended for very high speed loading >350mm/s) | ||||
| # | ||||
| bowden_apply_correction: 1		# 1 to enable, 0 disabled. Requires Encoder | ||||
| bowden_allowable_load_delta: 20.0	# How close in mm the correction moves will attempt to get to target. Requires Encoder | ||||
| 
 | ||||
| # This test verifies the filament is free of extruder before the fast bowden movement to reduce possibility of grinding filament | ||||
| bowden_pre_unload_test: 1		# 1 to check for bowden movement before full pull (slower), 0 don't check (faster). Requires Encoder | ||||
| 
 | ||||
| # ADVANCED: If pre-unload test is enabled, this controls the detection of successful bowden pre-unload test and represents | ||||
| # the fraction of allowable mismatch between actual movement and that seen by encoder. Setting to 50% tolerance usually | ||||
| # works well. Increasing will make test more tolerant. Value of 100% essentially disables error detection | ||||
| bowden_pre_unload_error_tolerance: 50 | ||||
| 
 | ||||
| 
 | ||||
| # Extruder homing ----------------------------------------------------------------------------------------------------- | ||||
| # ███████╗██╗  ██╗████████╗    ██╗  ██╗ ██████╗ ███╗   ███╗██╗███╗   ██╗ ██████╗  | ||||
| # ██╔════╝╚██╗██╔╝╚══██╔══╝    ██║  ██║██╔═══██╗████╗ ████║██║████╗  ██║██╔════╝  | ||||
| # █████╗   ╚███╔╝    ██║       ███████║██║   ██║██╔████╔██║██║██╔██╗ ██║██║  ███╗ | ||||
| # ██╔══╝   ██╔██╗    ██║       ██╔══██║██║   ██║██║╚██╔╝██║██║██║╚██╗██║██║   ██║ | ||||
| # ███████╗██╔╝ ██╗   ██║██╗    ██║  ██║╚██████╔╝██║ ╚═╝ ██║██║██║ ╚████║╚██████╔╝ | ||||
| # ╚══════╝╚═╝  ╚═╝   ╚═╝╚═╝    ╚═╝  ╚═╝ ╚═════╝ ╚═╝     ╚═╝╚═╝╚═╝  ╚═══╝ ╚═════╝  | ||||
| # | ||||
| # Happy Hare needs a reference "homing point" close to the extruder from which to accurately complete the loading of | ||||
| # the toolhead. This homing operation takes place after the fast bowden load and it is anticipated that that load | ||||
| # operation will leave the filament just shy of the homing point. If using a toolhead sensor this initial extruder | ||||
| # homing is unnecessary (but can be forced) because the homing will occur inside the extruder for the optimum in accuracy. | ||||
| # You still should set this homing method because it is also used for the determination and calibration of bowden length. | ||||
| # | ||||
| # In addition to an entry sensor "extruder" it is possible for Happy Hare to "feel" for the extruder gear entry | ||||
| # by colliding with it. This can be done with encoder based collision detection, the compression of the sync-feedback | ||||
| # (aka buffer) sensor or using "touch" (stallguard) on the gear stepper. Note that encoder collision detection is not | ||||
| # completely deterministic and you will have to find the sweetspot for your setup by adjusting the TMC current reduction. | ||||
| # Note that reduced current during collision detection can also prevent unecessary filament griding. | ||||
| # | ||||
| # Possible extruder_homing_endtop names: | ||||
| #   collision            - Detect the collision with the extruder gear by monitoring encoder movement (Requires encoder) | ||||
| #                          Fast bowden load will move to the extruder gears | ||||
| #   mmu_gear_touch       - Use touch detection when the gear stepper hits the extruder (Requires stallguard) | ||||
| #                          Fast bowden load will move to extruder_homing_buffer distance before extruder gear, then home | ||||
| #   extruder             - If you have a "filament entry" endstop configured (Requires 'extruder' endstop) | ||||
| #                          Fast bowden load will move to extruder_homing_buffer distance before sensor, then home | ||||
| #   filament_compression - If you have a "sync-feedback" sensor with compression switch configured | ||||
| #                          Fast bowden load will move to extruder_homing_buffer distance before extruder gear, then home | ||||
| #   none                 - Don't attempt to home. Only possibiliy if lacking all sensor options | ||||
| #                          Fast bowden load will move to the extruder gears. Option is fine if using toolhead sensor | ||||
| # Note: The homing_endstop will be ignored ("none") if a toolhead sensor is available unless "extruder_force_homing: 1" | ||||
| # | ||||
| extruder_homing_max: 80			# Maximum distance to advance in order to attempt to home the extruder | ||||
| extruder_homing_endstop: extruder	# Filament homing method/endstop name (fallback if toolhead sensor not available) | ||||
| extruder_homing_buffer: 25		# Amount to reduce the fast bowden load so filament doesn't overshoot the extruder homing point | ||||
| extruder_collision_homing_current: 30	# % gear_stepper current (10%-100%) to use when homing to extruder homing (100 to disable) | ||||
| 
 | ||||
| # If you have a toolhead sensor it will always be used as a homing point making the homing outside of the extruder | ||||
| # potentially unnecessary. However you can still force this initial homing step by setting this option in which case | ||||
| # the filament will home to the extruder and then home to the toolhead sensor in two steps | ||||
| # | ||||
| extruder_force_homing: 0 | ||||
| 
 | ||||
| 
 | ||||
| # Toolhead loading and unloading -------------------------------------------------------------------------------------- | ||||
| # ████████╗ ██████╗  ██████╗ ██╗     ██╗  ██╗███████╗ █████╗ ██████╗     ██╗      ██████╗  █████╗ ██████╗  | ||||
| # ╚══██╔══╝██╔═══██╗██╔═══██╗██║     ██║  ██║██╔════╝██╔══██╗██╔══██╗    ██║     ██╔═══██╗██╔══██╗██╔══██╗ | ||||
| #    ██║   ██║   ██║██║   ██║██║     ███████║█████╗  ███████║██║  ██║    ██║     ██║   ██║███████║██║  ██║ | ||||
| #    ██║   ██║   ██║██║   ██║██║     ██╔══██║██╔══╝  ██╔══██║██║  ██║    ██║     ██║   ██║██╔══██║██║  ██║ | ||||
| #    ██║   ╚██████╔╝╚██████╔╝███████╗██║  ██║███████╗██║  ██║██████╔╝    ███████╗╚██████╔╝██║  ██║██████╔╝ | ||||
| #    ╚═╝    ╚═════╝  ╚═════╝ ╚══════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═════╝     ╚══════╝ ╚═════╝ ╚═╝  ╚═╝╚═════╝  | ||||
| # | ||||
| # It is possible to define highly customized loading and unloading sequences, however, unless you have a specialized | ||||
| # setup it is probably easier to opt for the built-in toolhead loading and unloading sequence which already offers a | ||||
| # high degree of customization. If you need even more control then edit the _MMU_LOAD_SEQUENCE and _MMU_UNLOAD_SEQUENCE | ||||
| # macros in mmu_sequence.cfg - but be careful! | ||||
| # | ||||
| # An MMU must have a known point at the end of the bowden from which it can precisely load the extruder. Generally this | ||||
| # will either be the extruder entrance (which is controlled with settings above) or by homing to toolhead sensor. If | ||||
| # you have toolhead sensor it is past the extruder gear and the driver needs to know the max distance (from end of | ||||
| # bowden move) to attempt homing | ||||
| # | ||||
| toolhead_homing_max: 40			# Maximum distance to advance in order to attempt to home to defined homing endstop | ||||
| 
 | ||||
| # IMPORTANT: These next three settings are based on the physical dimensions of your toolhead | ||||
| # Once a homing position is determined, Happy Hare needs to know the final move distance to the nozzle. There is only | ||||
| # one correct value for your setup - use 'toolhead_ooze_reduction' (which corresponds to the residual filament left in | ||||
| # your nozzle) to control excessive oozing on load. See doc for table of proposed values for common configurations. | ||||
| # | ||||
| # NOTE: If you have a toolhead sensor you can automate the calculation of these parameters! Read about the | ||||
| # `MMU_CALIBRATE_TOOLHEAD` command (https://github.com/moggieuk/Happy-Hare/wiki/Blobbing-and-Stringing#---calibrating-toolhead) | ||||
| # | ||||
| toolhead_extruder_to_nozzle: 72		# Distance from extruder gears (entrance) to nozzle | ||||
| toolhead_sensor_to_nozzle: 62		# Distance from toolhead sensor to nozzle (ignored if not fitted) | ||||
| toolhead_entry_to_extruder: 8		# Distance from extruder "entry" sensor to extruder gears (ignored if not fitted) | ||||
| 
 | ||||
| # This setting represents how much residual filament is left behind in the nozzle when filament is removed, it is thus | ||||
| # used to reduce the extruder loading length and prevent excessive blobbing but also in the calculation of purge volume. | ||||
| # Note that this value can also be measured with the `MMU_CALIBRATE_TOOLHEAD` procedure | ||||
| # | ||||
| toolhead_residual_filament: 0		# Reduction in extruder loading length because of residual filament left behind | ||||
| 
 | ||||
| # TUNING: Finally, this is the last resort tuning value to fix blobbing. It is expected that this value is NEAR ZERO as | ||||
| # it represents a further reduction in extruder load length to fix blobbing. If using a wipetower and you experience blobs | ||||
| # on it, increase this value (reduce the quantity of filament loaded). If you experience gaps, decrease this value. If gaps | ||||
| # and already at 0 then perhaps the 'toolhead_extruder_to_nozzle' or 'toolhead_residual_filament' settings are incorrect. | ||||
| # Similarly a value >+5mm also suggests the four settings above are not correct. Also see 'retract' setting in | ||||
| # 'mmu_macro_vars.cfg' for final in-print ooze tuning. | ||||
| # | ||||
| toolhead_ooze_reduction: 0		# Reduction in extruder loading length to prevent ooze (represents filament remaining) | ||||
| 
 | ||||
| # Distance added to the extruder unload movement to ensure filament is free of extruder. This adds some degree of tolerance | ||||
| # to slightly incorrect configuration or extruder slippage. However don't use as an excuse for incorrect toolhead settings | ||||
| # | ||||
| toolhead_unload_safety_margin: 10	# Extra movement safety margin (default: 10mm) | ||||
| 
 | ||||
| # If not synchronizing gear and extruder and you experience a "false" clog detection immediately after the tool change | ||||
| # it might be because of a long bowden and/or large internal diameter that causes slack in the filament. This optional | ||||
| # move will tighten the filament after a load by % of current clog detection length. Gear stepper will run at 50% current | ||||
| # | ||||
| toolhead_post_load_tighten: 60		# % of clog detection length, 0 to disable. Ignored if 'sync_to_extruder: 1' | ||||
| 
 | ||||
| # ADVANCED: Controls the detection of successful extruder load/unload movement and represents the fraction of allowable | ||||
| # mismatch between actual movement and that seen by encoder. Setting to 100% tolerance effectively turns off checking. | ||||
| # Some designs of extruder have a short move distance that may not be picked up by encoder and cause false errors. This | ||||
| # allows masking of those errors. However the error often indicates that your extruder load speed is too high or the | ||||
| # friction is too high on the filament and in that case masking the error is not a good idea. Try reducing friction | ||||
| # and lowering speed first! | ||||
| # | ||||
| toolhead_move_error_tolerance: 60 | ||||
| 
 | ||||
| 
 | ||||
| # Tip forming --------------------------------------------------------------------------------------------------------- | ||||
| # ████████╗██╗██████╗     ███████╗ ██████╗ ██████╗ ███╗   ███╗██╗███╗   ██╗ ██████╗  | ||||
| # ╚══██╔══╝██║██╔══██╗    ██╔════╝██╔═══██╗██╔══██╗████╗ ████║██║████╗  ██║██╔════╝  | ||||
| #    ██║   ██║██████╔╝    █████╗  ██║   ██║██████╔╝██╔████╔██║██║██╔██╗ ██║██║  ███╗ | ||||
| #    ██║   ██║██╔═══╝     ██╔══╝  ██║   ██║██╔══██╗██║╚██╔╝██║██║██║╚██╗██║██║   ██║ | ||||
| #    ██║   ██║██║         ██║     ╚██████╔╝██║  ██║██║ ╚═╝ ██║██║██║ ╚████║╚██████╔╝ | ||||
| #    ╚═╝   ╚═╝╚═╝         ╚═╝      ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝╚═╝╚═╝  ╚═══╝ ╚═════╝  | ||||
| # | ||||
| # Tip forming responsibility can be split between slicer (in-print) and standalone macro (not in-print) or forced to always | ||||
| # be done by Happy Hare's standalone macro. Since you always need the option to form tips without the slicer so it is | ||||
| # generally easier to completely turn off the slicer, force "standalone" tip forming and tune only in Happy Hare. | ||||
| # | ||||
| # When Happy Hare is asked to form a tip it will run the referenced macro. Two are reference examples are provided but | ||||
| # you can implement your own: | ||||
| #   _MMU_FORM_TIP .. default tip forming similar to popular slicers like Superslicer and Prusaslicer | ||||
| #   _MMU_CUT_TIP  .. for Filametrix (originally ERCFv2) or similar style toolhead filament cutting system | ||||
| # | ||||
| # NOTE: For MMU located cutting like the optional EREC cutter you should set still this to _MMU_FORM_TIP to build a decent | ||||
| # tip prior to extraction and cutting after the unload. | ||||
| # | ||||
| # Often it is useful to increase the extruder current for the rapid movement to ensure high torque and no skipped steps | ||||
| # | ||||
| # If opting for slicer tip forming you MUST configure where the slicer leaves the filament in the extruder since | ||||
| # there is no way to determine this. This can be ignored if all tip forming is performed by Happy Hare | ||||
| # | ||||
| force_form_tip_standalone: 1		# 0 = Slicer in print else standalone, 1 = Always standalone tip forming (TURN SLICER OFF!) | ||||
| form_tip_macro: _MMU_CUT_TIP           # Name of macro to call to perform the tip forming (or cutting) operation | ||||
| extruder_form_tip_current: 100		# % of extruder current (100%-150%) to use when forming tip (100 to disable) | ||||
| slicer_tip_park_pos: 0			# This specifies the position of filament in extruder after slicer completes tip forming | ||||
| 
 | ||||
| 
 | ||||
| # Purging ------------------------------------------------------------------------------------------------------------- | ||||
| # ██████╗ ██╗   ██╗██████╗  ██████╗ ██╗███╗   ██╗ ██████╗  | ||||
| # ██╔══██╗██║   ██║██╔══██╗██╔════╝ ██║████╗  ██║██╔════╝  | ||||
| # ██████╔╝██║   ██║██████╔╝██║  ███╗██║██╔██╗ ██║██║  ███╗ | ||||
| # ██╔═══╝ ██║   ██║██╔══██╗██║   ██║██║██║╚██╗██║██║   ██║ | ||||
| # ██║     ╚██████╔╝██║  ██║╚██████╔╝██║██║ ╚████║╚██████╔╝ | ||||
| # ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚═╝╚═╝  ╚═══╝ ╚═════╝  | ||||
| # | ||||
| # After a toolchange it is necessary to purge the old filament. Similar to tip forming this can be done by the slicer and/or | ||||
| # by Happy Hare using an extension like Blobifer. If a purge_macro is defined it will be called when not printing or whenever | ||||
| # the slicer isn't going to purge (like initial tool load). You can force it to always be called in a print by setting | ||||
| # force_purge_standalone, but remember to turn off the slicer wipetower | ||||
| # | ||||
| # The default is for no (empty) macro so purging will not be done out of a print and thus wipetower. Two options are shipped with | ||||
| # Happy Hare but you can also build your own custom one: | ||||
| #   _MMU_PURGE .. default purging that just dumps the desired amount of filament (setup correct parking before enabling this!) | ||||
| #   BLOBIFER   .. for excellent Blobifer addon (https://github.com/Dendrowen/Blobifier) | ||||
| # | ||||
| # Often it is useful to increase the extruder current for the often rapid puring movement to ensure high torque and no skipped steps | ||||
| # | ||||
| force_purge_standalone: 0		# 0 = Slicer wipetower in print else standalone, 1 = Always standalone purging (TURN WIPETOWER OFF!) | ||||
| purge_macro: _MMU_PURGE			# Name of macro to call to perform the standalone purging operation. E.g. BLOBIFIER, _MMU_PURGE | ||||
| extruder_purge_current: 100		# % of extruder current (100%-150%) to use when purging (100 to disable) | ||||
| 
 | ||||
| 
 | ||||
| # Synchronized gear/extruder movement ---------------------------------------------------------------------------------- | ||||
| # ███╗   ███╗ ██████╗ ████████╗ ██████╗ ██████╗     ███████╗██╗   ██╗███╗   ██╗ ██████╗ | ||||
| # ████╗ ████║██╔═══██╗╚══██╔══╝██╔═══██╗██╔══██╗    ██╔════╝╚██╗ ██╔╝████╗  ██║██╔════╝ | ||||
| # ██╔████╔██║██║   ██║   ██║   ██║   ██║██████╔╝    ███████╗ ╚████╔╝ ██╔██╗ ██║██║      | ||||
| # ██║╚██╔╝██║██║   ██║   ██║   ██║   ██║██╔══██╗    ╚════██║  ╚██╔╝  ██║╚██╗██║██║      | ||||
| # ██║ ╚═╝ ██║╚██████╔╝   ██║   ╚██████╔╝██║  ██║    ███████║   ██║   ██║ ╚████║╚██████╗ | ||||
| # ╚═╝     ╚═╝ ╚═════╝    ╚═╝    ╚═════╝ ╚═╝  ╚═╝    ╚══════╝   ╚═╝   ╚═╝  ╚═══╝ ╚═════╝ | ||||
| # | ||||
| # This controls whether the extruder and gear steppers are synchronized during printing operations | ||||
| # If you normally run with maxed out gear stepper current consider reducing it with 'sync_gear_current' | ||||
| # If equipped with TMC drivers the current of the gear and extruder motors can be controlled to optimize performance. | ||||
| # This can be useful to control gear stepper temperature when printing with synchronized motor | ||||
| # | ||||
| sync_to_extruder: 1			# Gear motor is synchronized to extruder during print | ||||
| sync_gear_current: 70			# % of gear_stepper current (10%-100%) to use when syncing with extruder during print | ||||
| sync_form_tip: 0			# Synchronize during standalone tip formation (initial part of unload) | ||||
| sync_purge: 0				# Synchronize during standalone purging (last part of load) | ||||
| 
 | ||||
| # Optionally it is possible to leverage feedback for a "compression/expansion" sensor in the bowden path from MMU to | ||||
| # extruder to ensure that the two motors are kept in sync as viewed by the filament (the signal feedback state can be | ||||
| # binary supplied by one or two switches: -1 (expanded) and 1 (compressed) of proportional value between -1.0 and 1.0 | ||||
| # Requires [mmu_sensors] setting | ||||
| # | ||||
| sync_feedback_enable: 0			# 0 = Turn off (even with fitted sensor), 1 = Turn on | ||||
| sync_multiplier_high: 1.05		# Maximum factor to apply to gear stepper 'rotation_distance' | ||||
| sync_multiplier_low: 0.95		# Minimum factor to apply | ||||
| 
 | ||||
| 
 | ||||
| # ESpooler control ----------------------------------------------------------------------------------------------------- | ||||
| # ███████╗███████╗██████╗  ██████╗  ██████╗ ██╗     ███████╗██████╗  | ||||
| # ██╔════╝██╔════╝██╔══██╗██╔═══██╗██╔═══██╗██║     ██╔════╝██╔══██╗ | ||||
| # █████╗  ███████╗██████╔╝██║   ██║██║   ██║██║     █████╗  ██████╔╝ | ||||
| # ██╔══╝  ╚════██║██╔═══╝ ██║   ██║██║   ██║██║     ██╔══╝  ██╔══██╗ | ||||
| # ███████╗███████║██║     ╚██████╔╝╚██████╔╝███████╗███████╗██║  ██║ | ||||
| # ╚══════╝╚══════╝╚═╝      ╚═════╝  ╚═════╝ ╚══════╝╚══════╝╚═╝  ╚═╝ | ||||
| #                                                                   | ||||
| # If your MMU has a dc motor (often N20) controlled respooler/assist then how it operates can be controlled with these | ||||
| # settings. Typically the espooler will be controlled with PWM signal. This will be at the maximum at speeds equal or | ||||
| # above 'espooler.max_stepper_speed'. The PWM signal will scale downwards towards 0 for slower speeds. The falloff being | ||||
| # controlled by the 'espooler_speed_exponent' setting according to this formula and allows for non-linear characteristics | ||||
| # the DC motor (0.5 is a good starting value). | ||||
| #  | ||||
| #     espooler_pwm = (stepper_speed / espooler_max_stepper_speed) ^ {espooler_speed_exponent} | ||||
| # | ||||
| # Regardless of h/w configuration you can enable/disable actions with the 'espooler_operations' list. E.g. remove 'play' to | ||||
| # turn off operation while printing. Options are: | ||||
| # | ||||
| #    rewind - when filament is being unloaded under MMU control (aka respool) | ||||
| #    assist - when filament is being loaded under MMU control (% of "rewind" speed but with minimum of "print" power) | ||||
| #    print  - while printing. Generally set 'espooler_printing_power' to a low percentage just to allow motor to be turned | ||||
| #             freely or set to 0 to enable/allow "burst" assist movements | ||||
| # | ||||
| # If using a digitally controlled espooler motor (not PWM) then you should turn off the "print" mode and set | ||||
| # 'espooler_min_stepper_speed' to prevent "over movement" | ||||
| # | ||||
| espooler_min_distance: 200			# Individual stepper movements less than this distance will not active espooler | ||||
| espooler_max_stepper_speed: 200			# Gear stepper speed at which espooler will be at maximum power | ||||
| espooler_min_stepper_speed: 0			# Gear stepper speed at which espooler will become inactive (useful for non PWM control) | ||||
| espooler_speed_exponent: 0.5			# Controls non-linear espooler power relative to stepper speed (see notes) | ||||
| espooler_assist_reduced_speed: 50		# Control the % of the rewind speed that is applied to assisting load (want rewind to be faster) | ||||
| espooler_printing_power: 0			# If >0, fixes the % of PWM power while printing. 0=allows burst movement | ||||
| espooler_operations: rewind, assist, print	# List of operational modes (allows disabling even if h/w is configured) | ||||
| # | ||||
| # The following burst configuration is used only if 'print' operation is enabled and 'espooler_printing_power: 0' | ||||
| # | ||||
| espooler_assist_extruder_move_length: 100	# Distance (mm) extruder needs to move between each assist burst | ||||
| espooler_assist_burst_power: 100		# The % power of the burst move | ||||
| espooler_assist_burst_duration: 0.4		# The duration of the burst move is seconds | ||||
| espooler_assist_burst_trigger: 0		# If trigger assist switch is fitted 0=disable, 1=enable | ||||
| espooler_assist_burst_trigger_max: 3		# If trigger assist switch is fitted this limits the max number of back-to-back advances | ||||
| 
 | ||||
| 
 | ||||
| # Filament Management Options ---------------------------------------------------------------------------------------- | ||||
| # ███████╗██╗██╗            ███╗   ███╗ ██████╗ ███╗   ███╗████████╗ | ||||
| # ██╔════╝██║██║            ████╗ ████║██╔════╝ ████╗ ████║╚══██╔══╝ | ||||
| # █████╗  ██║██║            ██╔████╔██║██║  ███╗██╔████╔██║   ██║    | ||||
| # ██╔══╝  ██║██║            ██║╚██╔╝██║██║   ██║██║╚██╔╝██║   ██║    | ||||
| # ██║     ██║███████╗██╗    ██║ ╚═╝ ██║╚██████╔╝██║ ╚═╝ ██║   ██║    | ||||
| # ╚═╝     ╚═╝╚══════╝╚═╝    ╚═╝     ╚═╝ ╚═════╝ ╚═╝     ╚═╝   ╚═╝    | ||||
| # | ||||
| # - Clog detection is available when encoder is fitted and it can detect when filament is not moving and pause the print | ||||
| # - EndlessSpool feature allows detection of runout on one spool and the automatic mapping of tool to an alternative | ||||
| #   gate (spool). Set to '1', this feature requires clog detection or gate sensor or pre-gate sensors. EndlessSpool | ||||
| #   functionality can optionally be extended to attempt to load an empty gate with 'endless_spool_on_load'. On some MMU | ||||
| #   designs (with linear selector) it can also be configured to eject filament remains to a designated gate rather than | ||||
| #   defaulting to current gate. A custom gate will disable pre-gate runout detection for EndlessSpool because filament | ||||
| #   end must completely pass through the gate for selector to move | ||||
| # | ||||
| enable_clog_detection: 2		# 0 = disable, 1 = static length clog detection, 2 = automatic length clog detection | ||||
| enable_endless_spool: 1			# 0 = disable, 1 = enable endless spool | ||||
| endless_spool_on_load: 0		# 0 = don't apply endless spool on load, 1 = run endless spool if gate is empty | ||||
| endless_spool_eject_gate: -1		# Which gate to eject the filament remains. -1 = current gate | ||||
| #endless_spool_groups:			# Default EndlessSpool groups (see later in file) | ||||
| # | ||||
| # Spoolman support requires you to correctly enable spoolman with moonraker first. If enabled, the gate SpoolId will | ||||
| # be used to load filament details and color from the spoolman database and Happy Hare will activate/deactivate | ||||
| # spools as they are used. The enabled variation allows for either the local map or the spoolman map to be the | ||||
| # source of truth as well as just fetching filament attributes. See this table for explanation: | ||||
| # | ||||
| #                    | Activate/  | Fetch filament attributes | Filament gate    | Filament gate     | | ||||
| #   spoolman_support | Deactivate | attributes from spoolman  | assignment shown | assignment pulled | | ||||
| #                    | spool?     | based on spool_id?        | in spoolman db?  | from spoolman db? | | ||||
| #   -----------------+------------+---------------------------+------------------+-------------------+ | ||||
| #        off         |     no     |           no              |        no        |        no         | | ||||
| #        readonly    |     yes    |           yes             |        no        |        no         | | ||||
| #        push        |     yes    |           yes             |        yes       |        no         | | ||||
| #        pull        |     yes    |           yes             |        yes       |        yes        | | ||||
| # | ||||
| spoolman_support: off			# off = disabled, readonly = enabled, push = local gate map, pull = remote gate map | ||||
| pending_spool_id_timeout: 20            # Seconds after which this pending spool_id (set with rfid) is voided | ||||
| # | ||||
| # Mainsail/Fluid UI can visualize the color of filaments next to the extruder/tool chooser. The color is dynamic and | ||||
| # can be customized to your choice: | ||||
| # | ||||
| #    slicer   - Color from slicer tool map (what the slicer expects) | ||||
| #    allgates - Color from all the tools in the gate map after running through the TTG map | ||||
| #    gatemap  - As per gatemap but hide empty tools | ||||
| #    off      - Turns off support | ||||
| # | ||||
| # Note: Happy Hare will also add the 'spool_id' variable to the Tx macro if spoolman is enabled | ||||
| # | ||||
| t_macro_color: slicer			# 'slicer' = default | 'allgates' = mmu | 'gatemap' = mmu without empty gates | 'off' | ||||
| 
 | ||||
| 
 | ||||
| # Print Statistics --------------------------------------------------------------------------------------------------- | ||||
| # ███████╗████████╗ █████╗ ████████╗███████╗ | ||||
| # ██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝ | ||||
| # ███████╗   ██║   ███████║   ██║   ███████╗ | ||||
| # ╚════██║   ██║   ██╔══██║   ██║   ╚════██║ | ||||
| # ███████║   ██║   ██║  ██║   ██║   ███████║ | ||||
| # ╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝   ╚══════╝ | ||||
| # | ||||
| # These parameters determine how print statistic data is shown in the console. This table can show a lot of data, | ||||
| # probably more than you'd want to see. Below you can enable/disable options to your needs. | ||||
| # | ||||
| # +-----------+---------------------+----------------------+----------+ | ||||
| # |  114(46)  |      unloading      |       loading        | complete | | ||||
| # |   swaps   | pre  |   -   | post | pre  |   -   | post  |   swap   | | ||||
| # +-----------+------+-------+------+------+-------+-------+----------+ | ||||
| # | all time  | 0:07 | 47:19 | 0:00 | 0:01 | 37:11 | 33:39 |  2:00:38 | | ||||
| # |     - avg | 0:00 |  0:24 | 0:00 | 0:00 |  0:19 |  0:17 |     1:03 | | ||||
| # | this job  | 0:00 | 10:27 | 0:00 | 0:00 |  8:29 |  8:30 |    28:02 | | ||||
| # |     - avg | 0:00 |  0:13 | 0:00 | 0:00 |  0:11 |  0:11 |     0:36 | | ||||
| # |      last | 0:00 |  0:12 | 0:00 | 0:00 |  0:10 |  0:14 |     0:39 | | ||||
| # +-----------+------+-------+------+------+-------+-------+----------+ | ||||
| #             Note: Only formats correctly on Python3 | ||||
| # | ||||
| # Comma separated list of desired columns | ||||
| # Options: pre_unload, form_tip, unload, post_unload, pre_load, load, purge, post_load, total | ||||
| console_stat_columns: unload, load, post_load, total | ||||
| 
 | ||||
| # Comma separated list of rows. The order determines the order in which they're shown. | ||||
| # Options: total, total_average, job, job_average, last | ||||
| console_stat_rows: total, total_average, job, job_average, last | ||||
| 
 | ||||
| # How you'd want to see the state of the gates and how they're performing | ||||
| #   string     - poor, good, perfect, etc.. | ||||
| #   percentage - rate of success | ||||
| #   emoticon   - fun sad to happy faces (python3 only) | ||||
| console_gate_stat: emoticon | ||||
| 
 | ||||
| # Always display the full statistics table | ||||
| console_always_output_full: 1	# 1 = Show full table, 0 = Only show totals out of print | ||||
| 
 | ||||
| 
 | ||||
| # Miscellaneous, but you should review ------------------------------------------------------------------------------- | ||||
| # ███╗   ███╗██╗███████╗ ██████╗ | ||||
| # ████╗ ████║██║██╔════╝██╔════╝ | ||||
| # ██╔████╔██║██║███████╗██║      | ||||
| # ██║╚██╔╝██║██║╚════██║██║      | ||||
| # ██║ ╚═╝ ██║██║███████║╚██████╗ | ||||
| # ╚═╝     ╚═╝╚═╝╚══════╝ ╚═════╝ | ||||
| # | ||||
| # Important you verify these work for you setup/workflow. Temperature and timeouts | ||||
| # | ||||
| timeout_pause: 72000		# Idle time out (printer shuts down) in seconds used when in MMU pause state | ||||
| disable_heater: 600		# Delay in seconds after which the hotend heater is disabled in the MMU_PAUSE state | ||||
| default_extruder_temp: 200	# Default temperature for performing swaps and forming tips when not in print (overridden by gate map) | ||||
| extruder_temp_variance: 2	# When waiting for extruder temperature this is the +/- permissible variance in degrees (>= 1) | ||||
| # | ||||
| # These are auto calibration/tuning settings. Once the gear rotation_distance and encoder are calibrated, enabling these options | ||||
| # will lessen the initial calibration and will automatically tune bowden length and individual gate rotation_distance differences. | ||||
| # Note: What can be tuned is based on "variable_rotation_distance" and "variable_bowden_lengths" settings in mmu_hardware.cfg | ||||
| #       E.g. with fixed bowden and multiple BMG gears and encoder like the ERCF, the bowden length is tuned on gate#0 and | ||||
| #            rotation_distance (MMU_CALIBRATE_GATE) is tuned for other gates. | ||||
| # | ||||
| autotune_bowden_length: 0       # Automated bowden length calibration/tuning. 1=automatic, 0=manual/off | ||||
| autotune_rotation_distance: 0   # Automated gate calibration/tuning (requires encoder). 1=automatic, 0=manual/off | ||||
| # | ||||
| # Other workflow options | ||||
| # | ||||
| startup_home_if_unloaded: 0	# 1 = force mmu homing on startup if unloaded, 0 = do nothing | ||||
| startup_reset_ttg_map: 0	# 1 = reset TTG map on startup, 0 = do nothing | ||||
| show_error_dialog: 0		# 1 = show pop-up dialog in addition to console message, 0 = show error in console | ||||
| preload_attempts: 5		# How many "grabbing" attempts are made to pick up the filament with preload feature | ||||
| strict_filament_recovery: 0	# If enabled with MMU with toolhead sensor, this will cause filament position recovery to | ||||
| 				# perform extra moves to look for filament trapped in the space after extruder but before sensor | ||||
| filament_recovery_on_pause: 1	# 1 = Run a quick check to determine current filament position on pause/error, 0 = disable | ||||
| retry_tool_change_on_error: 0	# Whether to automatically retry a failed tool change. If enabled Happy Hare will perform | ||||
| 				# the equivalent of 'MMU_RECOVER' + 'Tx' commands which usually is all that is necessary | ||||
| 				# to recover. Note that enabling this can mask problems with your MMU | ||||
| bypass_autoload: 1		# If extruder sensor fitted this controls the automatic loading of extruder for bypass operation | ||||
| has_filament_buffer: 1          # Whether the MMU has a filament buffer. Set to 0 if using Filamentalist or DC eSpooler, etc | ||||
| # | ||||
| # Advanced options. Don't mess unless you fully understand. Read documentation. | ||||
| # | ||||
| encoder_move_validation: 1	# ADVANCED: 1 = Normally Encoder validates move distances are within given tolerance | ||||
| 				#           0 = Validation is disabled (eliminates slight pause between moves but less safe) | ||||
| print_start_detection: 1	# ADVANCED: Enabled for Happy Hare to automatically detect start and end of print and call | ||||
| 				# ADVANCED: MMU_PRINT_START and MMU_PRINT_END automatically. Harmless to leave enabled but can disable | ||||
|                                 #           if you think it is causing problems and known START/END is covered in your macros | ||||
| extruder: extruder		# ADVANCED: Name of the toolhead extruder that MMU is using | ||||
| gcode_load_sequence: 0		# VERY ADVANCED: Gcode loading sequence 1=enabled, 0=internal logic (default) | ||||
| gcode_unload_sequence: 0	# VERY ADVANCED: Gcode unloading sequence, 1=enabled, 0=internal logic (default) | ||||
| 
 | ||||
| 
 | ||||
| # ADVANCED: Klipper tuning ------------------------------------------------------------------------------------------- | ||||
| # ██╗  ██╗██╗     ██╗██████╗ ██████╗ ███████╗██████╗  | ||||
| # ██║ ██╔╝██║     ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗ | ||||
| # █████╔╝ ██║     ██║██████╔╝██████╔╝█████╗  ██████╔╝ | ||||
| # ██╔═██╗ ██║     ██║██╔═══╝ ██╔═══╝ ██╔══╝  ██╔══██╗ | ||||
| # ██║  ██╗███████╗██║██║     ██║     ███████╗██║  ██║ | ||||
| # ╚═╝  ╚═╝╚══════╝╚═╝╚═╝     ╚═╝     ╚══════╝╚═╝  ╚═╝ | ||||
| # | ||||
| # Timer too close is a catch all error, however it has been found to occur on some systems during homing and probing | ||||
| # operations especially so with CANbus connected MCUs. Happy Hare uses many homing moves for reliable extruder loading | ||||
| # and unloading and enabling this option affords klipper more tolerance and avoids this dreaded error | ||||
| # | ||||
| update_trsync: 0		# 1 = Increase TRSYNC_TIMEOUT, 0 = Leave the klipper default | ||||
| # | ||||
| # Some CANbus boards are prone to this but it have been seen on regular USB boards where a comms timeout will kill | ||||
| # the print. Since it seems to occur only on homing moves they can be safely retried to workaround. This has been | ||||
| # working well in practice | ||||
| canbus_comms_retries: 3		# Number of retries. Recommend the default of 3. | ||||
| # | ||||
| # Older neopixels have very finicky timing and can generate lots of "Unable to obtain 'neopixel_result' response" | ||||
| # errors in klippy.log. An often cited workaround is to increase BIT_MAX_TIME in neopixel.py. This option does that | ||||
| # automatically for you to save dirtying klipper | ||||
| update_bit_max_time: 1		# 1 = Increase BIT_MAX_TIME, 0 = Leave the klipper default | ||||
| 
 | ||||
| 
 | ||||
| # ADVANCED: MMU macro overrides --- ONLY SET IF YOU'RE COMFORTABLE WITH KLIPPER MACROS ------------------------------- | ||||
| # ███╗   ███╗ █████╗  ██████╗██████╗  ██████╗ ███████╗ | ||||
| # ████╗ ████║██╔══██╗██╔════╝██╔══██╗██╔═══██╗██╔════╝ | ||||
| # ██╔████╔██║███████║██║     ██████╔╝██║   ██║███████╗ | ||||
| # ██║╚██╔╝██║██╔══██║██║     ██╔══██╗██║   ██║╚════██║ | ||||
| # ██║ ╚═╝ ██║██║  ██║╚██████╗██║  ██║╚██████╔╝███████║ | ||||
| # ╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝ | ||||
| # | ||||
| # 'pause_macro' defines what macro to call on MMU error (must put printer in paused state) | ||||
| # Other macros are detailed in 'mmu_sequence.cfg' | ||||
| # Also see form_tip_macro in Tip Forming section and purge_macro in Purging section | ||||
| # | ||||
| pause_macro: PAUSE 					# What macro to call to pause the print | ||||
| action_changed_macro: _MMU_ACTION_CHANGED		# Called when action (printer.mmu.action) changes | ||||
| print_state_changed_macro: _MMU_PRINT_STATE_CHANGED	# Called when print state (printer.mmu.print_state) changes | ||||
| mmu_event_macro: _MMU_EVENT				# Called on useful MMU events | ||||
| pre_unload_macro: _MMU_PRE_UNLOAD			# Called before starting the unload | ||||
| post_form_tip_macro: _MMU_POST_FORM_TIP			# Called immediately after tip forming | ||||
| post_unload_macro: _MMU_POST_UNLOAD			# Called after unload completes | ||||
| pre_load_macro: _MMU_PRE_LOAD				# Called before starting the load | ||||
| post_load_macro: _MMU_POST_LOAD				# Called after the load is complete | ||||
| unload_sequence_macro: _MMU_UNLOAD_SEQUENCE		# VERY ADVANCED: Optionally called based on 'gcode_unload_sequence' | ||||
| load_sequence_macro: _MMU_LOAD_SEQUENCE			# VERY ADVANCED: Optionally called based on 'gcode_load_sequence' | ||||
| 
 | ||||
| 
 | ||||
| # ADVANCED: See documentation for use of these ----------------------------------------------------------------------- | ||||
| # ██████╗ ███████╗███████╗███████╗████████╗    ██████╗ ███████╗███████╗███████╗ | ||||
| # ██╔══██╗██╔════╝██╔════╝██╔════╝╚══██╔══╝    ██╔══██╗██╔════╝██╔════╝██╔════╝ | ||||
| # ██████╔╝█████╗  ███████╗█████╗     ██║       ██║  ██║█████╗  █████╗  ███████╗ | ||||
| # ██╔══██╗██╔══╝  ╚════██║██╔══╝     ██║       ██║  ██║██╔══╝  ██╔══╝  ╚════██║ | ||||
| # ██║  ██║███████╗███████║███████╗   ██║       ██████╔╝███████╗██║     ███████║ | ||||
| # ╚═╝  ╚═╝╚══════╝╚══════╝╚══════╝   ╚═╝       ╚═════╝ ╚══════╝╚═╝     ╚══════╝ | ||||
| # | ||||
| # These are the values that the various "RESET" commands will reset too rather than the built-in defaults. The lenght | ||||
| # of the lists must match the number of gates on your MMU | ||||
| # | ||||
| # e.g. MMU_GATE_MAP RESET=1              - will use all the 'gate_XXX' values | ||||
| #      MMU_TTG_MAP RESET=1               - will use the 'tool_to_gate_map' | ||||
| #      MMU_ENDLESS_SPOOL_GROUPS RESET=1  - will use the 'endless_spool_groups' | ||||
| # | ||||
| # Gate:                #0      #1      #2      #3      #4      #5      #6      #7      #8 | ||||
| #gate_status:          1,      0,      1,      2,      2,     -1,     -1,      0,      1 | ||||
| #gate_filament_name:   one,    two,    three,  four,   five,   six,    seven,  eight,  nine | ||||
| #gate_material:        PLA,    ABS,    ABS,    ABS+,   PLA,    PLA,    PETG,   TPU,    ABS | ||||
| #gate_color:           red,    black,  yellow, green,  blue,   indigo, ffffff, grey,   black | ||||
| #gate_temperature:     210,    240,    235,    245,    210,    200,    215,    240,    240 | ||||
| #gate_spool_id:        3,      2,      1,      4,      5,      6,      7,      -1,     9 | ||||
| #gate_speed_override:  100,    100,    100,    100,    100,    100,    100,    50,     100 | ||||
| #endless_spool_groups: 0,      1,      2,      1,      0,      0,      3,      4,      1 | ||||
| # | ||||
| # Tool:                T0      T1      T2      T3      T4      T5      T6      T7      T8 | ||||
| #tool_to_gate_map:     0,      1,      2,      3,      4,      5,      6,      7,      8 | ||||
| 
 | ||||
| 
 | ||||
| # ADVANCED/CUSTOM MMU: See documentation for use of these ------------------------------------------------------------ | ||||
| #  ██████╗██╗   ██╗███████╗████████╗ ██████╗ ███╗   ███╗    ███╗   ███╗███╗   ███╗██╗   ██╗ | ||||
| # ██╔════╝██║   ██║██╔════╝╚══██╔══╝██╔═══██╗████╗ ████║    ████╗ ████║████╗ ████║██║   ██║ | ||||
| # ██║     ██║   ██║███████╗   ██║   ██║   ██║██╔████╔██║    ██╔████╔██║██╔████╔██║██║   ██║ | ||||
| # ██║     ██║   ██║╚════██║   ██║   ██║   ██║██║╚██╔╝██║    ██║╚██╔╝██║██║╚██╔╝██║██║   ██║ | ||||
| # ╚██████╗╚██████╔╝███████║   ██║   ╚██████╔╝██║ ╚═╝ ██║    ██║ ╚═╝ ██║██║ ╚═╝ ██║╚██████╔╝ | ||||
| #  ╚═════╝ ╚═════╝ ╚══════╝   ╚═╝    ╚═════╝ ╚═╝     ╚═╝    ╚═╝     ╚═╝╚═╝     ╚═╝ ╚═════╝  | ||||
| # | ||||
| # Normally all these settings are set based on your choice of 'mmu_vendor' and 'mmu_version' in mmu_hardware.cfg, but they | ||||
| # can be overridden. If you have selected a vendor of "Other" and your MMU has a selector you must set these CAD based | ||||
| # dimensions else you will get arbitrary defaults. You may also need to set additional attributes in '[mmu_machine]' | ||||
| # section of mmu_hardware.cfg. | ||||
| # | ||||
| #cad_gate0_pos: 4.2					# Approximate distance from endstop to first gate. Used for rough calibration only | ||||
| #cad_gate_width: 21.0					# Width of each gate | ||||
| #cad_bypass_offset: 0					# Distance from limit of travel back to the bypass (e.g. ERCF v2.0) | ||||
| #cad_last_gate_offset: 2.0				# Distance from limit of travel back to last gate | ||||
| #cad_selector_tolerance: 10.0				# How much extra selector movement to allow for calibration | ||||
| #cad_gate_directions = [1, 1, 0, 0]			# Directions of gear depending on gate (3DChameleon) | ||||
| #cad_release_gates = [2, 3, 0, 1]			# Gate to move to when releasing filament (3DChameleon) | ||||
| 
 | ||||
| # SUPPLEMENTAL USER CONFIG retained after upgrade -------------------------------------------------------------------- | ||||
| # | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_purge.cfg | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_sequence.cfg | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_software.cfg | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/base/mmu_state.cfg | ||||
|  | @ -1,38 +0,0 @@ | |||
| [Variables] | ||||
| mmu__revision = 3771 | ||||
| mmu_calibration_bowden_home = 'encoder' | ||||
| mmu_calibration_bowden_lengths = [1425.1, 1425.1, 1425.1, 1425.1, 1425.1, 1425.1, 1425.1, 1425.1] | ||||
| mmu_calibration_clog_length = 8.9 | ||||
| mmu_encoder_resolution = 0.968523 | ||||
| mmu_gear_rotation_distances = [22.731687, 22.686238, 22.849841, 22.94982, 22.958909, 22.94982, 22.895286, 22.958909] | ||||
| mmu_selector_bypass = 179.7 | ||||
| mmu_selector_offsets = [6.1, 26.9, 50.9, 74.1, 97.3, 121.3, 144.5, 167.7] | ||||
| mmu_servo_angles = {'down': 90, 'up': 10, 'move': 35} | ||||
| mmu_state_enable_endless_spool = 1 | ||||
| mmu_state_endless_spool_groups = [0, 1, 0, 2, 3, 4, 5, 6] | ||||
| mmu_state_filament_pos = 0 | ||||
| mmu_state_filament_remaining = 0 | ||||
| mmu_state_filament_remaining_color = '' | ||||
| mmu_state_gate_color = ['', '', '', '', '', '', '', ''] | ||||
| mmu_state_gate_filament_name = ['', '', '', '', '', '', '', ''] | ||||
| mmu_state_gate_material = ['', '', '', '', '', '', '', ''] | ||||
| mmu_state_gate_selected = 1 | ||||
| mmu_state_gate_speed_override = [100, 100, 100, 100, 100, 100, 100, 100] | ||||
| mmu_state_gate_spool_id = [-1, -1, -1, -1, -1, -1, -1, -1] | ||||
| mmu_state_gate_status = [-1, 1, 2, -1, -1, -1, -1, -1] | ||||
| mmu_state_gate_temperature = [200, 200, 200, 200, 200, 200, 200, 200] | ||||
| mmu_state_last_tool = 0 | ||||
| mmu_state_tool_selected = 0 | ||||
| mmu_state_tool_to_gate_map = [1, 1, 1, 1, 1, 1, 1, 1] | ||||
| mmu_statistics_counters = {'servo_down': {'count': 1133, 'limit': 5000, 'warning': 'Inspect servo arm for wear/damage', 'pause': False}, 'mmu_restarts': {'count': 256, 'limit': -1, 'warning': ''}, 'cutter_blade': {'count': 67, 'limit': 3000, 'warning': 'Inspect/replace filament cutting blade', 'pause': False}} | ||||
| mmu_statistics_gate_0 = {'pauses': 0, 'loads': 2, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 2, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_1 = {'pauses': 7, 'loads': 16, 'load_distance': 20400.457, 'load_delta': 7020.311, 'unloads': 16, 'unload_distance': 9610.7, 'unload_delta': 534.671, 'load_failures': 8, 'unload_failures': 5, 'quality': 0.4424617663045427} | ||||
| mmu_statistics_gate_2 = {'pauses': 1, 'loads': 14, 'load_distance': 19284.879, 'load_delta': 4486.816, 'unloads': 15, 'unload_distance': 13736.0, 'unload_delta': 411.062, 'load_failures': 6, 'unload_failures': 2, 'quality': 0.5699077987480133} | ||||
| mmu_statistics_gate_3 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_4 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_5 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_6 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_7 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_swaps = {'pre_load': 9.64, 'load': 1067.77, 'total': 1120.72, 'pre_unload': 9.38, 'post_unload': 7.24, 'unload': 710.67, 'purge': 44.02, 'post_load': 92.64, 'total_swaps': 12, 'swaps_since_pause': 2, 'swaps_since_pause_record': 3, 'form_tip': 144.15, 'total_pauses': 8, 'pause': 1367.03} | ||||
| nvm_offset = -0.11599999999999978 | ||||
| 
 | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/optional/client_macros.cfg | ||||
|  | @ -1 +0,0 @@ | |||
| /home/pi/Happy-Hare/config/optional/mmu_menu.cfg | ||||
|  | @ -335,7 +335,7 @@ variable_cut_stepper_current    : 100				; % of stepper current to use for cutti | |||
| # lightly touches the depressor pin | ||||
| # NOTE: this is with skew correction ON | ||||
| variable_cutting_axis           : "x"		; "x" or "y". Determines cut direction (axis) during cut motion, used for park distance | ||||
| variable_pin_loc_xy             : 14, 351	; x,y coordinates of depressor pin | ||||
| variable_pin_loc_xy             : 19.54, 353	; x,y coordinates of depressor pin | ||||
| 
 | ||||
| # This distance is added to "pin_loc_x" or "pin_loc_y" depending on the 'cutting_axis' | ||||
| # to determine the starting position and to create a small safety distance that aids | ||||
|  | @ -346,7 +346,7 @@ variable_pin_park_dist          : 5.0		; Distance in mm | |||
| # extremes of your printer edges (e.g. it should be a bit larger than 0, or whatever Xmin is) to avoid | ||||
| # banging the toolhead or gantry. Typically x position will match x in pin_loc_xy if cutting in y direction | ||||
| # or y position will match y in pin_loc_xy if cutting in x direction, but diagonal cuts are possible | ||||
| variable_pin_loc_compressed_xy  : 6, 351	; x,y coordinates of fully depressed location | ||||
| variable_pin_loc_compressed_xy  : 3.54, 353	; x,y coordinates of fully depressed location | ||||
| 
 | ||||
| # Retract length and speed after the cut so that the cutter blade doesn't | ||||
| # get stuck on return to origin position | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| [Variables] | ||||
| mmu__revision = 4243 | ||||
| mmu__revision = 3731 | ||||
| mmu_calibration_bowden_home = 'encoder' | ||||
| mmu_calibration_bowden_lengths = [1425.1, 1425.1, 1425.1, 1425.1, 1425.1, 1425.1, 1425.1, 1425.1] | ||||
| mmu_calibration_clog_length = 8.9 | ||||
|  | @ -9,9 +9,9 @@ mmu_selector_bypass = 179.7 | |||
| mmu_selector_offsets = [6.1, 26.9, 50.9, 74.1, 97.3, 121.3, 144.5, 167.7] | ||||
| mmu_servo_angles = {'down': 90, 'up': 10, 'move': 35} | ||||
| mmu_state_enable_endless_spool = 1 | ||||
| mmu_state_endless_spool_groups = [0, 1, 2, 3, 4, 5, 6, 7] | ||||
| mmu_state_filament_pos = 10 | ||||
| mmu_state_filament_remaining = 10.0 | ||||
| mmu_state_endless_spool_groups = [0, 1, 0, 2, 3, 4, 5, 6] | ||||
| mmu_state_filament_pos = 0 | ||||
| mmu_state_filament_remaining = 0 | ||||
| mmu_state_filament_remaining_color = '' | ||||
| mmu_state_gate_color = ['', '', '', '', '', '', '', ''] | ||||
| mmu_state_gate_filament_name = ['', '', '', '', '', '', '', ''] | ||||
|  | @ -19,20 +19,20 @@ mmu_state_gate_material = ['', '', '', '', '', '', '', ''] | |||
| mmu_state_gate_selected = 1 | ||||
| mmu_state_gate_speed_override = [100, 100, 100, 100, 100, 100, 100, 100] | ||||
| mmu_state_gate_spool_id = [-1, -1, -1, -1, -1, -1, -1, -1] | ||||
| mmu_state_gate_status = [-1, 1, 0, -1, -1, -1, -1, -1] | ||||
| mmu_state_gate_status = [-1, 1, 2, -1, -1, -1, -1, -1] | ||||
| mmu_state_gate_temperature = [200, 200, 200, 200, 200, 200, 200, 200] | ||||
| mmu_state_last_tool = 0 | ||||
| mmu_state_tool_selected = 1 | ||||
| mmu_state_tool_selected = 0 | ||||
| mmu_state_tool_to_gate_map = [1, 1, 1, 1, 1, 1, 1, 1] | ||||
| mmu_statistics_counters = {'servo_down': {'count': 1209, 'limit': 5000, 'warning': 'Inspect servo arm for wear/damage', 'pause': False}, 'mmu_restarts': {'count': 311, 'limit': -1, 'warning': ''}, 'cutter_blade': {'count': 72, 'limit': 3000, 'warning': 'Inspect/replace filament cutting blade', 'pause': False}} | ||||
| mmu_statistics_counters = {'servo_down': {'count': 1133, 'limit': 5000, 'warning': 'Inspect servo arm for wear/damage', 'pause': False}, 'mmu_restarts': {'count': 248, 'limit': -1, 'warning': ''}, 'cutter_blade': {'count': 67, 'limit': 3000, 'warning': 'Inspect/replace filament cutting blade', 'pause': False}} | ||||
| mmu_statistics_gate_0 = {'pauses': 0, 'loads': 2, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 2, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_1 = {'pauses': 7, 'loads': 17, 'load_distance': 21959.049, 'load_delta': 7303.358, 'unloads': 16, 'unload_distance': 9610.7, 'unload_delta': 534.671, 'load_failures': 8, 'unload_failures': 5, 'quality': 0.39797587469336376} | ||||
| mmu_statistics_gate_2 = {'pauses': 1, 'loads': 18, 'load_distance': 23812.234, 'load_delta': 7179.788, 'unloads': 23, 'unload_distance': 17861.3, 'unload_delta': 2802.706, 'load_failures': 9, 'unload_failures': 5, 'quality': 0.6142025669990863} | ||||
| mmu_statistics_gate_1 = {'pauses': 7, 'loads': 16, 'load_distance': 20400.457, 'load_delta': 7020.311, 'unloads': 16, 'unload_distance': 9610.7, 'unload_delta': 534.671, 'load_failures': 8, 'unload_failures': 5, 'quality': 0.4424617663045427} | ||||
| mmu_statistics_gate_2 = {'pauses': 1, 'loads': 14, 'load_distance': 19284.879, 'load_delta': 4486.816, 'unloads': 15, 'unload_distance': 13736.0, 'unload_delta': 411.062, 'load_failures': 6, 'unload_failures': 2, 'quality': 0.5699077987480133} | ||||
| mmu_statistics_gate_3 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_4 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_5 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_6 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_gate_7 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} | ||||
| mmu_statistics_swaps = {'pre_load': 10.54, 'load': 1165.82, 'total': 1160.5, 'pre_unload': 11.5, 'post_unload': 8.76, 'unload': 825.66, 'purge': 46.32, 'post_load': 106.49, 'total_swaps': 12, 'swaps_since_pause': 2, 'swaps_since_pause_record': 3, 'form_tip': 158.85, 'total_pauses': 8, 'pause': 1367.03} | ||||
| mmu_statistics_swaps = {'pre_load': 9.64, 'load': 1067.77, 'total': 1120.72, 'pre_unload': 9.38, 'post_unload': 7.24, 'unload': 710.67, 'purge': 44.02, 'post_load': 92.64, 'total_swaps': 12, 'swaps_since_pause': 2, 'swaps_since_pause_record': 3, 'form_tip': 144.15, 'total_pauses': 8, 'pause': 1367.03} | ||||
| nvm_offset = -0.11599999999999978 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										87
									
								
								printer.cfg
									
										
									
									
									
								
							
							
						
						
									
										87
									
								
								printer.cfg
									
										
									
									
									
								
							|  | @ -1,7 +1,6 @@ | |||
| # MMU to be disconnected, so let's have klipper able to run without it. | ||||
| #[include mmu/base/*.cfg] | ||||
| #[include mmu/optional/client_macros.cfg] | ||||
| #[include mmu/optional/mmu_menu.cfg] | ||||
| [include mmu/base/*.cfg] | ||||
| [include mmu/optional/client_macros.cfg] | ||||
| [include mmu/optional/mmu_menu.cfg] | ||||
| [include timelapse.cfg] | ||||
| # This file contains common pin mappings for the BigTreeTech Octopus V1. | ||||
| # To use this config, the firmware should be compiled for the STM32F446 with a "32KiB bootloader" | ||||
|  | @ -442,73 +441,23 @@ enable_force_move: True | |||
| #*# | ||||
| #*# [scanner] | ||||
| #*# mode = touch | ||||
| #*# scanner_touch_threshold = 1250 | ||||
| #*# scanner_touch_speed = 2 | ||||
| #*# scanner_touch_z_offset = 0.100 | ||||
| #*# scanner_touch_threshold = 3000 | ||||
| #*# scanner_touch_speed = 3 | ||||
| #*# | ||||
| #*# [scanner model default] | ||||
| #*# model_coef = 1.3305122102001719, | ||||
| #*# 	1.778716040310351, | ||||
| #*# 	0.7680440090844358, | ||||
| #*# 	0.23859921897576467, | ||||
| #*# 	0.43324242351119213, | ||||
| #*# 	0.7990293243051444, | ||||
| #*# 	-0.29774573915060454, | ||||
| #*# 	-0.826319532368512, | ||||
| #*# 	0.3149315990912823, | ||||
| #*# 	0.46089389855396873 | ||||
| #*# model_domain = 3.190439773591761e-07,3.333428586585128e-07 | ||||
| #*# model_range = 0.100000,5.000000 | ||||
| #*# model_temp = 27.128733 | ||||
| #*# model_coef = 1.4660235274886952, | ||||
| #*# 	  1.8088603709207522, | ||||
| #*# 	  0.7349055898946472, | ||||
| #*# 	  0.2687409591730736, | ||||
| #*# 	  0.47813534708329936, | ||||
| #*# 	  0.669955108628895, | ||||
| #*# 	  -0.3235976797345473, | ||||
| #*# 	  -0.6702739199959514, | ||||
| #*# 	  0.2940760023005045, | ||||
| #*# 	  0.3745733001336773 | ||||
| #*# model_domain = 3.2050348407481734e-07,3.335190657416707e-07 | ||||
| #*# model_range = 0.200000,5.100000 | ||||
| #*# model_temp = 30.248095 | ||||
| #*# model_offset = 0.00000 | ||||
| #*# model_mode = touch | ||||
| #*# model_fw_version = CARTOGRAPHER 5.0.0 | ||||
| #*# | ||||
| #*# [bed_mesh default] | ||||
| #*# version = 1 | ||||
| #*# points = | ||||
| #*# 	0.004141, 0.004549, -0.000733, -0.001003, -0.005359, -0.005042, -0.009642, -0.013812, -0.010166, -0.007716, -0.004855, -0.000425, 0.002495, -0.001015, -0.004729, -0.005912, -0.006870, -0.002302, 0.004081, 0.009434, 0.018398, 0.025699, 0.022665, 0.017863, 0.018018, 0.013572, 0.009637, 0.005972, -0.000404, 0.011483 | ||||
| #*# 	0.006567, 0.003236, 0.006012, 0.004138, -0.002341, -0.005950, -0.010710, -0.011375, -0.007339, -0.007375, -0.007296, -0.005194, 0.004181, 0.003895, -0.011801, -0.011846, -0.009110, -0.004997, 0.009130, 0.008604, 0.017817, 0.027138, 0.032314, 0.022720, 0.015723, 0.012146, 0.013784, 0.015243, 0.006402, 0.013213 | ||||
| #*# 	0.015125, 0.012134, 0.010536, 0.006715, 0.005960, 0.001845, -0.000486, -0.005612, -0.005394, -0.002616, -0.000621, -0.000459, 0.001777, -0.000055, -0.006750, -0.009486, -0.008739, -0.006074, 0.002905, 0.013089, 0.022485, 0.027253, 0.029100, 0.026988, 0.023004, 0.015705, 0.013318, 0.009580, 0.008696, 0.013590 | ||||
| #*# 	0.020752, 0.018108, 0.016423, 0.015550, 0.012114, 0.007824, 0.004757, 0.003697, -0.000854, 0.003628, 0.004182, 0.004141, 0.001848, 0.004134, -0.000465, -0.009647, -0.007692, -0.000302, -0.000788, 0.011563, 0.027374, 0.031254, 0.026888, 0.032574, 0.026990, 0.017737, 0.023616, 0.015541, 0.013764, 0.022188 | ||||
| #*# 	0.028236, 0.022995, 0.017853, 0.020215, 0.015295, 0.008719, 0.007567, 0.005262, 0.005299, 0.006798, 0.010862, 0.006510, 0.004132, 0.008693, 0.001344, -0.005151, -0.003890, -0.002739, 0.003711, 0.013027, 0.022634, 0.029440, 0.030338, 0.028053, 0.028985, 0.025826, 0.026912, 0.018018, 0.013308, 0.027996 | ||||
| #*# 	0.026930, 0.022417, 0.021918, 0.017893, 0.013448, 0.009868, 0.008131, 0.005941, 0.006464, 0.009398, 0.009043, 0.007900, 0.007752, 0.006433, 0.003930, 0.001782, -0.002447, -0.001598, 0.003841, 0.012138, 0.023313, 0.029493, 0.031403, 0.031326, 0.031194, 0.027562, 0.022597, 0.021976, 0.018974, 0.026856 | ||||
| #*# 	0.029299, 0.024563, 0.018284, 0.020053, 0.015134, 0.011038, 0.007319, 0.006661, 0.006559, 0.009320, 0.009079, 0.008744, 0.010833, 0.006747, 0.006316, 0.005284, -0.000912, -0.001439, 0.004928, 0.013298, 0.022567, 0.028930, 0.031029, 0.029758, 0.029212, 0.025781, 0.027079, 0.020701, 0.017009, 0.025382 | ||||
| #*# 	0.031455, 0.025955, 0.022857, 0.019364, 0.013151, 0.010999, 0.009623, 0.008720, 0.004140, 0.010588, 0.011060, 0.013321, 0.007625, 0.009022, 0.007956, 0.005831, 0.005892, -0.001514, 0.005559, 0.018575, 0.020410, 0.031243, 0.030774, 0.031800, 0.038259, 0.031613, 0.022392, 0.024867, 0.026914, 0.020700 | ||||
| #*# 	0.029243, 0.028111, 0.022949, 0.016939, 0.012835, 0.012467, 0.013531, 0.008741, 0.006449, 0.008657, 0.013844, 0.013789, 0.010883, 0.004140, 0.004490, 0.004612, 0.000478, 0.000490, 0.004319, 0.013193, 0.026911, 0.032451, 0.031452, 0.031437, 0.031625, 0.033729, 0.029190, 0.024654, 0.022058, 0.027502 | ||||
| #*# 	0.031447, 0.026607, 0.020228, 0.017005, 0.013440, 0.011023, 0.006877, 0.003219, 0.003708, 0.006436, 0.008403, 0.009931, 0.006449, 0.005267, -0.001583, -0.002725, -0.003085, -0.000431, 0.001272, 0.008410, 0.022612, 0.031793, 0.028617, 0.022367, 0.030688, 0.029047, 0.031412, 0.020171, 0.017549, 0.022100 | ||||
| #*# 	0.029691, 0.027286, 0.020073, 0.015962, 0.008717, 0.009395, 0.006407, 0.004179, -0.002743, -0.000788, 0.002132, 0.004823, -0.001062, -0.002748, -0.005456, -0.007313, -0.009897, -0.010492, -0.004780, 0.007642, 0.017719, 0.022314, 0.022409, 0.021429, 0.022620, 0.019002, 0.017279, 0.013300, 0.012185, 0.022299 | ||||
| #*# 	0.027214, 0.022930, 0.017864, 0.017329, 0.012725, 0.004741, 0.001983, -0.001464, -0.003246, -0.000889, -0.000556, 0.000500, 0.000687, -0.005355, -0.006733, -0.010802, -0.012216, -0.011587, -0.004968, 0.006015, 0.018337, 0.013297, 0.019614, 0.023682, 0.018036, 0.018233, 0.015469, 0.012113, 0.018492, 0.011011 | ||||
| #*# 	0.022373, 0.021051, 0.017864, 0.012471, 0.008716, 0.006432, 0.000036, -0.004988, -0.003958, -0.002406, -0.001275, -0.004444, -0.004800, -0.004561, -0.009028, -0.009527, -0.010000, -0.009645, -0.005256, 0.003028, 0.012414, 0.015850, 0.017859, 0.016012, 0.015562, 0.015568, 0.013336, 0.010532, 0.009063, 0.017900 | ||||
| #*# 	0.021848, 0.016660, 0.012861, 0.010557, 0.008612, 0.004148, 0.000399, -0.002715, -0.005298, -0.002714, -0.000445, -0.005080, -0.006038, -0.005060, -0.010185, -0.009668, -0.008834, -0.011597, -0.005905, 0.005284, 0.013702, 0.012615, 0.015732, 0.018138, 0.012186, 0.013513, 0.017834, 0.003829, 0.008415, 0.018073 | ||||
| #*# 	0.022602, 0.015587, 0.011012, 0.009007, 0.008211, 0.004084, 0.000849, -0.000350, -0.002716, -0.000963, -0.000138, -0.003621, -0.005213, -0.005522, -0.004784, -0.008491, -0.009218, -0.008966, -0.005133, 0.003042, 0.009507, 0.013274, 0.013549, 0.013766, 0.015559, 0.016716, 0.014435, 0.011015, 0.005084, 0.012858 | ||||
| #*# 	0.018351, 0.015604, 0.013295, 0.012176, 0.009749, 0.007578, 0.004305, 0.000909, 0.000120, 0.004836, 0.004383, 0.003024, -0.001115, -0.001403, 0.002707, -0.002191, -0.007175, -0.005037, 0.000397, 0.005434, 0.008452, 0.018318, 0.020658, 0.020138, 0.027486, 0.022306, 0.021724, 0.016258, 0.015580, 0.016702 | ||||
| #*# 	0.023398, 0.017273, 0.014179, 0.013007, 0.013371, 0.008961, 0.004136, 0.004139, 0.005443, 0.008857, 0.008535, 0.008120, 0.006306, 0.004301, 0.003903, 0.002512, -0.000419, -0.000609, 0.001683, 0.008729, 0.016646, 0.022171, 0.023460, 0.023092, 0.025825, 0.026271, 0.024361, 0.021418, 0.016835, 0.020293 | ||||
| #*# 	0.026593, 0.020045, 0.017367, 0.016348, 0.012509, 0.009024, 0.008383, 0.008283, 0.009129, 0.008983, 0.009782, 0.010993, 0.011181, 0.008018, 0.004126, 0.005337, 0.001855, 0.001594, 0.005285, 0.010838, 0.024356, 0.025792, 0.022367, 0.026468, 0.029222, 0.025777, 0.026842, 0.019004, 0.022390, 0.022832 | ||||
| #*# 	0.027033, 0.023453, 0.018625, 0.013299, 0.011158, 0.010994, 0.009701, 0.008328, 0.009861, 0.013287, 0.014116, 0.015428, 0.013151, 0.008698, 0.009486, 0.005439, 0.003055, 0.000719, 0.006462, 0.014431, 0.022154, 0.026713, 0.024950, 0.027837, 0.028052, 0.026637, 0.022413, 0.017956, 0.018670, 0.022427 | ||||
| #*# 	0.029327, 0.023293, 0.018019, 0.017815, 0.017422, 0.013250, 0.013196, 0.011157, 0.014375, 0.018989, 0.023197, 0.022981, 0.020380, 0.017525, 0.013787, 0.013257, 0.006581, 0.003970, 0.010598, 0.018047, 0.024218, 0.026964, 0.032690, 0.029481, 0.031984, 0.026977, 0.021775, 0.021959, 0.019035, 0.023460 | ||||
| #*# 	0.031663, 0.023508, 0.018081, 0.017529, 0.018112, 0.016985, 0.015537, 0.016760, 0.020266, 0.026618, 0.027582, 0.027746, 0.026278, 0.022228, 0.017836, 0.013151, 0.008567, 0.008139, 0.012313, 0.017817, 0.026769, 0.032518, 0.033354, 0.031144, 0.026941, 0.025824, 0.022986, 0.019139, 0.017185, 0.022654 | ||||
| #*# 	0.031488, 0.023623, 0.018118, 0.017962, 0.019838, 0.017859, 0.018480, 0.022450, 0.025788, 0.031825, 0.032049, 0.031579, 0.027154, 0.022528, 0.016809, 0.014924, 0.005424, 0.009818, 0.011649, 0.016757, 0.027541, 0.030788, 0.036016, 0.029191, 0.027177, 0.025775, 0.025126, 0.027016, 0.020414, 0.025183 | ||||
| #*# 	0.035607, 0.021562, 0.017692, 0.015561, 0.016730, 0.017687, 0.018118, 0.021418, 0.026686, 0.031315, 0.031841, 0.027341, 0.022363, 0.015712, 0.009796, 0.005130, 0.000396, -0.000444, 0.008495, 0.016123, 0.024390, 0.029230, 0.028765, 0.025849, 0.024619, 0.022423, 0.022082, 0.022231, 0.022061, 0.027891 | ||||
| #*# 	0.043964, 0.024179, 0.014501, 0.012289, 0.013264, 0.013898, 0.017824, 0.018148, 0.022408, 0.026969, 0.026924, 0.022414, 0.014977, 0.009010, 0.003012, -0.000418, -0.003892, -0.003276, 0.004107, 0.014431, 0.022990, 0.022580, 0.024808, 0.023387, 0.021065, 0.027130, 0.027243, 0.021855, 0.023213, 0.031467 | ||||
| #*# 	0.060099, 0.031499, 0.017280, 0.012255, 0.010777, 0.013306, 0.014271, 0.016368, 0.019241, 0.022392, 0.022365, 0.017815, 0.009551, 0.004140, -0.000447, -0.003210, -0.005008, -0.001131, 0.004985, 0.014441, 0.022418, 0.025921, 0.026948, 0.024730, 0.026395, 0.027129, 0.026958, 0.026657, 0.023521, 0.028451 | ||||
| #*# 	0.073079, 0.036760, 0.015789, 0.008771, 0.008746, 0.008720, 0.009015, 0.011211, 0.013293, 0.017568, 0.016008, 0.013141, 0.005220, 0.000342, -0.004867, -0.005212, -0.005043, -0.004462, 0.002001, 0.013269, 0.018429, 0.026000, 0.026930, 0.025832, 0.025783, 0.027135, 0.022403, 0.021909, 0.023205, 0.027519 | ||||
| #*# 	0.075660, 0.035724, 0.010739, 0.004137, 0.002715, 0.000362, 0.000355, 0.000240, 0.004142, 0.008220, 0.008697, 0.006020, 0.001274, -0.005018, -0.009594, -0.011496, -0.012400, -0.009846, -0.004837, 0.004023, 0.011238, 0.017775, 0.019838, 0.020333, 0.022210, 0.021112, 0.018758, 0.014701, 0.013612, 0.020221 | ||||
| #*# 	0.063849, 0.024969, 0.006275, -0.004398, -0.005000, -0.005031, -0.008510, -0.007577, -0.003304, -0.000429, 0.001920, 0.000001, -0.005000, -0.009645, -0.012949, -0.014127, -0.017519, -0.016153, -0.011865, -0.005017, 0.004085, 0.011240, 0.014449, 0.016999, 0.017442, 0.014983, 0.013287, 0.008935, 0.008580, 0.013426 | ||||
| #*# 	0.047570, 0.013019, 0.001633, -0.006082, -0.009606, -0.010260, -0.011903, -0.011992, -0.009599, -0.005027, -0.002671, -0.004084, -0.008438, -0.013071, -0.016090, -0.018868, -0.020674, -0.020079, -0.016068, -0.009599, -0.000540, 0.008251, 0.012981, 0.013275, 0.014277, 0.013323, 0.011943, 0.008287, 0.006290, 0.011704 | ||||
| #*# 	0.037640, 0.011676, -0.002971, -0.005330, -0.008764, -0.009654, -0.010416, -0.011782, -0.009665, -0.005926, -0.003595, -0.004464, -0.008332, -0.013487, -0.016957, -0.018932, -0.021343, -0.020032, -0.015588, -0.007664, 0.000727, 0.008716, 0.011447, 0.011014, 0.012942, 0.012301, 0.008995, 0.008277, 0.006446, 0.011272 | ||||
| #*# x_count = 30 | ||||
| #*# y_count = 30 | ||||
| #*# mesh_x_pps = 2 | ||||
| #*# mesh_y_pps = 2 | ||||
| #*# algo = bicubic | ||||
| #*# tension = 0.2 | ||||
| #*# min_x = 30.0 | ||||
| #*# max_x = 310.0 | ||||
| #*# min_y = 30.0 | ||||
| #*# max_y = 310.0 | ||||
| #*# | ||||
| #*# [skew_correction Calilantern] | ||||
| #*# xy_skew = 0.0004221439779203628 | ||||
| #*# xz_skew = 0.0 | ||||
| #*# yz_skew = 0.0 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue