Skip to content

Pico MMU

lhndo edited this page Oct 23, 2025 · 272 revisions

Contents:


LH Stinger - Pico MMU

Files: https://github.com/lhndo/LH-Stinger/tree/main/User_Mods/MMU/Stinger%20Pico%20MMU%20-%20%40LH

CAD: Online CAD Viewer

Videos: https://www.youtube.com/@LemurHaze/

LH Stinger - LHS - Pico MMU


BOM

Item Quantity
EMAX ES3004 Servo (EMAX) 1
Nema 17 (max 40mm length) 1
Steel D-Shaft 5mm x 90mm ** 2
Bearing MR115 4
Bearing MR83 4
BMG Hardened Drive Gears (with grub screw) 4 pairs!
PTFE Tube 4mm OD, 3mm ID 1
ECAS 4 Collet 8
Belt GT2 * 25cm
Heat Insert M3 5mm (D) x 4mm (L) 23
Screw Cap Head M3 10mm 3
Screw Cap Head M3 22mm 2
Screw Cap Head M3 30mm 2
Screw Cap Head M3 8mm 2
Screw Countersunk M3 10mm 12
Screw Countersunk M3 16mm 4
Screw Countersunk M3 8mm 1
Screw Grub M3 6mm (optional) 2

*The belt width used is non-standard ~4mm, which can be easily cut with scissors from a 6mm one ** Alternatively, you can use round shafts with the following MOD


Note:

Feel free to ask in the LH Stinger Discord | multi-material if there's an existing solution or mod for your extruder or toolhead of choice.


Print

Filament: PLA, PETG, etc. The 4 lane version uses 113g of filament in total

  • 0.4mm nozzle, 0.4mm line width, 0.2mm layer height (idler arms at 0.12mm if you can print that well)
  • 3 perimeters, 95% infill
    • It is highly recommended to use the print settings included in the Orca files, and change your speeds and acceleration (includes per object settings and painted seams)
  • Make sure your extrusion multiplier is spot on. The tolerances are very small so print some parts and check for fitting.
  • Some slight post processing might be needed.
  • The Idler arms have to be printed top face down on a smooth sheet (not textured PEI)
    • You can improvise by flipping over your PEI sheet over and taping some Kapton on the smooth side, or taping down a temporary piece of glass, fr4, etc. over your printbed.


Options

Filament Hub and Sensor

Please ask in the community if there's an existing hub solution for your extruder of choice.


Filament Cutters

For Orbiter 2 and Sherpa Mini: https://github.com/lhndo/LH-Stinger/tree/main/User_Mods/Toolhead/Filament%20Cutter%20-%20Orbiter%20-%20Sherpa%20-%20%20%40RPi


BTT EBB42 Board Mount


Spool Holder

GitHub: https://github.com/lhndo/LH-Stinger/tree/main/User_Mods/MMU/Spool%20Holder%20-%20%40LH


Accessories

GitHub: https://github.com/lhndo/LH-Stinger/tree/main/User_Mods/MMU/Accessories%20-%20%40LH



Assembly

MMU Unit

CAD: Online CAD Viewer


Notes

  • Please reference the CAD model for assembly and part reference
  • The entire assembly will be done off the stepper motor, and then mounting it on in the end

Order of Assembly

Tip

Open the Online CAD Viewer to reference the parts required Have the Properties window open, and click on the components to view their name


  1. Post process the parts if needed
  2. Add the heat inserts. Be careful around areas with very thin walls Note: The Base Plate only requires 3 heat inserts out of the four holes!
  3. Attach the ECAS PTFE Collets (x8) to the Base Lane Modules
  4. Insert the small idler bearings into each Idler Arm and secure them with the M3 10mm countersunk screws
  5. Attach the Idler Arms to the Base Lane Modules. The screws act like shafts, so make sure the arms can fall down by themselves without much pressure. Note: the outmost right Idler is not secured with a screw at this stage.
  6. Secure the lower Front Bracket piece that sits on the stepper face to the Base Plate
  7. Attach all the Lane Modules to the Base Plate
  8. Secure the Module Clamps (x4) that hold the Lanes onto the Base Plate
  9. Attach the large A Back Plate (opposite end from the gears) onto the base and secure the screws
  • The following screw (1), along with the rest of the in-line screws acting as shafts, should not be torqued all the way. Just enough so that it allows the idler arm to fall by itself


  1. Insert a piece of filament to finish securing the Lane Modules to the Base Plate (2)
  2. Insert the lower shaft with the stack of bearings, spacers, herringbone gear, and extruder gears. Note: leave the BMG gears loose at this point.
  3. Insert the upper shaft with the bearings, camshaft, and spacers
  4. Attach the large A Front Plate and temporarily secure it with the two M3 30mm screws, and the M3 22mm screw with the PTFE bushing (the screw on which the belt rides on is covered with a piece of PTFE tube)
  5. Attach the herringbone gear onto the Stepper Motor shaft
  6. Position the Pico Assembly onto the Stepper Motor and secure it with the two long M3 30mm screws
  7. Align the extruder gears with the filament path and lock them in place
  8. Align the stepper herringbone gear to the upper gear
  9. Secure the Servo motor onto the Servo Slider Mount and attach it to the main assembly
  10. Insert the Pressure Tabs with the compression belt patch described in the section below. Don't tension the pressure adjustment screws at this stage
  11. Proceed with the Belt Drive Setup and remember to attach the Upper Tie Bar after completing that step.

Notes:

  • ❗ Lube the printed herringbone gears, the tip of the cams and the top of the idler arms with Super Lube, or a plastic safe silicone grease.
  • It is expected for the assembly to settle in place after some days of operation, and you should go over to check and fine tune things after that period. The rubber tabs might relax and the partial creep/position of the plastic parts might reach their final state.

Pressure Tabs

  • Cut two pieces of gt2 belt measuring 5mm wide and 5 teeth (10mm) long and insert them as shown below
    • Alternatively you can do the same with 2mm thick rubber, silicone or TPU

