Initial import of my Klipper macros, modules and scripts

Macros as they run on the printer (Voron 2.4 + AFC Box Turtle +
Blobifier + Beacon + bd_pressure + bdwidth + iHeater), the Klipper
modules they need (xy_drift, bdwidth_status, bdpressure_check), MCU
firmware update scripts, install.sh with Moonraker update manager
support, and READMEs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-10 13:45:11 +02:00
commit 6dbb4ca3fb
24 files changed
+3906

No files matched your search

+88
View File
@@ -0,0 +1,88 @@
# MCU firmware update scripts
| Script | Does |
|---|---|
| `update_all_mcus.sh` | Pulls Klipper, builds and flashes **Klipper** to every MCU, prints a summary, restarts Klipper |
| `update_katapult_all_mcus.sh` | Builds and flashes **Katapult** (the bootloader) to every MCU |
Based on the [Voron guide to automating MCU updates](https://docs.vorondesign.com/community/howto/drachenkatze/automating_klipper_mcu_updates.html)
and [Esoterical's CANBus guide](https://canbus.esoterical.online/).
Run them on the Klipper host, between prints:
```bash
~/klipper-macros/scripts/update_all_mcus.sh
```
They stop Klipper while flashing (and need `sudo` for that).
## These scripts are for one printer
They contain the original printer's boards, build configs, CAN UUIDs and
serial IDs:
| Board | Name in the script | Connection | Build config (`KCONFIG_CONFIG=`) |
|---|---|---|---|
| LDO Leviathan (CAN bridge) | `Main MCU` | CAN `5a2b9f704f54` | `leviathan` |
| BoxTurtle MC (Pi Pico) | `MC_1 (BoxTurtle)` | CAN `acc4091027b4` | `BoxTurtleMC` |
| BTT EBB42 | `EBB42` | CAN `4b5324a91849` | `EBB42` |
| AFC-Lite (Box Turtle) | `Turtle_1` | CAN `59a2feeada77` | `Turtle_1` |
| LDO Nitehawk-SB | `NHK` | USB `usb-Klipper_stm32g0b1xx_550039000A50315058393320-if00` | `nhk` |
| iHeater | `iHeater` | USB `usb-Klipper_stm32f042x6_0C0020000E43304754393320-if00` | `iHeater` |
**Running them unchanged on another printer will not work, and flashing the
wrong firmware to a board can leave it unusable until it is reflashed by hand.**
## Adapting them to your printer
1. **Make one build config per board.** In `~/klipper` (and in `~/katapult`
for the Katapult script), run `make menuconfig KCONFIG_CONFIG=<name>` for
each board, with the settings from your board's documentation. The file
`<name>` is saved in that folder and the script uses it to build.
2. **Find your IDs.**
- CAN boards: `~/katapult/scripts/flashtool.py -i can0 -q`, or the
`canbus_uuid` values in `printer.cfg`.
- USB boards: `ls /dev/serial/by-id/`, or the `serial:` values in
`printer.cfg`.
3. **Edit the flash blocks.** Each board has one block like this:
```bash
printf "Update EBB42 firmware\n"
make clean
make clean KCONFIG_CONFIG=EBB42
make KCONFIG_CONFIG=EBB42
flash_device "EBB42" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u 4b5324a91849
```
For each of your boards, set the name, the `KCONFIG_CONFIG` and the
flash command:
- CAN board via Katapult: `... flashtool.py -i can0 -f <bin> -u <uuid>`
- USB board via Katapult: `... flashtool.py -f <bin> -d /dev/serial/by-id/<id>`
- USB board via Klipper's own flashing: `make flash KCONFIG_CONFIG=<name> FLASH_DEVICE=/dev/serial/by-id/<id>`
Delete the blocks of boards you do not have.
4. **Keep the CAN bridge last.** If your mainboard is a USB-to-CAN bridge,
flash it after all CAN boards: while it reboots, the CAN bus is gone.
5. **Update the names in `print_summary`.** The list
`for name in "Main MCU" "MC_1 (BoxTurtle)" ...` must contain the same names
as your `flash_device` calls, otherwise they show as SKIPPED.
6. **Katapult script:** Katapult can only replace itself if you build it as
a *deployment application* ("Build Katapult deployment application" in
`make menuconfig`); a normal Katapult build flashed through Katapult
overwrites the application slot instead. Check the Katapult docs for your
board before using that script, and keep a way to flash over USB/DFU.
The `CAN_DEVICES` / `CAN_DEVICE_ORDER` lists at the top of the scripts are
not used by the flashing itself; they only document the UUIDs.
## Known differences between the two scripts
`update_katapult_all_mcus.sh` ends after the last board: it does not print
the summary and does not start Klipper again. Run `sudo systemctl start
klipper` afterwards, or add the last lines of `update_all_mcus.sh`
(`print_summary` and the restart) to it.
+118
View File
@@ -0,0 +1,118 @@
#!/bin/bash
# https://docs.vorondesign.com/community/howto/drachenkatze/automating_klipper_mcu_updates.html
# https://canbus.esoterical.online/mainboard_klipper_updating.html
# Status tracking
declare -A FLASH_STATUS
declare -A FLASH_OUTPUT
# CAN devices to check (name -> uuid) — CAN BRIDGE MUST BE LAST
declare -A CAN_DEVICES
declare -a CAN_DEVICE_ORDER # preserve order since bash associative arrays don't
CAN_DEVICES["MC_1 (BoxTurtle)"]="acc4091027b4"
CAN_DEVICES["EBB42"]="4b5324a91849"
CAN_DEVICES["Turtle_1"]="59a2feeada77"
CAN_DEVICES["Main MCU"]="5a2b9f704f54" # CAN bridge — LAST
CAN_DEVICE_ORDER=("MC_1 (BoxTurtle)" "EBB42" "Turtle_1" "Main MCU")
# NHK and iHeater are serial devices, not CAN — skipped from CAN check
flash_device() {
local name="$1"
shift
local output
output=$("$@" 2>&1)
local exit_code=$?
FLASH_OUTPUT["$name"]="$output"
if [ $exit_code -eq 0 ]; then
FLASH_STATUS["$name"]="✅ SUCCESS"
else
FLASH_STATUS["$name"]="❌ FAILED (exit $exit_code)"
fi
echo "$output"
return $exit_code
}
print_summary() {
printf "\n========================================\n"
printf " FIRMWARE UPDATE SUMMARY\n"
printf "========================================\n"
local all_ok=true
for name in "Main MCU" "MC_1 (BoxTurtle)" "NHK" "EBB42" "Turtle_1" "iHeater"; do
local status="${FLASH_STATUS[$name]:-⚠️ SKIPPED}"
printf "%-20s %s\n" "$name" "$status"
if [[ "$status" != *"SUCCESS"* ]]; then
all_ok=false
fi
done
printf "========================================\n"
if $all_ok; then
printf "All devices updated successfully! 🎉\n"
else
printf "Some devices failed or were skipped.\n"
printf "\nFailed device details:\n"
for name in "Main MCU" "MC_1 (BoxTurtle)" "NHK" "EBB42" "Turtle_1" "iHeater"; do
if [[ "${FLASH_STATUS[$name]}" == *"FAILED"* ]]; then
printf "\n--- %s ---\n" "$name"
printf "%s\n" "${FLASH_OUTPUT[$name]}"
fi
done
fi
printf "========================================\n"
}
printf "Pulling klipper changes\n"
sudo service klipper stop
cd ~/klipper
git pull
printf "\nUpdate MC_1 firmware\n"
# MC_1
make clean
make clean KCONFIG_CONFIG=BoxTurtleMC
make KCONFIG_CONFIG=BoxTurtleMC
flash_device "MC_1 (BoxTurtle)" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u acc4091027b4
printf "Update nhk firmware\n"
# nhk
# https://docs.ldomotors.com/en/Toolboard/nitehawk-sb-v2
make clean
make clean KCONFIG_CONFIG=nhk
make KCONFIG_CONFIG=nhk
flash_device "NHK" make flash KCONFIG_CONFIG=nhk FLASH_DEVICE=/dev/serial/by-id/usb-Klipper_stm32g0b1xx_550039000A50315058393320-if00
printf "Update EBB42 firmware\n"
# EBB42
# https://canbus.esoterical.online/toolhead_flashing/common_hardware/BigTreeTech%20EBB42%20V1.2/README.html
make clean
make clean KCONFIG_CONFIG=EBB42
make KCONFIG_CONFIG=EBB42
flash_device "EBB42" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u 4b5324a91849
printf "Update Turtle_1 firmware\n"
# Turtle_1
make clean
make clean KCONFIG_CONFIG=Turtle_1
make KCONFIG_CONFIG=Turtle_1
flash_device "Turtle_1" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u 59a2feeada77
printf "Update Mcu firmware\n"
# Main Mcu
make clean
make clean KCONFIG_CONFIG=leviathan
make KCONFIG_CONFIG=leviathan
flash_device "Main MCU" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/klipper/out/klipper.bin -u 5a2b9f704f54
#flash_device "Main MCU" python3 ~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-Klipper_stm32f446xx_3B0017000251303532383235-if00
printf "Update iHeater firmware\n"
# iHeater
make clean
make clean KCONFIG_CONFIG=iHeater
make KCONFIG_CONFIG=iHeater
flash_device "iHeater" python3 ~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-Klipper_stm32f042x6_0C0020000E43304754393320-if00
print_summary
printf "\nStarting klipper\n"
printf "%s " "Press enter to continue"
read ans
sudo service klipper start
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
# https://docs.vorondesign.com/community/howto/drachenkatze/automating_klipper_mcu_updates.html
# https://canbus.esoterical.online/mainboard_klipper_updating.html
# Status tracking
declare -A FLASH_STATUS
declare -A FLASH_OUTPUT
# CAN devices to check (name -> uuid) — CAN BRIDGE MUST BE LAST
declare -A CAN_DEVICES
declare -a CAN_DEVICE_ORDER # preserve order since bash associative arrays don't
CAN_DEVICES["MC_1 (BoxTurtle)"]="acc4091027b4"
CAN_DEVICES["EBB42"]="4b5324a91849"
CAN_DEVICES["Turtle_1"]="59a2feeada77"
CAN_DEVICES["Main MCU"]="5a2b9f704f54" # CAN bridge — LAST
CAN_DEVICE_ORDER=("MC_1 (BoxTurtle)" "EBB42" "Turtle_1" "Main MCU")
# NHK and iHeater are serial devices, not CAN — skipped from CAN check
flash_device() {
local name="$1"
shift
local output
output=$("$@" 2>&1)
local exit_code=$?
FLASH_OUTPUT["$name"]="$output"
if [ $exit_code -eq 0 ]; then
FLASH_STATUS["$name"]="✅ SUCCESS"
else
FLASH_STATUS["$name"]="❌ FAILED (exit $exit_code)"
fi
echo "$output"
return $exit_code
}
print_summary() {
printf "\n========================================\n"
printf " FIRMWARE UPDATE SUMMARY\n"
printf "========================================\n"
local all_ok=true
for name in "Main MCU" "MC_1 (BoxTurtle)" "NHK" "EBB42" "Turtle_1" "iHeater"; do
local status="${FLASH_STATUS[$name]:-⚠️ SKIPPED}"
printf "%-20s %s\n" "$name" "$status"
if [[ "$status" != *"SUCCESS"* ]]; then
all_ok=false
fi
done
printf "========================================\n"
if $all_ok; then
printf "All devices updated successfully! 🎉\n"
else
printf "Some devices failed or were skipped.\n"
printf "\nFailed device details:\n"
for name in "Main MCU" "MC_1 (BoxTurtle)" "NHK" "EBB42" "Turtle_1" "iHeater"; do
if [[ "${FLASH_STATUS[$name]}" == *"FAILED"* ]]; then
printf "\n--- %s ---\n" "$name"
printf "%s\n" "${FLASH_OUTPUT[$name]}"
fi
done
fi
printf "========================================\n"
}
printf "Pulling klipper changes\n"
sudo service klipper stop
cd ~/katapult
printf "\nUpdate MC_1 firmware\n"
# MC_1
make clean
make clean KCONFIG_CONFIG=BoxTurtleMC
make KCONFIG_CONFIG=BoxTurtleMC
flash_device "MC_1 (BoxTurtle)" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/katapult/out/katapult.bin -u acc4091027b4
printf "Update nhk firmware\n"
# nhk
# https://docs.ldomotors.com/en/Toolboard/nitehawk-sb-v2
make clean
make clean KCONFIG_CONFIG=nhk
make KCONFIG_CONFIG=nhk
flash_device "NHK" make flash KCONFIG_CONFIG=nhk FLASH_DEVICE=/dev/serial/by-id/usb-Klipper_stm32g0b1xx_550039000A50315058393320-if00
printf "Update EBB42 firmware\n"
# EBB42
# https://canbus.esoterical.online/toolhead_flashing/common_hardware/BigTreeTech%20EBB42%20V1.2/README.html
make clean
make clean KCONFIG_CONFIG=EBB42
make KCONFIG_CONFIG=EBB42
flash_device "EBB42" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/katapult/out/katapult.bin -u 4b5324a91849
printf "Update Turtle_1 firmware\n"
# Turtle_1
make clean
make clean KCONFIG_CONFIG=Turtle_1
make KCONFIG_CONFIG=Turtle_1
flash_device "Turtle_1" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/katapult/out/katapult.bin -u 59a2feeada77
printf "Update Mcu firmware\n"
# Main Mcu
make clean
make clean KCONFIG_CONFIG=leviathan
make KCONFIG_CONFIG=leviathan
flash_device "Main MCU" python3 ~/katapult/scripts/flashtool.py -i can0 -f ~/katapult/out/katapult.bin -u 5a2b9f704f54
#flash_device "Main MCU" python3 ~/katapult/scripts/flashtool.py -f ~/katapult/out/katapult.bin -d /dev/serial/by-id/usb-Klipper_stm32f446xx_3B0017000251303532383235-if00
printf "Update iHeater firmware\n"
# iHeater
make clean
make clean KCONFIG_CONFIG=iHeater
make KCONFIG_CONFIG=iHeater
flash_device "iHeater" python3 ~/katapult/scripts/flashtool.py -f ~/katapult/out/katapult.bin -d /dev/serial/by-id/usb-Klipper_stm32f042x6_0C0020000E43304754393320-if00