Not yet qualified on real hardware. Klipper-MMU has not run on a real MMU yet. Every device is a software candidate: it builds, boots and passes the simulators. Default images advertise
ACTUATION=0and do not move motors; the actuator build is an experimental opt-in. Check pins, polarities, currents and safe-off on your own bench before you flash it onto a printer you care about.
Klipper-MMU has two halves, installed separately:
klippy/extras/klipper_mmu. It does nothing until a [klipper_mmu NAME] section names it, so printers without an MMU are unaffected.src/Kconfig and one to src/Makefile, plus a src/klipper_mmu symlink. It does not build, flash or restart anything.Installing either half does not make the MMU move: the default firmware advertises ACTUATION=0.
Before you build: every build needs a buffer input (switched, or DiffA/DiffB on the STM32H723) and a filament-arrival signal (a toolhead switch on the MMU board's own pin, or FPS arrival) wired to the MMU board. MMUs without a buffer of their own need a sensored one fitted; the overview lists them.
For a BoxTurtle on an AFC Lite board, the BoxTurtle quick start is the shorter path: it builds a tested configuration step by step. This page covers the installer for any device.
Klipper-MMU ships inside OpenAMS, in its klipper_mmu/ directory, and the OpenAMS installer installs it. If OpenAMS is not installed yet, start with the OpenAMS install guide. From the openams checkout, with -k pointing at the Klipper checkout:
./install.sh # links klippy/extras/klipper_mmu (the host module)
./install.sh --with-mcu-addon # also installs the MCU add-on hooks
Those two commands run exactly:
python3 klipper_mmu/tools/install.py install-host <klipper dir>
python3 klipper_mmu/tools/install.py install <klipper dir>
src/Kconfig and src/Makefile. The installer prints both paths and the undo command before it runs.install.sh refuses to run when klippy/extras/klipper_mmu.py exists, because that file would compete with the extra's name.[update_manager openams] entry covers Klipper-MMU too: an update pulls the new sources through the symlinks. Rebuild the MMU firmware after an update, because the MCU add-on is compiled into it.Build the MMU firmware in a separate Klipper checkout, not the one behind your running printer. From the klipper_mmu directory of your openams checkout, add the MCU add-on hooks to it:
python3 tools/install.py install /path/to/klipper
python3 tools/install.py check /path/to/klipper
Both includes are optional, so if the add-on is later moved or deleted, make menuconfig and make still work for other firmware built from that checkout, such as the printer mainboard. Run check before building MMU firmware.
Driver extensions. Some boards also need small extensions to Klipper's own STM32 drivers: local TMC UART access, paired PWM for powered rewind, and paired ADC reads for the analog DiffA/DiffB buffer. The BoxTurtle on an AFC Lite needs them. They are a separate, explicit step:
python3 tools/install.py install-driver-api /path/to/klipper
python3 tools/install.py check-driver-api /path/to/klipper
This patches thirteen Klipper source files in place, and only when they match Klipper revision ce7002bedf37e938bb483572949f3703ac6476cb; other bytes are refused. It needs the standard patch utility. Before a Klipper update that touches those files, run remove-driver-api, update, then reinstall. Each driver option is off by default and is selected in make menuconfig; installing them does not enable motion.
Keep the MMU's configuration and build output apart from the printer's with Klipper's own overrides, and pass both on every make:
make KCONFIG_CONFIG="$PWD/klipper-mmu.config" OUT=out-mmu/ menuconfig
make KCONFIG_CONFIG="$PWD/klipper-mmu.config" OUT=out-mmu/ olddefconfig
make KCONFIG_CONFIG="$PWD/klipper-mmu.config" OUT=out-mmu/ -j4
An environment variable alone is not enough: the Makefile assigns KCONFIG_CONFIG itself. The printer's .config and out/ are left alone. Back up klipper-mmu.config. To clean only the MMU output, run the same command with clean; do not use distclean, which deletes .config regardless.
In make menuconfig:
Flash with Klipper's own DFU or Katapult instructions for your board and transport. OpenAMS does not add a flashing tool.
In the printer's configuration, add a section that names the MMU. The smallest one is:
[klipper_mmu box]
mcu: mcu
mcu names the Klipper MCU that runs the MMU firmware: mcu for the main [mcu] section, or box for an [mcu box] section. Every command takes MMU=box to pick the section. KLIPPER_MMU_QUERY MMU=box is read-only and shows whether Klipper sees the MMU board. Restart Klipper after every change.
Further options are separate opt-ins:
| Option | What it does |
|---|---|
diff_probe |
Raw DiffA/DiffB probe for building the buffer calibration, on the safe image. |
diagnostic_startup, diff_calibration_file |
Hosted board startup, and the absolute path to the measured DiffA/DiffB calibration record. |
bowden_estimate_file |
Where KLIPPER_MMU_CALIBRATE stores the measured Bowden length. |
openams_motion, openams_idx, openams_fps, openams_family, openams_bays, openams_path_length_mm, openams_host_watchdog_ms, openams_lease_max_age_ms |
Let OpenAMS drive the MMU: its topology and the guarded motion lease. |
path_reconciliation, driver_restart |
Enable KLIPPER_MMU_RECONCILE_PATH and KLIPPER_MMU_RESTART_DRIVER. |
feeder_rotation_distances |
One rotation distance per lane, in mm, replacing the firmware's own list. |
selector_gate_steps, selector_calibration_file |
Selector gate positions, on selector machines. |
gate_metadata_file, tool_mapping_file, maintenance_counters_file |
Optional records for the gate metadata, tool map and maintenance commands. |
The BoxTurtle quick start adds them in order, and the G-code commands page lists the options each command needs. For a buffer whose DiffA/DiffB pair is read by the MMU firmware, use source_oams: klipper_mmu NAME in its [fps] section, and do not assign those ADC pins to a second reader on the host.
python3 klipper_mmu/tools/install.py check <klipper dir> # MCU add-on hooks
python3 klipper_mmu/tools/install.py check-host <klipper dir> # host module link
Exit status 0 means installed, 1 absent, and 2 a conflict, an incomplete installation or an error; the message names the file to look at.
check, then install if a hook is missing, and rebuild the MMU firmware../install.sh -u removes the host-module link, the marked Kconfig and Makefile blocks and the src/klipper_mmu link. It does not remove the driver extensions: run python3 klipper_mmu/tools/install.py remove-driver-api <klipper dir> for those. Removal leaves .config and build output alone; use a clean build afterwards.The full installer reference covers every action, its safety checks and the driver extensions in detail.