Note: You can also replace the tabs with two 5x10x2mm rubber or TPU pieces cut from random household items

TIP: Adding a touch of superglue on the backside of the pressure tabs and gluing the belt patches makes installation easier

Based on an idea by @jeremytodd1


Video

mace-man has done an excellent assembly overview video which you can view here: you can turn on Japanese > English Subtitles https://www.youtube.com/watch?v=IR1lWgtxqaw


Belt Drive

Belt Preparation

  • Cut a 25cm section of belt and trim it down to ~4mm with a pair of scissors (takes 10 seconds).

    Alternatively, print and use the following Belt Cutting Jig (Try the scissors method above first)


Belt Installation

  1. Move the adjustable sliding servo mount to the right, as close to the unit as possible

  1. Install the servo pulley for a test fit and trim the belt to the correct length (~18.5cm)

At this point, it is good to remind you to never backdrive or stall the servo, as doing so can cause damage and strip its internal gears!

If you hear the servo buzz during operation then it means it's stalling while trying to reach or maintain an angle.

Check that the belt is not at its movement limit, make adjustments to the camshaft by backing off the pressure, lube the cams and the idler arms.


  1. Remove the servo pulley from the shaft. Insert a filament strand in the last right lane (furthest from the gears) and rotate the cam shaft so that the last right lane is selected as in the image below.


  1. Command the servo to 135 degrees using SP_TEST_SERVO ANGLE=135 macro While holding the cam shaft in position with the last lane selected, reposition the belt and insert the servo pulley back into the shaft matching the position in the image below (1)


  1. Add the pulley cover and secure it with the M3 10mm countersunk screw onto the servo shaft (1)

  2. Slide the servo mount to the left so that the belt is tensioned (not too tight) and tighten the screw (2)


  1. Home the servo by running the SP_HOME macro and proceed adjusting the cam shaft pressure and calibrating the servo selection angles which are then set in sp_mmu.cfg

You're done! The cam shaft is now timed correctly and it will be able to achieve the full range of motion !

For support please join the LH Stinger Discord


Filament Sensor and Hub

  1. Solder the wires to the outer microswitch pins (polarity does not matter)
    • It is recommended to have the top wire (further from the microswitch button) shorter
    • Ensure that the exposed part of the cable is not longer than the surface of contact
  2. Set the 4mm bearing ball into the hole
  3. Push the microswitch with the protrusion inside the ball bearing hole.
    • Align the cables so they would exit though the top, and route the lower (black) wire behind the pins
  4. Position the cables to line up with the hole formed by the door
  5. With the microswitch sitting flush on the opposite side, slide the door between the microswitch and the hub body compressing everything inside
  6. Secure the door with a M2 8mm Button Head screw
  7. Insert a zip tie though the holes to act as a cable strain relief
  8. Use a multimeter and a strand of filament to test the triggering function
  9. Crimp the wires, attach a JST connector and plug it into an endstop port which has a hardware pull-up

Notes

  • Make sure the hub is printed in the recommended orientation with the layer height set at 0.12 or lower
  • The print should be flawless with the flow ratio very well calibrated (definitely not over extruded)
  • Insert some dummy PTFE segments for testing and insert a filament strand into each lane and test for smoothness
  • If there are any snagging points, try clearing them by inserting a ~2mm rounded allen key, or any other metal object to scrape the walls inside the hub
  • Make sure the switch operates smoothly and you can hear the click.
    • If too much force is present, you can try adding a piece of tape on the front face of the microswitch to distance it a bit from the ball
    • If too little force is present and it fails to click in certain positions, then try cleaning the hub surface that meets the microswitch face

Software

Klipper

Download the Configuration Files

  1. Place the files above in your config directory and add [include sp_mmu.cfg] to your printer.cfgbelow ❗ any other macro includes (This replaces the base RESUME macro)

  2. Adjust the following parameters in your printer.cfg to allow for fast retractions during the tip forming procedure


[extruder]
max_extrude_only_velocity: 130
max_extrude_only_accel: 3000
max_extrude_only_distance: 1000.0
max_extrude_cross_section: 5

Caution

If your extruder is not capable of these speeds, then set them to the maximum it can reach. For a standalone/non UART extruder driver running in Stealthchop mode (i.e. Creality printers), max_extrude_only_velocity would be around 40 to 45 mm/s



Warning

The latest Klipper releases (post Aug 1, 2025) refactored Manual Stepper and other related modules which introduced new bugs, breaking the expected operation. To test if you are affected by this issue, please run: SP_TEST_SYNC and follow the instructions printed in the console.

If you are impacted by this, then you have two options:

A: Try setting variable_legacy_klipper: 1 in sp_mmu.cfg. (set by default) Then in printer.cfg under the [extruder] section set min_temp and min_extruder_temp to 0 More information can be found here

B: Revert to a known working Klipper version using the commands below:


cd ~/klipper
sudo systemctl stop klipper
git reset --hard 17ce45d2
sudo systemctl start klipper


  • For Rat Rig printers running RatOS please consult this guide: Pico-MMU-RatOS

Hardware

  • Set up your pins corresponding to your hardware in sp_mmu.cfg

Wiring examples:

LH Stinger

LH Stinger Breakbeat with Fysetc Spyder FYSETC Spider H7

Diagram by Zemlos01


BTT EBB 42

The provided configuration and the wiring example below is for a BTT EBB42 board connected to a Raspberry Pi though USB and being supplied with 24V from the main PSU

EBB 42 Firmware Flashing Instructions

Diagram by Nick1



Calibration

MMU Calibration

The goals for the MMU calibration process are the following:

  1. Find the cam shaft angles that provide most pressure for each lane.
  2. Ensure that the applied force is equal and sufficient on both sides of the unit (first and last lane)
  3. Troubleshoot the issues with the inner lanes if the pressure is not equal

