The guard's timer read the sensor while G28 ran; bdpressure.py writes the
probe mode at every homing move, and Klipper allows only one I2C request
at a time per device: KeyError ('i2c_response', 1), Klipper shut down
during HOME. The guard now wraps the sensor's i2c in a reactor mutex at
connect; bdpressure and bdpressure_check (now looks up sensor.i2c at
every use) go through it too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 KiB
klipper-macros
My Klipper macros, the small Klipper modules they need, and helper scripts, from a Voron 2.4 (350) with an AFC Box Turtle (5 lanes), Blobifier, Beacon, Nitehawk-SB toolboard, bd_pressure, bdwidth and an iHeater chamber heater.
Installs with one script and updates through Moonraker's update manager.
Contents
Macros (macros/)
printer.cfg includes only macros/klipper-macros.cfg; that file includes
everything below, grouped by topic. Comment out what you do not use there.
| File | Macros | Needs |
|---|---|---|
save_variables.cfg |
the one [save_variables] for all macros (file bd_pa_variables.cfg in the config folder) |
— |
messages.cfg |
_ERROR, _WARN: errors and warnings shown in the console and on the display (M117, the status line in Mainsail and KlipperScreen); PAUSE shows AFC's error, RESUME, CANCEL_PRINT and PRINT_WARMUP clear the display |
— |
| blobifier/ | ||
blobifier.cfg |
BLOBIFIER, BLOBIFIER_CLEAN, BLOBIFIER_PARK, BLOBIFIER_SHAKE_BUCKET, ...: purge bucket and nozzle brush for AFC (Turtleblobifier, heavily modified) |
Blobifier hardware, AFC |
blobifier_hw.cfg |
servo and bucket switch pins | — |
| print/ | ||
print_start_end.cfg |
PRINT_WARMUP, PRINT_START, PRINT_END |
Beacon, AFC, Blobifier, HEAT_SOAK, iHeater, bd_pressure PA macros (bdwidth is no longer enabled while printing) |
pause_resume.cfg |
PAUSE, RESUME, CANCEL_PRINT, M600 (RESUME also handles a running HEAT_SOAK, and after a PAUSE purges 40 mm with BLOBIFIER_CHECKED first: a failed check keeps the print paused, RESUME PURGE=0 skips the purge; CANCEL_PRINT runs the same cleanup as PRINT_END) |
heating/heat_soak.cfg, leds/, blobifier/, afc/purge_check.cfg |
filament.cfg |
LOAD_FILAMENT, UNLOAD_FILAMENT |
— |
homing.cfg |
HOME: X/Y, then Z always with Beacon contact (also when already homed); _Z_CHECK: stops the print when Klipper's Z and the Beacon reading differ (run in PRINT_START after the soak) |
Beacon |
nozzle_guard.cfg |
[bdp_guard], _GUARD_ON PHASE=<name>, _GUARD_OFF: bd_pressure watches the nozzle force during print-start moves where nothing should touch it (QGL, Z homing, mesh); mode: log only reports the peak per phase, mode: stop shuts Klipper down on a touch |
extras/bdp_guard.py + bd_pressure load-check firmware |
idle_timeout.cfg |
[idle_timeout]: heaters, chamber heater and motors off |
iHeater macros |
| heating/ | ||
heat_soak.cfg |
HEAT_SOAK, STOP_HEAT_SOAK, CANCEL_HEAT_SOAK, HEAT_SOAK_RESUME, RESUME |
— |
soak_my_bed.cfg |
SOAK_MY_BED (homes and levels first) |
soak-my-bed |
bed_fans.cfg |
Bed fans through SET_HEATER_TEMPERATURE/M190/M140/TURN_OFF_HEATERS overrides |
[fan_generic BedFans] |
chamber_iheater.cfg |
iHeater MCU, heater and sensors, M141, M191, iHEATER_ON, iHEATER_OFF |
iHeater chamber heater |
filament_drying.cfg |
START_DRYING, STOP_DRYING, STATUS_DRYING |
bed fans, chamber heater (optional) |
| afc/ | ||
xy_safety_check.cfg |
AFC_XY_SAFETY_CHECK, _AFC_STORE_HOME_REFERENCE, AFC_XY_RESUME: lost-step check around tool changes |
extras/xy_drift.py (CoreXY) |
lane_tools.cfg |
LANE_FEED_UNTIL_HUB_OPEN, LANE_FEED_ABORT |
AFC |
purge_check.cfg |
BLOBIFIER_CHECKED: checks every AFC purge with bd_pressure (and optionally bdwidth motion); a bd_pressure that does not answer fails the check, PURGE_CHECK_IGNORE_SENSOR lets the current print finish without it |
Blobifier, AFC, extras/bdpressure_check.py + bd_pressure load-check firmware, extras/bdwidth_status.py |
purge_until_empty.cfg |
PURGE_UNTIL_EMPTY: purges a snapped filament out until there is no more nozzle pressure |
same as purge_check.cfg |
| pressure_advance/ | ||
bd_pa_spoolman.cfg + bd_pa_*.sh |
LANE_CALIBRATE_PA, PA_CALIBRATE_ALL_LANES, LANE_RECAL_PA, SET_SPOOL_ID, PA_STATUS: pressure advance per lane/spool, cached locally and in Spoolman; a calibration with no result, a pause during the test or too few/stuck sensor readings is rejected and not saved |
bd_pressure, AFC, Spoolman, gcode_shell_command |
| spoolman/ | ||
active_spool.cfg |
SET_ACTIVE_SPOOL, CLEAR_ACTIVE_SPOOL |
Spoolman in Moonraker |
| leds/ | ||
stealthburner_leds.cfg |
Stealthburner logo status (_STATUS STATE=...: heating and print progress as a filling logo, paused, error flash from _ERROR, part ready once the bed is cool, dim when idle and nobody is near) and the nozzle light |
led_effect, neopixel:bt_logo and rainbow_turtle from AFC |
| sensors/ | ||
motion_sensor.cfg |
PIR motion sensor: case light and nozzle LEDs on while someone is near (timeout from the last motion), CASELIGHT MODE=AUTO|ON|OFF |
sensor on a pin, [output_pin caselight], leds/stealthburner_leds.cfg |
Klipper modules (extras/)
| File | For |
|---|---|
xy_drift.py |
AFC_XY_SAFETY_CHECK: measures lost XY steps from the stepper step counts at the endstop triggers (CoreXY). The toolhead position after homing cannot show lost steps. |
bdwidth_status.py |
exposes bdwidth's motion counter and width to macros (present: False with neutral values when no bdwidth is configured, so the macros also work without it), and keeps a USB dropout of bdwidth (port: usb) from shutting down Klipper: the read is retried every 10 s and the port reopened |
bdpressure_check.py |
bd_pressure load check (BDP_CHECK_START/STOP/QUERY). Needs the load-check firmware from the bd_pressure load-check-extension branch; on stock firmware it reports "not available" and does nothing. Also reports how many readings the last PA_CALIBRATE got (pa_points, pa_distinct), used to reject runs with a silent or stuck sensor. |
bdp_guard.py |
nozzle collision guard: while armed (BDP_GUARD_ARM/DISARM/QUERY) reads the bd_pressure force every 20 ms over I2C and, in stop mode, shuts Klipper down when it stays above the threshold. Reports reads, peak and errors per phase in the console and klippy.log. Puts a lock on the sensor's I2C connection that bdpressure.py and bdpressure_check.py also go through (Klipper allows one I2C request at a time per device). Needs the load-check firmware. |
Scripts (scripts/)
Firmware update scripts for all MCUs (Klipper and Katapult). They contain this printer's CAN UUIDs and serial IDs: see scripts/README.md before using them on another printer.
Tools (tools/)
effective_config.py builds the config Klipper gets from
klipper-macros.cfg (includes expanded, duplicate sections merged) and
compares it between git refs, for example python tools/effective_config.py HEAD
after a change. CLAUDE.md has the notes for working on this repo with
Claude Code.
Install
On the Klipper host:
cd ~ && git clone https://mangavalk.com/mangavalk/klipper-macros.git
~/klipper-macros/install.sh
install.sh:
- links
extras/*.pyinto~/klipper/klippy/extras/(and hides them from Klipper's update manager), - links
macros/to~/printer_data/config/klipper-macrosandscripts/to~/printer_data/config/klipper-macros-scripts, so the files show up in Mainsail/Fluidd and can be edited there, - makes the shell scripts executable,
- adds this section to
moonraker.conf(once, with a backup):
[update_manager klipper-macros]
type: git_repo
path: ~/klipper-macros
origin: https://mangavalk.com/mangavalk/klipper-macros.git
primary_branch: main
managed_services: klipper
install_script: install.sh
Then:
- In
printer.cfg, after[include mainsail.cfg]and after the AFC includes ([include AFC/*.cfg]):[include klipper-macros/klipper-macros.cfg]bd_pa_spoolman.cfgwraps AFC'sSET_SPOOL_IDwithrename_existing, which only works when AFC is loaded first; otherwise Klipper stops withExisting command 'SET_SPOOL_ID' not found in gcode_macro rename. - Restart the Klipper service (
sudo systemctl restart klipper, or Mainsail → services → klipper → restart). ARESTARTorFIRMWARE_RESTARTdoes not load new or changed Python modules. - Restart Moonraker once, so the update manager shows
klipper-macros.
Updates then come through Moonraker; it re-runs install.sh and restarts
Klipper.
Adapting to another printer
These are the settings of one printer. Before using a file, check:
- Names:
fila_width_0(bdwidth),bd_pa(bd_pressure),sb_leds,caselight,BedFans,iHeater_H, lane nameslane1..lane5. - Pins and serial IDs:
blobifier/blobifier_hw.cfg(PC1,PC3),sensors/motion_sensor.cfg(PC0),heating/chamber_iheater.cfg(serial ID). - Positions: the bed centre
X175 Y175(350 mm bed) inprint/homing.cfgandprint/print_start_end.cfg.AFC_XY_SAFETY_CHECKuses the axis limits from your config. - Settings at the top of a file (
variable_...):afc/purge_check.cfg(mode: "enforce",motion_check: Falsebecause this printer's bdwidth motion reading is unreliable),pressure_advance/bd_pa_spoolman.cfg(spoolman_url),heating/bed_fans.cfg,heating/filament_drying.cfg. xy_drift.pyis for CoreXY only.
Comment out files you do not need in klipper-macros.cfg.
Uninstall
~/klipper-macros/install.sh --uninstall
Then remove the include from printer.cfg and the
[update_manager klipper-macros] section from moonraker.conf, and restart
the Klipper service.
Credits
Some files started from other projects and were modified here; their original licenses apply to those parts:
| File | Based on |
|---|---|
blobifier/ |
Turtleblobifier (AFC version of Dendrowen/Blobifier) |
leds/stealthburner_leds.cfg |
tanaes/whopping_Voron_mods (Rainbow Barf logo LEDs) |
heating/bed_fans.cfg |
Ellis' bed fan macros (ellis3dp.com) |
heating/heat_soak.cfg |
community HEAT_SOAK macro |
heating/chamber_iheater.cfg |
iHeater vendor configuration |
heating/filament_drying.cfg |
community filament drying macro |
print/pause_resume.cfg, print/filament.cfg |
KlipperScreen recommended macros |
scripts/ |
Voron docs: automating MCU updates, Esoterical's CANBus guide |
Uses: Klipper, AFC-Klipper-Add-On, bd_pressure, bdwidth, klipper-led_effect, soak-my-bed, Spoolman.