Files
klipper-macros/README.md
T
mangavalkandClaude Opus 5.5 8eef0ee298 bdp_guard: one lock for all I2C transfers of the bd_pressure
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>
2026-10-18 23:06:49 +02:00

173 lines
11 KiB
Markdown

# 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](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:
```bash
cd ~ && git clone https://mangavalk.com/mangavalk/klipper-macros.git
~/klipper-macros/install.sh
```
`install.sh`:
- links `extras/*.py` into `~/klipper/klippy/extras/` (and hides them from
Klipper's update manager),
- links `macros/` to `~/printer_data/config/klipper-macros` and `scripts/` 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):
```ini
[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:
1. In `printer.cfg`, after `[include mainsail.cfg]` **and after the AFC
includes** (`[include AFC/*.cfg]`):
```ini
[include klipper-macros/klipper-macros.cfg]
```
`bd_pa_spoolman.cfg` wraps AFC's `SET_SPOOL_ID` with `rename_existing`,
which only works when AFC is loaded first; otherwise Klipper stops with
`Existing command 'SET_SPOOL_ID' not found in gcode_macro rename`.
2. Restart the **Klipper service** (`sudo systemctl restart klipper`, or
Mainsail → services → klipper → restart). A `RESTART` or
`FIRMWARE_RESTART` does not load new or changed Python modules.
3. 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 names `lane1..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) in `print/homing.cfg`
and `print/print_start_end.cfg`.
`AFC_XY_SAFETY_CHECK` uses the axis limits from your config.
- **Settings at the top of a file** (`variable_...`): `afc/purge_check.cfg`
(`mode: "enforce"`, `motion_check: False` because 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.py` is for CoreXY only.
Comment out files you do not need in `klipper-macros.cfg`.
## Uninstall
```bash
~/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](https://github.com/ImSundee/Turtleblobifier) (AFC version of [Dendrowen/Blobifier](https://github.com/Dendrowen/Blobifier)) |
| `leds/stealthburner_leds.cfg` | [tanaes/whopping_Voron_mods](https://github.com/tanaes/whopping_Voron_mods) (Rainbow Barf logo LEDs) |
| `heating/bed_fans.cfg` | Ellis' bed fan macros ([ellis3dp.com](https://ellis3dp.com/Print-Tuning-Guide/)) |
| `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](https://klipperscreen.readthedocs.io/en/latest/macros/#recommended) |
| `scripts/` | [Voron docs: automating MCU updates](https://docs.vorondesign.com/community/howto/drachenkatze/automating_klipper_mcu_updates.html), [Esoterical's CANBus guide](https://canbus.esoterical.online/) |
Uses: [Klipper](https://github.com/Klipper3d/klipper),
[AFC-Klipper-Add-On](https://github.com/ArmoredTurtle/AFC-Klipper-Add-On),
[bd_pressure](https://github.com/markniu/bd_pressure),
[bdwidth](https://github.com/markniu/bdwidth),
[klipper-led_effect](https://github.com/julianschill/klipper-led_effect),
[soak-my-bed](https://github.com/marcofailli/soak-my-bed),
[Spoolman](https://github.com/Donkie/Spoolman).