Angle Calibration

  1. Load a strand of filament inside each lane (approx. 20cm long). You will need to be able to move these by hand later on.
  2. Use SP_TEST_SERVO and SP_TEST_MMU macros to verify that the motors are functional
  3. Loosen up Pressure Adjustment screws and find your ideal servo engagement angles by using the SP_TEST_SERVO macro and write them down
    • Usually the ideal angle for each lane ends up in the position illustrated below, with a bit of gap showing between the cam tip and the idler arm cutout
    • ❗ If the servo motor buzzes and struggles to reach the angle due to high pressure, please check the Troubleshooting section. Overdriving the servo motor will kill it!
  4. Double check if the belt tension is still slightly firm at 0 angle. Usually during the initial setups this can loosen up up a bit due to slack and forces at play
  5. Set the found angle values in sp_mmu.cfg under variable_angles and restart Klipper!

Pressure Adjustment

  1. Use the SP_TEST_SERVO macro to manually select the first lane (lane 0 closest to the belt) by typing its angle (use the dropdown arrow next to the macro button to type the angle)
  2. Move a piece of filament by hand back and forth though the selected lane.
    • If you can backdrive the stepper motor without the filament skipping then your pressure is very good.
    • If needed, adjust the Pressure Adjustment screws, but be careful not to overdrive the servo. Switch the servo angle back and forth and listen to the motor. Back off the pressure if it struggles and you can hear it buzz.
    • Don't overdo it. Too much pressure and extrusion force can wear out the unit, move the issues elsewhere, or hide certain symptoms, such as obstructions inside the toolhead's filament path. It is better to be a touch on the looser side
  3. Move to the last lane (lane 3) and do the same adjustment as before.
  4. Go back to the first lane and check it still operates correctly in terms of pressure force
  5. A few rounds of back and forth might be required to ensure that equal pressure is applied between the first and last lanes.
  6. Test the middle lanes
    • If you have issue with these, then check the last point in the troubleshooting section
    • Fine tuning the angle by a few degrees while checking for filament grip can also help finding more grip
  • Note: The procedure above requires that the angles calibration is done right. Feel free to go back and finding a better cam angle position for any lane that causes issues.

Rotation Distance Calibration

  1. With a piece of filament loaded up to the hub, disconnect the PTFE tube
  2. Command 10mm of distance on that lane with SP_FORCE_MOVE_LANE (use the dropdown macro arrow) to disable the anti backlash algorithm
  3. Type _SP_OFF in the console to disable the motor and push the filament back by hand to the end of the PTFE tube
  4. Use SP_FORCE_MOVE_LANE again on the same lane and command 100mm of filament
  5. Measure the filament distance moved from the end of the PTFE tube
  6. Calculate the new rotation distance with the following calculator: https://www.service-uplink.de/esteps_cal/calculator.php (previous default rotation distance is 18.3)
  7. Update the rotation_distance variable in [manual_stepper sp_motor] section from sp_mmu.cfg and restart klipper for the new value the take effect
  8. Repeat the SP_FORCE_MOVE_LANE 100mm move and verify that it moves the correct distance

Toolhead Distance Calibration

  1. Cut a piece of filament long enough to cover the distance to the nozzle and remove the PTFE tubes
  2. Pick a reference point such as the top the filament hub
  3. Manually insert the filament strand and measure the following distances from your reference point
    1. Distance to the filament sensor trigger point
    2. Distance to the extruder gears
  4. Heat up to hotend and manually insert the piece of filament down to the nozzle until filament comes out of the nozzle (hold the extruder lever open)
    1. Quickly pull the filament strand out and measure the distance from the melted tip to your reference point
  5. Using the previous three measured distances you can subtract and determine the distance variables required for the #Distances section in sp_mmu.cfg

Note: The filament tips usually breaks off at the transition point between the coldzone and the hotzone

Tip Forming Distance Setup Example: Orbiter 2 with Dragon HF + MZE extender

Filament Cutter Distances Setup Example: Sherpa Mini with Dragon UHF

Diagram by Zemlos01


Tip Forming Calibration

Note

Skip this step if using a filament cutter.

  • This step should be performed after calibrating the sections above and ensuring the distance variables are set correctly.

  • This process doesn't use the Pico unit itself. You will be doing the operations by hand

  • The Tip Forming Calibration is done with the SP_TEST_MANUAL_TIP_FORMING macro which simulates the filament changes.

  • Start with the default settings and try staying as close as possible if your setup is similar to the one used for tune this

    • Dragon HF + MZE Plus extender and Orbiter 2 extruder
    • PLA @ 220C
  • Adjust the following parameters in your printer.cfg to allow for fast retractions, or test your own extruder speed limits - lower if the extruder skips

[extruder]
max_extrude_only_velocity: 130
max_extrude_only_accel: 3000
max_extrude_only_distance: 1000.0
max_extrude_cross_section: 5

Process

  1. Remove the PTFE tubes from the filament hub
  2. Have a separate filament strand readily available
  3. Heat up the hotend to your printing temperature
  4. Insert the filament by hand down to the extruder gears and run the macro
    • Use the drop down arrow to define your own parameters
  5. Wait for the process to finish and then gently remove the filament from the extruder and inspect the tip
  6. Once done transfer your settings to the relevant section in sp_mmu.cfg

Filament movement diagram
  • variable_pause_push_dist: 0.5 - mm
    small push of filament to compensate for variable_pause_retract
  • variable_pause_push_speed: 10 - mm/s
    push speed
  • variable_cooldown_dist: 5 - mm
    retract distance for the first cooldown move - short values (~5mm) act as a dip move - cooldown performs a pull, push, pull move - progressively slower and shorter
  • variable_cooldown_pull_speed: 70 - mm/s
    fast pulling speed to break the filament from the meltzone
  • variable_cooldown_pause: 0 - seconds
    pause after the first cooldown move
  • variable_cooldown_secondary_moves: 1 - seconds
    enable secondary push retract cooldown moves
  • variable_dip_melt_gap: 2 - mm
    0 disables dip move - distance from the meltzone where the filament dip move will stop before reaching it (how close to get to the fire) - this variable can make a big difference
  • variable_dip_speed: 30 - mm/s
    how fast to approach the dip point
  • variable_dip_pause: 2 - seconds
    not actually a pause but a slow crawl towards the heat to burn the strings from the filament tip (how long to stay close to the fire) - this variable can make a big difference
  • variable_park_speed: 130 - mm/s
    final long retract - should be as fast as you can to break the strings

Goals

  • The tip is conical with no bulging that would snag inside the filament path
  • The stringing part is short or non existent
  • There is no blob or major string left behind the extruder blocking the filament path (this is the no.1 failure cause)
  • The results are consistent with every change

Tips

  • Use dry filament
  • Optimize for reliability instead of speed
  • Make sure your hotend doesn't suffer from heat creep. Seeing different results with same settings might be a symptom of this
    • Try reducing the amount of time the filament moves inside the cold zone (cooldown_dist or cooldown_pause)
    • Lower the filament temperature and take pauses between tests
  • Change one variable at a time and observe the changes
  • The two extreme states usually observed are:
    • Filament with extreme stringing and blobs hanging from it (increase pull speeds, decrease dip_melt_gap or increase dip_pause)
    • Filament with a bulging tip (increase dip_melt_gap )
  • Once satisfied, try running the same settings multiple times to ensure that the end result is consistent
  • Test with other filaments of the same type


Features

Guest Lane

The Guest Lane feature provides an optional lane for introducing an additional guest filament, particularly useful for feeding TPU, or temporary filaments, without routing them through the PICO MMU.

This feature is particularly useful in 3 lane units with a 4 lane hub configuration, but can also be used in 4 lane Pico units, ideally with a 5 lane hub design.

The implementation makes it behave the same as having an extra lane, the only difference being that you will be prompted to insert or remove the filament by hand into the hub. The guest lane becomes T3 in 3 lane units, and T4 in four lane ones.

Once the filament is detected, the code will proceed with the lane change functions.

The guest lane feature is enabled by default in the configuration: variable_has_guest_lane: 1 # enable guest lane support (eg. 3+1 setups) - the guest lane uses the last filament set in the slicer


The Guest Lane will automatically correspond to the last filament listed in the slicer.


Park Purge

The Park Purge feature enables printing without the need for purge towers on the print bed by purging into a bucket. It ensures the correct amount of filament is flushed, as specified by the slicer, to prevent color bleeding.


  1. To set up this feature add _SP_SET_PURGE PURGE=[first_flush_volume] in the Change filament G-code section of the slicer

  2. Disable the Prime Tower option in Process > Multimaterial

  3. In sp_mmu.cfg set:

variable_use_park: 1
variable_park_purge: 1

Purge Macros

External Purge macros or Purge Routines can implemented be by editing the user macro [gcode_macro _SP_PURGE] from sp_mmu.cfg.

_SP_PURGE is called whenever a purge action is performed by the hotend during the changing process.

An example of such macro which uses a brush and a purge shute can be found here: https://github.com/lhndo/LH-Stinger/tree/main/User_Mods/Other/Mini%20Purge%20Shute%20-%20%40LH#gcode


  • For more advanced implementations a printer['gcode_macro _SP_VARS_RUNTIME'].print_start_change variable is also available to query in your PRINT_START macro. This is set to 1 if a filament change was done at print start, otherwise it is 0

Hybrid Purge

Hybrid Purge enables using a park purge routine and a prime tower at the same time. This is similar to the Bambu change routine which use a smaller purge tower to ensure a clean nozzle close to the printed part.

  1. Enable variable_use_park and variable_park_purge in sp_mmu.cfg to purge into a "bucket"
  2. Enable Prime Tower in Orca slicer
  3. Set Machine Filament Change G-Code to _SP_SET_PURGE PURGE={first_flush_volume * 9}
  4. Set the Flush Volume multiplier to 0.1

This ratio will purge 90% of the volume into the purge bucket, and 10% into the Prime Tower


Infinite Spool

The Infinite Spool feature allows for automatic loading of a new lane when a runout sensor event is triggered. The next available lane will be loaded (n+1), going back around to the first lane when reaching the end.

This feature is experimental since at the moment there is no post check routine implemented to verify the success of the procedure.

Flow

  1. Filament ends and the filament sensor is triggered, generating a runout event
  2. Printer pauses print, parks and purges as much as possible of the old filament
  3. The new lane is loaded and slowly pushes the old filament though the hotend
  4. The rest of the old filament is purged out to avoid air gaps
  5. Print resumes

As this process uses the new filament to push out the old one, it greatly depends on internal extruder geometry. Based on my testing during development with the Orbiter 2 extruder I had a 100% success rate loading a new lane while pushing out the old one, but results my vary depending on the setup.

Setup

In sp_mmu.cfg set:

# Advance
variable_infinite_spool: 1

Notes:

  • Make sure your park positions are defined since parking is enforced during this procedure
  • For testing the feature during idle, enable the runout sensor from the dashboard, have a short piece of filament loaded and extrude extrude it until the end passes the sensor.
  • Prepare your filament spools so that they can freely release the end of the filament.

Filament Cutter

Note: The filament cutter has to be positioned between the hotend and the extruder, and not above the extruder.

Set the following variables:

Important

  • variable_dist_filament_park - mm - distance from the extruder gears to the cutting blade
  • variable_tip_length_below_cut - mm - length of the filament tip left inside the hotend below the cutting blade (below dist_filament_park) - set it to 5mm if unsure
    • this value is automatically subtracted during the hotend loading stage.
  • If using parking, you might also want to set variable_skip_first_park: 1 to avoid one extra unnecessary move


  • Replace the _SP_TIP_FORM macro from sp_mmu.cfg to the one from the example below, and modify it for your setup:

[gcode_macro _SP_TIP_FORM]   ## Filament Cut Macro
variable_cut_position_x: 254
variable_cut_position_y: -99  ## -99 means no movement
variable_clear_position_x: 216
variable_clear_position_y: -99 ## -99 means no movement
variable_approach_speed: 400
variable_cut_speed: 140
variable_filament_retract_speed: 130
variable_z_hop: 0.4

gcode:
  {% set sp = printer['gcode_macro _SP_VARS'] %}
  {% set hop = [printer.toolhead.axis_maximum.z, printer.gcode_move.gcode_position.z+z_hop] | min  %}
  {% set saved_z = 0 %}
  {% set fil_cut_position = sp.dist_extruder_to_meltzone - sp.dist_filament_park - sp.tip_length_below_cut %}

  RESPOND MSG="SP: Filament Cut"

  {% if not "xy" in printer.toolhead.homed_axes %}
    G28 X Y
  {% endif %}
  G90
  M83

  {% if "z" in printer.toolhead.homed_axes and z_hop > 0 %}
    {% set saved_z = printer.gcode_move.gcode_position.z %}
    G0 Z{hop}    ## Z Hop
  {% endif %}


  {% set clear_move = "" %}
  {% if clear_position_x != -99 %} {% set clear_move = clear_move + 'X' ~ clear_position_x ~ ' ' %} {% endif %}
  {% if clear_position_y != -99 %} {% set clear_move = clear_move + 'Y' ~ clear_position_y ~ ' ' %} {% endif %}

  {% set cut_move = "" %}
  {% if cut_position_x != -99 %} {% set cut_move = cut_move + 'X' ~ cut_position_x ~ ' ' %} {% endif %}
  {% if cut_position_y != -99 %} {% set cut_move = cut_move + 'Y' ~ cut_position_y ~ ' ' %} {% endif %}

  G0 {clear_move} F{60*approach_speed}                      ## Approach clear position
  G0 E-{fil_cut_position} F{60*filament_retract_speed}      ## Retract filament close to the cutter blade
  G0 {cut_move} F{60*cut_speed}                             ## Move to cut
  G0 {clear_move} F{60*cut_speed}                           ## Move back to clear position

  ## Restore Z Position
  {% if saved_z > 0 %}
    G0 Z{saved_z}
  {% endif %}

  M400

Note

The cut and clear positions are defined as the toolhead/nozzle coordinates.
You can get them from the mainsail/fluidd UI by positioning the toolhead using the dashboard controls.
The cut position defines the location of the toolhead when the cutting lever is fully engaged.
The clear position defines the location of the toolhead when the cutting lever is fully released.
The macro executes a Clear > Cut > Clear move sequence
Since the lever is activated by a single axis move, one of your variable_cut_position axis should probably be set at -99



Macros

Note: Remember to use the dropdown arrow on the macro buttons for parameters ⬇️. Lanes are counted from 0, so in a four lane setup you will have Lane 0,1,2,3, with the first one being closest to the belt drive.


Important

  • The following macros are meant to be used for testing, setting and error recovery in case of issues during print time.
  • They are listed in order of complexity and operation and I recommend starting testing them from the top and progressing towards the bottom
  • All the printing operations should be automatically handled by the slicer T commands and automatically pause when an error is encountered.
  • The MMU system cannot detect an error past the extruder gears so I recommend monitoring the print and hitting PAUSE to fix the issue if something happens
  • ❗ Do not execute the T0, T1, T2 ... macros by hand. Those are only to be sent by the slicer during print. Use SP_LOAD_LANE or other variants instead.

TESTS

SP_TEST_SERVO Allows you to manually move the angle of the cam shaft to find the point where it engages with maximum force for each lane. Keep an eye it transitions smoothly between lanes, doesn't get stuck or makes noises while trying to hold position. This might damage your servo. The angle value needs to be provided: i.e: SP_TEST_SERVO ANGLE=135

SP_TEST_MMU Tests each lane in succession by moving the filament in an out for a tiny bit. Good for testing the mechanical operation of the unit stand alone

SP_TEST_SYNC Tests if the extruder can move in sync with the Pico MMU stepper motor. Please follow the printed instructions in the console.

SP_TEST_LOAD_UNLOAD_EXTRUDER Tests both operations in sequence between the HUB and the extruder

SP_TEST_MANUAL_TIP_FORMING Helper macro for testing or calibrating the TIP FORMING variables (test later in the process) Please see the Tip Forming Calibration section above


OPERATIONS

SP_HOME

Homes the unit, frees the filament and turns the servo and the motor off


SP_FORCE_MOVE_LANE

Lets you manually move the filament inside a lane. It is handy for calibrating distances, or for manually doing move commands


SP_LOAD_HUB and SP_UNLOAD_HUB

  • Load or unloads a lane between the Pico MMU unit and the HUB
    • If no filament is in the hub triggering the sensor when running SP_LOAD_HUB, then the macro can park the filament precisely inside the hub. Otherwise it will load the set configuration distance.
    • If you want to unload a lane and a filament is present in the hub, then use SP_UNLOAD_HUB FORCE=1
    • If you want to load the hub for fixed distance bypassing the sensor check, you can run SP_LOAD_HUB NO_SENSOR_CHECK=1

SP_LOAD_EXTRUDER and SP_UNLOAD_EXTRUDER

Lets you load or test the filament operations between the HUB and the extruder


SP_LOAD_HOTEND and SP_UNLOAD_HOTEND

Loads and unloads the filament previously parked in the coldzone. It automatically heats the hotend if needed


SP_LOAD_LANE and SP_UNLOAD_LANE

Loads the filament from the HUB to the nozzle, chaining LOAD EXTRUDER and LOAD HOTEND and doing some error checks in between

  • For SP_UNLOAD_LANE, leaving the LANE blank will automatically unload last loaded lane

Warning

By default the SP_LOAD_LANE macro will PURGE filament during the unload and load process dictated by variable_print_start_change_purge. You can disable purging in the macro dropdown menu or by running it with PURGE=0.


SP_FILAMENT_CHANGE

Replicates the entire unloading and loading procedure that is usually encountered during print time.

  • leave UNLOAD_LANE blank to automatically unload last loaded lane

Warning

By default this macro will PURGE filament during the unload and load process dictated by variable_print_start_change_purge. You can disable purging in the macro dropdown menu or by running it with PURGE=0.


SET

SP_FORCE_SET_LOADED_LANE

The loaded lane and state of the hotend are always tracked and saved on the SD to be recalled between host resets

You can use these to manually set the current physical state of the machine for the code to recall in case you loaded the filament manually into the extruder or into the hotend


SP_CLEAR_ERROR_CODES

Clear the internal error variable used by the chained commands to track the success of the previous execution


SP_INIT

Initializes the MMU, clears the variables, homes and turns off the unit



Slicer Setup


Orca Slicer

The LH Stinger profiles have the following settings built-in and a "LH Stinger- Pico MMU" printer profile is available for selection in the drop-down. You can find the latest profiles here: https://github.com/lhndo/LH-Stinger/tree/main/Config/Orca_Slicer


Warning

Do not upgrade to Orca Slicer 2.3.0 until the Purge Tower Bug is fixed!

Printer

  1. Add: _SP_PRINT_START LANE=[initial_tool] TEMP=[nozzle_temperature_initial_layer] to your slicer's Machine Start G-code before your PRINT_START macro or start G-code

  2. Add: _SP_PRINT_END to your slicer's Machine end G-code after the PRINT_END macro

  1. Add: _SP_SET_PURGE PURGE=[first_flush_volume] to the Change Filament G-code and make sure there are no other M600 G-code commands set or emitted anywhere

  1. Make sure your G-code flavor is set to Klipper and your extrusions are you use relative E distances Remove any G82 commands from you custom macros/G-code

  1. Set most fields of the Multimaterial tab to 0, and set the Tool Changing Time to 20, or to your measured time later on. Make sure Manual Filament Change is disabled and all the other fields match the image below.


  1. Set Retraction when switching material to 0


Filament

In the Filament Multimaterial tab set all fields to 0

  • If using MPC feed forward, or any particular filament g-code, make sure to set it in the filament Advanced tab. These are applied after filament change.

Flushing Volumes

  • The Flushing Volumes for filament transitions can be adjusted here in the dialog before.
  • These are automatically computed by Orca Slicer and dependent on the saturation and brightness of the color swatch you choose for the material, and the Multiplier you set in this dialog box.
  • Adjust these here if you see color bleed on prints after color changes.
  • Alternatively you can set a Minimum purge on wipe tower in the filament tab (image above) to cap the minimum purge amount.


Process

Adjust your Multimaterial settings in the Process / Print Profile tab


Tips


  • You can also use the unit as a filament selector for single color prints. Make sure you assign the right filament/lane to the objects in the slicer (Select Object > Right Click > Change Filament) and the _SP_PRINT_START macro will automatically unload and load the right filament before starting the print.

  • The operational success of the MMU highly dependent on the tip forming procedure. Make sure you experiment and adjust this to get consistent results, and that your tips are sharp when parked inside the hub and don't leave any filament blobs blocking the extruder tube past the gears. Please see the Tip Forming Calibration section

    • Verify your klipper [extruder] limits for extrude only moves and make sure they are set high enough to be able to perform fast moves
    • Use dry filament
    • Make sure your hotend is cooled properly and doesn't suffer from heat creep or clogs when moving hot filament inside the coldzone
  • Be smart when slicing or picking up the models to print. Try to minimize the color changes as much as possible to reduce filament waste, time, or chances of failure due to heat creep and other issues. It is usually best to print multiple objects and the same time and trying to have enough volume of filament moving though the hotend between changes.

  • If printing the same material type then equalize your material temperature presets between filaments. Otherwise the hotend will have to heat up and cool down between changes.

  • When printing flat designs increase the layer height to minimize the number of changes

  • Using park_purge and purge_unload might help with tip forming with setups prone to heat creep by feeding cold filament to the heatbreak zone.


Troubleshooting


Cam not applying enough pressure on the lane selectors

  • Adjust the pressure screws
  • Make sure the servo angle set for that lane is at the optimum point, applying most pressure possible
  • Print a thicker pressure tab (the one under the adjustment screws)
  • Insert a TPU tab that has a higher hardness
  • Add a layer or two of tape (kapton) on the top smooth surface of the arm

Cam applying too much pressure / Servo motor buzzing when trying to reach position

  • ❗ Never operate with the servo motor buzzing trying to reach its target angle. It will kill it!
  • Lube the camshaft tips and the top of the idler arms with silicone (or plastic friendly) grease
  • Adjust the pressure screws
  • If that's not enough, print thinner pressure tabs (the ones that go over the Belt/TPU tab)
  • In the slicer, move the arms -0.2mm on Z under the bed surface and reprint them. This will space them farther away from the cams
  • Lube the cam shaft tips with super lube or silicone based grease

Note: New builds might require a bit of time for the parts and tolerances to settle in place

Some lanes don't work properly during print

  • Check to see if you have retry messages during the loading/unloading steps on that particular print
  • Check to see if the idler pressure and angle is correct for that lane
  • Make sure the filament path from the roll to the hub is smooth without much friction
  • Insert a filament tip by hand into the extruder and hotend and see if you find snagging points
  • Check the filament path entrance past the extruder and see if there are blobs blocking it. An non ideal unload or tip forming from the previous print can also cause issues with the next loaded lane

Tip forming doesn't look good

  • Use dry filament
  • Make sure you don't have heat creep issues and your heartbreak performs well
  • Lower filament temperature
  • Try printing multiple objects or larger sections between successive lane changes
  • Check to see if you upped your max_extrude_only speed and accel limits in klipper as instructed
  • Double check your distances by inserting a piece of filament by hand as instructed in the calibration section
  • Make sure that dist_filament_park is short so that the final fast retract move has enough distance
  • Slightly increase dist_extruder_to_meltzone and compensate with end_of_load_filament_move
  • Extend the pause dwell time (G4 command)
  • Try fine tuning the initial pushing distances in the tip forming macro

Blobs or excess extrusion after filament change

If the slicer settings are correct, then this is usually caused by some distance variables being too long, especially those below the sensor such as variable_dist_extruder_to_meltzone Adjust the distance until no filament comes out of the nozzle after the lane is loaded. You can test this by running SP_FILAMENT_CHANGE LANE=1 PURGE=0

If using a filament cutter, than make sure * variable_dist_filament_park and variable_tip_length_below_cut are set correctly.

Klipper Error: "Pin PB6 used multiple times in config"

  • Make sure you have a only one [duplicate_pin_override] section in your config, and consolidate all the pins in that one.
  • For example if you printer is already a [duplicate_pin_override] section in printer.cfg, move the filament sensor pin into that one, and delete the duplicate section from sp_mmu.cfg.
    • There might be other issues with this due to the fact that the duplicate pin section usually sits below the MCU definition, so you might have to move that as well into printer.cfg, above the duplicate pin section, and then have the [include pico_mmu.cfg] underneath it. The normal configuration hierarchy is [mcu] > [duplicate_pin_override] > Other section using the pins.

Klipper Error: "Section 'servo sp_servo' is not a valid config section"

  • This error was encountered in proprietary versions of klipper such as Creality.

  • Make sure servo.py is present in /klipper/klippy/extras (CR K1Max - /usr/share/klipper/klippy/extras), and if not, copy the file onto your klipper host from here: Klipper repository

  • You can find your klipper path by running this over ssh: sudo find / -type d -name "klippy" 2>/dev/null

Klipper Error: "No such file ... sp_mmu_data.cfg' on Creality Klipper printers"

  • try changing the [save_variables] path to filename: /usr/data/sp_mmu_data.cfg
  • for Sonic Pad users: /mnt/UDISK/printer_config/sp_mmu_data.cfg

MCU Protocol Error: Firmware mismatch on BTT EBB42

Your MCU needs to be flashed with the same version of klipper running on your host.

BTT EBB 42 V1.2 - Klipper Firmware Flashing

  1. SSH to your Raspberry Pi
  2. On the EBB 42 press and hold the BOOT button followed by the RST button to enter the** DFU mode**
  3. Run cd ~/klipper/ and then make menuconfig
  4. Match the settings to the attached image
  5. Press Q and Y to exit and save
  6. Run make clean and make
  7. Run lsusb and verify that the board is connected and booted in **DFU mode **
    • If the EBB42 is connected through a USB hub but not detected, try connecting it directly to the controller host
  8. Look for STM Device in DFU Mode and copy the address ID (eg. 0483:df11)
  9. Run sudo dfu-util -d 0483:df11 -R -a 0 -s 0x8000000:leave -D out/klipper.bin to flash the board (replace the ID after -d if required)
  10. Press RST button then run ls /dev/serial/by-id/* to find the serial port of the board
  11. Replace the [mcu PICO_MMU] serial in sp_mmu.cfg if needed eg. serial: /dev/serial/by-id/usb-Klipper_stm32g0b1xx_4E0026001250425539383920-if00
  12. Run sudo systemctl restart klipper

Note: If at the end of the dfu-util flashing process you see the following error messages, just ignore them. The flash procedure was probably successful.

Download done.
File downloaded successfully
dfu-util: Error during download get_status
Failed to flash


Extruder not moving in sync with the Pico MMU. Move happens after the Pico is done jamming the filament into the extruder gears

This issues have been reported on printers running certain Klipper version (below v0.12.00, or very recent v0.13.xx).

To test for this problem you can run: SP_TEST_SYNC in the console and follow the instructions printed in the console.


To solve this, you can try an alternate sync move method by setting variable_legacy_klipper to 1:

Then in printer.cfg under the [extruder] section set min_temp and min_extruder_temp to 0


"Timer too close" or "Unhandled exception during run" Klipper errors

  • ❗ Make sure to have your sensor wired to a pin that has a hardware pullup. On the Fysetc Spider these can be found on the Z Max and Z Min ports. The BTT Octopus Pro all of the endstops are pulled up.

"Timer too close" or "Homing failed due to printer shutdown" triggered during "Unloading Extruder" stage

  • This error happens due to a klipper bug on short homing moves along with a possible overloaded system
  • Increase variable_dist_sensor_to_synced_move and variable_overshoot_factor
  • In moonraker.cfg set the following values and restart moonraker:
[file_manager]
enable_object_processing: True
default_metadata_parser_timeout: 30

Advanced:

  • Klipper Firmware:
    • edit klipper/klippy/mcu.py on your Pi and change the following variables:
      TRSYNC_TIMEOUT = 0.05
      TRSYNC_SINGLE_MCU_TIMEOUT = 0.45
    

  • Kalico firmware
    • in printer.cfg add:
    [danger_options]
    single_mcu_trsync_timeout: 0.45
    multi_mcu_trsync_timeout: 0.05
    

FAQ

Q: What is LH Stinger?

A:

  • LH STINGER is a new 3D printer design build as a long lasting open source platform with a no compromise approach at its core
  • It is the host of this project, and while the MMU system is built specifically for it, it's also meant to give something back to the 3D printing modding scene in the RepRap spirit, just like other projects part of this platform.

Q: What does this project bring compared to other MMU systems?

A:

  • Around 20 second filament changes with no filament buffer required in the toolhead hub configuration
  • Minimal BOM and printed parts (87g) which can be printed and assembled in a few hours
  • A new minimalistic hardware design requiring a single stepper motor and one servo
  • A simple software solution tightly coupled with the unit, written with native Klipper macros, with all the code available in a single file

Q: Can it have more lanes than 4?

A: For an expanded setup I believe that a more comprehensive solution such as the TradRack or ERCF are better suited for it.


Q: I have printer X, can I use this?

A: The main challenges on newer commercial printers are usually:

  • Installing a filament cutter (finding a toolhead that integrates one)
  • Setting up the software with proprietary/locked klipper versions

A: There general prerequisites for this using the Pico MMU are:

  • Your printer runs up to date mainline Klipper, or Kalico firmware (Creality OS and other proprietary variants are not recommended)
  • You can connect an additional board (EBB42, ERCF EASY BRD, etc.) to your Klipper host (Raspberry Pi USB), or you have a free stepper driver slot, a servo port, and a filament sensor/endstop port on your printer's mainboard
  • You can install a toolhead filament sensor on your direct drive extruder (above the extruder and preferably integrated with an toolhead hub)
  • Your printer prints exceptionally well with no extrusion or heat creep issues, you use well calibrated filament profiles, and you dry your filament.
  • You have basic knowledge of custom Klipper setups and configurations
  • A toolhead with a filament cutter (positioned under the extruder) is highly recommended

Q: I don't know anything about Klipper, do you have a solution for firmware X

A: Half of this project is dedicated to creating a minimalistic software integration, tightly coupled with the hardware and written in native Klipper Macro code If you are thinking about this and want to upgrade your printer (if possible) consider moving to Klipper first and getting familiar with it before jumping into this project.


Q: Is there a toolhead hub or a filament sensor for setup X?

A: The filament sensor+hub provided is made for the Orbiter V2-2.5 extruder. You can check the with community (Discord, Printables, etc.) if there is a solution available for your hardware Alternately, the CAD files provided include the basic parts that you can easily adapt to your setup


Q: Does the MMU work with a bowden extruder?

A: It could work, but it might not be reliable. This filament changing solution was create to operate with a toolhead sensor and hub on top of a fast direct drive extruder


Q: Can my filament sensor be positioned after the extruder?

A: This setup configuration is not implemented at the moment


Q: Do I need a filament cutter?

A: While I had good success with tip forming, this has proved hard to replicate by other users with various printer setups. Even so, it's impossible to beat the reliability of a filament cutter setup, and it's highly recommended if you plan to do unattended MMU prints, or prints with many filament swaps. For the tip forming process you will need a fast extruder and a hotend resilient to heat creep. Filament cutters are good at preventing the issues occurring inside the hotend such as blobs and heat creep. If you plan on installing a filament cutter, then make sure it cuts the filament below the extruder gears!


Q: How can I test if my setup can produce good filament tips?

A:

You can try the following things before committing to a MMU system

  1. Heat up the hotend, and insert a filament strand by hand
  2. Keep the extruder lever open and push on the filament to purge some molten plastic
  3. Quickly pull out the filament from the extruder by hand and inspect the tip

Then try replicating the same procedure in Klipper

  1. Adjust the following parameters in your printer.cfg to allow for fast retractions, or test your own extruder speed limits - lower if the extruder skips
[extruder]
max_extrude_only_velocity: 130
max_extrude_only_accel: 3000
max_extrude_only_distance: 1000.0
max_extrude_cross_section: 5
  1. Load the filament normally, heat up your hotend and paste the following G-code in the console
M83
G0 E0.5 F300
G0 E-5 F600
G4 P2000
G0 E4 F2000
G4 P500
G0 E-28 F7800
G0 E-150 F2000
  1. Inspect the filament tip

Q: Can I use servo X instead?

A: Only the recommended servo has been tested and has a mount available for it. It has been wildly used and battle tested in the RC community for many years. Please feel free to test other solutions and let us know on the results.

A few things to keep in mind when choosing a servo:

  • Pick a mini size metal geared servo (~20g) with 3.5kg+ of force and 140+ degrees of travel (but not speed controlled 360deg)
  • Digital or analog doesn't matter, the wiring and control is identical
  • Don't buy hobby electronics servos or clones. Get a reputable RC brand that has been heavily tested on RC builds. Check with your local hobby store.
  • Alternatively look at the TradRack BOM servo recommendations which use a similar format
  • Don't run servos with higher specs/sizes than the recommended EMAX on an EBB42. Its 5V rail is specced for 1A, while larger servos draw 1.5A+ when stalled.
  • Once you source your servo you will have to find its min and max pulse_width values to get the full motion range. You can do so with SET_SERVO SERVO=config_name WIDTH=<seconds>

Q: Can I use the Orbiter 2 Filament Sensor (Official)?

A: The Orbiter 2 Smart Filament Sensor is not suited for mmu usage due to an internal 1s delay https://github.com/RobertLorincz/Orbiter-2-Smart-Sensor/issues/1

There is a beta firmware here: https://github.com/RobertLorincz/Orbiter-2-Smart-Sensor/tree/main/Firmware But requires a UPDI programmer to flash it


Q: Where can I find the STL files?

A:

  • The STL files are packed in a .3mf project file which can be opened in any Slic3r derivative software (Prusa Slicer, SuperSlicer, BambuLab etc.)
  • All the parts are prepared in the Stinger Pico MMU.3mf file which can be downloaded from GitHub
  • The project file is originally made for Orca Slicer and includes a multitude of custom settings, such as individual layer heights, custom seams, custom supports, infill orientation, perimeter modes, etc. It allows me to organize the printed plates, define critical settings, communicate information regarding optional parts, and quickly update the project.
  • If you need the individual STL files you can either load the .3mf in one of the slicers mentioned above, select the parts, right click and hit export. Alternately if you can export the files from the CAD source.

Q: How I use the included Orca Slicer settings with my own printer profiles?

A:

  1. Load the 3mf file in Orca Slicer
  2. Choose your Printer profile
  3. Hit "Transfer" on the subsequent dialogs
  4. Select your filament profile
  5. Go to the "Speed" tab part of the Process profile and adjust the speed, acceleration and jerk settings to according to your machine limits

Q: Where can I find 3 Lane variant or the winch drive version?

A: The files can be found here: https://github.com/lhndo/LH-Stinger/tree/main/User_Mods/MMU/Stinger%20Pico%20MMU%20-%20%40LH/Legacy The winch drive was retired to simplify the choice process and get rid of the confusion for new users The previous assembly guide can be found here: Pico-MMU-Winch


License

This work is licensed under a Creative Commons (4.0 International License) Attribution—Noncommercial—Share Alike


Support

For support please join us on the LH Stinger Discord


If you have found any use of this, and you would like to support the development of this project you can follow the link below 😉

Buy Me a Coffee at ko-fi.com

Clone this wiki locally