From d24a99627548408bd9cd0fbb41dd824a58451016 Mon Sep 17 00:00:00 2001 From: Shahovalov MIkhail Date: Sun, 11 Oct 2026 22:03:03 +0300 Subject: [PATCH] LeoVoron2.4 config (history squashed 2026-10-11) --- .autocommit.sh | 95 +++ .gitignore | 11 + KAMP_Settings.cfg | 36 + KlipperScreen.conf | 22 + crowsnest.conf | 59 ++ firmware/.CAN | 59 ++ firmware/boot_btt_mmb.CAN | 80 +++ firmware/boot_btt_mmb.CAN.old | 43 ++ firmware/boot_rp_sb2209.can | 54 ++ firmware/boot_rp_sb2209.can.old | 53 ++ firmware/boot_sht36_v2.config | 78 +++ firmware/boot_sht36_v2.config.old | 43 ++ firmware/btt_mmb.CAN | 122 ++++ firmware/btt_mmb.CAN.old | 67 ++ firmware/config.manta723.CAN | 67 ++ firmware/ebb_rp2240.CAN | 86 +++ firmware/ebb_rp2240.CAN.old | 69 ++ firmware/hbb.cfg | 109 +++ firmware/hbb.cfg.old | 126 ++++ firmware/host_linux.config | 50 ++ firmware/octopus-pro.config | 136 ++++ firmware/octopus-pro.config.old | 126 ++++ firmware/rp_sb2209.CAN | 101 +++ firmware/rp_sb2209.CAN.old | 70 ++ firmware/sht36_v2.CAN | 105 +++ firmware/sht36_v2.CAN.old | 55 ++ firmware/update_fw.sh | 320 +++++++++ firmware/update_fw.sh.old | 40 ++ hbb.cfg | 124 ++++ macros/calibrate_flow.cfg | 262 ++++++++ macros/config_backup.cfg | 9 + macros/homing.cfg | 174 +++++ macros/main.cfg | 746 +++++++++++++++++++++ macros/nevermore.cfg | 30 + macros/nozzle_scrub.cfg | 158 +++++ macros/stealthburner_leds.cfg | 254 +++++++ macros/tools.cfg | 91 +++ mmu/addons/blobifier.cfg | 924 ++++++++++++++++++++++++++ mmu/addons/blobifier_hw.cfg | 28 + mmu/addons/mmu_eject_buttons.cfg | 31 + mmu/addons/mmu_eject_buttons_hw.cfg | 21 + mmu/addons/mmu_erec_cutter.cfg | 91 +++ mmu/addons/mmu_erec_cutter_hw.cfg | 10 + mmu/base/bigtreetech-mmb-ercf.cfg.bkp | 123 ++++ mmu/base/mmu.cfg | 118 ++++ mmu/base/mmu_cut_tip.cfg | 1 + mmu/base/mmu_form_tip.cfg | 1 + mmu/base/mmu_hardware.cfg | 413 ++++++++++++ mmu/base/mmu_leds.cfg | 1 + mmu/base/mmu_macro_vars.cfg | 536 +++++++++++++++ mmu/base/mmu_parameters.cfg | 689 +++++++++++++++++++ mmu/base/mmu_purge.cfg | 1 + mmu/base/mmu_sequence.cfg | 1 + mmu/base/mmu_software.cfg | 1 + mmu/base/mmu_state.cfg | 1 + mmu/mmu_vars.cfg | 36 + mmu/optional/client_macros.cfg | 1 + mmu/optional/mmu_menu.cfg | 1 + mmu_klipperscreen.conf | 757 +++++++++++++++++++++ moonraker.conf | 112 ++++ octopus_pro_1.1.cfg | 235 +++++++ printer.cfg | 235 +++++++ rapido_ace.cfg | 17 + rapido_v2.cfg | 5 + sonar.conf | 17 + toolhead_sb.cfg | 174 +++++ toolhead_sht36v2.cfg | 104 +++ 67 files changed, 8815 insertions(+) create mode 100755 .autocommit.sh create mode 100644 .gitignore create mode 100644 KAMP_Settings.cfg create mode 100644 KlipperScreen.conf create mode 100644 crowsnest.conf create mode 100644 firmware/.CAN create mode 100644 firmware/boot_btt_mmb.CAN create mode 100644 firmware/boot_btt_mmb.CAN.old create mode 100644 firmware/boot_rp_sb2209.can create mode 100644 firmware/boot_rp_sb2209.can.old create mode 100644 firmware/boot_sht36_v2.config create mode 100644 firmware/boot_sht36_v2.config.old create mode 100644 firmware/btt_mmb.CAN create mode 100644 firmware/btt_mmb.CAN.old create mode 100644 firmware/config.manta723.CAN create mode 100644 firmware/ebb_rp2240.CAN create mode 100644 firmware/ebb_rp2240.CAN.old create mode 100644 firmware/hbb.cfg create mode 100644 firmware/hbb.cfg.old create mode 100644 firmware/host_linux.config create mode 100644 firmware/octopus-pro.config create mode 100644 firmware/octopus-pro.config.old create mode 100644 firmware/rp_sb2209.CAN create mode 100644 firmware/rp_sb2209.CAN.old create mode 100644 firmware/sht36_v2.CAN create mode 100644 firmware/sht36_v2.CAN.old create mode 100755 firmware/update_fw.sh create mode 100755 firmware/update_fw.sh.old create mode 100644 hbb.cfg create mode 100644 macros/calibrate_flow.cfg create mode 100644 macros/config_backup.cfg create mode 100644 macros/homing.cfg create mode 100644 macros/main.cfg create mode 100644 macros/nevermore.cfg create mode 100644 macros/nozzle_scrub.cfg create mode 100644 macros/stealthburner_leds.cfg create mode 100644 macros/tools.cfg create mode 100644 mmu/addons/blobifier.cfg create mode 100644 mmu/addons/blobifier_hw.cfg create mode 100644 mmu/addons/mmu_eject_buttons.cfg create mode 100644 mmu/addons/mmu_eject_buttons_hw.cfg create mode 100644 mmu/addons/mmu_erec_cutter.cfg create mode 100644 mmu/addons/mmu_erec_cutter_hw.cfg create mode 100644 mmu/base/bigtreetech-mmb-ercf.cfg.bkp create mode 100644 mmu/base/mmu.cfg create mode 120000 mmu/base/mmu_cut_tip.cfg create mode 120000 mmu/base/mmu_form_tip.cfg create mode 100644 mmu/base/mmu_hardware.cfg create mode 120000 mmu/base/mmu_leds.cfg create mode 100644 mmu/base/mmu_macro_vars.cfg create mode 100644 mmu/base/mmu_parameters.cfg create mode 120000 mmu/base/mmu_purge.cfg create mode 120000 mmu/base/mmu_sequence.cfg create mode 120000 mmu/base/mmu_software.cfg create mode 120000 mmu/base/mmu_state.cfg create mode 100644 mmu/mmu_vars.cfg create mode 120000 mmu/optional/client_macros.cfg create mode 120000 mmu/optional/mmu_menu.cfg create mode 100644 mmu_klipperscreen.conf create mode 100644 moonraker.conf create mode 100644 octopus_pro_1.1.cfg create mode 100644 printer.cfg create mode 100644 rapido_ace.cfg create mode 100644 rapido_v2.cfg create mode 100644 sonar.conf create mode 100644 toolhead_sb.cfg create mode 100644 toolhead_sht36v2.cfg diff --git a/.autocommit.sh b/.autocommit.sh new file mode 100755 index 0000000..34f0b17 --- /dev/null +++ b/.autocommit.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +####################################################################### +## NOTE: This script originates from here but I tweaked the pull ## +## command, changed default location for backup, and added a comment ## +## for reference later. ## +####################################################################### + +##################################################################### +### Please set the paths accordingly. In case you don't have all ### +### the listed folders, just keep that line commented out. ### +##################################################################### +### Path to your config folder you want to backup +config_folder=~/printer_data/config + +# NOTE: The above should work for just about everyone, but a somewhat +# recent update to moonraker changed paths, etc. You can run the +# provided moonraker script 'data-path-fix.sh' to fix/update +# older installs + +### Path to your Klipper folder, by default that is '~/klipper' +klipper_folder=~/klipper + +### Path to your Moonraker folder, by default that is '~/moonraker' +moonraker_folder=~/moonraker + +### Path to your Mainsail folder, by default that is '~/mainsail' +mainsail_folder=~/mainsail + +### Path to your Fluidd folder, by default that is '~/fluidd' +#fluidd_folder=~/fluidd + +### The branch of the repository that you want to save your config +### By default that is 'main' +branch=main + +db_file=~/printer_data/database/moonraker-sql.db + +##################################################################### +##################################################################### + + + +##################################################################### +################ !!! DO NOT EDIT BELOW THIS LINE !!! ################ +##################################################################### +grab_version(){ + if [ ! -z "$klipper_folder" ]; then + klipper_commit=$(git -C $klipper_folder describe --always --tags --long | awk '{gsub(/^ +| +$/,"")} {print $0}') + m1="Klipper version: $klipper_commit" + fi + if [ ! -z "$moonraker_folder" ]; then + moonraker_commit=$(git -C $moonraker_folder describe --always --tags --long | awk '{gsub(/^ +| +$/,"")} {print $0}') + m2="Moonraker version: $moonraker_commit" + fi + if [ ! -z "$mainsail_folder" ]; then + mainsail_ver=$(head -n 1 $mainsail_folder/.version) + m3="Mainsail version: $mainsail_ver" + fi + if [ ! -z "$fluidd_folder" ]; then + fluidd_ver=$(head -n 1 $fluidd_folder/.version) + m4="Fluidd version: $fluidd_ver" + fi +} + +# Here we copy the sqlite database for backup +# To RESTORE the database, stop moonraker, then use the following command: +# cp ~/printer_data/config/moonraker-sql.db ~/printer_data/database/ +# Finally, restart moonraker + +if [ -f $db_file ]; then + echo "sqlite based history database found! Copying..." + cp ~/printer_data/database/moonraker-sql.db ~/printer_data/config/ +else + echo "sqlite based history database not found" +fi + +# To fully automate this and not have to deal with auth issues, generate a legacy token on Github +# then update the command below to use the token. Run the command in your base directory and it will +# handle auth. This should just be executed in your shell and not committed to any files or +# Github will revoke the token. =) +# git remote set-url origin https://XXXXXXXXXXX@github.com/EricZimmerman/Voron24Configs.git/ +# Note that that format is for changing things after the repository is in use, vs initially + +push_config(){ + cd $config_folder + git pull origin $branch --no-rebase + git add . + current_date=$(date +"%Y-%m-%d %T") + git commit -m "Autocommit from $current_date" -m "$m1" -m "$m2" -m "$m3" -m "$m4" + git push origin $branch +} + +grab_version +push_config diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1d7a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +printer-*.cfg +KAMP +mainsail.cfg +moonraker_obico_macros.cfg +timelapse.cfg +autocommit.sh +moonraker-sql.db +moonraker-obico.cfg +moonraker-obico-update.cfg +telegram.conf +.*.*.bkp diff --git a/KAMP_Settings.cfg b/KAMP_Settings.cfg new file mode 100644 index 0000000..cd7683a --- /dev/null +++ b/KAMP_Settings.cfg @@ -0,0 +1,36 @@ +# Below you can include specific configuration files depending on what you want KAMP to do: + +# [include ./KAMP/Adaptive_Meshing.cfg] # Include to enable adaptive meshing configuration. +# [include ./KAMP/Line_Purge.cfg] # Include to enable adaptive line purging configuration. +[include ./KAMP/Voron_Purge.cfg] # Include to enable adaptive Voron logo purging configuration. +[include ./KAMP/Smart_Park.cfg] # Include to enable the Smart Park function, which parks the printhead near the print area for final heating. + +[gcode_macro _KAMP_Settings] +description: This macro contains all adjustable settings for KAMP + +# The following variables are settings for KAMP as a whole. +variable_verbose_enable: True # Set to True to enable KAMP information output when running. This is useful for debugging. + +# The following variables are for adjusting adaptive mesh settings for KAMP. +variable_mesh_margin: 0 # Expands the mesh size in millimeters if desired. Leave at 0 to disable. +variable_fuzz_amount: 1 # Slightly randomizes mesh points to spread out wear from nozzle-based probes. Leave at 0 to disable. + +# The following variables are for those with a dockable probe like Klicky, Euclid, etc. # ---------------- Attach Macro | Detach Macro +variable_probe_dock_enable: False # Set to True to enable the usage of a dockable probe. # --------------------------------------------- +variable_attach_macro: 'Attach_Probe' # The macro that is used to attach the probe. # Klicky Probe: 'Attach_Probe' | 'Dock_Probe' +variable_detach_macro: 'Dock_Probe' # The macro that is used to store the probe. # Euclid Probe: 'Deploy_Probe' | 'Stow_Probe' + # Legacy Gcode: 'M401' | 'M402' + +# The following variables are for adjusting adaptive purge settings for KAMP. +variable_purge_height: 0.8 # Z position of nozzle during purge, default is 0.8. +variable_tip_distance: 10 # Distance between tip of filament and nozzle before purge. Should be similar to PRINT_END final retract amount. +variable_purge_margin: 12 # Distance the purge will be in front of the print area, default is 10. +variable_purge_amount: 30 # Amount of filament to be purged prior to printing. +variable_flow_rate: 12 # Flow rate of purge in mm3/s. Default is 12. + +# The following variables are for adjusting the Smart Park feature for KAMP, which will park the printhead near the print area at a specified height. +variable_smart_park_height: 10 # Z position for Smart Park, default is 10. + +gcode: # Gcode section left intentionally blank. Do not disturb. + + {action_respond_info(" Running the KAMP_Settings macro does nothing, it is only used for storing KAMP settings. ")} diff --git a/KlipperScreen.conf b/KlipperScreen.conf new file mode 100644 index 0000000..3ebcec0 --- /dev/null +++ b/KlipperScreen.conf @@ -0,0 +1,22 @@ +# +# MMU "Happy Hare edition" menus +# +[include mmu_klipperscreen.conf] + +# To use this KlipperScreen panel, create a symlink: +# $MOONRAKER_OBICO_HOME/scripts/klipper_screen_obico_panel.py ->$KLIPPER_SCREEN_HOME/panels/obico.py +[menu __main more obico] +name: Obico +icon: network +panel: obico + +#~# --- Do not edit below this line. This section is auto generated --- #~# +#~# +#~# [main] +#~# theme = colorized +#~# print_sort_dir = date_desc +#~# language = ru +#~# +#~# [graph Printer] +#~# extruder = False +#~# diff --git a/crowsnest.conf b/crowsnest.conf new file mode 100644 index 0000000..771e514 --- /dev/null +++ b/crowsnest.conf @@ -0,0 +1,59 @@ +#### crowsnest.conf +#### This is a typical default config. +#### Also used as default in mainsail / MainsailOS +#### See: +#### https://github.com/mainsail-crew/crowsnest/blob/master/README.md +#### for details to configure to your needs. + + +##################################################################### +#### ##### +#### Information about ports and according URL's ##### +#### ##### +##################################################################### +#### ##### +#### Port 8080 equals /webcam/?action=[stream/snapshot] ##### +#### Port 8081 equals /webcam2/?action=[stream/snapshot] ##### +#### Port 8082 equals /webcam3/?action=[stream/snapshot] ##### +#### Port 8083 equals /webcam4/?action=[stream/snapshot] ##### +#### ##### +##################################################################### +#### RTSP Stream URL: ( if enabled and supported ) ##### +#### rtsp://:/stream.h264 ##### +##################################################################### + + +[crowsnest] +log_path: /home/biqu/printer_data/logs/crowsnest.log +log_level: verbose # Valid Options are quiet/verbose/debug +delete_log: false # Deletes log on every restart, if set to true +no_proxy: false + +#[cam xy] +#mode: ustreamer # ustreamer - Provides mjpg and snapshots. (All devices), camera-streamer - Provides webrtc, mjpg and snapshots. (rpi + Raspi OS based only) +#enable_rtsp: false # If camera-streamer is used, this enables also usage of an rtsp server +#rtsp_port: 8554 # Set different ports for each device! +#port: 8080 # HTTP/MJPG Stream/Snapshot Port +#device: /dev/v4l/by-path/platform-5101000.usb-usb-0:1.3:1.0-video-index0 # See Log for available ... +#resolution: 1280x720 #640x480 # widthxheight format 2048x1536 +#max_fps: 15 # If Hardware Supports this it will be forced, otherwise ignored/coerced. +#custom_flags: # You can run the Stream Services with custom flags. +#v4l2ctl: # Add v4l2-ctl parameters to setup your camera, see Log what your cam is capable of. + +[cam head] +mode: ustreamer +port: 8080 +#device: /dev/v4l/by-path/platform-5101000.usb-usb-0:1.1:1.0-video-index0 +device: /dev/v4l/by-id/usb-DSJ_UC60_Video_200901010001-video-index0 +resolution: 1600x1200 #176x144, 320x240, 352x288, 640x480, 640x360, 640x400, 800x600, 1024x768, 1280x720, 1280x960, 1600x1200, 1920x1080, 2048x1536, 2560x1440, 2592x1944 +max_fps: 30 +v4l2ctl: focus_automatic_continuous=0 #brightness=-10, backlight_compensation=0 + +#[cam bed_cam] +#mode: ustreamer +#port: 8080 +#device: /dev/video0 # The CSI +#resolution: 1600x1200 #176x144, 320x240, 352x288, 640x480, 640x360, 640x400, 800x600, 1024x768, 1280x720, 1280x960, 1600x1200, 1920x1080, 2048x1536, 2560x1440, 2592x1944 +#max_fps: 15 +#custom_flags: --format=UYVY + diff --git a/firmware/.CAN b/firmware/.CAN new file mode 100644 index 0000000..dc58ed7 --- /dev/null +++ b/firmware/.CAN @@ -0,0 +1,59 @@ +# CONFIG_LOW_LEVEL_OPTIONS is not set +CONFIG_MACH_AVR=y +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_AVR_SELECT=y +CONFIG_BOARD_DIRECTORY="avr" +CONFIG_MACH_atmega2560=y +# CONFIG_MACH_atmega1280 is not set +# CONFIG_MACH_at90usb1286 is not set +# CONFIG_MACH_at90usb646 is not set +# CONFIG_MACH_atmega32u4 is not set +# CONFIG_MACH_atmega1284p is not set +# CONFIG_MACH_atmega644p is not set +# CONFIG_MACH_atmega328p is not set +# CONFIG_MACH_atmega328 is not set +# CONFIG_MACH_atmega168 is not set +CONFIG_MCU="atmega2560" +CONFIG_AVRDUDE_PROTOCOL="wiring" +CONFIG_CLOCK_FREQ=16000000 +CONFIG_AVR_CLKPR=-1 +CONFIG_AVR_STACK_SIZE=256 +CONFIG_AVR_WATCHDOG=y +CONFIG_SERIAL=y +CONFIG_SERIAL_BAUD_U2X=y +CONFIG_SERIAL_PORT=0 +CONFIG_SERIAL_BAUD=250000 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y diff --git a/firmware/boot_btt_mmb.CAN b/firmware/boot_btt_mmb.CAN new file mode 100644 index 0000000..2fe1310 --- /dev/null +++ b/firmware/boot_btt_mmb.CAN @@ -0,0 +1,80 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_LPC176X is not set +CONFIG_MACH_STM32=y +# CONFIG_MACH_RPXXXX is not set +CONFIG_BOARD_DIRECTORY="stm32" +CONFIG_MCU="stm32g0b1xx" +CONFIG_CLOCK_FREQ=64000000 +CONFIG_FLASH_SIZE=0x20000 +CONFIG_FLASH_BOOT_ADDRESS=0x8000000 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x24000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x8000000 +CONFIG_FLASH_START=0x8000000 +CONFIG_LAUNCH_APP_ADDRESS=0x8002000 +CONFIG_BLOCK_SIZE=64 +CONFIG_STM32_SELECT=y +# CONFIG_MACH_STM32F103 is not set +# CONFIG_MACH_STM32F207 is not set +# CONFIG_MACH_STM32F401 is not set +# CONFIG_MACH_STM32F405 is not set +# CONFIG_MACH_STM32F407 is not set +# CONFIG_MACH_STM32F429 is not set +# CONFIG_MACH_STM32F446 is not set +# CONFIG_MACH_STM32F031 is not set +# CONFIG_MACH_STM32F042 is not set +# CONFIG_MACH_STM32F070 is not set +# CONFIG_MACH_STM32F072 is not set +# CONFIG_MACH_STM32G0B0 is not set +CONFIG_MACH_STM32G0B1=y +# CONFIG_MACH_STM32H723 is not set +# CONFIG_MACH_STM32H743 is not set +CONFIG_MACH_STM32G0=y +CONFIG_MACH_STM32G0Bx=y +CONFIG_HAVE_STM32_USBFS=y +CONFIG_HAVE_STM32_FDCANBUS=y +CONFIG_STM32_DFU_ROM_ADDRESS=0 +CONFIG_STM32_FLASH_START_0000=y +# CONFIG_STM32_FLASH_START_2000 is not set +CONFIG_STM32_CLOCK_REF_8M=y +# CONFIG_STM32_CLOCK_REF_12M is not set +# CONFIG_STM32_CLOCK_REF_16M is not set +# CONFIG_STM32_CLOCK_REF_20M is not set +# CONFIG_STM32_CLOCK_REF_25M is not set +# CONFIG_STM32_CLOCK_REF_32M is not set +# CONFIG_STM32_CLOCK_REF_INTERNAL is not set +CONFIG_CLOCK_REF_FREQ=8000000 +CONFIG_STM32F0_TRIM=16 +# CONFIG_STM32_USB_PA11_PA12 is not set +# CONFIG_STM32_SERIAL_USART1 is not set +# CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 is not set +# CONFIG_STM32_SERIAL_USART2 is not set +# CONFIG_STM32_SERIAL_USART2_ALT_PD6_PD5 is not set +# CONFIG_STM32_SERIAL_USART3 is not set +# CONFIG_STM32_SERIAL_USART3_ALT_PD9_PD8 is not set +# CONFIG_STM32_CANBUS_PA11_PA12 is not set +# CONFIG_STM32_CANBUS_PA11_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB8_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB5_PB6 is not set +# CONFIG_STM32_MMENU_CANBUS_PB12_PB13 is not set +# CONFIG_STM32_MMENU_CANBUS_PD0_PD1 is not set +CONFIG_STM32_MMENU_CANBUS_PB0_PB1=y +# CONFIG_STM32_MMENU_CANBUS_PD12_PD13 is not set +# CONFIG_STM32_MMENU_CANBUS_PC2_PC3 is not set +CONFIG_STM32_CANBUS_PB0_PB1=y +CONFIG_STM32_APP_START_2000=y +# CONFIG_STM32_APP_START_1000 is not set +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x6177 +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INITIAL_PINS="" +CONFIG_ENABLE_DOUBLE_RESET=y +# CONFIG_ENABLE_BUTTON is not set +# CONFIG_ENABLE_LED is not set +CONFIG_HAVE_CHIPID=y +CONFIG_KATAPULT_VERSION="v0.0.1-96-gbc1ecea" diff --git a/firmware/boot_btt_mmb.CAN.old b/firmware/boot_btt_mmb.CAN.old new file mode 100644 index 0000000..92ec9f8 --- /dev/null +++ b/firmware/boot_btt_mmb.CAN.old @@ -0,0 +1,43 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +CONFIG_MACH_LPC176X=y +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_RPXXXX is not set +CONFIG_LPC_SELECT=y +CONFIG_BOARD_DIRECTORY="lpc176x" +CONFIG_MACH_LPC1768=y +# CONFIG_MACH_LPC1769 is not set +CONFIG_MCU="lpc1768" +CONFIG_CLOCK_FREQ=100000000 +CONFIG_FLASH_SIZE=0x80000 +CONFIG_FLASH_BOOT_ADDRESS=0x0 +CONFIG_RAM_START=0x10000000 +CONFIG_RAM_SIZE=0x7ee0 +CONFIG_STACK_SIZE=512 +CONFIG_LPC_FLASH_START_0000=y +# CONFIG_LPC_FLASH_START_4000 is not set +CONFIG_FLASH_APPLICATION_ADDRESS=0x0000 +CONFIG_LPC_USB=y +# CONFIG_LPC_SERIAL_UART0_P03_P02 is not set +# CONFIG_LPC_SERIAL_UART3_P429_P428 is not set +CONFIG_FLASH_START=0x0000 +CONFIG_LAUNCH_APP_ADDRESS=0x4000 +CONFIG_BLOCK_SIZE=64 +CONFIG_USBSERIAL=y +CONFIG_USB=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x6177 +CONFIG_USB_SERIAL_NUMBER_CHIPID=y +CONFIG_USB_SERIAL_NUMBER="12345" + +# +# USB ids +# +# end of USB ids + +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INITIAL_PINS="" +CONFIG_ENABLE_DOUBLE_RESET=y +# CONFIG_ENABLE_BUTTON is not set +# CONFIG_ENABLE_LED is not set +CONFIG_HAVE_CHIPID=y +CONFIG_KATAPULT_VERSION="v0.0.1-96-gbc1ecea" diff --git a/firmware/boot_rp_sb2209.can b/firmware/boot_rp_sb2209.can new file mode 100644 index 0000000..51393be --- /dev/null +++ b/firmware/boot_rp_sb2209.can @@ -0,0 +1,54 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +CONFIG_MACH_RPXXXX=y +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10004000 +CONFIG_FLASH_START=0x10000000 +CONFIG_LAUNCH_APP_ADDRESS=0x10004000 +CONFIG_BLOCK_SIZE=64 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RP2040_HAVE_STAGE2=y +# CONFIG_RP2040_FLASH_W25Q080 is not set +CONFIG_RP2040_FLASH_GENERIC_03=y +CONFIG_RP2040_STAGE2_FILE="boot2_generic_03h.S" +CONFIG_RP2040_STAGE2_CLKDIV=4 +# CONFIG_RPXXXX_FLASH_START_0100 is not set +CONFIG_RPXXXX_FLASH_START_4000=y +# CONFIG_RPXXXX_USB is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +CONFIG_RPXXXX_CANBUS=y +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x6177 +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INITIAL_PINS="" +CONFIG_ENABLE_DOUBLE_RESET=y +# CONFIG_ENABLE_BUTTON is not set +CONFIG_ENABLE_LED=y +CONFIG_STATUS_LED_PIN="gpio26" +CONFIG_BUILD_DEPLOYER=y +CONFIG_HAVE_CHIPID=y +CONFIG_KATAPULT_VERSION="v0.0.1-96-gbc1ecea" diff --git a/firmware/boot_rp_sb2209.can.old b/firmware/boot_rp_sb2209.can.old new file mode 100644 index 0000000..c9b123f --- /dev/null +++ b/firmware/boot_rp_sb2209.can.old @@ -0,0 +1,53 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +CONFIG_MACH_RPXXXX=y +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10000100 +CONFIG_FLASH_START=0x10000000 +CONFIG_LAUNCH_APP_ADDRESS=0x10004000 +CONFIG_BLOCK_SIZE=64 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RP2040_HAVE_STAGE2=y +# CONFIG_RP2040_FLASH_W25Q080 is not set +CONFIG_RP2040_FLASH_GENERIC_03=y +CONFIG_RP2040_STAGE2_FILE="boot2_generic_03h.S" +CONFIG_RP2040_STAGE2_CLKDIV=4 +CONFIG_RPXXXX_FLASH_START_0100=y +# CONFIG_RPXXXX_FLASH_START_4000 is not set +# CONFIG_RPXXXX_USB is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +CONFIG_RPXXXX_CANBUS=y +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x6177 +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INITIAL_PINS="" +CONFIG_ENABLE_DOUBLE_RESET=y +# CONFIG_ENABLE_BUTTON is not set +CONFIG_ENABLE_LED=y +CONFIG_STATUS_LED_PIN="gpio26" +CONFIG_HAVE_CHIPID=y +CONFIG_KATAPULT_VERSION="v0.0.1-96-gbc1ecea" diff --git a/firmware/boot_sht36_v2.config b/firmware/boot_sht36_v2.config new file mode 100644 index 0000000..1b15281 --- /dev/null +++ b/firmware/boot_sht36_v2.config @@ -0,0 +1,78 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_LPC176X is not set +CONFIG_MACH_STM32=y +# CONFIG_MACH_RPXXXX is not set +CONFIG_BOARD_DIRECTORY="stm32" +CONFIG_MCU="stm32f072xb" +CONFIG_CLOCK_FREQ=48000000 +CONFIG_FLASH_SIZE=0x20000 +CONFIG_FLASH_BOOT_ADDRESS=0x8000000 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x4000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x8002000 +CONFIG_FLASH_START=0x8000000 +CONFIG_LAUNCH_APP_ADDRESS=0x8002000 +CONFIG_BLOCK_SIZE=64 +CONFIG_STM32_SELECT=y +# CONFIG_MACH_STM32F103 is not set +# CONFIG_MACH_STM32F207 is not set +# CONFIG_MACH_STM32F401 is not set +# CONFIG_MACH_STM32F405 is not set +# CONFIG_MACH_STM32F407 is not set +# CONFIG_MACH_STM32F429 is not set +# CONFIG_MACH_STM32F446 is not set +# CONFIG_MACH_STM32F031 is not set +# CONFIG_MACH_STM32F042 is not set +# CONFIG_MACH_STM32F070 is not set +CONFIG_MACH_STM32F072=y +# CONFIG_MACH_STM32G0B0 is not set +# CONFIG_MACH_STM32G0B1 is not set +# CONFIG_MACH_STM32H723 is not set +# CONFIG_MACH_STM32H743 is not set +CONFIG_MACH_STM32F0=y +CONFIG_MACH_STM32F0x2=y +CONFIG_HAVE_STM32_USBFS=y +CONFIG_HAVE_STM32_CANBUS=y +CONFIG_STM32_DFU_ROM_ADDRESS=0 +# CONFIG_STM32_FLASH_START_0000 is not set +CONFIG_STM32_FLASH_START_2000=y +# CONFIG_STM32_FLASH_START_1000 is not set +# CONFIG_STM32_FLASH_START_4000 is not set +CONFIG_ARMCM_RAM_VECTORTABLE=y +CONFIG_STM32_CLOCK_REF_8M=y +# CONFIG_STM32_CLOCK_REF_12M is not set +# CONFIG_STM32_CLOCK_REF_16M is not set +# CONFIG_STM32_CLOCK_REF_20M is not set +# CONFIG_STM32_CLOCK_REF_25M is not set +# CONFIG_STM32_CLOCK_REF_32M is not set +# CONFIG_STM32_CLOCK_REF_INTERNAL is not set +CONFIG_CLOCK_REF_FREQ=8000000 +CONFIG_STM32F0_TRIM=16 +# CONFIG_STM32_USB_PA11_PA12 is not set +# CONFIG_STM32_SERIAL_USART1 is not set +# CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 is not set +# CONFIG_STM32_SERIAL_USART2 is not set +# CONFIG_STM32_SERIAL_USART2_ALT_PA15_PA14 is not set +# CONFIG_STM32_CANBUS_PA11_PA12 is not set +# CONFIG_STM32_CANBUS_PA11_PB9 is not set +CONFIG_STM32_MMENU_CANBUS_PB8_PB9=y +# CONFIG_STM32_MMENU_CANBUS_PD0_PD1 is not set +CONFIG_STM32_CANBUS_PB8_PB9=y +CONFIG_STM32_APP_START_2000=y +# CONFIG_STM32_APP_START_1000 is not set +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x6177 +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INITIAL_PINS="" +CONFIG_ENABLE_DOUBLE_RESET=y +# CONFIG_ENABLE_BUTTON is not set +CONFIG_ENABLE_LED=y +CONFIG_STATUS_LED_PIN="PC13" +CONFIG_BUILD_DEPLOYER=y +CONFIG_HAVE_CHIPID=y +CONFIG_KATAPULT_VERSION="v0.0.1-91-g604b7e5" diff --git a/firmware/boot_sht36_v2.config.old b/firmware/boot_sht36_v2.config.old new file mode 100644 index 0000000..58ae680 --- /dev/null +++ b/firmware/boot_sht36_v2.config.old @@ -0,0 +1,43 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +CONFIG_MACH_LPC176X=y +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_RPXXXX is not set +CONFIG_LPC_SELECT=y +CONFIG_BOARD_DIRECTORY="lpc176x" +CONFIG_MACH_LPC1768=y +# CONFIG_MACH_LPC1769 is not set +CONFIG_MCU="lpc1768" +CONFIG_CLOCK_FREQ=100000000 +CONFIG_FLASH_SIZE=0x80000 +CONFIG_FLASH_BOOT_ADDRESS=0x0 +CONFIG_RAM_START=0x10000000 +CONFIG_RAM_SIZE=0x7ee0 +CONFIG_STACK_SIZE=512 +CONFIG_LPC_FLASH_START_0000=y +# CONFIG_LPC_FLASH_START_4000 is not set +CONFIG_FLASH_APPLICATION_ADDRESS=0x0000 +CONFIG_LPC_USB=y +# CONFIG_LPC_SERIAL_UART0_P03_P02 is not set +# CONFIG_LPC_SERIAL_UART3_P429_P428 is not set +CONFIG_FLASH_START=0x0000 +CONFIG_LAUNCH_APP_ADDRESS=0x4000 +CONFIG_BLOCK_SIZE=64 +CONFIG_USBSERIAL=y +CONFIG_USB=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x6177 +CONFIG_USB_SERIAL_NUMBER_CHIPID=y +CONFIG_USB_SERIAL_NUMBER="12345" + +# +# USB ids +# +# end of USB ids + +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INITIAL_PINS="" +CONFIG_ENABLE_DOUBLE_RESET=y +# CONFIG_ENABLE_BUTTON is not set +# CONFIG_ENABLE_LED is not set +CONFIG_HAVE_CHIPID=y +CONFIG_KATAPULT_VERSION="v0.0.1-91-g604b7e5" diff --git a/firmware/btt_mmb.CAN b/firmware/btt_mmb.CAN new file mode 100644 index 0000000..9fff607 --- /dev/null +++ b/firmware/btt_mmb.CAN @@ -0,0 +1,122 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +CONFIG_MACH_STM32=y +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="stm32" +CONFIG_MCU="stm32g0b1xx" +CONFIG_CLOCK_FREQ=64000000 +CONFIG_FLASH_SIZE=0x20000 +CONFIG_FLASH_BOOT_ADDRESS=0x8000000 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x24000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x8002000 +CONFIG_STM32_SELECT=y +# CONFIG_MACH_STM32F103 is not set +# CONFIG_MACH_STM32F207 is not set +# CONFIG_MACH_STM32F401 is not set +# CONFIG_MACH_STM32F405 is not set +# CONFIG_MACH_STM32F407 is not set +# CONFIG_MACH_STM32F429 is not set +# CONFIG_MACH_STM32F446 is not set +# CONFIG_MACH_STM32F765 is not set +# CONFIG_MACH_STM32F031 is not set +# CONFIG_MACH_STM32F042 is not set +# CONFIG_MACH_STM32F070 is not set +# CONFIG_MACH_STM32F072 is not set +# CONFIG_MACH_STM32G070 is not set +# CONFIG_MACH_STM32G071 is not set +# CONFIG_MACH_STM32G0B0 is not set +CONFIG_MACH_STM32G0B1=y +# CONFIG_MACH_STM32G431 is not set +# CONFIG_MACH_STM32G474 is not set +# CONFIG_MACH_STM32H723 is not set +# CONFIG_MACH_STM32H743 is not set +# CONFIG_MACH_STM32H750 is not set +# CONFIG_MACH_STM32L412 is not set +# CONFIG_MACH_N32G452 is not set +# CONFIG_MACH_N32G455 is not set +CONFIG_MACH_STM32G0=y +CONFIG_MACH_STM32G0Bx=y +CONFIG_HAVE_STM32_USBFS=y +CONFIG_HAVE_STM32_FDCANBUS=y +CONFIG_HAVE_STM32_USBCANBUS=y +CONFIG_STM32_DFU_ROM_ADDRESS=0 +CONFIG_STM32_FLASH_START_2000=y +# CONFIG_STM32_FLASH_START_0000 is not set +CONFIG_STM32_CLOCK_REF_8M=y +# CONFIG_STM32_CLOCK_REF_12M is not set +# CONFIG_STM32_CLOCK_REF_16M is not set +# CONFIG_STM32_CLOCK_REF_20M is not set +# CONFIG_STM32_CLOCK_REF_24M is not set +# CONFIG_STM32_CLOCK_REF_25M is not set +# CONFIG_STM32_CLOCK_REF_INTERNAL is not set +CONFIG_CLOCK_REF_FREQ=8000000 +CONFIG_STM32F0_TRIM=16 +# CONFIG_STM32_USB_PA11_PA12 is not set +# CONFIG_STM32_SERIAL_USART1 is not set +# CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 is not set +# CONFIG_STM32_SERIAL_USART2 is not set +# CONFIG_STM32_SERIAL_USART2_ALT_PD6_PD5 is not set +# CONFIG_STM32_SERIAL_USART3 is not set +# CONFIG_STM32_SERIAL_USART3_ALT_PD9_PD8 is not set +# CONFIG_STM32_SERIAL_USART5 is not set +# CONFIG_STM32_CANBUS_PA11_PA12 is not set +# CONFIG_STM32_CANBUS_PA11_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB8_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB12_PB13 is not set +# CONFIG_STM32_MMENU_CANBUS_PD0_PD1 is not set +CONFIG_STM32_MMENU_CANBUS_PB0_PB1=y +# CONFIG_STM32_MMENU_CANBUS_PD12_PD13 is not set +# CONFIG_STM32_MMENU_CANBUS_PC2_PC3 is not set +# CONFIG_STM32_USBCANBUS_PA11_PA12 is not set +CONFIG_STM32_CANBUS_PB0_PB1=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_WANT_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_INITIAL_PINS="" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y diff --git a/firmware/btt_mmb.CAN.old b/firmware/btt_mmb.CAN.old new file mode 100644 index 0000000..729be63 --- /dev/null +++ b/firmware/btt_mmb.CAN.old @@ -0,0 +1,67 @@ +# CONFIG_LOW_LEVEL_OPTIONS is not set +CONFIG_MACH_AVR=y +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_AVR_SELECT=y +CONFIG_BOARD_DIRECTORY="avr" +CONFIG_MACH_atmega2560=y +# CONFIG_MACH_atmega1280 is not set +# CONFIG_MACH_at90usb1286 is not set +# CONFIG_MACH_at90usb646 is not set +# CONFIG_MACH_atmega32u4 is not set +# CONFIG_MACH_atmega1284p is not set +# CONFIG_MACH_atmega644p is not set +# CONFIG_MACH_atmega328p is not set +# CONFIG_MACH_atmega328 is not set +# CONFIG_MACH_atmega168 is not set +CONFIG_MCU="atmega2560" +CONFIG_AVRDUDE_PROTOCOL="wiring" +CONFIG_CLOCK_FREQ=16000000 +CONFIG_AVR_CLKPR=-1 +CONFIG_AVR_STACK_SIZE=256 +CONFIG_AVR_WATCHDOG=y +CONFIG_SERIAL=y +CONFIG_SERIAL_BAUD_U2X=y +CONFIG_SERIAL_PORT=0 +CONFIG_SERIAL_BAUD=250000 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y diff --git a/firmware/config.manta723.CAN b/firmware/config.manta723.CAN new file mode 100644 index 0000000..729be63 --- /dev/null +++ b/firmware/config.manta723.CAN @@ -0,0 +1,67 @@ +# CONFIG_LOW_LEVEL_OPTIONS is not set +CONFIG_MACH_AVR=y +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_AVR_SELECT=y +CONFIG_BOARD_DIRECTORY="avr" +CONFIG_MACH_atmega2560=y +# CONFIG_MACH_atmega1280 is not set +# CONFIG_MACH_at90usb1286 is not set +# CONFIG_MACH_at90usb646 is not set +# CONFIG_MACH_atmega32u4 is not set +# CONFIG_MACH_atmega1284p is not set +# CONFIG_MACH_atmega644p is not set +# CONFIG_MACH_atmega328p is not set +# CONFIG_MACH_atmega328 is not set +# CONFIG_MACH_atmega168 is not set +CONFIG_MCU="atmega2560" +CONFIG_AVRDUDE_PROTOCOL="wiring" +CONFIG_CLOCK_FREQ=16000000 +CONFIG_AVR_CLKPR=-1 +CONFIG_AVR_STACK_SIZE=256 +CONFIG_AVR_WATCHDOG=y +CONFIG_SERIAL=y +CONFIG_SERIAL_BAUD_U2X=y +CONFIG_SERIAL_PORT=0 +CONFIG_SERIAL_BAUD=250000 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y diff --git a/firmware/ebb_rp2240.CAN b/firmware/ebb_rp2240.CAN new file mode 100644 index 0000000..448b041 --- /dev/null +++ b/firmware/ebb_rp2240.CAN @@ -0,0 +1,86 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +CONFIG_MACH_RPXXXX=y +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10004000 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RPXXXX_HAVE_BOOTLOADER=y +# CONFIG_RPXXXX_FLASH_START_0100 is not set +CONFIG_RPXXXX_FLASH_START_4000=y +CONFIG_RP2040_STAGE2_FILE="boot2_w25q080.S" +CONFIG_RP2040_STAGE2_CLKDIV=2 +# CONFIG_RPXXXX_USB is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +CONFIG_RPXXXX_CANBUS=y +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_WANT_LOAD_CELL_PROBE=y +CONFIG_NEED_SOS_FILTER=y +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_WANT_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_INITIAL_PINS="" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y +CONFIG_HAVE_SOFTWARE_DIVIDE_REQUIRED=y diff --git a/firmware/ebb_rp2240.CAN.old b/firmware/ebb_rp2240.CAN.old new file mode 100644 index 0000000..8d7a267 --- /dev/null +++ b/firmware/ebb_rp2240.CAN.old @@ -0,0 +1,69 @@ +# CONFIG_LOW_LEVEL_OPTIONS is not set +CONFIG_MACH_AVR=y +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_AVR_SELECT=y +CONFIG_BOARD_DIRECTORY="avr" +CONFIG_MACH_atmega2560=y +# CONFIG_MACH_atmega1280 is not set +# CONFIG_MACH_at90usb1286 is not set +# CONFIG_MACH_at90usb646 is not set +# CONFIG_MACH_atmega32u4 is not set +# CONFIG_MACH_atmega1284p is not set +# CONFIG_MACH_atmega644p is not set +# CONFIG_MACH_atmega328p is not set +# CONFIG_MACH_atmega328 is not set +# CONFIG_MACH_atmega168 is not set +CONFIG_MCU="atmega2560" +CONFIG_AVRDUDE_PROTOCOL="wiring" +CONFIG_CLOCK_FREQ=16000000 +CONFIG_AVR_CLKPR=-1 +CONFIG_AVR_STACK_SIZE=256 +CONFIG_AVR_WATCHDOG=y +CONFIG_SERIAL=y +CONFIG_SERIAL_BAUD_U2X=y +CONFIG_SERIAL_PORT=0 +CONFIG_SERIAL_BAUD=250000 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_WANT_LOAD_CELL_PROBE=y +CONFIG_NEED_SOS_FILTER=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y diff --git a/firmware/hbb.cfg b/firmware/hbb.cfg new file mode 100644 index 0000000..c9a335f --- /dev/null +++ b/firmware/hbb.cfg @@ -0,0 +1,109 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +CONFIG_MACH_RPXXXX=y +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_USBSERIAL=y +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10000100 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RP2040_HAVE_STAGE2=y +CONFIG_RPXXXX_FLASH_START_0100=y +# CONFIG_RPXXXX_FLASH_START_4000 is not set +CONFIG_RP2040_FLASH_W25Q080=y +# CONFIG_RP2040_FLASH_GENERIC_03 is not set +CONFIG_RP2040_STAGE2_FILE="boot2_w25q080.S" +CONFIG_RP2040_STAGE2_CLKDIV=2 +CONFIG_RPXXXX_USB=y +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +# CONFIG_RPXXXX_CANBUS is not set +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER_CHIPID=y +CONFIG_USB_SERIAL_NUMBER="12345" + +# +# USB ids +# +# end of USB ids + +<<<<<<< HEAD +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +======= +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_THERMOCOUPLE=y +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +<<<<<<< HEAD +CONFIG_WANT_THERMOCOUPLE=y +======= +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +<<<<<<< HEAD +======= +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_WANT_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_INITIAL_PINS="" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y +<<<<<<< HEAD +CONFIG_HAVE_SOFTWARE_DIVIDE_REQUIRED=y +======= +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 diff --git a/firmware/hbb.cfg.old b/firmware/hbb.cfg.old new file mode 100644 index 0000000..0565dcc --- /dev/null +++ b/firmware/hbb.cfg.old @@ -0,0 +1,126 @@ +<<<<<<< HEAD +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +======= +# CONFIG_LOW_LEVEL_OPTIONS is not set +CONFIG_MACH_AVR=y +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +<<<<<<< HEAD +CONFIG_MACH_RPXXXX=y +======= +# CONFIG_MACH_RPXXXX is not set +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +<<<<<<< HEAD +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_USBSERIAL=y +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10000100 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RP2040_HAVE_STAGE2=y +CONFIG_RPXXXX_FLASH_START_0100=y +# CONFIG_RPXXXX_FLASH_START_4000 is not set +CONFIG_RP2040_FLASH_W25Q080=y +# CONFIG_RP2040_FLASH_GENERIC_03 is not set +CONFIG_RP2040_STAGE2_FILE="boot2_w25q080.S" +CONFIG_RP2040_STAGE2_CLKDIV=2 +CONFIG_RPXXXX_USB=y +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +# CONFIG_RPXXXX_CANBUS is not set +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER_CHIPID=y +CONFIG_USB_SERIAL_NUMBER="12345" + +# +# USB ids +# +# end of USB ids + +======= +CONFIG_AVR_SELECT=y +CONFIG_BOARD_DIRECTORY="avr" +CONFIG_MACH_atmega2560=y +# CONFIG_MACH_atmega1280 is not set +# CONFIG_MACH_at90usb1286 is not set +# CONFIG_MACH_at90usb646 is not set +# CONFIG_MACH_atmega32u4 is not set +# CONFIG_MACH_atmega1284p is not set +# CONFIG_MACH_atmega644p is not set +# CONFIG_MACH_atmega328p is not set +# CONFIG_MACH_atmega328 is not set +# CONFIG_MACH_atmega168 is not set +CONFIG_MCU="atmega2560" +CONFIG_AVRDUDE_PROTOCOL="wiring" +CONFIG_CLOCK_FREQ=16000000 +CONFIG_AVR_CLKPR=-1 +CONFIG_AVR_STACK_SIZE=256 +CONFIG_AVR_WATCHDOG=y +CONFIG_SERIAL=y +CONFIG_SERIAL_BAUD_U2X=y +CONFIG_SERIAL_PORT=0 +CONFIG_SERIAL_BAUD=250000 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +<<<<<<< HEAD +CONFIG_HAVE_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_WANT_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_INITIAL_PINS="" +======= +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +<<<<<<< HEAD +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y +======= +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 diff --git a/firmware/host_linux.config b/firmware/host_linux.config new file mode 100644 index 0000000..8ab6fa2 --- /dev/null +++ b/firmware/host_linux.config @@ -0,0 +1,50 @@ +# CONFIG_LOW_LEVEL_OPTIONS is not set +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +CONFIG_MACH_LINUX=y +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="linux" +CONFIG_CLOCK_FREQ=50000000 +CONFIG_LINUX_SELECT=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_BMI160=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_WANT_TRIGGER_ANALOG=y +CONFIG_NEED_SOS_FILTER=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y diff --git a/firmware/octopus-pro.config b/firmware/octopus-pro.config new file mode 100644 index 0000000..31eb564 --- /dev/null +++ b/firmware/octopus-pro.config @@ -0,0 +1,136 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +CONFIG_MACH_STM32=y +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="stm32" +CONFIG_MCU="stm32h723xx" +CONFIG_CLOCK_FREQ=520000000 +CONFIG_FLASH_SIZE=0x40000 +CONFIG_FLASH_BOOT_ADDRESS=0x8000000 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x20000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x8020000 +CONFIG_STM32_SELECT=y +# CONFIG_MACH_STM32F103 is not set +# CONFIG_MACH_STM32F207 is not set +# CONFIG_MACH_STM32F401 is not set +# CONFIG_MACH_STM32F405 is not set +# CONFIG_MACH_STM32F407 is not set +# CONFIG_MACH_STM32F429 is not set +# CONFIG_MACH_STM32F446 is not set +# CONFIG_MACH_STM32F765 is not set +# CONFIG_MACH_STM32F031 is not set +# CONFIG_MACH_STM32F042 is not set +# CONFIG_MACH_STM32F070 is not set +# CONFIG_MACH_STM32F072 is not set +# CONFIG_MACH_STM32G070 is not set +# CONFIG_MACH_STM32G071 is not set +# CONFIG_MACH_STM32G0B0 is not set +# CONFIG_MACH_STM32G0B1 is not set +# CONFIG_MACH_STM32G431 is not set +# CONFIG_MACH_STM32G474 is not set +CONFIG_MACH_STM32H723=y +# CONFIG_MACH_STM32H743 is not set +# CONFIG_MACH_STM32H750 is not set +# CONFIG_MACH_STM32L412 is not set +# CONFIG_MACH_N32G452 is not set +# CONFIG_MACH_N32G455 is not set +CONFIG_MACH_STM32H7=y +CONFIG_HAVE_STM32_USBOTG=y +CONFIG_HAVE_STM32_FDCANBUS=y +CONFIG_HAVE_STM32_USBCANBUS=y +CONFIG_STM32_DFU_ROM_ADDRESS=0x1ff09800 +CONFIG_STM32_FLASH_START_20000=y +# CONFIG_STM32_FLASH_START_0000 is not set +# CONFIG_STM32_CLOCK_REF_8M is not set +# CONFIG_STM32_CLOCK_REF_12M is not set +# CONFIG_STM32_CLOCK_REF_16M is not set +# CONFIG_STM32_CLOCK_REF_20M is not set +# CONFIG_STM32_CLOCK_REF_24M is not set +CONFIG_STM32_CLOCK_REF_25M=y +# CONFIG_STM32_CLOCK_REF_INTERNAL is not set +CONFIG_CLOCK_REF_FREQ=25000000 +CONFIG_STM32F0_TRIM=16 +# CONFIG_STM32_USB_PA11_PA12 is not set +# CONFIG_STM32_SERIAL_USART1 is not set +# CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 is not set +# CONFIG_STM32_SERIAL_USART2 is not set +# CONFIG_STM32_SERIAL_USART2_ALT_PD6_PD5 is not set +# CONFIG_STM32_SERIAL_USART3 is not set +# CONFIG_STM32_SERIAL_USART3_ALT_PD9_PD8 is not set +# CONFIG_STM32_SERIAL_UART4 is not set +# CONFIG_STM32_CANBUS_PA11_PA12 is not set +# CONFIG_STM32_CANBUS_PA11_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB8_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB5_PB6 is not set +# CONFIG_STM32_MMENU_CANBUS_PB12_PB13 is not set +# CONFIG_STM32_MMENU_CANBUS_PD0_PD1 is not set +# CONFIG_STM32_MMENU_CANBUS_PB0_PB1 is not set +# CONFIG_STM32_MMENU_CANBUS_PD12_PD13 is not set +# CONFIG_STM32_MMENU_CANBUS_PC2_PC3 is not set +CONFIG_STM32_USBCANBUS_PA11_PA12=y +# CONFIG_STM32_CMENU_CANBUS_PB8_PB9 is not set +# CONFIG_STM32_CMENU_CANBUS_PB5_PB6 is not set +# CONFIG_STM32_CMENU_CANBUS_PB12_PB13 is not set +CONFIG_STM32_CMENU_CANBUS_PD0_PD1=y +# CONFIG_STM32_CMENU_CANBUS_PB0_PB1 is not set +# CONFIG_STM32_CMENU_CANBUS_PD12_PD13 is not set +# CONFIG_STM32_CMENU_CANBUS_PC2_PC3 is not set +CONFIG_STM32_CANBUS_PD0_PD1=y +CONFIG_USBCANBUS=y +CONFIG_USB=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER_CHIPID=y +CONFIG_USB_SERIAL_NUMBER="12345" + +# +# USB ids +# +# end of USB ids + +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_WANT_LOAD_CELL_PROBE=y +CONFIG_NEED_SOS_FILTER=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_INITIAL_PINS="PE11" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y diff --git a/firmware/octopus-pro.config.old b/firmware/octopus-pro.config.old new file mode 100644 index 0000000..18179dc --- /dev/null +++ b/firmware/octopus-pro.config.old @@ -0,0 +1,126 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +CONFIG_MACH_STM32=y +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="stm32" +CONFIG_MCU="stm32h723xx" +CONFIG_CLOCK_FREQ=520000000 +CONFIG_FLASH_SIZE=0x40000 +CONFIG_FLASH_BOOT_ADDRESS=0x8000000 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x20000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x8020000 +CONFIG_STM32_SELECT=y +# CONFIG_MACH_STM32F103 is not set +# CONFIG_MACH_STM32F207 is not set +# CONFIG_MACH_STM32F401 is not set +# CONFIG_MACH_STM32F405 is not set +# CONFIG_MACH_STM32F407 is not set +# CONFIG_MACH_STM32F429 is not set +# CONFIG_MACH_STM32F446 is not set +# CONFIG_MACH_STM32F765 is not set +# CONFIG_MACH_STM32F031 is not set +# CONFIG_MACH_STM32F042 is not set +# CONFIG_MACH_STM32F070 is not set +# CONFIG_MACH_STM32F072 is not set +# CONFIG_MACH_STM32G070 is not set +# CONFIG_MACH_STM32G071 is not set +# CONFIG_MACH_STM32G0B0 is not set +# CONFIG_MACH_STM32G0B1 is not set +# CONFIG_MACH_STM32G431 is not set +# CONFIG_MACH_STM32G474 is not set +CONFIG_MACH_STM32H723=y +# CONFIG_MACH_STM32H743 is not set +# CONFIG_MACH_STM32H750 is not set +# CONFIG_MACH_STM32L412 is not set +# CONFIG_MACH_N32G452 is not set +# CONFIG_MACH_N32G455 is not set +CONFIG_MACH_STM32H7=y +CONFIG_HAVE_STM32_USBOTG=y +CONFIG_HAVE_STM32_FDCANBUS=y +CONFIG_HAVE_STM32_USBCANBUS=y +CONFIG_STM32_DFU_ROM_ADDRESS=0x1ff09800 +CONFIG_STM32_FLASH_START_20000=y +# CONFIG_STM32_FLASH_START_0000 is not set +# CONFIG_STM32_CLOCK_REF_8M is not set +# CONFIG_STM32_CLOCK_REF_12M is not set +# CONFIG_STM32_CLOCK_REF_16M is not set +# CONFIG_STM32_CLOCK_REF_20M is not set +# CONFIG_STM32_CLOCK_REF_24M is not set +CONFIG_STM32_CLOCK_REF_25M=y +# CONFIG_STM32_CLOCK_REF_INTERNAL is not set +CONFIG_CLOCK_REF_FREQ=25000000 +CONFIG_STM32F0_TRIM=16 +# CONFIG_STM32_USB_PA11_PA12 is not set +# CONFIG_STM32_SERIAL_USART1 is not set +# CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 is not set +# CONFIG_STM32_SERIAL_USART2 is not set +# CONFIG_STM32_SERIAL_USART2_ALT_PD6_PD5 is not set +# CONFIG_STM32_SERIAL_USART3 is not set +# CONFIG_STM32_SERIAL_USART3_ALT_PD9_PD8 is not set +# CONFIG_STM32_SERIAL_UART4 is not set +# CONFIG_STM32_CANBUS_PA11_PA12 is not set +# CONFIG_STM32_CANBUS_PA11_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB8_PB9 is not set +# CONFIG_STM32_MMENU_CANBUS_PB12_PB13 is not set +# CONFIG_STM32_MMENU_CANBUS_PD0_PD1 is not set +# CONFIG_STM32_MMENU_CANBUS_PB0_PB1 is not set +# CONFIG_STM32_MMENU_CANBUS_PD12_PD13 is not set +# CONFIG_STM32_MMENU_CANBUS_PC2_PC3 is not set +CONFIG_STM32_USBCANBUS_PA11_PA12=y +# CONFIG_STM32_CMENU_CANBUS_PB8_PB9 is not set +# CONFIG_STM32_CMENU_CANBUS_PB12_PB13 is not set +CONFIG_STM32_CMENU_CANBUS_PD0_PD1=y +# CONFIG_STM32_CMENU_CANBUS_PB0_PB1 is not set +# CONFIG_STM32_CMENU_CANBUS_PD12_PD13 is not set +# CONFIG_STM32_CMENU_CANBUS_PC2_PC3 is not set +CONFIG_STM32_CANBUS_PD0_PD1=y +CONFIG_USBCANBUS=y +CONFIG_USB=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER_CHIPID=y +CONFIG_USB_SERIAL_NUMBER="12345" + +# +# USB ids +# +# end of USB ids + +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_THERMOCOUPLE=y +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_WANT_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_INITIAL_PINS="PE11" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y diff --git a/firmware/rp_sb2209.CAN b/firmware/rp_sb2209.CAN new file mode 100644 index 0000000..8aa58f8 --- /dev/null +++ b/firmware/rp_sb2209.CAN @@ -0,0 +1,101 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +CONFIG_MACH_RPXXXX=y +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10004000 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RPXXXX_HAVE_BOOTLOADER=y +# CONFIG_RPXXXX_FLASH_START_0100 is not set +CONFIG_RPXXXX_FLASH_START_4000=y +CONFIG_RP2040_STAGE2_FILE="boot2_w25q080.S" +CONFIG_RP2040_STAGE2_CLKDIV=2 +# CONFIG_RPXXXX_USB is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +CONFIG_RPXXXX_CANBUS=y +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +<<<<<<< HEAD +CONFIG_WANT_ADC=y +CONFIG_WANT_SPI=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_WANT_I2C=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_HARD_PWM=y +CONFIG_WANT_BUTTONS=y +CONFIG_WANT_TMCUART=y +CONFIG_WANT_NEOPIXEL=y +CONFIG_WANT_PULSE_COUNTER=y +CONFIG_WANT_ST7920=y +CONFIG_WANT_HD44780=y +======= +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_THERMOCOUPLE=y +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_WANT_ADXL345=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_MPU9250=y +CONFIG_WANT_ICM20948=y +<<<<<<< HEAD +CONFIG_WANT_THERMOCOUPLE=y +======= +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_SENSOR_ANGLE=y +<<<<<<< HEAD +======= +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INLINE_STEPPER_HACK=y +CONFIG_HAVE_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_WANT_STEPPER_OPTIMIZED_BOTH_EDGE=y +CONFIG_INITIAL_PINS="!gpio6" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y +<<<<<<< HEAD +CONFIG_HAVE_SOFTWARE_DIVIDE_REQUIRED=y +======= +>>>>>>> 7bdc831c64e9cd32031a268cdce0910c4c7f23c9 diff --git a/firmware/rp_sb2209.CAN.old b/firmware/rp_sb2209.CAN.old new file mode 100644 index 0000000..ed8166c --- /dev/null +++ b/firmware/rp_sb2209.CAN.old @@ -0,0 +1,70 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +CONFIG_MACH_RPXXXX=y +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="rp2040" +CONFIG_MCU="rp2040" +CONFIG_CLOCK_FREQ=12000000 +CONFIG_FLASH_SIZE=0x200000 +CONFIG_FLASH_BOOT_ADDRESS=0x10000100 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x42000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x10004000 +CONFIG_RPXXXX_SELECT=y +CONFIG_MACH_RP2040=y +# CONFIG_MACH_RP2350 is not set +CONFIG_RPXXXX_HAVE_BOOTLOADER=y +# CONFIG_RPXXXX_FLASH_START_0100 is not set +CONFIG_RPXXXX_FLASH_START_4000=y +CONFIG_RP2040_STAGE2_FILE="boot2_w25q080.S" +CONFIG_RP2040_STAGE2_CLKDIV=2 +# CONFIG_RPXXXX_USB is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_0_1 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_12_13 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_16_17 is not set +# CONFIG_RPXXXX_SERIAL_UART0_PINS_28_29 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_4_5 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_8_9 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_20_21 is not set +# CONFIG_RPXXXX_SERIAL_UART1_PINS_24_25 is not set +CONFIG_RPXXXX_CANBUS=y +# CONFIG_RPXXXX_USBCANBUS is not set +CONFIG_RPXXXX_CANBUS_GPIO_RX=4 +CONFIG_RPXXXX_CANBUS_GPIO_TX=5 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_SENSORS=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INITIAL_PINS="!gpio6" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_STEPPER_BOTH_EDGE=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y +CONFIG_INLINE_STEPPER_HACK=y diff --git a/firmware/sht36_v2.CAN b/firmware/sht36_v2.CAN new file mode 100644 index 0000000..d007b66 --- /dev/null +++ b/firmware/sht36_v2.CAN @@ -0,0 +1,105 @@ +CONFIG_LOW_LEVEL_OPTIONS=y +# CONFIG_MACH_AVR is not set +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +CONFIG_MACH_STM32=y +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_BOARD_DIRECTORY="stm32" +CONFIG_MCU="stm32f072xb" +CONFIG_CLOCK_FREQ=48000000 +CONFIG_FLASH_SIZE=0x20000 +CONFIG_FLASH_BOOT_ADDRESS=0x8000000 +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=0x4000 +CONFIG_STACK_SIZE=512 +CONFIG_FLASH_APPLICATION_ADDRESS=0x8002000 +CONFIG_STM32_SELECT=y +# CONFIG_MACH_STM32F103 is not set +# CONFIG_MACH_STM32F207 is not set +# CONFIG_MACH_STM32F401 is not set +# CONFIG_MACH_STM32F405 is not set +# CONFIG_MACH_STM32F407 is not set +# CONFIG_MACH_STM32F429 is not set +# CONFIG_MACH_STM32F446 is not set +# CONFIG_MACH_STM32F765 is not set +# CONFIG_MACH_STM32F031 is not set +# CONFIG_MACH_STM32F042 is not set +# CONFIG_MACH_STM32F070 is not set +CONFIG_MACH_STM32F072=y +# CONFIG_MACH_STM32G070 is not set +# CONFIG_MACH_STM32G071 is not set +# CONFIG_MACH_STM32G0B0 is not set +# CONFIG_MACH_STM32G0B1 is not set +# CONFIG_MACH_STM32G431 is not set +# CONFIG_MACH_STM32G474 is not set +# CONFIG_MACH_STM32H723 is not set +# CONFIG_MACH_STM32H743 is not set +# CONFIG_MACH_STM32H750 is not set +# CONFIG_MACH_STM32L412 is not set +# CONFIG_MACH_N32G452 is not set +# CONFIG_MACH_N32G455 is not set +CONFIG_MACH_STM32F0=y +CONFIG_MACH_STM32F0x2=y +CONFIG_HAVE_STM32_USBFS=y +CONFIG_HAVE_STM32_CANBUS=y +CONFIG_HAVE_STM32_USBCANBUS=y +CONFIG_STM32_DFU_ROM_ADDRESS=0 +CONFIG_STM32_FLASH_START_2000=y +# CONFIG_STM32_FLASH_START_1000 is not set +# CONFIG_STM32_FLASH_START_4000 is not set +# CONFIG_STM32_FLASH_START_0000 is not set +CONFIG_ARMCM_RAM_VECTORTABLE=y +CONFIG_STM32_CLOCK_REF_8M=y +# CONFIG_STM32_CLOCK_REF_12M is not set +# CONFIG_STM32_CLOCK_REF_16M is not set +# CONFIG_STM32_CLOCK_REF_20M is not set +# CONFIG_STM32_CLOCK_REF_24M is not set +# CONFIG_STM32_CLOCK_REF_25M is not set +# CONFIG_STM32_CLOCK_REF_INTERNAL is not set +CONFIG_CLOCK_REF_FREQ=8000000 +CONFIG_STM32F0_TRIM=16 +# CONFIG_STM32_USB_PA11_PA12 is not set +# CONFIG_STM32_SERIAL_USART1 is not set +# CONFIG_STM32_SERIAL_USART1_ALT_PB7_PB6 is not set +# CONFIG_STM32_SERIAL_USART2 is not set +# CONFIG_STM32_SERIAL_USART2_ALT_PA15_PA14 is not set +# CONFIG_STM32_CANBUS_PA11_PA12 is not set +# CONFIG_STM32_CANBUS_PA11_PB9 is not set +CONFIG_STM32_MMENU_CANBUS_PB8_PB9=y +# CONFIG_STM32_MMENU_CANBUS_PD0_PD1 is not set +# CONFIG_STM32_USBCANBUS_PA11_PA12 is not set +CONFIG_STM32_CANBUS_PB8_PB9=y +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_SENSORS=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANSERIAL=y +CONFIG_CANBUS=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_CANBUS_FILTER=y +CONFIG_INITIAL_PINS="!PC13" +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_HAVE_CHIPID=y +CONFIG_HAVE_STEPPER_BOTH_EDGE=y +CONFIG_HAVE_BOOTLOADER_REQUEST=y +CONFIG_INLINE_STEPPER_HACK=y diff --git a/firmware/sht36_v2.CAN.old b/firmware/sht36_v2.CAN.old new file mode 100644 index 0000000..377a943 --- /dev/null +++ b/firmware/sht36_v2.CAN.old @@ -0,0 +1,55 @@ +# CONFIG_LOW_LEVEL_OPTIONS is not set +CONFIG_MACH_AVR=y +# CONFIG_MACH_ATSAM is not set +# CONFIG_MACH_ATSAMD is not set +# CONFIG_MACH_LPC176X is not set +# CONFIG_MACH_STM32 is not set +# CONFIG_MACH_HC32F460 is not set +# CONFIG_MACH_RPXXXX is not set +# CONFIG_MACH_PRU is not set +# CONFIG_MACH_AR100 is not set +# CONFIG_MACH_LINUX is not set +# CONFIG_MACH_SIMU is not set +CONFIG_AVR_SELECT=y +CONFIG_BOARD_DIRECTORY="avr" +CONFIG_MACH_atmega2560=y +# CONFIG_MACH_atmega1280 is not set +# CONFIG_MACH_at90usb1286 is not set +# CONFIG_MACH_at90usb646 is not set +# CONFIG_MACH_atmega32u4 is not set +# CONFIG_MACH_atmega1284p is not set +# CONFIG_MACH_atmega644p is not set +# CONFIG_MACH_atmega328p is not set +# CONFIG_MACH_atmega328 is not set +# CONFIG_MACH_atmega168 is not set +CONFIG_MCU="atmega2560" +CONFIG_AVRDUDE_PROTOCOL="wiring" +CONFIG_CLOCK_FREQ=16000000 +CONFIG_AVR_CLKPR=-1 +CONFIG_AVR_STACK_SIZE=256 +CONFIG_AVR_WATCHDOG=y +CONFIG_SERIAL=y +CONFIG_SERIAL_BAUD_U2X=y +CONFIG_SERIAL_PORT=0 +CONFIG_SERIAL_BAUD=250000 +CONFIG_USB_VENDOR_ID=0x1d50 +CONFIG_USB_DEVICE_ID=0x614e +CONFIG_USB_SERIAL_NUMBER="12345" +CONFIG_WANT_GPIO_BITBANGING=y +CONFIG_WANT_DISPLAYS=y +CONFIG_WANT_SENSORS=y +CONFIG_WANT_LIS2DW=y +CONFIG_WANT_LDC1612=y +CONFIG_WANT_HX71X=y +CONFIG_WANT_ADS1220=y +CONFIG_WANT_SOFTWARE_I2C=y +CONFIG_WANT_SOFTWARE_SPI=y +CONFIG_NEED_SENSOR_BULK=y +CONFIG_CANBUS_FREQUENCY=1000000 +CONFIG_HAVE_GPIO=y +CONFIG_HAVE_GPIO_ADC=y +CONFIG_HAVE_GPIO_SPI=y +CONFIG_HAVE_GPIO_I2C=y +CONFIG_HAVE_GPIO_HARD_PWM=y +CONFIG_HAVE_STRICT_TIMING=y +CONFIG_INLINE_STEPPER_HACK=y diff --git a/firmware/update_fw.sh b/firmware/update_fw.sh new file mode 100755 index 0000000..360702c --- /dev/null +++ b/firmware/update_fw.sh @@ -0,0 +1,320 @@ +#!/usr/bin/env bash +# Сборка и прошивка Klipper на всех MCU принтера leo-voron: +# host — linux-процесс klipper_mcu на CB2 (/usr/local/bin/klipper_mcu, сервис klipper-mcu) +# mcu — Octopus Pro 1.1 (stm32h723, USB-CAN bridge; прошивается по USB через katapult) +# toolhead — EBB SB2209 (rp2040; прошивается по CAN через katapult) +# +# Использование: +# update_fw.sh [-h] [--build-only|--no-build] [--force] [host|mcu|toolhead ...] +# без целей — все три +# --build-only — только собрать прошивки в ~/firmware, ничего не прошивать +# --no-build — не собирать, прошить уже собранные ~/firmware/<цель>_klipper.{bin,elf} +# --force — не останавливаться, если Moonraker недоступен для проверки печати +# +# Исходники Klipper НЕ обновляются (это делает Moonraker Update Manager). +# Скрипт интерактивный: пароль sudo спрашивается один раз в начале. +# +# Полезные команды: +# make menuconfig KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/octopus-pro.config +# make flash FLASH_DEVICE=0483:df11 # stm32 в DFU +# python3 ~/katapult/scripts/flashtool.py -i can0 -q # список узлов на CAN +# python3 ~/katapult/scripts/flashtool.py -i can0 -u -r # запрос бутлоадера +# make flash FLASH_DEVICE=/dev/serial/by-id/usb-Klipper_rp2040_45474E621A87A43A-if00 KCONFIG_CONFIG=.../hbb.cfg +# +# Старые тулхеды (UUID): +# rp_sb2209 = 350f10596216 +# sht36_v2 = 8ce295109ef0 + +set -Eeuo pipefail + +# ---------- Константы ---------- +MOONRAKER="http://127.0.0.1:7125" +KLIPPER="$HOME/klipper" +KATAPULT="$HOME/katapult/scripts/flashtool.py" +CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +OUT_DIR="$HOME/firmware" +KLIPPY_LOG="$HOME/printer_data/logs/klippy.log" +CAN_IF="can0" +JOBS=4 + +MCU_UUID="afcf80281237" +MCU_CFG="octopus-pro.config" +KATAPULT_SERIAL_GLOB='/dev/serial/by-id/usb-katapult_stm32h723xx_*' + +TOOLHEAD_UUID="d7e70bd38059" +TOOLHEAD_CFG="ebb_rp2240.CAN" + +HOST_CFG="host_linux.config" +HOST_BIN="/usr/local/bin/klipper_mcu" + +ALL_TARGETS=(host mcu toolhead) + +# ---------- Разбор аргументов ---------- +BUILD_ONLY=0 +NO_BUILD=0 +FORCE=0 +TARGETS=() +for arg in "$@"; do + case "$arg" in + -h|--help) sed -n '2,16p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;; + --build-only) BUILD_ONLY=1 ;; + --no-build) NO_BUILD=1 ;; + --force) FORCE=1 ;; + host|mcu|toolhead) TARGETS+=("$arg") ;; + *) echo "Неизвестный аргумент: $arg (см. -h)" >&2; exit 2 ;; + esac +done +[ ${#TARGETS[@]} -eq 0 ] && TARGETS=("${ALL_TARGETS[@]}") +[ "$BUILD_ONLY" = 1 ] && [ "$NO_BUILD" = 1 ] && { echo "--build-only и --no-build несовместимы" >&2; exit 2; } +want() { local t; for t in "${TARGETS[@]}"; do [ "$t" = "$1" ] && return 0; done; return 1; } + +# ---------- Лог и трапы ---------- +mkdir -p "$OUT_DIR" +LOG="$OUT_DIR/update_fw-$(date +%Y%m%d-%H%M).log" +exec > >(trap '' INT; exec tee -a "$LOG") 2>&1 +START_TS=$(date +%s) +STAGE="инициализация" +KLIPPER_STOPPED=0 + +on_err() { + echo + echo "!!! ОШИБКА на этапе: $STAGE (лог: $LOG)" >&2 +} +on_exit() { + local rc=$? + rm -rf "${BUILD_TMP:-}" + if [ "$KLIPPER_STOPPED" = 1 ]; then + echo; echo "=== Запуск klipper ===" + sudo systemctl start klipper || echo "!!! Не удалось запустить klipper — запустите вручную: sudo systemctl start klipper" >&2 + fi + [ $rc -ne 0 ] && echo "Завершено с ошибкой (код $rc)." + exit $rc +} +trap on_err ERR +trap on_exit EXIT +trap 'exit 130' INT + +section() { echo; echo "=== $* ==="; } +die() { echo "!!! [$STAGE] $*" >&2; exit 1; } + +# Ждать, пока команда-условие не вернёт 0 (таймаут в секундах) +wait_for() { + local timeout=$1 msg=$2; shift 2 + local deadline=$((SECONDS + timeout)) + while [ "$SECONDS" -lt "$deadline" ]; do + if "$@" >/dev/null 2>&1; then return 0; fi + sleep 1 + done + echo "!!! Таймаут ($timeout с): $msg" >&2 + return 1 +} +# Klipper отвечает на запрос UUID только пока ему не назначен node id (canserial.c), +# поэтому -q годится лишь для узлов, только что перезагруженных после прошивки. +can_has_uuid() { local out; out=$(python3 "$KATAPULT" -i "$CAN_IF" -q 2>/dev/null) || return 1; grep -q "$1" <<< "$out"; } +katapult_serial() { local d; for d in $KATAPULT_SERIAL_GLOB; do [ -e "$d" ] && { echo "$d"; return 0; }; done; return 1; } +klippy_state() { curl -s --max-time 5 "$MOONRAKER/printer/info" | jq -r '.result.state // empty' 2>/dev/null; } +klippy_ready() { [ "$(klippy_state)" = "ready" ]; } +mcu_versions() { + curl -s --max-time 5 "$MOONRAKER/printer/objects/query?mcu&mcu%20EBBCan&mcu%20host" \ + | jq -r '.result.status | to_entries[] | "\(.key)\t\(.value.mcu_version // "?")\t\(.value.mcu_constants.MCU // "?")"' 2>/dev/null \ + || echo "недоступно" +} + +# ---------- Preflight ---------- +STAGE="предварительные проверки" +section "Preflight" +echo "Цели: ${TARGETS[*]} build-only=$BUILD_ONLY no-build=$NO_BUILD лог: $LOG" + +[ -d "$KLIPPER" ] || die "Нет исходников Klipper: $KLIPPER" +[ -f "$KATAPULT" ] || die "Нет katapult flashtool: $KATAPULT" +want host && { [ -f "$CONFIG_DIR/$HOST_CFG" ] || die "Нет конфига $CONFIG_DIR/$HOST_CFG"; } +want mcu && { [ -f "$CONFIG_DIR/$MCU_CFG" ] || die "Нет конфига $CONFIG_DIR/$MCU_CFG"; } +want toolhead && { [ -f "$CONFIG_DIR/$TOOLHEAD_CFG" ] || die "Нет конфига $CONFIG_DIR/$TOOLHEAD_CFG"; } + +KLIPPER_VER=$(git -C "$KLIPPER" describe --always --tags --long --dirty 2>/dev/null || echo unknown) +echo "Klipper в $KLIPPER: $KLIPPER_VER" + +# Артефакт цели: ~/firmware/<цель>_klipper. (симлинк на <цель>-<версия>.) +artifact() { case "$1" in host) echo "$OUT_DIR/host_klipper.elf" ;; *) echo "$OUT_DIR/$1_klipper.bin" ;; esac; } + +if [ "$NO_BUILD" = 1 ]; then + echo "Без сборки — используются готовые прошивки:" + for t in "${TARGETS[@]}"; do + f=$(artifact "$t") + [ -s "$f" ] || die "Нет готовой прошивки $f (соберите: $0 --build-only $t)" + real=$(readlink -f "$f") + echo " $t: $(basename "$real") ($(stat -c %s "$real") байт)" + case "$(basename "$real")" in + *"-${KLIPPER_VER}."*) ;; + *) echo " !!! $t: прошивка собрана не из текущего $KLIPPER_VER" ;; + esac + done +fi + +BEFORE="" +if [ "$BUILD_ONLY" = 0 ]; then + if want mcu || want toolhead; then + ip -br link show "$CAN_IF" 2>/dev/null | grep -q " UP " || die "$CAN_IF не поднят" + fi + + # Печать не должна идти + KSTATE=$(klippy_state || true) + PRINT_STATE=$(curl -s --max-time 5 "$MOONRAKER/printer/objects/query?print_stats" \ + | jq -r '.result.status.print_stats.state // empty' 2>/dev/null || true) + if [ -z "$KSTATE" ]; then + if [ "$FORCE" = 1 ]; then + echo "Moonraker недоступен, проверка печати пропущена (--force)" + else + die "Moonraker недоступен — не могу проверить, идёт ли печать (--force чтобы пропустить)" + fi + elif [ -z "$PRINT_STATE" ]; then + echo "klippy в состоянии '$KSTATE' (не ready) — печать не идёт, продолжаю" + else + echo "print_stats.state = $PRINT_STATE" + case "$PRINT_STATE" in + printing|paused) die "Идёт печать ($PRINT_STATE) — прошивка отменена" ;; + esac + fi + + echo "Версии MCU до обновления:" + BEFORE=$(mcu_versions); echo "$BEFORE" | sed 's/^/ /' + + # Пароль sudo — один раз, до остановки сервисов + sudo -v || die "Нужны права sudo" +fi + +# ---------- Сборка ---------- +BUILD_TMP=$(mktemp -d) +build() { # build <цель> <конфиг> <артефакт: bin|elf> + local name=$1 ext=$3 + STAGE="сборка $name" + section "Сборка $name ($2)" + # Собираем из копии: olddefconfig переписывает конфиг и создаёт <конфиг>.old, + # а файлы в репозитории должны оставаться нетронутыми + local cfg="$BUILD_TMP/$2" + cp "$CONFIG_DIR/$2" "$cfg" + make -C "$KLIPPER" clean KCONFIG_CONFIG="$cfg" >/dev/null + make -C "$KLIPPER" olddefconfig KCONFIG_CONFIG="$cfg" + make -C "$KLIPPER" -j"$JOBS" KCONFIG_CONFIG="$cfg" + local src="$KLIPPER/out/klipper.$ext" + [ -s "$src" ] || die "Сборка $name не дала $src" + local dst="$OUT_DIR/${name}-${KLIPPER_VER}.$ext" + cp "$src" "$dst" + ln -sfn "$(basename "$dst")" "$(artifact "$name")" + echo "-> $dst ($(stat -c %s "$dst") байт)" +} + +if [ "$NO_BUILD" = 0 ]; then + want mcu && build mcu "$MCU_CFG" bin + want toolhead && build toolhead "$TOOLHEAD_CFG" bin + want host && build host "$HOST_CFG" elf +fi + +if [ "$BUILD_ONLY" = 1 ]; then + section "Готово (только сборка)" + ls -l "$OUT_DIR"/*_klipper.* 2>/dev/null + exit 0 +fi + +# ---------- Прошивка ---------- +STAGE="остановка klipper" +section "Остановка klipper" +sudo systemctl stop klipper +KLIPPER_STOPPED=1 + +if want host; then + STAGE="прошивка host MCU" + section "Прошивка host (klipper-mcu)" + # flash-linux.sh копирует /klipper.elf в /usr/local/bin/klipper_mcu и перезапускает klipper-mcu. + # Подсовываем ему каталог с артефактом из ~/firmware, а не out/ (там может быть сборка другой цели) + mkdir -p "$BUILD_TMP/host" + cp "$(artifact host)" "$BUILD_TMP/host/klipper.elf" + HOST_PID_OLD=$(systemctl show -p ExecMainPID --value klipper-mcu) + sudo "$KLIPPER/scripts/flash-linux.sh" "$BUILD_TMP/host" + [ "$(stat -c %Y "$HOST_BIN")" -ge "$START_TS" ] || die "$HOST_BIN не обновился" + host_restarted() { + [ "$(systemctl show -p ExecMainPID --value klipper-mcu)" != "$HOST_PID_OLD" ] \ + && [ "$(systemctl show -p SubState --value klipper-mcu)" = "running" ] && [ -e /tmp/klipper_host_mcu ] + } + if ! wait_for 10 "klipper-mcu не перезапустился (PID $HOST_PID_OLD)" host_restarted; then + journalctl -u klipper-mcu -n 8 --no-pager -o cat || true + die "klipper-mcu не работает после прошивки (см. journalctl -u klipper-mcu)" + fi + # Убедиться, что процесс не падает в цикле перезапуска (Restart=always) + sleep 3 + [ "$(systemctl show -p SubState --value klipper-mcu)" = "running" ] \ + || { journalctl -u klipper-mcu -n 8 --no-pager -o cat || true; die "klipper-mcu перезапускается в цикле"; } + echo "klipper-mcu перезапущен (PID $HOST_PID_OLD -> $(systemctl show -p ExecMainPID --value klipper-mcu)), $HOST_BIN обновлён" +fi + +if want mcu; then + STAGE="прошивка Octopus Pro" + section "Прошивка mcu (Octopus Pro, uuid $MCU_UUID)" + python3 "$KATAPULT" -i "$CAN_IF" -u "$MCU_UUID" -r + wait_for 20 "не появился katapult serial ($KATAPULT_SERIAL_GLOB). Проверьте USB или перезагрузите плату" katapult_serial + DEV=$(katapult_serial) + echo "katapult serial: $DEV" + sleep 1 # порт может быть ещё не готов сразу после появления симлинка + python3 "$KATAPULT" -d "$DEV" -f "$(artifact mcu)" + # После прошивки плата перезагружается в Klipper и снова поднимает USB-CAN мост + wait_for 30 "Octopus не вернулся на $CAN_IF после прошивки" can_has_uuid "$MCU_UUID" + echo "Octopus снова на $CAN_IF" +fi + +if want toolhead; then + STAGE="прошивка тулхеда" + section "Прошивка toolhead (EBB SB2209, uuid $TOOLHEAD_UUID)" + # flashtool сам отправляет запрос бутлоадера по UUID и заливает прошивку + python3 "$KATAPULT" -i "$CAN_IF" -u "$TOOLHEAD_UUID" -f "$(artifact toolhead)" + wait_for 30 "тулхед не вернулся на $CAN_IF после прошивки" can_has_uuid "$TOOLHEAD_UUID" + echo "Тулхед снова на $CAN_IF" +fi + +section "Узлы на $CAN_IF" +python3 "$KATAPULT" -i "$CAN_IF" -q || true + +# ---------- Запуск и проверка ---------- +STAGE="запуск klipper" +section "Запуск klipper" +sudo systemctl start klipper +KLIPPER_STOPPED=0 + +STAGE="проверка после прошивки" +if wait_for 90 "klippy не перешёл в ready" klippy_ready; then + echo "klippy: ready" +else + echo "klippy state: $(klippy_state)" + curl -s --max-time 5 "$MOONRAKER/printer/info" | jq -r '.result.state_message // empty' 2>/dev/null || true + echo "--- хвост $KLIPPY_LOG ---" + tail -n 40 "$KLIPPY_LOG" 2>/dev/null || true +fi + +section "Версии" +KLIPPY_VER=$(curl -s --max-time 5 "$MOONRAKER/printer/info" | jq -r '.result.software_version // "?"' 2>/dev/null || echo "?") +echo "klippy (хост): $KLIPPY_VER" +# klippy считает untracked-файлы в klippy/extras (autotune, Happy-Hare) как -dirty, прошивки — нет +KLIPPY_VER=${KLIPPY_VER%-dirty} +AFTER=$(mcu_versions) +MISMATCH=0 +if [ -z "$AFTER" ] || [ "$AFTER" = "недоступно" ]; then + echo "!!! Версии MCU недоступны (klippy не ready)"; MISMATCH=1 +else + printf '%-12s %-32s %s\n' "MCU" "было" "стало" + while IFS=$'\t' read -r name ver _; do + old=$(printf '%s\n' "$BEFORE" | awk -F'\t' -v n="$name" '$1==n{print $2}') + printf '%-12s %-32s %s\n' "$name" "${old:-?}" "$ver" + [ "$ver" = "$KLIPPY_VER" ] || { echo "!!! $name: версия $ver != klippy $KLIPPY_VER"; MISMATCH=1; } + done <<< "$AFTER" +fi + +# Только строки после последнего старта klippy, чтобы не ловить старые ошибки +if tac "$KLIPPY_LOG" 2>/dev/null | sed '/^Start printer at/q' | grep -E "Command format mismatch|Protocol error|Lost communication" | tail -5 | grep .; then + echo "!!! В klippy.log есть ошибки протокола (см. выше)"; MISMATCH=1 +fi + +if [ "$MISMATCH" = 0 ]; then + echo; echo "Готово: все MCU на $KLIPPY_VER. Дальше: QUAD_GANTRY_LEVEL и проверить TAP/z_offset." +else + echo; echo "Есть расхождения — проверьте вывод выше; при необходимости FIRMWARE_RESTART или повторить: $0 <цель>" + exit 1 +fi diff --git a/firmware/update_fw.sh.old b/firmware/update_fw.sh.old new file mode 100755 index 0000000..f595d14 --- /dev/null +++ b/firmware/update_fw.sh.old @@ -0,0 +1,40 @@ +#!/bin/bash + +mkdir -p ~/firmware + +sudo service klipper stop + +cd ~/klipper +make clean +#make menuconfig KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/config.manta723.CAN +make -j4 KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/octopus-pro.config +#make flash FLASH_DEVICE=0483:df11 +mv ~/klipper/out/klipper.bin ~/firmware/octopus_klipper.bin + +make clean +#make menuconfig KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/rp_sb2209.CAN +make -j4 KCONFIG_CONFIG=/home/biqu/printer_data/config/firmware/rp_sb2209.CAN +mv ~/klipper/out/klipper.bin ~/firmware/toolhead_klipper.bin + +cd ~/katapult/scripts +# Update MCU Octopus Pro +echo "Start update MCU Octopus Pro" +#echo "" +#python3 flash_can.py -i can0 -u 6c3c86ee0b29 -f ~/firmware/octopus_klipper.bin +python3 ~/katapult/scripts/flashtool.py -i can0 -u afcf80281237 -r +python3 flash_can.py -f ~/firmware/octopus_klipper.bin -d /dev/serial/by-id/usb-katapult_stm32h723xx_320006001751313431393536-if00 +sleep 2 +#read -p "MCU Manta M5P firmware flashed, please check above for any errors. Press [Enter] to continue, or [Ctrl+C] to abort" +#echo "Finish update MCU octopus" + +# Update Toolhead MCU +echo "Start update Toolhead MCU" +#echo "" +python3 flash_can.py -i can0 -u 350f10596216 -f ~/firmware/toolhead_klipper.bin +sleep 2 +#read -p "MCU EBB36 firmware flashed, please check above for any errors. Press [Enter] to continue, or [Ctrl+C] to abort" +#echo "Finish update MCU EBB36" + +#echo "" + +sudo service klipper start diff --git a/hbb.cfg b/hbb.cfg new file mode 100644 index 0000000..e103084 --- /dev/null +++ b/hbb.cfg @@ -0,0 +1,124 @@ +[mcu HBB] +serial: /dev/serial/by-id/usb-Klipper_rp2040_45474E621A87A43A-if00 + +[neopixel HBB_LED] +pin: HBB: gpio20 +chain_count: 7 +color_order: GRB +initial_RED: 0.4 +initial_GREEN: 0.4 +initial_BLUE: 0.4 + +[gcode_macro _hbb_varible] +variable_in_progress_key_1: False +variable_in_progress_key_2: False +variable_in_progress_key_3: False +variable_in_progress_key_4: False +variable_in_progress_key_5: False +variable_in_progress_key_6: False +variable_in_progress_key_7: False +variable_status: { + 'ready': {'r': 0.4, 'g': 0.4, 'b': 0.4, 'w': 0.0}, + 'in_progress': {'r': 0.0, 'g': 0.04, 'b': 0.0, 'w': 0.0}, + 'busy': {'r': 0.4, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'prepare': {'r': 0.4, 'g': 0.4, 'b': 0.0, 'w': 0.0}, + 'disabled': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0} + } +variable_num_count: 7 +gcode: + +[gcode_macro _set_status] +gcode: + {% set key_num = params.KEY_NUM|int %} + {% set status = params.STATUS|string %} + {% set led = printer["gcode_macro _hbb_varible"]['status'][status] %} + SET_LED LED=HBB_LED RED={led.r} GREEN={led.g} BLUE={led.b} INDEX={key_num} + + +[gcode_macro _default_release] +gcode: + {% set key_num = params.KEY_NUM|int %} + {% set macro = params.MACRO|string %} + {% set in_progress = printer["gcode_macro _hbb_varible"]['in_progress_key_{}'.format(key_num)] %} + {% if in_progress == False %} + SET_GCODE_VARIABLE MACRO=_hbb_varible VARIABLE=in_progress_key_{key_num} VALUE=True + _set_status KEY_NUM={key_num} STATUS=in_progress + {macro} + _set_status KEY_NUM={key_num} STATUS=ready + SET_GCODE_VARIABLE MACRO=_hbb_varible VARIABLE=in_progress_key_{key_num} VALUE=False + {% endif %} + + +#[delayed_gcode init_hbb] +#initial_duration: 1 +#gcode: + #{% set hbb_varible = printer["gcode_macro _hbb_varible"] %} + #{% set num_count = printer["gcode_macro _hbb_varible"].num_count | int %} + #{% for key_index in range(1, num_count+1) %} + #_set_status KEY_NUM=key_index STATUS=ready + #{% endfor %} + + + + +[gcode_button hbb_key_1] +pin: HBB: gpio25 +press_gcode: +release_gcode: + {% set key_num = 1 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_1 %} + _default_release KEY_NUM={key_num} MACRO="LOAD_FILAMENT" + + +[gcode_button hbb_key_2] +pin: HBB: gpio26 +press_gcode: +release_gcode: + {% set key_num = 2 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_2 %} + _default_release KEY_NUM={key_num} MACRO="UNLOAD_FILAMENT" + + +[gcode_button hbb_key_3] +pin: HBB: gpio27 +press_gcode: +release_gcode: + {% set key_num = 3 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_3 %} + _set_status KEY_NUM={key_num} STATUS=disabled + + +[gcode_button hbb_key_4] +pin: HBB: gpio19 +press_gcode: +release_gcode: + {% set key_num = 4 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_4 %} + _default_release KEY_NUM={key_num} MACRO="G32" + + +[gcode_button hbb_key_5] +pin: HBB: gpio18 +press_gcode: +release_gcode: + {% set key_num = 5 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_5 %} + _set_status KEY_NUM={key_num} STATUS=disabled + +[gcode_button hbb_key_6] +pin: HBB: gpio13 +press_gcode: +release_gcode: + {% set key_num = 6 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_6 %} + _default_release KEY_NUM={key_num} MACRO="PARKFRONT" + +[gcode_button hbb_key_7] +pin: HBB: gpio12 +press_gcode: +release_gcode: + {% set key_num = 7 %} + {% set in_progress = printer["gcode_macro _hbb_varible"].in_progress_key_7 %} + _default_release KEY_NUM={key_num} MACRO="PARKCENTER" + + diff --git a/macros/calibrate_flow.cfg b/macros/calibrate_flow.cfg new file mode 100644 index 0000000..fd1f705 --- /dev/null +++ b/macros/calibrate_flow.cfg @@ -0,0 +1,262 @@ +######################################### +###### FLOW MULTIPLIER CALIBRATION ###### +######################################### +# Written by Frix_x#0161 # +# @version: 1.5 + +# CHANGELOG: +# v1.5: moved the install notes into a proper markdown file in: doc > features > flow_calibration.md +# v1.4: fix issue when extrude_factor is != 1 +# v1.3: fix the logging +# v1.2: fix for those using absolute extrusion that leads to an error +# v1.1: added part cooling fan control and some speed optimizations +# v1.0: first flow calibration macro + +# ------------------------------------------------------------------------------------------------------------------------- +# If you want to use it into your own config, please install it as a standalone macro as described in the +# installation section of this file: doc > features > flow_calibration.md +# ------------------------------------------------------------------------------------------------------------------------- + +### What is it ? ### +# The main reason for this set of macros is to get a filament and slicer agnostic way to calibrate the flow extrusion multiplier. +# The goal is to make it easy to set, share and use it. + +# This macro is parametric and most of the values can be adjusted with their respective input parameters. +# It can be called without any parameters - in which case the default values would be used - or with any combination of parameters as desired. + +# Feel free to ping me on Discord (Frix_x#0161) if you need help or have any comments to improve it :) + +# https://github.com/yomgui1/klipper-voron-config/blob/main/doc/features/flow_calibration.md?ysclid=lzuo22xrfl138875688 + +# =========================================================================================================== +# DO NOT MODIFY THOSE VARIABLES (they are used internaly by the flow calibration macro) +[gcode_macro _FLOW_CALIB_VARIABLES] +variable_last_shell_thickness: 0.0 +variable_last_evalue: 0.0 +gcode: + +[gcode_macro FLOW_MULTIPLIER_CALIBRATION] +description: Print a small tower to calibrate the extrusion flow multiplier by measuring the shell +gcode: + # + # PARAMETERS + # + {% set do_raft = params.DO_RAFT|default(1)|int %} # whether to print a raft or not + {% set do_retract = params.DO_RECTRACT|default(0)|int %} # whether to enable retract/unrectract on travel moves + {% set print_size = params.PRINT_SIZE|default(40)|int %} # size of the printed object on the build plate + {% set print_height = params.HEIGHT|default(15)|int %} # height of the printed object + {% set corner_radius = params.CORNER_RADIUS|default(8)|int %} # radius of the corners to smooth the shell and toolpath + {% set number_of_perimeters = params.PERIMETERS|default(2)|int %} # number of perimeters to print the shell + {% set fan_speed = params.FAN_SPEED|default(20)|int %} # part cooling fan speed in percent (0-100) + + {% set e_multiplier = params.EXTRUSION_MULTIPLIER|default(1.00)|float %} # extrusion multiplier for the shell + {% set filament_diameter = params.FILAMENT_DIAMETER|default(1.75)|float %} # filament diameter + {% set extrusion_width = params.EXTRUSION_WIDTH|default(0.4)|float %} # extrusion width goal for one line + {% set layer_height = params.LAYER_HEIGHT|default(0.2)|float %} # layer height for the print + + {% set retract_length = params.RETRACT_LENGTH|default(0.5)|float %} # how much to retract when traveling between print moves + {% set initial_purge = params.PURGE_MM|default(1)|int %} # mm of filament to purge before printing. set to 0 to disable + {% set z_hop_height = 2 * layer_height %} + + {% set feedrate_print = params.CONTROL_SPEED|default(100)|int * 60 %} # print feedrate + {% set feedrate_travel = params.TRAVEL_SPEED|default(200)|int * 60 %} # travel feedrate between print moves + {% set feedrate_raft = params.RAFT_SPEED|default(60)|int * 60 %} # print feedrate for printing raft + {% set feedrate_z = params.Z_LIFT_SPEED|default(20)|int * 60 %} # z axis travel feedrate + {% set feedrate_retract = params.RETRACT_SPEED|default(50)|int * 60 %} # retract and deretract feedrate + + # + # COMPUTED VALUES + # + {% set e_per_mm = ((extrusion_width - layer_height) * layer_height + 3.14159 * (layer_height / 2)**2) / (3.14159 * (filament_diameter / 2)**2) %} # computed E factor (similar to Slic3r/PrusaSlicer/SuperSlicer) + {% set spacing = extrusion_width - layer_height * (1 - 3.14159 / 4) %} # line spacing during the print + {% set shell_thickness = extrusion_width + (number_of_perimeters|float - 1) * spacing %} # theoric shell thickness + + {% set max_x = printer.toolhead.axis_maximum.x|float %} + {% set max_y = printer.toolhead.axis_maximum.y|float %} + {% set x_start = max_x / 2 - print_size / 2 %} + {% set y_start = max_y / 2 - print_size / 2 %} + {% set x_end = x_start + print_size %} + {% set y_end = y_start + print_size %} + + {% set num_raft_lines = ([print_size, max_x]|min / spacing)|round(0, 'floor')|int %} + {% set raft_size = num_raft_lines * spacing %} + + # + # STARTING... + # + {action_respond_info("")} + {action_respond_info("Starting extrusion flow calibration print")} + {action_respond_info("This operation can not be interrupted by normal means. Hit the \"emergency stop\" button to stop it if needed")} + {action_respond_info("")} + {action_respond_info("Exrusion multiplier used: %.4f" % e_multiplier)} + {action_respond_info("Number of perimeters to print: %d" % number_of_perimeters)} + {action_respond_info("THEORIC SHELL THICKNESS: %.4f" % shell_thickness)} + {action_respond_info("")} + {action_respond_info("Measure the shell thickness using a caliper or micrometer. Then call the computation macro with the measured value:")} + {action_respond_info("COMPUTE_FLOW_MULTIPLIER MEASURED_THICKNESS=xxx.xxx")} + {action_respond_info("")} + + SAVE_GCODE_STATE NAME=STATE_FLOW_MULTIPLIER_CALIBRATION + + # + # set variables for later computation + # + SET_GCODE_VARIABLE MACRO=_FLOW_CALIB_VARIABLES VARIABLE=last_shell_thickness VALUE={shell_thickness} + SET_GCODE_VARIABLE MACRO=_FLOW_CALIB_VARIABLES VARIABLE=last_evalue VALUE={e_multiplier} + + # + # purging before raft + # + G90 + M83 + G92 E0.0 + G0 X{x_start} Y{y_start - 5} Z{layer_height} F{feedrate_travel} # move at the start position to do a purge line + + G91 # use relative coordinates for the prime line + G1 E{initial_purge} F{5 * 60} + G1 X{raft_size} E{raft_size * e_per_mm * 1.5} F{feedrate_raft / 2} # print prime line + G1 Y-{extrusion_width} E{extrusion_width * e_per_mm} F{feedrate_raft / 2} # move to next line + G1 X-{raft_size} E{raft_size * e_per_mm} F{feedrate_raft / 2} # print second prime line + + G1 E-{retract_length} F{feedrate_retract} # retract + G0 Z{z_hop_height} F{feedrate_z} # z-hop + + G90 # back to absolute coordinates + G0 X{x_start} Y{y_start} F{feedrate_travel} # move to start position + G1 Z{layer_height} F{feedrate_z} # move to print height + G1 E{retract_length} F{feedrate_retract} # unretract + + # set extrude_factor + M221 S{e_multiplier * 100} + + # + # print the raft + # + {% if do_raft == 1 %} + G91 # use relative coordinates for the raft + {% for curr_raft_line in range(1, num_raft_lines + 2) %} + # print a raft line with alternating direction + G1 Y{loop.cycle(1.0, -1.0) * raft_size} E{raft_size * e_per_mm} F{feedrate_raft} + + # spacing move + {% if not loop.last %} + G1 X{spacing} E{spacing * e_per_mm} F{feedrate_raft} + {% endif %} + {% endfor %} + + G1 E-{retract_length} F{feedrate_retract} # retract + G0 Z{z_hop_height} F{feedrate_z} # z-hop + G90 # back to absolute coordinates + {% endif %} + + # + # print the shell + # + G90 + M106 S{fan_speed * 255 / 100} + + # for each layer + {% for curr_layer in range(1, (print_height / layer_height)|round|int) %} + G0 X{x_start + corner_radius} Y{y_start} F{feedrate_travel} # move to XY start position + G1 Z{(curr_layer * layer_height) + (layer_height if do_raft == 1 else 0)} F{feedrate_z} # move to Z start position + + # print one layer of the shell (in a for loop to do all the perimeters of one layer) + {% for perim_num in range(number_of_perimeters) %} + # compute values for the current perimeter (offset and radius) + {% set perim_offset = perim_num * spacing %} + {% set perim_radius = corner_radius - (perim_num * spacing) %} + + # start position of the current perimeter + G1 X{x_start + corner_radius} Y{y_start + perim_offset} F{feedrate_travel} + {% if do_retract == 1 %} + G1 E{retract_length} F{feedrate_retract} # unretract + {% endif %} + + # print the perimeter using the offset and radius computed + G1 X{x_end - corner_radius} Y{y_start + perim_offset} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print} + G3 X{x_end - perim_offset} Y{y_start + corner_radius} J{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print} + G1 X{x_end - perim_offset} Y{y_end - corner_radius} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print} + G3 X{x_end - corner_radius} Y{y_end - perim_offset} I-{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print} + G1 X{x_start + corner_radius} Y{y_end - perim_offset} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print} + G3 X{x_start + perim_offset} Y{y_end - corner_radius} J-{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print} + G1 X{x_start + perim_offset} Y{y_start + corner_radius} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print} + G3 X{x_start + corner_radius} Y{y_start + perim_offset} I{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print} + + {% if do_retract == 1 %} + G1 E-{retract_length} F{feedrate_retract} # retract + {% endif %} + {% endfor %} + + {% if do_retract == 1 %} + G91 + G0 Z{z_hop_height} F{feedrate_z} + G90 + {% endif %} + {% endfor %} + + # + # retract and move away + # + G1 E-{retract_length} F{feedrate_retract} + G91 + G0 Z20 F{feedrate_travel} + + RESTORE_GCODE_STATE NAME=STATE_FLOW_MULTIPLIER_CALIBRATION + + +[gcode_macro COMPUTE_FLOW_MULTIPLIER] +description: Compute a new flow multiplier by using the measured shell thickness on the calibration print +gcode: + {% set evalue = params.OLD_EXTRUSION_MULTIPLIER|default(0.0)|float %} # extrusion multiplier used for the calibration print + {% set theorical_thickness = params.THEORICAL_THICKNESS|default(0.0)|float %} # theorical shell thickness + {% set measured_thickness = params.MEASURED_THICKNESS|default(0.0)|float %} # measured shell thickness on the calibration print + + # if there is no OLD_EXTRUSION_MULTIPLIER passed as param, get the one from the last print calib run + {% if evalue == 0.0 %} + {% set last_evalue = printer["gcode_macro _FLOW_CALIB_VARIABLES"].last_evalue %} + + # then, if there is also no evalue saved from the last run, alert user + {% if last_evalue == 0.0 %} + {action_respond_info("It seems that no calibration print was run prior to this (or a restart of Klipper occured).")} + {action_respond_info("You can still manually use it by calling again this macro like that:")} + {action_respond_info("COMPUTE_FLOW_MULTIPLIER OLD_EXTRUSION_MULTIPLIER=xxx.xxx THEORICAL_THICKNESS=xxx.xxx MEASURED_THICKNESS=xxx.xxx")} + {action_raise_error("not enough data to perform the computation of the new flow !")} + {% else %} + {% set final_evalue = last_evalue %} + {action_respond_info("Using OLD_EXTRUSION_MULTIPLIER: %.3f" % final_evalue)} + {% endif %} + {% else %} + {% set final_evalue = evalue %} + {action_respond_info("Using OLD_EXTRUSION_MULTIPLIER: %.3f" % final_evalue)} + {% endif %} + + # similarly, if there is no THEORICAL_THICKNESS passed as param, get the one from the last print calib run + {% if theorical_thickness == 0.0 %} + {% set last_shell_thickness = printer["gcode_macro _FLOW_CALIB_VARIABLES"].last_shell_thickness %} + + # then, if there is also no evalue saved from the last run, alert user + {% if last_shell_thickness == 0.0 %} + {action_respond_info("It seems that no calibration print was run prior to this (or a restart of Klipper occured).")} + {action_respond_info("You can still manually use it by calling again this macro like that:")} + {action_respond_info("COMPUTE_FLOW_MULTIPLIER OLD_EXTRUSION_MULTIPLIER=xxx.xxx THEORICAL_THICKNESS=xxx.xxx MEASURED_THICKNESS=xxx.xxx")} + {action_raise_error("not enough data to perform the computation of the new flow !")} + {% else %} + {% set final_theorical_thickness = last_shell_thickness %} + {action_respond_info("Using THEORICAL_THICKNESS: %.3f" % final_theorical_thickness)} + {% endif %} + {% else %} + {% set final_theorical_thickness = theorical_thickness %} + {action_respond_info("Using THEORICAL_THICKNESS: %.3f" % final_theorical_thickness)} + {% endif %} + + # use the measured thickness from the user to compute a new flow value + {% if measured_thickness == 0.0 %} + {action_respond_info("You must use a caliper or micrometer to measure the calibration print shell thickness and call this macro with the measured value !!!")} + {action_respond_info("COMPUTE_FLOW_MULTIPLIER MEASURED_THICKNESS=xxx.xxx")} + {action_raise_error("not enough data to perform the computation of the new flow !")} + {% else %} + {% set new_evalue = final_theorical_thickness * final_evalue / measured_thickness %} + {action_respond_info("NEW COMPUTED FLOW VALUE: %.3f" % new_evalue)} + {action_respond_info("Use this new value as extrusion multiplier in your slicer of choice")} + {action_respond_info("")} + {% endif %} diff --git a/macros/config_backup.cfg b/macros/config_backup.cfg new file mode 100644 index 0000000..cbd2831 --- /dev/null +++ b/macros/config_backup.cfg @@ -0,0 +1,9 @@ +[gcode_shell_command backup_cfg] +command: sh /home/biqu/printer_data/config/.autocommit.sh +timeout: 30 +verbose: True + +[gcode_macro BACKUP_CFG] +description: Backs up config directory GitHub +gcode: + RUN_SHELL_COMMAND CMD=backup_cfg diff --git a/macros/homing.cfg b/macros/homing.cfg new file mode 100644 index 0000000..f206f74 --- /dev/null +++ b/macros/homing.cfg @@ -0,0 +1,174 @@ +[gcode_macro MOVE_UP] +variable_set_kinematic_z: 20 +variable_up_z: 10 +gcode: + SAVE_GCODE_STATE NAME=my_move_up_state + {% if not 'z' in printer.toolhead.homed_axes %} + SET_KINEMATIC_POSITION Z={set_kinematic_z} + {% endif %} + G91 + G0 Z{up_z} F1200 + RESTORE_GCODE_STATE NAME=my_move_up_state + +[gcode_macro _HOME_X] +variable_homing_current: 0.49 +variable_start_retract: 15 +gcode: + # Always use consistent run_current on A/B steppers during sensorless homing + {% set RUN_CURRENT_X = printer.configfile.settings['tmc5160 stepper_x'].run_current|float %} + {% set RUN_CURRENT_Y = printer.configfile.settings['tmc5160 stepper_y'].run_current|float %} + SET_TMC_CURRENT STEPPER=stepper_x CURRENT={homing_current} + SET_TMC_CURRENT STEPPER=stepper_y CURRENT={homing_current} + + M117 Homing X... + + SET_KINEMATIC_POSITION X={start_retract} + G91 + G1 X-{start_retract} F1200 + + M400 + G28 X + + G91 + G1 X-40 F1200 + #G4 P500 + + M117 + + SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X} + SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y} + + +[gcode_macro _HOME_Y] +variable_homing_current: 0.49 +variable_start_retract: 15 +gcode: + # Set current for sensorless homing + {% set RUN_CURRENT_X = printer.configfile.settings['tmc5160 stepper_x'].run_current|float %} + {% set RUN_CURRENT_Y = printer.configfile.settings['tmc5160 stepper_y'].run_current|float %} + SET_TMC_CURRENT STEPPER=stepper_x CURRENT={homing_current} + SET_TMC_CURRENT STEPPER=stepper_y CURRENT={homing_current} + #SET_TMC_FIELD FIELD=SGT STEPPER=stepper_x VALUE=1 + #G4 P1000 + + M117 Homing Y... + + SET_KINEMATIC_POSITION Y={start_retract} + G91 + G1 Y-{start_retract} F1200 + + M400 + G28 Y + + G91 + G1 Y-10 F1200 + #G4 P500 + + M117 + # Set current during print + SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X} + SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y} + + +[homing_override] +axes: xyz +gcode: + {% set home_all = 'X' not in params and 'Y' not in params and 'Z' not in params %} + {% set move_x = params.X|default(printer.toolhead.axis_maximum.y/2)|int %} + {% set move_y = params.Y|default(printer.toolhead.axis_maximum.y/2)|int %} + {% if params.Z == '' %} + {% set move_z = 10 %} + {% else %} + {% set move_z = params.Z|default(10)|int %} + {% endif %} + + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=homing VALUE=True + STATUS_HOMING + + {% if home_all or 'X' or 'Y' in params %} + INIT_TMC STEPPER=stepper_y + INIT_TMC STEPPER=stepper_x + {% endif %} + + {% if home_all or 'Z' in params %} + BED_MESH_CLEAR + MOVE_UP + {% endif %} + + {% if home_all or 'X' in params %} + _HOME_X + {% endif %} + + {% if home_all or 'Y' in params %} + _HOME_Y + {% endif %} + + + G90 + + {% if home_all or 'Z' in params %} + G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} F12000 #probe point + G28 Z + G1 Z{move_z} F1200 + {% endif %} + + #{ action_respond_info("Move X,Y => {},{}".format(params.X,params.Y)) } + + {% if params.X %} + + G1 X{move_x} F12000 + {% endif %} + + {% if params.Y %} + G1 Y{move_y} F12000 + {% endif %} + + STATUS_OFF + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=homing VALUE=False + +[gcode_macro CG28] +gcode: + {% if "xyz" not in printer.toolhead.homed_axes %} + G28 + {% endif %} + +[gcode_macro PARKFRONT] +gcode: + CG28 ; home if not already homed + SAVE_GCODE_STATE NAME=PARKFRONT + G90 ; absolute positioning + G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} Z{printer.toolhead.axis_maximum.z/2} F6000 + RESTORE_GCODE_STATE NAME=PARKFRONT + +[gcode_macro PARKFRONTLOW] +gcode: + CG28 ; home if not already homed + SAVE_GCODE_STATE NAME=PARKFRONT + G90 ; absolute positioning + G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} Z20 F6000 + RESTORE_GCODE_STATE NAME=PARKFRONT + +[gcode_macro PARKREAR] +gcode: + CG28 ; home if not already homed + SAVE_GCODE_STATE NAME=PARKREAR + G90 ; absolute positioning + G0 X{printer.toolhead.axis_minimum.x+10} Y{printer.toolhead.axis_maximum.y-10} Z{printer.toolhead.axis_maximum.z-50} F6000 + RESTORE_GCODE_STATE NAME=PARKREAR + +[gcode_macro PARKCENTER] +gcode: + CG28 ; home if not already homed + SAVE_GCODE_STATE NAME=PARKCENTER + G90 ; absolute positioning + G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} Z{printer.toolhead.axis_maximum.z/2} F6000 + RESTORE_GCODE_STATE NAME=PARKCENTER + +[gcode_macro PARKBED] +gcode: + CG28 ; home if not already homed + SAVE_GCODE_STATE NAME=PARKBED + G90 ; absolute positioning + G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} Z15 F6000 + RESTORE_GCODE_STATE NAME=PARKBED + diff --git a/macros/main.cfg b/macros/main.cfg new file mode 100644 index 0000000..a43b2be --- /dev/null +++ b/macros/main.cfg @@ -0,0 +1,746 @@ +[include stealthburner_leds.cfg] +[include config_backup.cfg] + +[gcode_macro _KNOMI_STATUS] +variable_homing: False +variable_probing: False +variable_qgling: False +variable_heating_nozzle: False +variable_heating_bed: False +gcode: + + +[include homing.cfg] +#[include private.cfg] +#[include nozzle_scrub.cfg] +[include ../KAMP_Settings.cfg] +#[include ../KAMP/KAMP_Settings.cfg] +[include tools.cfg] +[include nevermore.cfg] + + + + +[delayed_gcode init_printer] +initial_duration: 1 +gcode: + STATUS_READY + _Set_SoC_FAN_Speed Mode=Idle + #SET_FAN_SPEED FAN=SoC SPEED=0.3 + +[delayed_gcode _INIT_TIMELAPSE_CHECK_TIME] +initial_duration: 1 +gcode: SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=check_time VALUE=0.5 + +[gcode_button ps_lose] +pin: PC2 +press_gcode: + { action_respond_info("Power lose!") } + SHUTDOWN + +[gcode_macro SHUTDOWN] +gcode: + SET_PIN PIN=ps_on VALUE=0 + {action_respond_info('action:poweroff')} + {action_call_remote_method("shutdown_machine")} + +[gcode_macro _SET_IDLE_MODE] +gcode: + _CHAMBER_LED_OFF + _Set_SoC_FAN_Speed Mode=Idle + M84 + + +[gcode_macro _CHAMBER_LED_OFF] +gcode: + SET_LED LED="chamber_leds" RED=0 GREEN=0 BLUE=0 SYNC=0 TRANSMIT=1 + +[gcode_macro _CHAMBER_LED_ON] +gcode: + SET_LED LED="chamber_leds" RED=1 GREEN=1 BLUE=1 SYNC=0 TRANSMIT=1 + +[gcode_macro _Set_SoC_FAN_Speed] +description: Установка режима работы вентиляторов обдува блока электроники +variable_fan_mode_speeds: { 'Idle': [0,0], 'Printing': [0.3,0.6] } +variable_exist_fans: [ 'SoC_Left', 'SoC_Right'] +gcode: + {% set mode = params.MODE|default("Idle") %} + {% set fan_speeds = fan_mode_speeds[mode] %} + { action_respond_info("set soc fans %s" % (fan_speeds)) } + {% for fan in exist_fans %} + SET_FAN_SPEED FAN={fan} SPEED={fan_speeds[loop.index0]} + {% endfor %} + + +[gcode_macro _LED_SWITCH] +gcode: + {% set color_data = printer["neopixel chamber_leds"].color_data %} + {% if color_data[0][0] or color_data[0][1] or color_data[0][2] %} + SET_LED LED="chamber_leds" RED=0 GREEN=0 BLUE=0 SYNC=0 TRANSMIT=1 + {% else %} + SET_LED LED="chamber_leds" RED=1 GREEN=1 BLUE=1 SYNC=0 TRANSMIT=1 + {% endif %} + + +[gcode_button ps_double_click] +pin: !PG13 +press_gcode: + { action_respond_info("Double click!") } + _LED_SWITCH + +[gcode_button ps_triple_click] +pin: !PG12 +press_gcode: + { action_respond_info("Triple click!") } + { action_emergency_stop() } + + +[gcode_macro START_BED_MESH_CALIBRATE] +#rename_existing: _BED_MESH_CALIBRATE +gcode: + STATUS_MESHING + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=probing VALUE=True + BED_MESH_CALIBRATE ADAPTIVE=1 + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=probing VALUE=False + STATUS_READY + + +[gcode_macro QUAD_GANTRY_LEVEL] +rename_existing: QUAD_GANTRY_LEVEL_BASE +gcode: + _Set_SoC_FAN_Speed Mode=Printing + _CHAMBER_LED_ON + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=qgling VALUE=True + STATUS_LEVELING + QUAD_GANTRY_LEVEL_BASE + STATUS_READY + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=qgling VALUE=False + +[gcode_macro G32] +gcode: + M117 Homing + BED_MESH_CLEAR + G28 + QUAD_GANTRY_LEVEL + STATUS_CALIBRATING_Z + #G0 X350 Y350 Z30 F3600 + G28 Z + G0 Z10 F3600 + STATUS_READY + M117 + +[gcode_macro PRINT_START] +gcode: + #PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]} + {% set BED_TEMP = params.BED|default(60)|float %} + {% set EXTRUDER_TEMP = params.EXTRUDER|default(210)|float %} + {% set CHAMBER = params.CHAMBER|default(35)|float %} + {% set use_purge = params.PURGE|default(0)|int %} + {% if params.BED_TYPE %} + INIT_BED_TYPE BED_TYPE="{params.BED_TYPE}" + {% endif %} + SAVE_GCODE_STATE NAME=start + M117 Starting... + M140 S{BED_TEMP} + M141 S{CHAMBER} + M109 S150 + M190 S{BED_TEMP} + BED_MESH_CLEAR + G90 # Use absolute coordinates + #SET_GCODE_OFFSET Z=0.0 + G32 + #{% if not 'xyz' in printer.toolhead.homed_axes %} + #G32 ; home all axes + #{% elif not printer.quad_gantry_level.applied %} + #QUAD_GANTRY_LEVEL + #{% else %} + #G28 Z10 + #{% endif %} + START_BED_MESH_CALIBRATE #PRINT_MIN={params.PRINT_MIN} PRINT_MAX={params.PRINT_MAX} FORCE_NEW_MESH=True + #M191 S{CHAMBER} + Smart_Park + M117 Heating... + #M190 S{BED_TEMP} + M109 S{EXTRUDER_TEMP} ; M109 heat and wait for it to reach temp + {% if BED_TEMP > 90 %} + _NEVERMORE_ON + {% endif %} + M117 + STATUS_CLEANING + {% if use_purge %} + VORON_PURGE + {% endif %} + STATUS_PRINTING + RESTORE_GCODE_STATE NAME=start + SKEW_PROFILE LOAD=default + #SET_SKEW XY=140.56,141.21,99.82 + + + +[gcode_macro PRINT_END] +gcode: + {% set use_park = params.PARK|default(1)|int %} + {% if use_park %} + PRINT_END_PARK + {% endif %} + TURN_OFF_HEATERS + M107 ; turn off fan + _NEVERMORE_OFF + SET_STEPPER_ENABLE STEPPER=extruder ENABLE=0 #disable stepper + STATUS_OFF + INIT_BED_TYPE BED_TYPE="None" + M400 + TIMELAPSE_TAKE_FRAME + +[gcode_macro PRINT_END_PARK] +variable_retract_amount: 18 # +variable_park_speed: 6000 #3600 +variable_park_xy: [350,350] +variable_up_z: 4 #12 +gcode: + {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 60 %} + STATUS_BUSY + SET_SKEW CLEAR=1 + M400 ; wait for buffer to clear + G92 E0 ; zero the extruder + G1 E-{retract_amount} F{max_velocity} ;3600 ; retract filament {max_velocity} + G91 ; relative positioning + G0 Z1.00 X20.0 Y20.0 F20000 ; move nozzle to remove stringing + G1 Z{up_z} F3000 ; move nozzle up 2mm + G90 ; absolute positioning + G0 X{park_xy[0]} Y{park_xy[1]} F{park_speed} ; park nozzle at rear + SET_VELOCITY_DEFAULT + + + +[gcode_macro SET_VELOCITY_DEFAULT] +gcode: + SET_VELOCITY_LIMIT ACCEL={printer.configfile.settings.printer.max_accel} + SET_VELOCITY_LIMIT ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel / 2} + SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY={printer.configfile.settings.printer.square_corner_velocity} + + +[gcode_macro M141] +gcode: + {% set s = params.S|default(0)|float %} + #SET_TEMPERATURE_FAN_TARGET temperature_fan=chamber target={s} + +[gcode_macro M191] +gcode: + {% set s = params.S|default(0)|float %} + M141 S{s} + #TEMPERATURE_WAIT SENSOR="temperature_fan chamber" MINIMUM={s} + + + +[gcode_macro M600] +gcode: + #LCDRGB R=0 G=1 B=0 ; Turn LCD green + PAUSE ; Pause + +#[gcode_macro M106] +#rename_existing: M99106 +#variable_fan_aliases: { 'exhaust_fan': ['fan3'] } +#gcode: + #{% set fan = 'fan' + (params.P|int if params.P is defined else 0)|string %} + #{% set speed = (params.S|float / 255 if params.S is defined else 1.0) %} + #{ action_respond_info("M106 P{} S{}".format(params.P, params.S)) } + #{% if params.P is defined %} + #{% for key in fan_aliases %} + #{% if fan in fan_aliases[key] %} + #SET_FAN_SPEED FAN={key} SPEED={speed} + #{% endif %} + #{% endfor %} + #{% else %} + #M99106 S{speed} + #{% endif %} + + +[gcode_macro PAUSE] +rename_existing: BASE_PAUSE +gcode: + # Parameters + {% set z = params.Z|default(10)|int %} ; z hop amount + + {% if printer['pause_resume'].is_paused|int == 0 %} + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z} ; set z hop variable for reference in resume macro + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; set hotend temp variable for reference in resume macro + SAVE_GCODE_STATE NAME=PAUSE ; save current print position for resume + BASE_PAUSE ; pause print + {% if (printer.gcode_move.position.z + z) < printer.toolhead.axis_maximum.z %} ; check that zhop doesn't exceed z max + G91 ; relative positioning + G1 Z{z} F900 ; raise Z up by z hop amount + {% else %} + { action_respond_info("Pause zhop exceeds maximum Z height.") } ; if z max is exceeded, show message and set zhop value for resume to 0 + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0 + {% endif %} + G90 ; absolute positioning + G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} F6000 ; park toolhead at front center + SAVE_GCODE_STATE NAME=PAUSEPARK ; save parked position in case toolhead is moved during the pause (otherwise the return zhop can error) + M104 S0 ; turn off hotend + SET_IDLE_TIMEOUT TIMEOUT=43200 ; set timeout to 12 hours + {% endif %} + +[gcode_macro RESUME] +rename_existing: BASE_RESUME +variable_zhop: 0 +variable_etemp: 0 +gcode: + # Parameters + {% set e = params.E|default(2.5)|int %} + + {% if printer['pause_resume'].is_paused|int == 1 %} + #RESETRGB ; reset LCD color + SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; set timeout back to configured value + {% if etemp > 0 %} + M109 S{etemp|int} ; wait for hotend to heat back up + {% endif %} + RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=100 ; go back to parked position in case toolhead was moved during pause (otherwise the return zhop can error) + G91 ; relative positioning + M83 ; relative extruder positioning + {% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %} + G1 Z{zhop * -1} E{e} F900 ; prime nozzle by E, lower Z back down + {% else %} + G1 Z{zhop * -1} F900 ; lower Z back down without priming (just in case we are testing the macro with cold hotend) + {% endif %} + RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=60 ; restore position + BASE_RESUME ; resume print + {% endif %} + +[gcode_macro CANCEL_PRINT] +description: Cancel the actual running print +rename_existing: CANCEL_PRINT_BASE +gcode: + SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; + CLEAR_PAUSE + SDCARD_RESET_FILE + PRINT_END + CANCEL_PRINT_BASE + + + +[gcode_macro DUMP_PARAMETERS] +gcode: + {% for name1 in printer %} + {% for name2 in printer[name1] %} + { action_respond_info("printer['%s'].%s = %s" % (name1, name2, printer[name1][name2])) } + {% else %} + { action_respond_info("printer['%s'] = %s" % (name1, printer[name1])) } + {% endfor %} + {% endfor %} + +[gcode_macro M109] +rename_existing: M99109 +gcode: + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_nozzle VALUE=True + STATUS_HEATING + {% set s = params.S|float %} + + {% if s != 0 %} + M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp + TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree) + {% endif %} + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_nozzle VALUE=False + STATUS_OFF + +[gcode_macro M190] +rename_existing: M99190 +gcode: + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_bed VALUE=True + STATUS_HEATING + {% set s = params.S|float %} + + {% if s != 0 %} + M140 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set bed temp + TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={s} MAXIMUM={s+1} ; Wait for bed temp (within 1 degree) + {% endif %} + SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_bed VALUE=False + STATUS_OFF + +[gcode_macro DISABLE_XY] +gcode: + SET_STEPPER_ENABLE STEPPER=stepper_x ENABLE=0 + SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=0 + +[gcode_macro INIT_BED_TYPE] +variable_bed_z_offset: 0 +variable_bed_types: { 'Textured PEI Plate': -0.03, 'None': 0 } +gcode: + {% set bed_type = params.BED_TYPE|default("None") %} + {% set new_bed_z_offset = bed_types[bed_type] %} + {% if bed_z_offset != 0 %} + SET_GCODE_OFFSET Z_ADJUST={0-bed_z_offset|float} + SET_GCODE_VARIABLE MACRO=INIT_BED_TYPE VARIABLE=bed_z_offset VALUE=0 + {% endif %} + { action_respond_info("Selected bed type: {}".format(bed_type)) } + { action_respond_info("Used bed z offset: {}".format(bed_z_offset)) } + {% if new_bed_z_offset %} + { action_respond_info("Use bed type {} with z offset {}".format(bed_type, new_bed_z_offset)) } + SET_GCODE_VARIABLE MACRO=INIT_BED_TYPE VARIABLE=bed_z_offset VALUE={new_bed_z_offset} + SET_GCODE_OFFSET Z_ADJUST={new_bed_z_offset} + {% endif %} + + +[gcode_macro LOAD_FILAMENT] +variable_load_distance: 72 +variable_purge_distance: 0 +gcode: + {% set speed = params.SPEED|default(300) %} + {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 60 %} + SAVE_GCODE_STATE NAME=load_state + G91 + G92 E0 + G1 E{16} F300 # fast-load + G1 E{load_distance} F{max_velocity} # fast-load + G1 E{purge_distance} F{speed} # purge + RESTORE_GCODE_STATE NAME=load_state + +[gcode_macro UNLOAD_FILAMENT] +variable_unload_distance: 76 +variable_purge_distance: 0 +gcode: + {% set speed = params.SPEED|default(300) %} + {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 60 %} + SAVE_GCODE_STATE NAME=unload_state + G91 + G92 E0 + G1 E{purge_distance} F{speed} # purge + G1 E-{unload_distance} F{max_velocity} # fast-unload + RESTORE_GCODE_STATE NAME=unload_state + +[gcode_macro PURGE_AFTER_FILAMENT_CHANGE] +description: Безопасная очистка сопла после замены филамента с опциональным автоматическим хомингом +gcode: + # === ПРОВЕРКА СОСТОЯНИЯ ПРИНТЕРА === + {% if printer.idle_timeout.state == "Printing" %} + {action_respond_info("⚠️ ПРИНТЕР ЗАНЯТ ПЕЧАТЬЮ!")} + {action_respond_info("🛑 Очистка невозможна во время печати!")} + {action_raise_error("ОШИБКА: Принтер занят печатью!")} + {% elif printer['toolhead'].is_printing == true %} + {action_respond_info("⚠️ ДЕТЕКТИРОВАНА АКТИВНАЯ ПЕЧАТЬ!")} + {action_raise_error("ОШИБКА: Активная печать обнаружена!")} + {% endif %} + + # === ПРОВЕРКА НЕОБХОДИМОСТИ ХОМИНГА === + {% set homed_axes = printer.toolhead.homed_axes %} + {% set need_homing = false %} + + {% if 'x' not in homed_axes or 'y' not in homed_axes or 'z' not in homed_axes %} + {% set need_homing = true %} + {action_respond_info("🔍 Обнаружены непрохоменные оси: %s" % (['x','y','z']|reject('in', homed_axes)|join(', ')))} + + # Проверяем параметр AUTO_HOME + {% if params.AUTO_HOME|default(1)|int == 1 %} + {action_respond_info("✅ АВТОМАТИЧЕСКИЙ ХОМИНГ ВКЛЮЧЕН (AUTO_HOME=1)")} + {action_respond_info("🔄 Выполняем G28 для всех осей...")} + G28 + {% set need_homing = false %} # После хоминга оси прохомены + {% else %} + {action_respond_info("❓ Для автоматического хоминга используйте: PURGE_AFTER_FILAMENT_CHANGE AUTO_HOME=1")} + {action_respond_info("🛑 ИЛИ выполните хоминг вручную (кнопка 'Home All' в интерфейсе)")} + {action_raise_error("ТРЕБУЕТСЯ ХОМИНГ ОСЕЙ ПЕРЕД ОЧИСТКОЙ")} + {% endif %} + {% endif %} + + # === НАСТРОЙКА ПОД МАТЕРИАЛ === + {% set material = params.MATERIAL|default('PLA')|lower %} + + {% if material == 'pla' %} + {% set default_temp = 210 %} + {% set fan_speed_final = 255 %} + {% elif material == 'petg' %} + {% set default_temp = 230 %} + {% set fan_speed_final = 180 %} + {% elif material == 'abs' %} + {% set default_temp = 240 %} + {% set fan_speed_final = 0 %} + {% elif material == 'tpu' %} + {% set default_temp = 220 %} + {% set fan_speed_final = 100 %} + {% else %} + {% set default_temp = 220 %} + {% set fan_speed_final = 255 %} + {% endif %} + + {% set target_temp = params.TEMP|default(default_temp)|int %} + + # === СТАНДАРТНЫЕ ПАРАМЕТРЫ === + {% set retract_length = 18 %} + {% set retract_speed = 60 %} + {% set min_extrude = 50 %} + {% set max_extrude = 150 %} + + # === РАСЧЕТ ДЛИНЫ ВЫДАВЛИВАНИЯ === + {% set nozzle_diameter = params.NOZZLE|default(0.4)|float %} + {% set filament_diameter = params.FILAMENT_DIAM|default(1.75)|float %} + + {% set base_length = 80 %} + {% set diameter_factor = nozzle_diameter / 0.4 %} + {% set calculated_length = base_length * diameter_factor %} + + {% set total_length = params.LENGTH|default(calculated_length|round(0))|float %} + + {% if total_length < min_extrude %} + {action_respond_info("⚠️ Установлена минимальная длина очистки: %dмм" % min_extrude)} + {% set total_length = min_extrude %} + {% elif total_length > max_extrude %} + {action_respond_info("⚠️ ПРЕДУПРЕЖДЕНИЕ: Запрашиваемая длина %.1fмм превышает безопасный лимит %dмм" % (total_length, max_extrude))} + {% set total_length = max_extrude %} + {% endif %} + + {% set extrude_speed = params.SPEED|default(20)|int %} + + # === БЕЗОПАСНОЕ ПЕРЕМЕЩЕНИЕ В БЕЗОПАСНУЮ ПОЗИЦИЮ === + M118 СТАРТ: Перемещение в безопасную позицию + + # Проверяем текущие позиции и границы + {% set x_max = printer.configfile.settings['stepper_x']['position_max']|float %} + {% set y_max = printer.configfile.settings['stepper_y']['position_max']|float %} + + # Вычисляем безопасные координаты (90% от максимума) + {% set safe_x = x_max * 0.9 %} + {% set safe_y = y_max * 0.9 %} + + # Проверяем текущую Z позицию + {% set current_z = printer.toolhead.position.z %} + {% set safe_z = 50 if current_z < 50 else current_z %} + + # Проверяем, что координаты в допустимых пределах + {% if safe_x > x_max %} + {% set safe_x = x_max * 0.8 %} + {% endif %} + + {% if safe_y > y_max %} + {% set safe_y = y_max * 0.8 %} + {% endif %} + + # Относительное перемещение по Z сначала (если нужно поднять) + {% if current_z < 50 %} + M118 ПОЗИЦИЯ: Подъем по оси Z до 50мм + G91 + G1 Z{50 - current_z} F300 + G90 + {% endif %} + + # Перемещение в XY безопасную позицию + M118 ПОЗИЦИЯ: Перемещение в XY позицию (%.1f, %.1f) % (safe_x, safe_y) + G1 X{safe_x} Y{safe_y} F6000 + + # НАГРЕВ СОПЛА + M118 ПРОГРЕСС: Нагрев сопла до {target_temp|int}C для {material|upper} + M104 S{target_temp} + M109 S{target_temp} + + # ЦИКЛЫ ОЧИСТКИ + M118 ПРОГРЕСС: Предварительная очистка (3 цикла) + + {% for i in range(3) %} + G92 E0 + G1 E10 F{extrude_speed|float*60} + G1 E-5 F{retract_speed|float*60} + G4 P300 + M118 ПРОГРЕСС: Цикл {i+1}/3 завершен + {% endfor %} + + # ОСНОВНОЕ ВЫДАВЛИВАНИЕ + G92 E0 + + {% set first_part = total_length * 0.8 %} + M118 ПРОГРЕСС: Основное выдавливание: {first_part|round(1)}мм + G1 E{first_part} F{extrude_speed|float*60} + + {% set second_part = total_length * 0.2 %} + M118 ПРОГРЕСС: Финальное выдавливание: {second_part|round(1)}мм + M106 S{fan_speed_final} + G1 E{total_length} F{extrude_speed|float*60} + + G4 P1000 + + # РЕТРАКТ + M118 ПРОГРЕСС: Ретракт на {retract_length}мм + G91 + G1 E-{retract_length} F{retract_speed|float*60} + G90 + + # ЗАДЕРЖКА И ОХЛАЖДЕНИЕ + M118 ПРОГРЕСС: Задержка 2с для охлаждения + G4 P2000 + + M118 ПРОГРЕСС: Отключение обдува + M107 + + M118 ПРОГРЕСС: Охлаждение сопла + M104 S150 + G4 P3000 + M104 S0 + + # ФИНАЛЬНАЯ СТАТИСТИКА + {% set total_extruded = total_length - retract_length %} + {% set filament_area = 3.14159 * (filament_diameter/2)**2 %} + {% set volume_flow = filament_area * extrude_speed %} + {% set total_time = (total_length / extrude_speed) + 10 %} + + M118 СТАТИСТИКА: Материал: {material|upper} + M118 СТАТИСТИКА: Сопло: {nozzle_diameter|round(1)}мм + M118 СТАТИСТИКА: Выдавлено: {total_length|round(1)}мм (всего) + M118 СТАТИСТИКА: Чистый материал: {total_extruded|round(1)}мм + M118 СТАТИСТИКА: Объемный расход: {volume_flow|round(1)}мм3/сек + M118 ГОТОВО: Очистка завершена! ✅ + +[gcode_macro test_speed_fast] +gcode: + G28 X0 Y0 + GET_POSITION + G1 X0 Y0 F27000 + G1 X350 Y350 F27000 + G1 X0 Y0 F27000 + G1 X350 Y350 F27000 + + G1 X0 Y350 F36000 + + G1 X350 Y0 F27000 + G1 X0 Y350 F27000 + G1 X350 Y0 F27000 + G1 X0 Y350 F27000 + + G1 X0 Y0 F36000 + G1 X350 Y0 F36000 + G1 X350 Y350 F36000 + G1 X0 Y350 F36000 + G1 X0 Y0 F36000 + #DISABLE_XY + G28 X0 Y0 + GET_POSITION + +[gcode_macro TEST_SPEED] +# Home, get position, throw around toolhead, home again. +# If MCU stepper positions (first line in GET_POSITION) are greater than a full step different (your number of microsteps), then skipping occured. +# We only measure to a full step to accomodate for endstop variance. +# Example: TEST_SPEED SPEED=300 ACCEL=5000 ITERATIONS=10 +# https://github.com/AndrewEllis93/Print-Tuning-Guide/blob/main/articles/determining_max_speeds_accels.md + +description: Test for max speed and acceleration parameters for the printer. Procedure: Home -> ReadPositionFromMCU -> MovesToolhead@Vel&Accel -> Home -> ReadPositionfromMCU + +gcode: + # Speed + {% set speed = params.SPEED|default(printer.configfile.settings.printer.max_velocity)|int %} + # Iterations + {% set iterations = params.ITERATIONS|default(5)|int %} + # Acceleration + {% set accel = params.ACCEL|default(printer.configfile.settings.printer.max_accel)|int %} + # Minimum Cruise Ratio + {% set min_cruise_ratio = params.MIN_CRUISE_RATIO|default(0.5)|float %} + # Bounding inset for large pattern (helps prevent slamming the toolhead into the sides after small skips, and helps to account for machines with imperfectly set dimensions) + {% set bound = params.BOUND|default(20)|int %} + # Size for small pattern box + {% set smallpatternsize = SMALLPATTERNSIZE|default(20)|int %} + + # Large pattern + # Max positions, inset by BOUND + {% set x_min = printer.toolhead.axis_minimum.x + bound %} + {% set x_max = printer.toolhead.axis_maximum.x - bound %} + {% set y_min = printer.toolhead.axis_minimum.y + bound %} + {% set y_max = printer.toolhead.axis_maximum.y - bound %} + + # Small pattern at center + # Find X/Y center point + {% set x_center = (printer.toolhead.axis_minimum.x|float + printer.toolhead.axis_maximum.x|float ) / 2 %} + {% set y_center = (printer.toolhead.axis_minimum.y|float + printer.toolhead.axis_maximum.y|float ) / 2 %} + + # Set small pattern box around center point + {% set x_center_min = x_center - (smallpatternsize/2) %} + {% set x_center_max = x_center + (smallpatternsize/2) %} + {% set y_center_min = y_center - (smallpatternsize/2) %} + {% set y_center_max = y_center + (smallpatternsize/2) %} + + # Save current gcode state (absolute/relative, etc) + SAVE_GCODE_STATE NAME=TEST_SPEED + + # Output parameters to g-code terminal + { action_respond_info("TEST_SPEED: starting %d iterations at speed %d, accel %d" % (iterations, speed, accel)) } + + # Home and get position for comparison later: + M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66 + G28 + # QGL if not already QGLd (only if QGL section exists in config) + {% if printer.configfile.settings.quad_gantry_level %} + {% if printer.quad_gantry_level.applied == False %} + QUAD_GANTRY_LEVEL + G28 Z + {% endif %} + {% endif %} + # Move 50mm away from max position and home again (to help with hall effect endstop accuracy - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/24) + G90 + G1 X{printer.toolhead.axis_maximum.x-50} Y{printer.toolhead.axis_maximum.y-50} F{30*60} + M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66 + G28 X Y + G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60} + G4 P1000 + GET_POSITION + + # Go to starting position + G0 X{x_min} Y{y_min} Z{bound + 10} F{speed*60} + + # Set new limits + {% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %} + SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} MINIMUM_CRUISE_RATIO={min_cruise_ratio} + {% else %} + SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} ACCEL_TO_DECEL={accel / 2} + {% endif %} + + {% for i in range(iterations) %} + # Large pattern diagonals + G0 X{x_min} Y{y_min} F{speed*60} + G0 X{x_max} Y{y_max} F{speed*60} + G0 X{x_min} Y{y_min} F{speed*60} + G0 X{x_max} Y{y_min} F{speed*60} + G0 X{x_min} Y{y_max} F{speed*60} + G0 X{x_max} Y{y_min} F{speed*60} + + # Large pattern box + G0 X{x_min} Y{y_min} F{speed*60} + G0 X{x_min} Y{y_max} F{speed*60} + G0 X{x_max} Y{y_max} F{speed*60} + G0 X{x_max} Y{y_min} F{speed*60} + + # Small pattern diagonals + G0 X{x_center_min} Y{y_center_min} F{speed*60} + G0 X{x_center_max} Y{y_center_max} F{speed*60} + G0 X{x_center_min} Y{y_center_min} F{speed*60} + G0 X{x_center_max} Y{y_center_min} F{speed*60} + G0 X{x_center_min} Y{y_center_max} F{speed*60} + G0 X{x_center_max} Y{y_center_min} F{speed*60} + + # Small pattern box + G0 X{x_center_min} Y{y_center_min} F{speed*60} + G0 X{x_center_min} Y{y_center_max} F{speed*60} + G0 X{x_center_max} Y{y_center_max} F{speed*60} + G0 X{x_center_max} Y{y_center_min} F{speed*60} + {% endfor %} + + # Restore max speed/accel/accel_to_decel to their configured values + {% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %} + SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} MINIMUM_CRUISE_RATIO={printer.configfile.settings.printer.minimum_cruise_ratio} + {% else %} + SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel_to_decel} + {% endif %} + + # Re-home and get position again for comparison: + M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66 + G28 # This is a full G28 to fix an issue with CoreXZ - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/12 + # Go to XY home positions (in case your homing override leaves it elsewhere) + G90 + G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60} + G4 P1000 + GET_POSITION + + # Restore previous gcode state (absolute/relative, etc) + RESTORE_GCODE_STATE NAME=TEST_SPEED + + +[gcode_macro _bot_data] +variable_lapse_video_size: 0 +variable_lapse_filename: 'None' +variable_lapse_path: 'None' +gcode: + M118 Setting bot lapse variables diff --git a/macros/nevermore.cfg b/macros/nevermore.cfg new file mode 100644 index 0000000..abe634b --- /dev/null +++ b/macros/nevermore.cfg @@ -0,0 +1,30 @@ +## This is a simple include for the Nevermore. To use it with your printer, edit +## the pin definition in line 16 so it matches your printer. +## What you get: +## - a generic fan "Nevermore" which is adjustable in GCODE and in Mainsail/Fluidd +## - Commands in your 12864-controller to turn the fan on/off or adjust in 10%-steps +## - a Macro to turn the fan off some time after the print. +## +## Slicer integration: Add "SET_FAN_SPEED FAN=Nevermore SPEED=1" in your start-macro +## (or less fan depending on your needs, like SPEED=0.8) +## in your end print code, add "UPDATE_DELAYED_GCODE ID=filter_off DURATION=180" +## this keeps your Nevermore running for 180s after the print finishes to clean the chamber a bit more. +[delayed_gcode filter_off] +gcode: + SET_FAN_SPEED FAN=Nevermore SPEED=0 + +[gcode_macro TOGGLE_NEVERMORE] +gcode: + {% if printer['fan_generic Nevermore'].speed > 0 %} + SET_FAN_SPEED FAN=Nevermore SPEED=0 + {% else %} + SET_FAN_SPEED FAN=Nevermore SPEED=1 + {% endif %} + +[gcode_macro _NEVERMORE_ON] +gcode: + SET_FAN_SPEED FAN=Nevermore SPEED=1 + +[gcode_macro _NEVERMORE_OFF] +gcode: + SET_FAN_SPEED FAN=Nevermore SPEED=0 diff --git a/macros/nozzle_scrub.cfg b/macros/nozzle_scrub.cfg new file mode 100644 index 0000000..6b6ec96 --- /dev/null +++ b/macros/nozzle_scrub.cfg @@ -0,0 +1,158 @@ +[gcode_macro clean_nozzle] +variable_location_bucket_rear: True +variable_enable_purge: True + +# These parameters define your filament purging. The retract variable is used to retract right after purging to prevent unnecessary +# oozing. Some filament are particularly oozy and may continue to ooze out of the nozzle for a second or two after retracting. The +# ooze dwell variable makes allowance for this. Update as necessary. If you decided to not enable purge, you can ignore this section. +variable_purge_len: 20 ; Amount of filament, in mm, to purge. +variable_purge_spd: 150 ; Speed, in mm/min, of the purge. +variable_purge_temp_min: 200 ; Minimum nozzle temperature to permit a purge. Otherwise, purge will not occur. +variable_purge_ret: 2 ; Retract length, in mm, after purging to prevent slight oozing. Adjust as necessary. +variable_ooze_dwell: 4 ; Dwell/wait time, in seconds, after purging and retracting. + +# Adjust this so that your nozzle scrubs within the brush. Currently defaulted to be a lot higher for safety. Be careful not to go too low! +variable_brush_top: 0 + +# These parameters define your scrubbing, travel speeds, safe z clearance and how many times you want to wipe. Update as necessary. Wipe +# direction is randomized based off whether the left or right bucket is randomly selected in the purge & scrubbing routine. +variable_clearance_z: 5 ; When traveling, but not cleaning, the clearance along the z-axis between nozzle and brush. +variable_wipe_qty: 3 ; Number of complete (A complete wipe: left, right, left OR right, left, right) wipes. +variable_prep_spd_xy: 3000 ; Travel (not cleaning) speed along x and y-axis in mm/min. +variable_prep_spd_z: 1500 ; Travel (not cleaning) speed along z axis in mm/min. +variable_wipe_spd_xy: 5000 ; Nozzle wipe speed in mm/min. + + +# These parameters define the size of the brush. Update as necessary. A visual reference is provided below. Note that orientation of +# parameters remain the same whether bucket is at rear or front. +# +# ← brush_width → +# _________________ ↑ +# | | ↑ If you chose location_bucket_rear = True, Y position is acquired +# brush_start (x) | | brush_depth from your stepper_y position_max. Adjust your brush physically in +# |_________________| ↓ Y so that the nozzle scrubs within the brush. +# (y) ↓ +# brush_front +# __________________________________________________________ +# PRINTER FRONT +# +# +variable_brush_start: 75 +# This value is defaulted from brush location in CAD (rear left). Change if your brush width is different. +variable_brush_width: 52 + +## These are only used if location_bucket_rear is False. You specify a custom location in y axis for your brush - see diagram above. ## +variable_brush_front: 0 +variable_brush_depth: 2 + + +# These parameters define the size of your purge bucket. Update as necessary. If you decided to not enable purge, you can ignore +# this section. A visual reference is provided below. Note that orientation of parameters remain the same whether bucket is at rear +# or front. +# +# bucket_gap +# ← ---- → +# __________________________________________ +# | | | | +# | | | | +# bucket_start (x) | |______| | +# | | | | +# | | | | +# |_________________|. . . |_________________| +# ← ------------- → ← ------------- → +# bucket_left_width bucket_right_width +# _______________________________________________________________________________________ +# PRINTER FRONT +# +## For V2.4 350mm build, uncomment below +variable_bucket_left_width: 92 + +# These values are defaulted from bucket geometry in CAD (rear left location). Change only if you're using a custom bucket. +variable_bucket_right_width: 40 +variable_bucket_gap: 22 + +# For V1.8, you may need to measure where your bucket start is and input into bucket_start. Otherwise, a value of 0 is for a default +# installation of purge bucket at rear left. +variable_bucket_start: 0 +variable_bucket_pos: 1 +gcode: + STATUS_CLEANING + # First, check if the axes are homed. + {% if "xyz" in printer.toolhead.homed_axes %} + + ## Save the gcode state in this macro instance. + SAVE_GCODE_STATE NAME=clean_nozzle + + ## Set to absolute positioning. + G90 + + ## Grab max position of Y-axis from config to use in setting a fixed y position for location_bucket_rear = True. + {% set Ry = printer.configfile.config["stepper_y"]["position_max"]|float %} + + ## Check if user enabled purge option or not. + {% if enable_purge %} + + ### Randomly select left or right bin for purge. 0 = left, 1 = right + SET_GCODE_VARIABLE MACRO=clean_nozzle VARIABLE=bucket_pos VALUE={(range(2) | random)} + + ### Raise Z for travel. + G1 Z{brush_top + clearance_z} F{prep_spd_z} + + ### Check if user chose to use rear location. + {% if location_bucket_rear %} + G1 Y{Ry} F{prep_spd_xy} + {% else %} + G1 Y{brush_front + (brush_depth / 2)} F{prep_spd_xy} + {% endif %} + + ### Position for purge. Randomly selects middle of left or right bucket. It references from the middle of the left bucket. + G1 X{bucket_start + (bucket_left_width / (2 - bucket_pos)) + (bucket_pos * bucket_gap) + (bucket_pos * (bucket_right_width / 2))} + + ### Perform purge if the temp is up to min temp. If not, it will skip and continue executing rest of macro. Small retract after + ### purging to minimize any persistent oozing at 5x purge_spd. G4 dwell is in milliseconds, hence * 1000 in formula. + {% if printer.extruder.temperature >= purge_temp_min %} + M83 ; relative mode + G1 E{purge_len} F{purge_spd} + G1 E-{purge_ret} F{purge_spd * 5} + G4 P{ooze_dwell * 1000} + G92 E0 ; reset extruder + {% endif %} + + {% endif %} + + ## Position for wipe. Either left or right of brush based off bucket_pos to avoid unnecessary travel. + G1 Z{brush_top + clearance_z} F{prep_spd_z} + G1 X{brush_start + (brush_width * bucket_pos)} F{prep_spd_xy} + + ## Check if user chose to use rear location. + {% if location_bucket_rear %} + G1 Y{Ry} + {% else %} + G1 Y{brush_front + (brush_depth / 2)} + {% endif %} + + ## Move nozzle down into brush. + G1 Z{brush_top} F{prep_spd_z} + + ## Perform wipe. Wipe direction based off bucket_pos for cool random scrubby routine. + {% for wipes in range(1, (wipe_qty + 1)) %} + G1 X{brush_start + (brush_width * (1 - bucket_pos))} F{wipe_spd_xy} + G1 X{brush_start + (brush_width * bucket_pos)} F{wipe_spd_xy} + {% endfor %} + + ## Clear from area. + M117 Cleaned! + G1 Z{brush_top + clearance_z} F{prep_spd_z} + G1 X{bucket_start + (bucket_left_width / 4)} F{prep_spd_xy} #bugfix for right side mounted buckets + + ## Restore the gcode state to how it was before the macro. + RESTORE_GCODE_STATE NAME=clean_nozzle + + {% else %} + + ## raise error will stop any macros that clean_nozzle is referenced in from proceeding for safety. + { action_raise_error("Please home your axes!") } + M117 Please home first! + + {% endif %} + STATUS_READY diff --git a/macros/stealthburner_leds.cfg b/macros/stealthburner_leds.cfg new file mode 100644 index 0000000..2dba09d --- /dev/null +++ b/macros/stealthburner_leds.cfg @@ -0,0 +1,254 @@ +# Macros for setting the status leds on the Voron StealthBurner toolhead (or for any neopixel-type leds). +# +# You will need to configure a neopixel (or other addressable led, such as dotstar). See +# https://www.klipper3d.org/Config_Reference.html#neopixel for configuration details. + + +##################################### +# INSTRUCTIONS # +##################################### +# How to use all this stuff: +# +# 1. Copy this .cfg file into your Klipper config directory and then add [include stealthburner_leds.cfg] +# to the top of your printer.cfg in order to register the LEDs and macros with Klipper. +# 2. Define your LEDs by editing [neopixel sb_leds] below and entering the data pin from your control board +# as well as the color order. +# +# Note: RGB and RGBW are different and must be defined explicitly. RGB and RGBW are also not able to +# be mix-and-matched in the same chain. A separate data line would be needed for proper functioning. +# +# RGBW LEDs will have a visible yellow-ish phosphor section to the chip. If your LEDs do not have +# this yellow portion, you have RGB LEDs. +# +# 3. Save your config and restart Klipper. +# +# Note: We set RED and BLUE to 1.0 to make it easier for users and supporters to detect +# misconfigurations or miswiring. The default color format is for Neopixels with a dedicated +# white LED. On startup, all three SB LEDs should light up. +# +# If you get random colors across your LEDs, change the color_order to GRB and restart. Then +# omit the W for each suggested color_order in the next paragraph. +# +# If you get MAGENTA, your color order is correct. If you get CYAN, you need to use RGBW. If +# you get YELLOW, you need to use BRGW (note that BRG is only supported in the latest Klipper +# version). +# +# 4. Once you have confirmed that the LEDs are set up correctly, you must now decide where you want +# these macros called up...which means adding them to your existing gcode macros. NOTHING will happen +# unless you add the STATUS_????? macros to your existing gcode macros. +# +# Example: add STATUS_LEVELING to the beginning of your QGL gcode macro, and then add STATUS_READY +# to the end of it to set the logo LED and nozzle LEDs back to the `ready` state. +# +# Example: add STATUS_CLEANING to the beginning of your nozzle-cleaning macro, and then STATUS_READY +# to the end of it to return the LEDs back to `ready` state. +# +# 5. Feel free to change colors of each macro, create new ones if you have a need to. The macros provided below +# are just an example of what is possible. If you want to try some more complex animations, you will most +# likely have to use WLED with Moonraker and a small micro-controller +# +##################################### +# END INSTRUCTRUCTIONS # +##################################### + +[neopixel sb_leds] +#pin: EBBCan:gpio16 #sht:RGBLED +#pin: EXP1_6 +# The pin connected to the neopixel. This parameter must be provided. +chain_count: 3 +# The number of Neopixel chips that are "daisy chained" to the +# provided pin. The default is 1 (which indicates only a single +# Neopixel is connected to the pin). +color_order: GRBW +# Set the pixel order required by the LED hardware. Options are GRB, +# RGB, GRBW, or RGBW. The default is GRB. +initial_RED: 1.0 +initial_GREEN: 0.0 +initial_BLUE: 1.0 +initial_WHITE: 0.0 +# Sets the initial LED color of the Neopixel. Each value should be +# between 0.0 and 1.0. The WHITE option is only available on RGBW +# LEDs. The default for each color is 0.# + +# Most configuration for the macros can be done by modifying the variables in the _sb_vars macro +# at the start of this file. + +########## +# MACROS # +########## + +# The following status macros are available (these go inside of your macros): +# +# STATUS_READY +# STATUS_OFF +# STATUS_BUSY +# STATUS_HEATING +# STATUS_LEVELING +# STATUS_HOMING +# STATUS_CLEANING +# STATUS_MESHING +# STATUS_CALIBRATING_Z +# +# With additional macros for basic control: +# +# SET_NOZZLE_LEDS_ON +# SET_LOGO_LEDS_OFF +# SET_NOZZLE_LEDS_OFF +# +# Contributed by Voron discord users wile.e, Tetsunosuke, and etherwalker + + +[gcode_macro _sb_vars] +# User settings for the StealthBurner status leds. You can change the status colors and led +# configurations for the logo and nozzle here. +variable_colors: { + 'logo': { # Colors for logo states + 'busy': {'r': 0.4, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'cleaning': {'r': 0.0, 'g': 0.02, 'b': 0.5, 'w': 0.0}, + 'calibrating_z': {'r': 0.8, 'g': 0., 'b': 0.35, 'w': 0.0}, + 'heating': {'r': 0.3, 'g': 0.18, 'b': 0.0, 'w': 0.0}, + 'homing': {'r': 0.0, 'g': 0.6, 'b': 0.2, 'w': 0.0}, + 'leveling': {'r': 0.5, 'g': 0.1, 'b': 0.4, 'w': 0.0}, + 'meshing': {'r': 0.2, 'g': 1.0, 'b': 0.0, 'w': 0.0}, + 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'printing': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'standby': {'r': 0.01, 'g': 0.01, 'b': 0.01, 'w': 0.1}, + }, + 'nozzle': { # Colors for nozzle states + 'heating': {'r': 0.8, 'g': 0.35, 'b': 0.0, 'w':0.0}, + 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.0}, + 'standby': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, + }, + 'thermal': { + 'hot': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'cold': {'r': 0.3, 'g': 0.0, 'b': 0.3, 'w': 0.0} + } + } +variable_logo_led_name: "sb_leds" +# The name of the addressable LED chain that contains the logo LED(s) +variable_logo_idx: "1" +# A comma-separated list of indexes LEDs in the logo +variable_nozzle_led_name: "sb_leds" +# The name of the addressable LED chain that contains the nozzle LED(s). This will +# typically be the same LED chain as the logo. +variable_nozzle_idx: "2,3" +# A comma-separated list of indexes of LEDs in the nozzle +gcode: + # This section is required. Do Not Delete. + + +[gcode_macro _set_sb_leds] +gcode: + {% set red = params.RED|default(0)|float %} + {% set green = params.GREEN|default(0)|float %} + {% set blue = params.BLUE|default(0)|float %} + {% set white = params.WHITE|default(0)|float %} + {% set led = params.LED|string %} + {% set idx = (params.IDX|string).split(',') %} + {% set transmit_last = params.TRANSMIT|default(1) %} + + {% for led_index in idx %} + {% set transmit=transmit_last if loop.last else 0 %} + set_led led={led} red={red} green={green} blue={blue} white={white} index={led_index} transmit={transmit} + {% endfor %} + +[gcode_macro _set_sb_leds_by_name] +gcode: + {% set leds_name = params.LEDS %} + {% set color_name = params.COLOR %} + {% set color = printer["gcode_macro _sb_vars"].colors[leds_name][color_name] %} + {% set led = printer["gcode_macro _sb_vars"][leds_name + "_led_name"] %} + {% set idx = printer["gcode_macro _sb_vars"][leds_name + "_idx"] %} + {% set transmit = params.TRANSMIT|default(1) %} + + _set_sb_leds led={led} red={color.r} green={color.g} blue={color.b} white={color.w} idx="{idx}" transmit={transmit} + +[gcode_macro _set_logo_leds] +gcode: + {% set red = params.RED|default(0)|float %} + {% set green = params.GREEN|default(0)|float %} + {% set blue = params.BLUE|default(0)|float %} + {% set white = params.WHITE|default(0)|float %} + {% set led = printer["gcode_macro _sb_vars"].logo_led_name %} + {% set idx = printer["gcode_macro _sb_vars"].logo_idx %} + {% set transmit=params.TRANSMIT|default(1) %} + + _set_sb_leds led={led} red={red} green={green} blue={blue} white={white} idx="{idx}" transmit={transmit} + +[gcode_macro _set_nozzle_leds] +gcode: + {% set red = params.RED|default(0)|float %} + {% set green = params.GREEN|default(0)|float %} + {% set blue = params.BLUE|default(0)|float %} + {% set white = params.WHITE|default(0)|float %} + {% set led = printer["gcode_macro _sb_vars"].nozzle_led_name %} + {% set idx = printer["gcode_macro _sb_vars"].nozzle_idx %} + {% set transmit=params.TRANSMIT|default(1) %} + + _set_sb_leds led={led} red={red} green={green} blue={blue} white={white} idx="{idx}" transmit={transmit} + +[gcode_macro set_logo_leds_off] +gcode: + {% set transmit=params.TRANSMIT|default(1) %} + _set_logo_leds red=0 blue=0 green=0 white=0 transmit={transmit} + +[gcode_macro set_nozzle_leds_on] +gcode: + {% set transmit=params.TRANSMIT|default(1) %} + _set_sb_leds_by_name leds="nozzle" color="on" transmit={transmit} + +[gcode_macro set_nozzle_leds_off] +gcode: + {% set transmit=params.TRANSMIT|default(1) %} + _set_sb_leds_by_name leds="nozzle" color="off" transmit={transmit} + +[gcode_macro status_off] +gcode: + set_logo_leds_off transmit=0 + set_nozzle_leds_off + +[gcode_macro status_ready] +gcode: + _set_sb_leds_by_name leds="logo" color="standby" transmit=0 + _set_sb_leds_by_name leds="nozzle" color="standby" transmit=1 + +[gcode_macro status_busy] +gcode: + _set_sb_leds_by_name leds="logo" color="busy" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_heating] +gcode: + _set_sb_leds_by_name leds="logo" color="heating" transmit=0 + _set_sb_leds_by_name leds="nozzle" color="heating" transmit=1 + +[gcode_macro status_leveling] +gcode: + _set_sb_leds_by_name leds="logo" color="leveling" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_homing] +gcode: + _set_sb_leds_by_name leds="logo" color="homing" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_cleaning] +gcode: + _set_sb_leds_by_name leds="logo" color="cleaning" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_meshing] +gcode: + _set_sb_leds_by_name leds="logo" color="meshing" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_calibrating_z] +gcode: + _set_sb_leds_by_name leds="logo" color="calibrating_z" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_printing] +gcode: + _set_sb_leds_by_name leds="logo" color="printing" transmit=0 + set_nozzle_leds_on diff --git a/macros/tools.cfg b/macros/tools.cfg new file mode 100644 index 0000000..f8b758e --- /dev/null +++ b/macros/tools.cfg @@ -0,0 +1,91 @@ +#Аргументы +#NAME (строка) — отфильтруйте результаты по названию (отображайте только переменные с названиями, содержащими эту строку) +#VALUE (строка) — отфильтруйте результаты по значению (отображайте только значения, содержащие это значение) +#SHOW_CFG (целое число, 0-1) — установите значение 1, чтобы включить в вывод всю конфигурацию. По умолчанию 0 (конфигурация отфильтровывается) +#Примеры +#DUMP_VARIABLES: Возвращает все переменные (за исключением printer['configfile'].config и printer['configfile'].settings, так как они содержат всю конфигурацию). +#DUMP_VARIABLES NAME=stepper: Возвращает все переменные, в имени которых есть строка stepper. +#DUMP_VARIABLES VALUE=extruder : Возвращает все переменные, в значении которых есть строка extruder. +#DUMP_VARIABLES NAME=stepper VALUE=extruder : Возвращает все переменные, в названии которых есть строка stepper и в значении которых есть строка extruder. +#DUMP_VARIABLES SHOW_CFG=1 : Возвращает все переменные, включая конфигурацию. + +[gcode_macro DUMP_VARIABLES] +gcode: + {% set filter_name = params.NAME|default('')|string|lower %} + {% set filter_value = params.VALUE|default('')|string|lower %} + {% set show_cfg = params.SHOW_CFG|default(0)|int %} + + {% set out = [] %} + + {% for key1 in printer %} + {% for key2 in printer[key1] %} + {% if (show_cfg or not (key1|lower == 'configfile' and key2|lower in ['config', 'settings'])) and (filter_name in key1|lower or filter_name in key2|lower) and filter_value in printer[key1][key2]|string|lower %} + {% set dummy = out.append("printer['%s'].%s = %s" % (key1, key2, printer[key1][key2])) %} + {% endif %} + {% else %} + {% if filter_name in key1|lower and filter_value in printer[key1]|string|lower %} + {% set dummy = out.append("printer['%s'] = %s" % (key1, printer[key1])) %} + {% endif %} + {% endfor %} + {% endfor %} + + {action_respond_info(out|join("\n"))} + + +#Аргументы +#NAME (строка) (обязательно) — укажите имя переменной, которую вы хотите получить. +#Примеры +#GET_VARIABLE NAME=toolhead: Возвращает значение и тип переменной printer.toolhead. +#GET_VARIABLE NAME=bed_mesh.profiles.default.points.1.0: Возвращает значение и тип переменной printer.bed_mesh.profiles.default.points[1][0]. +[gcode_macro GET_VARIABLE] +gcode: + {% set names = (params.NAME).split('.')|list %} + {% set join = (params.JOIN)|default(1)|int %} + + {% set _dummy0 = namespace( break = 0 ) %} + {% set _dummy1 = namespace( out = printer[names|first] ) %} + + {% for name in names if _dummy0.break == 0 %} + {% if loop.index > 1 %} + {% if name in _dummy1.out %} + {% set _dummy1.out = _dummy1.out[name] %} + {% elif name[0] in '0123456789' and _dummy1.out is iterable and _dummy1.out is not string and _dummy1.out is not mapping and _dummy1.out|length > name[0]|int %} + {% set _dummy1.out = _dummy1.out[name|int] %} + {% else %} + {% set _dummy0.break = loop.index0 %} + {% endif %} + {% endif %} + {% endfor %} + + {% if _dummy1.out is boolean %} + { action_respond_info('Type: boolean') } + {% elif _dummy1.out is float %} + { action_respond_info('Type: float') } + {% elif _dummy1.out is integer %} + { action_respond_info('Type: integer') } + {% elif _dummy1.out is mapping %} + { action_respond_info('Type: mapping') } + {% elif _dummy1.out is string %} + { action_respond_info('Type: string') } + {% elif _dummy1.out is iterable %} + { action_respond_info('Type: iterable') } + {% elif _dummy1.out is none %} + { action_respond_info('Type: none') } + {% elif _dummy1.out is undefined %} + { action_respond_info('Type: undefined') } + {% elif _dummy1.out is callable %} + { action_respond_info('Type: callable') } + {% else %} + { action_respond_info('Type: unknown') } + {% endif %} + + {% if join and _dummy1.out is iterable and _dummy1.out is not string and _dummy1.out is not mapping %} + { action_respond_info('%s' % _dummy1.out|join("\n")) } + {% else %} + { action_respond_info('%s' % _dummy1.out) } + {% endif %} + + {% if _dummy0.break != 0 %} + { action_respond_info('"printer.%s" does not contain "%s"!' % (names[0:_dummy0.break]|join('.'), names[_dummy0.break])) } + {% endif %} + diff --git a/mmu/addons/blobifier.cfg b/mmu/addons/blobifier.cfg new file mode 100644 index 0000000..abcd5f2 --- /dev/null +++ b/mmu/addons/blobifier.cfg @@ -0,0 +1,924 @@ +# Include servo hardware definition separately to allow for automatic upgrade +[include blobifier_hw.cfg] + +########################################################################################## + +# Sample config to be used in conjunction with Blobifier Purge Tray, Bucket & Nozzle +# Scrubber mod. Created by Dendrowen (dendrowen on Discord). The Macro is based on a +# version, and Nozzle Scrubber is made by Hernsl (hernsl#8860 on Discord). The device is +# designed around a Voron V2.4 300mm, but should work for 250mm and 350mm too. This +# version only supports the assembly on the rear-left of the bed. If you decide to change +# that, please consider contributing to the project by creating a pull request with the +# needed changes. + +# IMPORTANT: The rear-left part of your bed becomes unusable by this mod because the +# toolhead needs to lower down to 0. Be sure not to use the left-rear 130x35mm. + +# The goals of this combination of devices is to dispose of purged filament during a +# multicolored print without the need of a purge block and without the flurries of +# filament poops consuming your entire 3D printer room. The Blobifier achieves that by +# purging onto a retractable tray which causes the filament to turn into a tiny blob +# rather then a large spiral. This keeps the waste relatively small. The bucket should be +# able to account for up to 200 filament swaps (for the 300mm V2). + +# The Blobifier uses some room at the back-left side of your printer, depending on your +# printer limits and positions. (usually max_pos.y - toolhead_y and brush_start + +# brush_width + toolhead_x). If you do place objects within this region, Blobifier will +# skip purging automatically. It does this by extending the EXCLUDE_OBJECT_* macro's, so +# make sure you have exclude objects enabled in your slicer. + +# If your using Blobifier in conjunction with the filament cutter on the stealthburner +# toolhead, you can place the pin at max_pos.y - 7 (e.g., max pos y is 307, place it at +# 300). The pin will then poke through the cavity in your toolhead. (Be careful with +# manually moving the toolhead. I have broken many filament cutter pins) + +# It is advised to use the start_gcode from Happy Hare. Then you will be able to fully +# and efficiently use this mod. Check the Happy Hare document at gcode_preprocessing.md +# in the Happy Hare github for more details. + +###################################### DISCLAIMER ######################################## + +# You, and you alone, are responsible for the correct execution of these macros and +# gcodes. Any damage that may occur to your machine remains your responsibility. +# Especially when executing this macro for the first few times, keep an eye on your +# printer and the +# emergency stop. + +########################################################################################## + +########################################################################################## +# Main macro. Usually you should only need to call this one or place it in the Happy Hare +# _MMU_POST_LOAD macro using the variable_user_post_load_extension: +# +# variable_user_post_load_extension : `BLOBIFIER` +# +# Notes on parameters: +# PURGE_LENGTH=[float] (optional) The length to purge. If omitted (default) it will check +# the purge_volumes matrix or variable_purge_length. This can be used +# to override and for testing. +# +[gcode_macro BLOBIFIER] +# These parameters define your filament purging. +# Note that the control of retraction is set in 'mmu_macro_vars.cfg' which can be increased +# if you experience excessive oozing. +variable_purge_spd: 400 # Speed, in mm/min, of the purge. +variable_purge_temp_min: 200 # Minimum nozzle purge temperature. +variable_toolhead_x: 70 # From the nozzle to the left of your toolhead +variable_toolhead_y: 50 # From the nozzle to the front of your toolhead + +# This macro will prevent a gcode movement downward while 'blobbing' if there might be a +# print in the way (e.g. You print something large and need the area where Blobifier does +# its... 'business'). However, at low heights (or at print start) this might not be +# desireable. You can force a 'safe descend' with this variable. Keep in mind that the +# height of the print is an estimation based on previous heights and certain assumptions +# so it might be wise to include a safety margin of 0.2mm +variable_force_safe_descend_height_until: 1.0 + +# Adjust this so that your nozzle scrubs within the brush. Be careful not to go too low! +# Start out with a high value (like, 6) and go +# down from there. +variable_brush_top: 6 + +# These parameters define your scrubbing, travel speeds, safe z clearance and how many +# times you want to wipe. Update as necessary. +variable_clearance_z: 2 # When traveling, but not cleaning, the + # clearance along the z-axis between nozzle + # and brush. +variable_wipe_qty: 2 # Number of complete (A complete wipe: left, + # right, left OR right, left, right) wipes. +variable_travel_spd_xy: 10000 # Travel (not cleaning) speed along x and + # y-axis in mm/min. +variable_travel_spd_z: 1000 # Travel (not cleaning) speed along z axis + # in mm/min. +variable_wipe_spd_xy: 10000 # Nozzle wipe speed in mm/min. + +# The acceleration to use when using the brush action. If set to 0, it uses the already +# set acceleration. However, in some cases this is not desirable for the last motion +# could be an 'outer contour' acceleration which is usually lower. +variable_brush_accel: 0 + +# Blobifier sends the toolhead to the maximum y position during purge operations and +# minimum x position during shake operations. This can cause issues when skew correction +# is set up. If you have skew correction enabled and get 'move out of range' errors +# regarding blobifier while skew is enabled, try increasing this value. Keep the +# adjustments small though! (0.1mm - 0.5mm) and increase it until it works. +variable_skew_correction: 0.1 + +# These parameters define the size of the brush. Update as necessary. A visual reference +# is provided below. +# +# ← brush_width → +# _________________ +# | | ↑ Y position is acquired from your +# brush_start (x) | | brush_depth stepper_y position_max. Adjust +# |_________________| ↓ your brush physically in Y so +# (y) that the nozzle scrubs within the +# brush_front brush. +# __________________________________________________________ +# PRINTER FRONT +# +# +# Start location of the brush. Defaults for 250, 300 and 350mm are provided below. +# Uncomment as necessary +#variable_brush_start: 34 # For 250mm build +variable_brush_start: 67 # For 300mm build +#variable_brush_start: 84 # for 350mm build + +# width of the brush +variable_brush_width: 35 + +# Location of where to purge. The tray is 15mm in length, so if you assemble it against +# the side of the bed (default), 10mm is a good location +variable_purge_x: 10 + +# Height of the tray. If it's below your bed, give this a negative number equal to the +# difference. If it's above your bed, give it a positive number. You can find this number +# by homing, optional QGL or equivalent, and moving you toolhead above the tray, and +# lowering it with the paper method. +variable_tray_top: 0.7 + +# Servo angles for tray positions +variable_tray_angle_out: 0 +variable_tray_angle_in: 180 + +# Increase this value if the servo doesn't have enough time to fully retract or extend +variable_dwell_time: 200 + +# ======================================================================================== +# ==================== BLOB TUNING ======================================================= +# ======================================================================================== + +# The following section defines how the purging sequence is executed. This is where you +# tune the purging to create pretty blobs. Refer to the visual reference for a better +# understanding. The visual is populated with example values. Below are some guides +# provided to help with tuning. +# +# \_____________/ +# |___|___| +# \_/ ______________ < End of third iteration. +# / \ HEIGHT: 3 x iteration_z_raise - (2 + 1) x iteration_z_change (3 x 5 - 2 x 1.2 = 11.4) +# | | EXTRUDED: 3 x max_iteration_length (3 x 50 = 150) +# / \ ______________ < End of second iteration. +# | \ HEIGHT: 2 x iteration_z_raise - 1 x iteration_z_change (2 x 5 - 1 x 1.2 = 8.8) +# / | EXTRUDED: 2 x max_iteration_length (2 x 50 = 100) +# | \ ______________ < End of first iteration. +# / \ HEIGHT: 1 x iteration_z_raise (1 x 5 = 5) +# | | EXTRUDED: 1 x max_iteration_length (1 x 50 = 50) +#___________ \ / ______________ < Start height of the nozzle. default value: 1.5mm +# |_______________\___________/_ ______________ < Bottom of the tray +# |_____________________________| +# | +# +########################### BLOB TUNING ############################## +# +-------------------------------------+----------------------------+ +# | Filament sticks to the nozzle at | Incr. purge start | +# | initial purge (first few mm) | | +# +-------------------------------------+----------------------------+ +# | Filament scoots out from under | Incr. temperature | +# | the nozzle at the first iteration | Decr. z_raise | +# | | Incr. purge_length_maximum | +# +-------------------------------------+----------------------------+ +# | Filament scoots out from under the | Decr. purge_spd | +# | the nozzle at later iterations | Decr. z_raise_exp | +# | | Decr. z_raise | +# | | Incr. purge_length_maximum | +# +-------------------------------------+----------------------------+ +# | Filament sticks to the nozzle at | Incr. z_raise_exp | +# | later iterations | (Not above 1) | +# +-------------------------------------+----------------------------+ +# + +# The height to raise the nozzle above the tray before purging. This allows any built up +# pressure to escape before the purge. +variable_purge_start: 0.2 + +# The amount to raise Z +variable_z_raise: 12 + +# As the nozzle gets higher and the blob wider, the Z raise needs to be reduced, this +# follows the following formula: +# (extruded_amount/max_purge_length)^z_raise_exp * z_raise +# 1 is linear, below 1 will cause z to raise less quickly over time, above 1 will make it +# raise quicker over time. 0.85 is a good starting point and you should not have it above 1 +variable_z_raise_exp: 0.85 + +# Lift the nozzle slightly after creating the blob te release pressure on the tray. +variable_eject_hop: 1.0 + +# Dwell time (ms) after purging and before cleaning to relieve pressure from the nozzle. +variable_pressure_release_time: 1000 + +# Set the part cooling fan speed. Disabling can help prevent the nozzle from cooling down +# and stimulate flow, Enabling it can prevent blobs from sticking together. Values range +# from 0 .. 1, or -1 if you don't want it changed. +#variable_part_cooling_fan: -1 # Leave it unchanged +#variable_part_cooling_fan: 0 # Disable the fan +variable_part_cooling_fan: 1 # Run it at full speed + +# Define the part fan name if you are using a fan other than [fan] +# Applies to [fan_generic] or other fan definitons +# Example would be if you are using auxiliary fan control in Orcaslicer (https://github.com/SoftFever/OrcaSlicer/wiki/Auxiliary-fan) +# If you are unsure if you need this, then probably just leave it commented out. + +#variable_fan_name: "fan_generic fan0" + + + +# ======================================================================================== +# ==================== PURGE LENGTH TUNING =============================================== +# ======================================================================================== + +# The absolute minimum to purge, even if you don't changed tools. This is to prime the +# nozzle before printing +variable_purge_length_minimum: 30 + +# The maximum amount of filament (in mm¹) to purge in a single blob. Blobifier will +# automatically purge multiple blobs if the purge amount exceeds this. +variable_purge_length_maximum: 150 + +# Default purge length to fall back on when neither the tool map purge_volumes or +# parameter PURGE_LENGTH is set. +variable_purge_length: 150 + +# The slicer values often are a bit too wasteful. Tune it here to get optimal values. +# 0.6 (60%) is a good starting point. +variable_purge_length_modifier: 0.6 + +# Fixed length of filament to add after the purge volume calculation. Happy Hare already +# shares info on the extra amount of filament to purge based on known residual filament, +# tip cutting fragment and initial retraction setting. However this setting can add a fixed +# amount on top on that if necessary although it is recommended to start with 0 and tune +# slicer purge matrix first. +# When should you alter this value: +# INCREASE: When the dark to light swaps are good, but light to dark aren't. +# DECREASE: When the light to dark swaps are good, but dark to light aren't. Don't +# forget to increase the purge_length_modifier +variable_purge_length_addition: 0 + +# ======================================================================================== +# ==================== BUCKET ============================================================ +# ======================================================================================== + +# Maximum number of blobs that fit in the bucket. Pauses the print if it exceeds this +# number. +variable_max_blobs: 400 +# Enable the bucket shaker. You need to have the shaker.stl installed +variable_enable_shaker: 1 +# The number of back-and-forth motions of one shake +variable_bucket_shakes: 10 +# During shaking acceleration can often be higher because you don't need to keep print +# quality in mind. Higher acceleration helps better with dispersing the blobs. +variable_shake_accel: 10000 + +# The frequency at which to shake the bucket. A decimal value ranging from 0 to 1, where 0 +# is never, and 1 is every time. This way the shaking occurs more often as the bucket +# fills up. Sensible values range from 0.75 to 0.95 +variable_bucket_shake_frequency: 0.95 + +# Height of the shaker arm. If your hotend hits your tray during shaking, increase. +variable_shaker_arm_z: 2 + +gcode: + + # ====================================================================================== + # ==================== RECORD STATE (INCL. FANS, SPEEDS, ETC...) ======================= + # ====================================================================================== + + # General state + SAVE_GCODE_STATE NAME=BLOBIFIER_state + + + # ====================================================================================== + # ==================== CHECK HOMING STATUS ============================================= + # ====================================================================================== + + {% if "xyz" not in printer.toolhead.homed_axes %} + RESPOND MSG="BLOBIFIER: Not homed! Home xyz before blobbing" + {% elif printer.quad_gantry_level and printer.quad_gantry_level.applied == False %} + RESPOND MSG="BLOBIFIER: QGL not applied! run quad_gantry_level before blobbing" + {% else %} + + # Part cooling fan + {% if part_cooling_fan >= 0 %} + {% set fan = fan_name|string %} + # Save the part cooling fan speed to be enabled again later + {% set backup_fan_speed = (printer[fan].speed if printer[fan] is defined else printer.fan.speed) %} + # Set part cooling fan speed + M106 S{part_cooling_fan * 255} + {% endif %} + + # Set feedrate to 100% for correct speed purging + {% set backup_feedrate = printer.gcode_move.speed_factor %} + M220 S100 + + # ====================================================================================== + # ==================== DEFINE BASIC VARIABLES ========================================== + # ====================================================================================== + + {% set sequence_vars = printer['gcode_macro _MMU_SEQUENCE_VARS'] %} + {% set park_vars = printer['gcode_macro _MMU_PARK'] %} + {% set filament_diameter = printer.configfile.config.extruder.filament_diameter|float %} + {% set filament_cross_section = (filament_diameter/2) ** 2 * 3.1415 %} + {% set from_tool = printer.mmu.last_tool %} + {% set to_tool = printer.mmu.tool %} + {% set bl_count = printer['gcode_macro _BLOBIFIER_COUNT'] %} + {% set pos = printer.gcode_move.gcode_position %} + {% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %} + {% set ignore_safe = safe.print_height < force_safe_descend_height_until %} + {% set restore_z = [printer['gcode_macro BLOBIFIER_PARK'].restore_z,pos.z]|max %} + {% set pos_max = printer.toolhead.axis_maximum %} + {% set position_y = pos_max.y - skew_correction %} + + # Get purge volumes from the slicer (if set up right. see + # https://github.com/moggieuk/Happy-Hare/wiki/Gcode-Preprocessing) + {% set pv = printer.mmu.slicer_tool_map.purge_volumes %} + + # ====================================================================================== + # ==================== DETERMINE PURGE LENGTH ========================================== + # ====================================================================================== + + {% if params.PURGE_LENGTH %} # =============== PARAM PURGE LENGTH ====================== + {action_respond_info("BLOBIFIER: param PURGE_LENGTH provided")} + {% set purge_len = params.PURGE_LENGTH|float %} + {% elif from_tool == to_tool and to_tool >= 0 %} # ==== TOOL DIDN'T CHANGE ============= + {action_respond_info("BLOBIFIER: Tool didn't change (T%s > T%s), %s" % (from_tool, to_tool, "priming" if purge_length_minimum else "skipping"))} + {% set purge_len = 0 %} + + {% elif pv %} # ============== FETCH FROM HAPPY HARE (LIKELY FROM SLICER) ============== + {% if from_tool < 0 and to_tool >= 0%} + {action_respond_info("BLOBIFIER: from tool unknown. Finding largest value for T? > T%d" % to_tool)} + {% set purge_vol = pv|map(attribute=to_tool)|max %} + {% elif to_tool < 0 %} + {action_respond_info("BLOBIFIER: tool(s) unknown. Finding largest value")} + {% set purge_vol = pv|map('max')|max %} + {% else %} + {% set purge_vol = pv[from_tool][to_tool]|float * purge_length_modifier %} + {action_respond_info("BLOBIFIER: Swapped T%s > T%s" % (from_tool, to_tool))} + {% endif %} + {% set purge_len = purge_vol / filament_cross_section %} + + {% set purge_len = purge_len + printer.mmu.extruder_filament_remaining + park_vars.retracted_length + purge_length_addition %} + + {% else %} # ========================= USE CONFIG VARIABLE ============================= + {action_respond_info("BLOBIFIER: No toolmap or PURGE_LENGTH. Using default")} + {% set purge_len = purge_length|float + printer.mmu.extruder_filament_remaining + park_vars.retracted_length %} + {% endif %} + + # ==================================== APPLY PURGE MINIMUM ============================= + {% set purge_len = [purge_len,purge_length_minimum]|max|round(0, 'ceil')|int %} + {action_respond_info("BLOBIFIER: Purging %dmm of filament" % (purge_len))} + + # ====================================================================================== + # ==================== PURGING SEQUENCE ================================================ + # ====================================================================================== + + # Set to absolute positioning. + G90 + + # Check for purge length and purge if necessary. + {% if purge_len|float > 0 %} + + # ==================================================================================== + # ==================== POSITIONING =================================================== + # ==================================================================================== + + # Retract the tray so it is not in the way + BLOBIFIER_SERVO POS=in + + # Move to the assembly, first a bit more to the right (brush_start) to avoid a + # potential filametrix pin if it's not already on the same Y coordinate. + {% if printer.toolhead.position.y != position_y %} + G1 X{[brush_start - 20, 30]|max} Y{position_y} F{travel_spd_xy} + {% endif %} + + # ==================================================================================== + # ==================== BUCKET SHAKE ================================================== + # ==================================================================================== + + {% if enable_shaker and (safe.shake or ignore_safe) %} + {% if (bl_count.current_blobs + 1) >= bl_count.next_shake %} + BLOBIFIER_SHAKE_BUCKET SHAKES={bucket_shakes} + _BLOBIFIER_CALCULATE_NEXT_SHAKE + {% endif %} + {% endif %} + + # ==================================================================================== + # ==================== POSITIONING ON TRAY =========================================== + # ==================================================================================== + {% if safe.tray or ignore_safe %} + G1 Z{tray_top + purge_start} F{travel_spd_z} + {% endif %} + + # Move over to the tray after z change (For cases when the tool is lower than the tray) + G1 X{purge_x} F{travel_spd_xy} + + # Extend the tray + BLOBIFIER_SERVO POS=out + + # ==================================================================================== + # ==================== HEAT HOTEND =================================================== + # ==================================================================================== + + {% if printer.extruder.temperature < purge_temp_min %} + {% if printer.extruder.target < purge_temp_min %} + M109 S{purge_temp_min} + {% else %} + TEMPERATURE_WAIT SENSOR=extruder MINIMUM={purge_temp_min} + {% endif %} + {% endif %} + + # ==================================================================================== + # ==================== START ITERATING =============================================== + # ==================================================================================== + + # Calculate total number of iterations based on the purge length and the max_iteration + # length. + {% set blobs = (purge_len / purge_length_maximum)|round(0, 'ceil')|int %} + {% set purge_per_blob = purge_len|float / blobs %} + {% set retracts_per_blob = (purge_per_blob / 40)|round(0, 'ceil')|int %} + {% set purge_per_retract = (purge_per_blob / retracts_per_blob)|int %} + {% set pulses_per_retract = (purge_per_blob / retracts_per_blob / 5)|round(0, 'ceil')|int %} + {% set pulses_per_blob = (purge_per_blob / 5)|round(0, 'ceil')|int %} + {% set purge_per_pulse = purge_per_blob / pulses_per_blob %} + {% set pulse_time_constant = purge_per_pulse * 0.95 / purge_spd / (purge_per_pulse * 0.95 / purge_spd + purge_per_pulse * 0.05 / 50) %} + {% set pulse_duration = purge_per_pulse / purge_spd %} + + # Repeat the process until purge_len is reached + {% for blob in range(blobs) %} + RESPOND MSG={"'BLOBIFIER: Blob %d of %d (%.1fmm)'" % (blob + 1, blobs, purge_per_blob)} + + {% if safe.tray or ignore_safe %} + G1 Z{tray_top + purge_start} F{travel_spd_z} + {% endif %} + + # relative positioning + G91 + # relative extrusion + M83 + + # Purge filament in a pulsating motion to purge the filament quicker and better + {% for pulse in range(pulses_per_blob) %} + # Calculations to determine z-speed + {% set purged_this_blob = pulse * purge_per_pulse %} + {% set z_last_pos = purge_start + ((purged_this_blob)/purge_length_maximum)**z_raise_exp * z_raise %} + {% set z_pos = purge_start + ((purged_this_blob + purge_per_pulse)/purge_length_maximum)**z_raise_exp * z_raise %} + {% set z_up = z_pos - z_last_pos %} + {% set speed = z_up / pulse_duration %} + + # Purge quickly + G1 Z{z_up * pulse_time_constant} E{purge_per_pulse * 0.95} F{speed} + # Purge a tiny bit slowly + G1 Z{z_up * (1 - pulse_time_constant)} E{purge_per_pulse * 0.05} F{speed} + + # retract and unretract filament every now and then for thorough cleaning + {% if pulse % pulses_per_retract == 0 and pulse > 0 %} + G1 E-2 F1800 + G1 E2 F800 + {% endif %} + {% endfor %} + + # ================================================================================== + # ==================== DEPOSIT BLOB ================================================ + # ================================================================================== + {% if safe.tray or ignore_safe %} + # Raise z a bit to relieve pressure on the blob preventing it to go sideways + G1 Z{eject_hop} F{travel_spd_z} + # Retract the tray + BLOBIFIER_SERVO POS=in + # Move the toolhead down to purge_start height lowering the blob below the tray + G90 # absolute positioning + G1 Z{tray_top} F{travel_spd_z} + # Extend the tray to 'cut off' the blob and prepare for the next blob + BLOBIFIER_SERVO POS=out + BLOBIFIER_SERVO POS=in + BLOBIFIER_SERVO POS=out + # Keep track of the # of blobs + _BLOBIFIER_COUNT + {% endif %} + {% endfor %} + {% endif %} + {% if safe.tray or ignore_safe %} + G1 Z{tray_top + 1} F{travel_spd_z} + G4 P{pressure_release_time} + {% endif %} + {% if safe.brush or ignore_safe %} + BLOBIFIER_CLEAN + {% else %} + G1 X{brush_start} F{travel_spd_xy} + {% endif %} + + # ====================================================================================== + # ==================== RESTORE STATE =================================================== + # ====================================================================================== + + # Retract to match what Happy Hare is expecting + G1 E-{park_vars.retracted_length} F{sequence_vars.retract_speed * 60} + + G90 # absolute positioning + G1 Z{restore_z} F{travel_spd_z} + + {% if part_cooling_fan >= 0 %} + # Reset part cooling fan if it was changed + M106 S{(backup_fan_speed * 255)|int} + {% endif %} + + M220 S{(backup_feedrate * 100)|int} + {% endif %} + + # Retract the tray + BLOBIFIER_SERVO POS=in + + RESTORE_GCODE_STATE NAME=BLOBIFIER_state + + +########################################################################################## +# Wipes the nozzle on the brass brush +# +[gcode_macro BLOBIFIER_CLEAN] +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set pos_max = printer.toolhead.axis_maximum %} + {% set position_y = pos_max.y - bl.skew_correction %} + {% set original_accel = printer.toolhead.max_accel %} + {% set original_minimum_cruise_ratio = printer.toolhead.minimum_cruise_ratio %} + {% set pos = printer.gcode_move.gcode_position %} + + SAVE_GCODE_STATE NAME=BLOBIFIER_CLEAN_state + + G90 + + {% if bl.brush_accel > 0 %} + SET_VELOCITY_LIMIT ACCEL={bl.brush_accel} MINIMUM_CRUISE_RATIO=0.1 + {% endif %} + + {% if pos.z < bl.brush_top + bl.clearance_z %} + G1 Z{bl.brush_top + bl.clearance_z} F{bl.travel_spd_z} + {% endif %} + G1 X{bl.brush_start} F{bl.travel_spd_xy} + G1 Y{position_y} + G1 Z{bl.brush_top + bl.clearance_z} F{bl.travel_spd_z} + + # Move nozzle down into brush. + G1 Z{bl.brush_top} F{bl.travel_spd_z} + + SET_VELOCITY_LIMIT ACCEL={original_accel} MINIMUM_CRUISE_RATIO={original_minimum_cruise_ratio} + + # Perform wipe. Wipe direction based off bucket_pos for cool random scrubby routine. + {% for wipes in range(1, (bl.wipe_qty + 1)) %} + G1 X{bl.brush_start + bl.brush_width} F{bl.wipe_spd_xy} + G1 X{bl.brush_start} F{bl.wipe_spd_xy} + {% endfor %} + + # Move away from the brush, but not onto the tray or in front of the filametrix cutter pin + G1 X{[bl.brush_start - 20, 30]|max} F{bl.travel_spd_xy} + + RESTORE_GCODE_STATE NAME=BLOBIFIER_CLEAN_state + + + +########################################################################################## +# Park the nozzle on the tray to prevent oozing during filament swaps. Place this +# extension in the post_form_tip extension in mmu_macro_vars.cfg: +# variable_user_post_form_tip_extension: "BLOBIFIER_PARK" +# +[gcode_macro BLOBIFIER_PARK] +variable_restore_z: 0 +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set pos = printer.gcode_move.gcode_position %} + {% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %} + {% set pos_max = printer.toolhead.axis_maximum %} + {% set position_y = pos_max.y - bl.skew_correction %} + + SET_GCODE_VARIABLE MACRO=BLOBIFIER_PARK VARIABLE=restore_z VALUE={pos.z} + + SAVE_GCODE_STATE NAME=blobifier_park_state + + {% if "xyz" in printer.toolhead.homed_axes and printer.quad_gantry_level and printer.quad_gantry_level.applied %} + G90 + + # Retract the tray + BLOBIFIER_SERVO POS=in + + G1 X{[bl.brush_start - 20, 30]|max} Y{position_y} F{bl.travel_spd_xy} + {% if safe.tray or ignore_safe %} + G1 Z{bl.tray_top} F{bl.travel_spd_z} + {% endif %} + G1 X{bl.purge_x} F{bl.travel_spd_xy} + + # Extend the tray + BLOBIFIER_SERVO POS=out + + {% else %} + RESPOND MSG="Please home (and QGL) before parking" + {% endif %} + + RESTORE_GCODE_STATE NAME=blobifier_park_state + +########################################################################################## +# Retract or extend the tray +# POS=[in|out] Retractor extend the tray +# +[gcode_macro BLOBIFIER_SERVO] +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set pos = params.POS %} + {% if pos == "in" %} + SET_SERVO SERVO=blobifier ANGLE={bl.tray_angle_in} + G4 P{bl.dwell_time} + {% elif pos == "out" %} + SET_SERVO SERVO=blobifier ANGLE={bl.tray_angle_out} + G4 P{bl.dwell_time} + {% else %} + {action_respond_info("BLOBIFIER: provide POS=[in|out]")} + {% endif %} + SET_SERVO SERVO=blobifier WIDTH=0 + +########################################################################################## +# Define exclude objects for those who haven't already +# +[exclude_object] + +########################################################################################## +# Overwrite the existing EXCLUDE_OBJECT_DEFINE to also check for safe descend. +# +[gcode_macro EXCLUDE_OBJECT_DEFINE] +rename_existing: _EXCLUDE_OBJECT_DEFINE +gcode: + # only reset on the first object at the beginning of a print + {% if printer.exclude_object.objects|length < 1 %} + _BLOBIFIER_RESET_SAFE_DESCEND + {% endif %} + _EXCLUDE_OBJECT_DEFINE {rawparams} + _BLOBIFIER_SAFE_DESCEND + UPDATE_DELAYED_GCODE ID=BLOBIFIER_SHOW_SAFE_DESCEND DURATION=1 + +[delayed_gcode BLOBIFIER_SHOW_SAFE_DESCEND] +gcode: + {% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %} + {action_respond_info( + "BLOBIFIER: Safe descend possible:\n - tray: %s\n - brush: %s\n - shake: %s" % + ( + "yes" if safe.tray else "no", + "yes" if safe.brush else "no", + "yes" if safe.shake else "no" + ) + )} + +########################################################################################## +# Use the EXCLUDE_OBJECT_START gcode macro to record the current height +# +[gcode_macro EXCLUDE_OBJECT_START] +rename_existing: _EXCLUDE_OBJECT_START +gcode: + _EXCLUDE_OBJECT_START {rawparams} + {% if printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'].first_layer %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=first_layer VALUE=False + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_height VALUE={printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'].print_layer_height} + {% else %} + {% set pos = printer.gcode_move.gcode_position %} + {% set last_height = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'].print_previous_height|float %} + {% if pos.z > last_height %} + {% set last_layer = (pos.z - last_height)|round(2) %} + {% set print_height = (pos.z + last_layer)|round(2) %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_previous_height VALUE={pos.z} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_height VALUE={print_height} + {% endif %} + {% endif %} + +########################################################################################## +# Reset the safe descend variables. +# +[gcode_macro _BLOBIFIER_RESET_SAFE_DESCEND] +gcode: + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=tray VALUE=True + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=brush VALUE=True + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=shake VALUE=True + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=first_layer VALUE=True + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_height VALUE=0 + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=print_previous_height VALUE=0 + +########################################################################################## +# Determine if it is safe to drop the toolhead (e.g. not hit a print) +# +[gcode_macro _BLOBIFIER_SAFE_DESCEND] +variable_tray: True # Assume it is safe +variable_brush: True +variable_shake: True +variable_first_layer: True +variable_print_height: 0 +variable_print_previous_height: 0 +variable_print_layer_height: 0.3 +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set pos_max = printer.toolhead.axis_maximum %} + {% set position_y = pos_max.y - bl.skew_correction %} + {% set tray = [bl.purge_x + bl.toolhead_x, position_y - bl.toolhead_y] %} + {% set brush = [bl.brush_start + bl.brush_width + bl.toolhead_x, position_y - bl.toolhead_y] %} + {% set shake = [bl.purge_x + bl.toolhead_x, position_y - bl.toolhead_y - 4] %} + {% set objects = printer.exclude_object.objects | map(attribute='polygon') %} + + {% for polygon in objects %} + {% for point in polygon %} + {% if point[0] < tray[0] and point[1] > tray[1] %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=tray VALUE=False + {% endif %} + {% if point[0] < brush[0] and point[1] > brush[1] %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=brush VALUE=False + {% endif %} + {% if point[0] < shake[0] and point[1] > shake[1] %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=shake VALUE=False + {% endif %} + {% endfor %} + {% endfor %} + +########################################################################################## +# Increment the blob count with 1 and check if the bucket is full. Pause +# the printer if it is. +# +[gcode_macro _BLOBIFIER_COUNT] +# Don't change these variables +variable_current_blobs: 0 +variable_last_shake: 0 +variable_next_shake: 0 +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} + {% if current_blobs >= bl.max_blobs %} + {action_respond_info("BLOBIFIER: Empty purge bucket!")} + M117 Empty purge bucket! + MMU_PAUSE MSG="Empty purge bucket!" + {% else %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE={current_blobs + 1} + _BLOBIFIER_SAVE_STATE + {action_respond_info( + "BLOBIFIER: Blobs in bucket: %s/%s. Next shake @ %s" + % (current_blobs + 1, bl.max_blobs, next_shake) + )} + {% endif %} + +########################################################################################## +# Reset the blob count to 0 +# +[gcode_macro _BLOBIFIER_COUNT_RESET] +gcode: + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE=0 + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=last_shake VALUE=0 + _BLOBIFIER_SAVE_STATE + + _BLOBIFIER_CALCULATE_NEXT_SHAKE + +########################################################################################## +# Shake the blob bucket to disperse the blobs +# +[gcode_macro BLOBIFIER_SHAKE_BUCKET] +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} + {% set original_accel = printer.toolhead.max_accel %} + {% set original_minimum_cruise_ratio = printer.toolhead.minimum_cruise_ratio %} + {% set position_x = bl.skew_correction %} + + {% if "xyz" not in printer.toolhead.homed_axes %} + {action_raise_error("BLOBIFIER: Not homed. Home xyz first")} + {% endif %} + + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=last_shake VALUE={count.current_blobs} + _BLOBIFIER_SAVE_STATE + SAVE_GCODE_STATE NAME=shake_bucket + + M400 + M117 (^_^) + + G90 + {% set shakes = params.SHAKES|default(10)|int %} + {% set pos_max = printer.toolhead.axis_maximum %} + {% set position_y = pos_max.y - bl.skew_correction %} + + # move to save y if not already there + {% if printer.toolhead.position.y != position_y %} + G1 X{bl.brush_start} Y{position_y} F{bl.travel_spd_xy} + {% endif %} + + # Retract the tray + BLOBIFIER_SERVO POS=in + + # move up a bit to prevent oozing on base + G1 Z{bl.shaker_arm_z} F{bl.travel_spd_z} + # slide into the slot + G1 X{position_x} F{bl.travel_spd_xy} + + M400 + M117 (+(+_+)+) + + SET_VELOCITY_LIMIT ACCEL={bl.shake_accel} MINIMUM_CRUISE_RATIO=0.1 + + # Shake away! + {% for shake in range(1, shakes) %} + G1 Y{position_y - 4} + G1 Y{position_y} + {% endfor %} + + SET_VELOCITY_LIMIT ACCEL={original_accel} MINIMUM_CRUISE_RATIO={original_minimum_cruise_ratio} + # move out of slot + G1 X{bl.purge_x} + + M400 + M117 (X_x) + + RESTORE_GCODE_STATE NAME=shake_bucket + +########################################################################################## +# Calculate when the bucket should be shaken. +# +[gcode_macro _BLOBIFIER_CALCULATE_NEXT_SHAKE] +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} + + {% set remaining_blobs = bl.max_blobs - count.last_shake %} + {% set next_shake = (1 - bl.bucket_shake_frequency) * remaining_blobs + count.last_shake %} + _BLOBIFIER_SAVE_STATE + _BLOBIFIER_SET_NEXT_SHAKE VALUE={next_shake|int} + +########################################################################################## +# Set when the bucket should be shaken next +# VALUE=[int] At what amount of blobs should it be shaken +# +[gcode_macro _BLOBIFIER_SET_NEXT_SHAKE] +gcode: + {% if params.VALUE %} + {% set next_shake = params.VALUE %} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=next_shake VALUE={next_shake} + _BLOBIFIER_SAVE_STATE + {% else %} + {action_respond_info("BLOBIFIER: Provide parameter VALUE=")} + {% endif %} + +########################################################################################## +# Some sanity checks +# +[delayed_gcode BLOBIFIER_INIT] +initial_duration: 5.0 +gcode: + _BLOBIFIER_INIT + # Extend and retract the tray to test + BLOBIFIER_SERVO POS=out + BLOBIFIER_SERVO POS=in + +[gcode_macro _BLOBIFIER_INIT] +gcode: + {% set bl = printer['gcode_macro BLOBIFIER'] %} + + # Valid part cooling fan setting + {% if bl.part_cooling_fan != -1 and (bl.part_cooling_fan < 0 or bl.part_cooling_fan > 1) %} + {action_emergency_stop("BLOBIFIER: Value %f is invalid for variable part_cooling_fan. Either -1 or a value from 0 .. 1 is valid." % (bl.part_cooling_fan))} + {% endif %} + + # Valid bucket shake frequency + {% if bl.bucket_shake_frequency < 0 or bl.bucket_shake_frequency > 1 %} + {action_emergency_stop("BLOBIFIER: Value %f is invalid for variable bucket_shake_frequency. Change it to a value between 0 .. 1" % (bl.bucket_shake_frequency))} + {% endif %} + + # Check if position is on 'next' + {% if printer.mmu %} + {% if printer['gcode_macro _MMU_SEQUENCE_VARS'].restore_xy_pos != 'next' %} + {action_respond_info("BLOBIFIER: If not using a wipe tower, consider setting restore_xy_pos: 'next' in mmu_macro_vars.cfg")} + {% endif %} + {% endif %} + + # Check the z_raise variable for normal values + {% if bl.z_raise < 3 %} + {action_respond_info("BLOBIFIER: variable_z_raise: %f is very low. This is the value z raises in total on a single blob. Make sure the value is correct before continuing." % (bl.z_raise))} + {% endif %} + + # Z raise exponent + {% if bl.z_raise_exp > 1 or bl.z_raise_exp < 0.5 %} + {action_respond_info("BLOBIFIER: variable_z_raise_exp has value: %f. This value is out of spec (0.5 ... 1.0)." % (bl.z_raise_exp))} + {% endif %} + + # cap user defined accels at printer max_accel if greater + {% if bl.shake_accel > printer.configfile.config.printer.max_accel|int %} + {action_respond_info("BLOBIFIER: variable_shake_accel has value: %d which is higher than your printer limit of %d. Reduce this if your printer skips steps." % (bl.shake_accel,printer.configfile.config.printer.max_accel|int))} + {% endif %} + {% if bl.brush_accel > printer.configfile.config.printer.max_accel|int %} + {action_respond_info("BLOBIFIER: variable_brush_accel has value: %d which is higher than your printer limit of %d. Reduce this if your printer skips steps." % (bl.brush_accel,printer.configfile.config.printer.max_accel|int))} + {% endif %} + +[delayed_gcode BLOBIFIER_LOAD_STATE] +initial_duration: 2.0 # Give it some time to boot up +gcode: + {% set sv = printer.save_variables.variables.blobifier %} + + {% if sv %} + # Restore state + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=last_shake VALUE={sv.last_shake} + SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE={sv.current_blobs} + {% endif %} + _BLOBIFIER_CALCULATE_NEXT_SHAKE + +[gcode_macro _BLOBIFIER_SAVE_STATE] +gcode: + {% set count = printer['gcode_macro _BLOBIFIER_COUNT'] %} + {% set sv = {'current_blobs': count.current_blobs, 'last_shake': count.last_shake} %} + SAVE_VARIABLE VARIABLE=blobifier VALUE="{sv}" diff --git a/mmu/addons/blobifier_hw.cfg b/mmu/addons/blobifier_hw.cfg new file mode 100644 index 0000000..5f76ae8 --- /dev/null +++ b/mmu/addons/blobifier_hw.cfg @@ -0,0 +1,28 @@ + +########################################################################################## +# The servo hardware configuration. Change the values to your needs. +# +[mmu_servo blobifier] +# Pin for the servo. +pin: PG14 +# Adjust this value until a 'BLOBIFIER_SERVO POS=out' extends the tray fully without a +# buzzing sound +minimum_pulse_width: 0.00053 +# Adjust this value until a 'BLOBIFIER_SERVO POS=in' retracts the tray fully without a +# buzzing sound +maximum_pulse_width: 0.0023 +# Leave this value at 180 +maximum_servo_angle: 180 + + +########################################################################################## +# The bucket hardware configuration. Change the pin to whatever pin you've connected the +# switch to. +# +[gcode_button bucket] +pin: ^PG15 # The pullup ( ^ ) is important here. +press_gcode: + M117 bucket installed +release_gcode: + M117 bucket removed + _BLOBIFIER_COUNT_RESET diff --git a/mmu/addons/mmu_eject_buttons.cfg b/mmu/addons/mmu_eject_buttons.cfg new file mode 100644 index 0000000..59080b6 --- /dev/null +++ b/mmu/addons/mmu_eject_buttons.cfg @@ -0,0 +1,31 @@ +# Include servo hardware definition separately to allow for automatic upgrade +[include mmu_eject_buttons_hw.cfg] + +########################################################################### +# Optional hardware MMU eject buttons (e.g. QuattroBox) +# +# This is the supplementary macro to support dedicated per-gate eject +# buttons for easy unloading. It is complimentary to the built-in auto +# preload of filament +# +# To configure: +# 1. Add this to your printer.cfg: +# +# [include mmu/addons/mmu_eject_buttons.cfg] +# + +########################################################################### +# Macro to simply call MMU_EJECT for the specified gate +# +# This logic is separated from actual button h/w setup to facilitate upgrades +# and to allow addition of logic (perhaps validation or warning logic) +# +[gcode_macro _MMU_EJECT_BUTTON] +description: Wrapper around ejecting filament via dedicated hardware buttons +gcode: + {% set gate = params.GATE|default(-1)|int %} + {% set mmu = printer['mmu'] %} + {% set current_gate = mmu.gate %} + + # TODO add validation and warning logic + MMU_EJECT GATE={gate} diff --git a/mmu/addons/mmu_eject_buttons_hw.cfg b/mmu/addons/mmu_eject_buttons_hw.cfg new file mode 100644 index 0000000..693ee57 --- /dev/null +++ b/mmu/addons/mmu_eject_buttons_hw.cfg @@ -0,0 +1,21 @@ + +########################################################################################## +# The eject button hardware configuration. Change the values to your needs and number +# of gates +# + +[gcode_button mmu_eject_button_0] +pin: mmu:EJECT_BUTTON_0 +press_gcode: _MMU_EJECT_BUTTON GATE=0 + +[gcode_button mmu_eject_button_1] +pin: mmu:EJECT_BUTTON_1 +press_gcode: _MMU_EJECT_BUTTON GATE=1 + +[gcode_button mmu_eject_button_2] +pin: mmu:EJECT_BUTTON_2 +press_gcode: _MMU_EJECT_BUTTON GATE=2 + +[gcode_button mmu_eject_button_3] +pin: mmu:EJECT_BUTTON_3 +press_gcode: _MMU_EJECT_BUTTON GATE=3 diff --git a/mmu/addons/mmu_erec_cutter.cfg b/mmu/addons/mmu_erec_cutter.cfg new file mode 100644 index 0000000..12e1d53 --- /dev/null +++ b/mmu/addons/mmu_erec_cutter.cfg @@ -0,0 +1,91 @@ +# Include servo hardware definition separately to allow for automatic upgrade +[include mmu_erec_cutter_hw.cfg] + +########################################################################### +# Optional EREC Filament Cutter Support +# +# https://github.com/kevinakasam/ERCF_Filament_Cutter +# +# This is the supplementary macro to support filament cutting at the MMU +# on a ERCF design. +# +# To configure: +# 1. Add this to your printer.cfg: +# +# [include mmu/addons/mmu_erec_cutter.cfg] +# +# 2. In mmu_macro_vars.cfg, change this line: +# +# variable_user_post_unload_extension : "EREC_CUTTER_ACTION" +# +# 3. Tune the servo configuration and macro "variables" below +# + +# EREC CUTTER CONFIGURATION ----------------------------------------------- +# (addons/mmu_erec_cutter.cfg) +# +[gcode_macro _EREC_VARS] +description: Empty macro to store the variables +gcode: # Leave empty + +# These variables control the servo movement +variable_servo_closed_angle : 70 ; Servo angle for closed position with bowden aligned MMU +variable_servo_open_angle : 10 ; Servo angle to open up the cutter and move bowden away from MMU +variable_servo_duration : 1.5 ; Time (s) of PWM pulse train to activate servo +variable_servo_idle_time : 1.8 ; Time (s) to let the servo to reach it's position + +# Controls for feed and cut lengths +variable_feed_length : 48 ; Distance in mm from gate parking position to blade (ERCFv1.1: 58, v2/other: 48) +variable_cut_length : 10 ; Amount in mm of filament to cut +variable_cut_attempts : 1 ; Number of times the cutter tries to cut the filament + + +########################################################################### +# Macro to perform the cutting step. Designed to be included to the +# _MMU_POST_UNLOAD step +# +[gcode_macro EREC_CUTTER_ACTION] +description: Cut off the filament tip at the MMU after the unload sequence is complete +gcode: + {% set vars = printer["gcode_macro _EREC_VARS"] %} + + MMU_LOG MSG="Cutting filament tip..." + + _CUTTER_OPEN + _MMU_STEP_MOVE MOVE={vars.feed_length + vars.cut_length} + {% for i in range(vars.cut_attempts - 1) %} + _CUTTER_CLOSE + _CUTTER_OPEN + {% endfor %} + _MMU_STEP_MOVE MOVE=-1 + _CUTTER_CLOSE + _MMU_EVENT EVENT="filament_cut" # Count as one cut for consumption counter + + _MMU_STEP_SET_FILAMENT STATE=2 # FILAMENT_POS_START_BOWDEN + _MMU_STEP_UNLOAD_GATE # Repeat gate parking move + _MMU_M400 # Wait on both move queues + +[gcode_macro _CUTTER_ANGLE] +description: Helper macro to set cutter servo angle +gcode: + {% set angle = params.ANGLE|default(0)|int %} + SET_SERVO SERVO=cut_servo ANGLE={angle} + +[gcode_macro _CUTTER_CLOSE] +description: Helper macro to set cutting servo the closed position +gcode: + {% set vars = printer["gcode_macro _EREC_VARS"] %} + SET_SERVO SERVO=cut_servo ANGLE={vars.servo_closed_angle} DURATION={vars.servo_duration} + G4 P{vars.servo_idle_time * 1000} + RESPOND MSG="EREC Cutter closed" + M400 + +[gcode_macro _CUTTER_OPEN] +description: Helper macro to set cutting servo the open position +gcode: + {% set vars = printer["gcode_macro _EREC_VARS"] %} + SET_SERVO SERVO=cut_servo ANGLE={vars.servo_open_angle} DURATION={vars.servo_duration} + G4 P{vars.servo_idle_time * 1000} + RESPOND MSG="EREC Cutter open" + M400 + diff --git a/mmu/addons/mmu_erec_cutter_hw.cfg b/mmu/addons/mmu_erec_cutter_hw.cfg new file mode 100644 index 0000000..4fec0c1 --- /dev/null +++ b/mmu/addons/mmu_erec_cutter_hw.cfg @@ -0,0 +1,10 @@ + +########################################################################################## +# The servo hardware configuration. Change the values to your needs. +# +[mmu_servo cut_servo] +pin: mmu:PA7 # Extra Pin on the ERCF easy Board +maximum_servo_angle: 180 # Set this to 60 for a 60° Servo +minimum_pulse_width: 0.0005 # Adapt these for your servo +maximum_pulse_width: 0.0025 # Adapt these for your servo + diff --git a/mmu/base/bigtreetech-mmb-ercf.cfg.bkp b/mmu/base/bigtreetech-mmb-ercf.cfg.bkp new file mode 100644 index 0000000..1bcf2e9 --- /dev/null +++ b/mmu/base/bigtreetech-mmb-ercf.cfg.bkp @@ -0,0 +1,123 @@ +[mcu ercf] +canbus_uuid=a76ed81c1ca6 + +# FILAMENT DRIVE GEAR STEPPER --------------------------------------------------------------------------------------------- +# Adapt accordingly to your setup and desires +# The default values are tested with the BOM NEMA14 motor +# Please adapt these values to the motor you are using +# Example : for NEMA17 motors, you'll usually set the stealthchop_threshold to 0 +# and use higher current +[tmc2209 manual_extruder_stepper gear_stepper] +uart_pin: ercf:PA10 +# uart_address: 0 +interpolate: True +run_current: 0.9 # NEMA14 motor +hold_current: 0.4 # Can be small +sense_resistor: 0.110 +stealthchop_threshold: 0 # 999999 to enable stealthChop +driver_IHOLDDELAY: 8 +driver_TPOWERDOWN: 20 +driver_TBL: 2 +driver_TOFF: 3 +driver_HEND: 1 +driver_HSTRT: 3 +driver_PWM_AUTOGRAD: True +driver_PWM_AUTOSCALE: True +driver_PWM_LIM: 12 +driver_PWM_REG: 8 +driver_PWM_FREQ: 1 +driver_PWM_GRAD: 14 +driver_PWM_OFS: 36 +driver_SGTHRS: 0 + +[manual_extruder_stepper gear_stepper] +step_pin: ercf:PB15 +dir_pin: ercf:PB14 +enable_pin: !ercf:PA8 # V1.0 +# enable_pin: !ercf:PB8 # V1.1 +rotation_distance: 22.7316868 # Bondtech 5mm Drive Gears. Must be manually verified and tuned. +gear_ratio: 50:17 +microsteps: 8 # Recommend 8 or 16. Try both to avoid Klipper 'Timer too close' error (also try adjusting num_moves) +full_steps_per_rotation: 200 # 200 for 1.8 degree, 400 for 0.9 degree +velocity: 50 +accel: 400 +# +# Uncomment if you want to use sensorless SELECTOR with the ERCF EASY BRD (yes, this is on the gear stepper!) +# This should be the pin of the physical selector endstop and is used to determine the difference between the true +# endstop and a blockage preventing selector movement. Don't forget to set 'sensorless_selector: 0' in ercf_parameters.cfg +endstop_pin: ^ercf:PD9 # Comment if using physical endstop switch (default) + + +# SELECTOR STEPPER -------------------------------------------------------------------------------------------------------- +[tmc2209 manual_stepper selector_stepper] +uart_pin: ercf:PC7 +# uart_address: 1 +run_current: 0.8 # NEMA17 motor +hold_current: 0.3 # Can be small if not using sensorless selector +interpolate: True +sense_resistor: 0.0750 +stealthchop_threshold: 0 # 999999 to enable stealthChop +driver_IHOLDDELAY: 8 +driver_TPOWERDOWN: 20 +driver_TBL: 2 +driver_TOFF: 3 +driver_HEND: 1 +driver_HSTRT: 3 +driver_PWM_AUTOGRAD: True +driver_PWM_AUTOSCALE: True +driver_PWM_LIM: 12 +driver_PWM_REG: 8 +driver_PWM_FREQ: 1 +driver_PWM_GRAD: 14 +driver_PWM_OFS: 36 +driver_SGTHRS: 0 +# Uncomment the lines below if you want to use sensorless selector homing +# (and configure ercf_parameters.cfg correctly) +# or comment out if using physical endstop switch (default) +#diag_pin: ^{selector_diag_pin} # Set to MCU pin connected to TMC DIAG pin +#driver_SGTHRS: 75 # 255 is most sensitive value, 0 is least sensitive + +[manual_stepper selector_stepper] +step_pin: ercf:PD2 +dir_pin: ercf:PB13 +enable_pin: !ercf:PD1 +rotation_distance: 40 +microsteps: 16 # Don't need high fidelity +full_steps_per_rotation: 200 # 200 for 1.8 degree, 400 for 0.9 degree +velocity: 200 +accel: 600 +# +# Select the endstop switch physical (for normal selector) or virtual (sensorless selector homing) +#endstop_pin: tmc2209_selector_stepper:virtual_endstop # Uncomment for sensorless selector homing +endstop_pin: ^ercf:PA3 + +# SELECTOR SERVO ----------------------------------------------------------------------------------------------------------- +[ercf_servo ercf_servo] +pin: ercf:PA0 +maximum_servo_angle: 180 +minimum_pulse_width: 0.00085 +maximum_pulse_width: 0.00215 + + +## ENCODER ----------------------------------------------------------------------------------------------------------------- +## The encoder_resolution is determined by running the ERCF_CALIBRATE_ENCODER. Be sure to read the manual +[ercf_encoder ercf_encoder] +encoder_pin: ^ercf:PA4 +encoder_resolution: 1.344990 # Set AFTER 'rotation_distance' is tuned for gear stepper (see manual) +extruder: extruder # The extruder to track with for runout/clog detection + +# These are advanced but settings for Automatic clog detection mode. Make sure you understand or ask questions on Discord +desired_headroom: 8.0 # The runout headroom that ERCF will attempt to maintain (closest ERCF comes to triggering runout) +average_samples: 4 # The "damping" effect of last measurement. Higher value means clog_length will be reduced more slowly + + +## TOOLHEAD SENSOR --------------------------------------------------------------------------------------------------------- +# Uncomment this section to enable toolhead sensor support +# +# ERCF Toolhead sensor START +#[filament_switch_sensor toolhead_sensor] +#pause_on_runout: False # Must be False +#switch_pin: ^EBBCan:PB9 +# ERCF Toolhead sensor END + + diff --git a/mmu/base/mmu.cfg b/mmu/base/mmu.cfg new file mode 100644 index 0000000..13ea2d3 --- /dev/null +++ b/mmu/base/mmu.cfg @@ -0,0 +1,118 @@ +######################################################################################################################## +# Happy Hare MMU Software +# +# EDIT THIS FILE BASED ON YOUR SETUP +# +# Copyright (C) 2022-2025 moggieuk#6538 (discord) +# moggieuk@hotmail.com +# This file may be distributed under the terms of the GNU GPLv3 license. +# +# Goal: Happy Hare MMU hardware pin config +# +# (\_/) +# ( *,*) +# (")_(") Happy Hare Ready +# +# +# This contains aliases for pins for MCU type MMB11 +# +[mcu mmu] +canbus_uuid=a76ed81c1ca6 + + +# PIN ALIASES FOR MMU MCU BOARD ---------------------------------------------------------------------------------------- +# ██████╗ ██╗███╗ ██╗ █████╗ ██╗ ██╗ █████╗ ███████╗ +# ██╔══██╗██║████╗ ██║ ██╔══██╗██║ ██║██╔══██╗██╔════╝ +# ██████╔╝██║██╔██╗ ██║ ███████║██║ ██║███████║███████╗ +# ██╔═══╝ ██║██║╚██╗██║ ██╔══██║██║ ██║██╔══██║╚════██║ +# ██║ ██║██║ ╚████║ ██║ ██║███████╗██║██║ ██║███████║ +# ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═╝╚══════╝ +# Section to create alias for pins used by MMU for easier integration into Klippain and RatOS. The names match those +# referenced in the mmu_hardware.cfg file. If you get into difficulty you can also comment out this aliases definition +# completely and configure the pin names directly into mmu_hardware.cfg. However, use of aliases is encouraged. + +# Note: that aliases are not created for TOOLHEAD_SENSOR, EXTRUDER_SENSOR or SYNC_FEEDBACK_SENSORS because those are +# most likely on the printer's main mcu. These should be set directly in mmu_hardware.cfg +# +[board_pins mmu] +mcu: mmu # Assumes using an external / extra mcu dedicated to MMU +aliases: + MMU_GEAR_UART=PA10, + MMU_GEAR_STEP=PB15, + MMU_GEAR_DIR=PB14, + MMU_GEAR_ENABLE=PB8, + MMU_GEAR_DIAG=PA3, + + MMU_GEAR_UART_1=, + MMU_GEAR_STEP_1=, + MMU_GEAR_DIR_1=, + MMU_GEAR_ENABLE_1=, + MMU_GEAR_DIAG_1=, + + MMU_GEAR_UART_2=, + MMU_GEAR_STEP_2=, + MMU_GEAR_DIR_2=, + MMU_GEAR_ENABLE_2=, + MMU_GEAR_DIAG_2=, + + MMU_GEAR_UART_3=, + MMU_GEAR_STEP_3=, + MMU_GEAR_DIR_3=, + MMU_GEAR_ENABLE_3=, + MMU_GEAR_DIAG_3=, + + MMU_SEL_UART=PC7, + MMU_SEL_STEP=PD2, + MMU_SEL_DIR=PB13, + MMU_SEL_ENABLE=PD1, + MMU_SEL_DIAG=PA4, + MMU_SEL_ENDSTOP=PB2, + MMU_SEL_SERVO=PA0, + + MMU_ENCODER=PA1, + MMU_GATE_SENSOR=, + MMU_NEOPIXEL=PA2, + + MMU_PRE_GATE_0=PB9, + MMU_PRE_GATE_1=PA8, + MMU_PRE_GATE_2=PC15, + MMU_PRE_GATE_3=PC13, + MMU_PRE_GATE_4=PC14, + MMU_PRE_GATE_5=PB12, + MMU_PRE_GATE_6=PB11, + MMU_PRE_GATE_7=PB10, + MMU_PRE_GATE_8=, + MMU_PRE_GATE_9=, + MMU_PRE_GATE_10=, + MMU_PRE_GATE_11=, + + MMU_POST_GEAR_0=, + MMU_POST_GEAR_1=, + MMU_POST_GEAR_2=, + MMU_POST_GEAR_3=, + MMU_POST_GEAR_4=, + MMU_POST_GEAR_5=, + MMU_POST_GEAR_6=, + MMU_POST_GEAR_7=, + MMU_POST_GEAR_8=, + MMU_POST_GEAR_9=, + MMU_POST_GEAR_10=, + MMU_POST_GEAR_11=, + + MMU_ESPOOLER_RWD_0={espooler_rwd_0_pin}, + MMU_ESPOOLER_FWD_0={espooler_fwd_0_pin}, + MMU_ESPOOLER_EN_0={espooler_en_0_pin}, + MMU_ESPOOLER_TRIG_0=, + MMU_ESPOOLER_RWD_1={espooler_rwd_1_pin}, + MMU_ESPOOLER_FWD_1={espooler_fwd_1_pin}, + MMU_ESPOOLER_EN_1={espooler_en_1_pin}, + MMU_ESPOOLER_TRIG_1=, + MMU_ESPOOLER_RWD_2={espooler_rwd_2_pin}, + MMU_ESPOOLER_FWD_2={espooler_rwd_2_pin}, + MMU_ESPOOLER_EN_2={espooler_en_2_pin}, + MMU_ESPOOLER_TRIG_2=, + MMU_ESPOOLER_RWD_3={espooler_rwd_3_pin}, + MMU_ESPOOLER_FWD_3={espooler_fwd_3_pin}, + MMU_ESPOOLER_EN_3={espooler_en_3_pin}, + MMU_ESPOOLER_TRIG_3=, + diff --git a/mmu/base/mmu_cut_tip.cfg b/mmu/base/mmu_cut_tip.cfg new file mode 120000 index 0000000..ca76fb5 --- /dev/null +++ b/mmu/base/mmu_cut_tip.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_cut_tip.cfg \ No newline at end of file diff --git a/mmu/base/mmu_form_tip.cfg b/mmu/base/mmu_form_tip.cfg new file mode 120000 index 0000000..15d1027 --- /dev/null +++ b/mmu/base/mmu_form_tip.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_form_tip.cfg \ No newline at end of file diff --git a/mmu/base/mmu_hardware.cfg b/mmu/base/mmu_hardware.cfg new file mode 100644 index 0000000..b254300 --- /dev/null +++ b/mmu/base/mmu_hardware.cfg @@ -0,0 +1,413 @@ +######################################################################################################################## +# Happy Hare MMU Software +# +# EDIT THIS FILE BASED ON YOUR SETUP +# +# Copyright (C) 2022-2025 moggieuk#6538 (discord) +# moggieuk@hotmail.com +# This file may be distributed under the terms of the GNU GPLv3 license. +# +# Goal: Happy Hare MMU hardware config file with config for MMB11 MCU board +# +# (\_/) +# ( *,*) +# (")_(") Happy Hare Ready +# +# +# Notes about setup of common external MCUs can be found here: +# https://github.com/moggieuk/Happy-Hare/blob/main/doc/mcu_notes.md +# +# Note about "touch" endstops: Happy Hare provides extremely flexible homing options using both single steppers or +# synced steppers. The "touch" option leverages stallguard and thus requires the appropriate 'diag_pin' and stallguard +# parameters set on the TMC driver section. If you have the diag_pin exposed, it is harmless to define this because +# they will only be used when explicitly needed and configured. +# +# Touch option for each stepper provides these benefits / possibilities (experimental): +# - on extruder stepper allows for the automatic detection of the nozzle! +# - on selector stepper allows for the automatic detection of filament stuck in the gate and subsequent recovery +# - on gear stepper allows for the automatic detection of the extruder entrance +# +# In summary, "touch" homing with your MMU is an advanced option that requires patience and careful tuning. Everything +# works with regular endstops and there are workaround options for certain homing points (like extruder entry) in +# the absence of any endstop. I'm really interested in creative setups. Ping me on Discord (moggieuk#6538) +# +# See 'mmu.cfg' for serial definition and pins aliases +# +# HOMING CAPABLE EXTRUDER (VERY ADVANCED) ----------------------------------------------------------------------------- +# With Happy Hare installed even the extruder can be homed. You will find the usual 'endstop' parameters can be added +# to your '[extruder]' section. Useless you have some clever load cell attached to your nozzle it only really makes +# sense to configure stallguard style "touch" homing. To do this add lines similar to this to your existing +# '[extruder]' definition in printer.cfg. +# +# [extruder] +# endstop_pin: tmc2209_extruder:virtual_endstop +# +# Also be sure to add the appropriate stallguard config to the TMC section, e.g. +# +# [tmc2209 extruder] +# diag_pin: E_DIAG # Set to MCU pin connected to TMC DIAG pin for extruder +# driver_SGTHRS: 100 # 255 is most sensitive value, 0 is least sensitive +# +# Happy Hare will take care of the rest and add a 'mmu_ext_touch' endstop automatically +# + + +# MMU MACHINE / TYPE --------------------------------------------------------------------------------------------------- +# ███╗ ███╗███╗ ███╗██╗ ██╗ ███╗ ███╗ █████╗ ██████╗██╗ ██╗██╗███╗ ██╗███████╗ +# ████╗ ████║████╗ ████║██║ ██║ ████╗ ████║██╔══██╗██╔════╝██║ ██║██║████╗ ██║██╔════╝ +# ██╔████╔██║██╔████╔██║██║ ██║ ██╔████╔██║███████║██║ ███████║██║██╔██╗ ██║█████╗ +# ██║╚██╔╝██║██║╚██╔╝██║██║ ██║ ██║╚██╔╝██║██╔══██║██║ ██╔══██║██║██║╚██╗██║██╔══╝ +# ██║ ╚═╝ ██║██║ ╚═╝ ██║╚██████╔╝ ██║ ╚═╝ ██║██║ ██║╚██████╗██║ ██║██║██║ ╚████║███████╗ +# ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚══════╝ +[mmu_machine] + +# Number of selectable gate on (each) MMU. Generally this is a single number, but with multi-mmu (type-B) setups +# it can be a comma separated list of the number of gates per unit. +# E.g. 'num_gates: 4,4,2' for a 2xBox Turtle and 1xNight Owl multiplexed setup +# +num_gates: 8 + +# MMU Vendor & Version is used to automatically configure some parameters and validate configuration +# If custom set to "Other" and uncomment the additional parameters below +# +# ERCF 1.1 add "s" suffix for Springy, "b" for Binky, "t" for Triple-Decky +# e.g. "1.1sb" for v1.1 with Springy mod and Binky encoder +# ERCF 2.0 community edition ERCFv2 +# ERCF 2.5 +# Tradrack 1.0 add "e" if encoder is fitted (assumed to be Binky) +# AngryBeaver 1.0 +# BoxTurtle 1.0 +# NightOwl 1.0 +# 3MS 1.0 +# 3D Chameleon 1.0 +# Pico 1.0 +# Prusa 3.0 NOT YET SUPPORTED - COMING SOON +# Other Generic setup that may require further customization of 'cad' parameters. See doc in mmu_parameters.cfg +# +mmu_vendor: ERCF # MMU family +mmu_version: 2.0 #2.5 # MMU hardware version number (add mod suffix documented above) + +# The following attributes are set internally from vendor/version above. Only uncomment to customize the vendor +# default or for custom ("Other") designs +# +#selector_type: LinearSelector # E.g. LinearSelector (type-A), VirtualSelector (type-B), MacroSelector, RotarySelector, ... +#variable_bowden_lengths: 0 # 1 = If MMU design has different bowden lengths per gate, 0 = bowden length is the same +#variable_rotation_distances: 1 # 1 = If MMU design has dissimilar drive/BMG gears, thus rotation distance, 0 = One drive gear (e.g. Tradrack) +#require_bowden_move: 1 # 1 = If MMU design has bowden move that is included in load/unload, 0 = zero length bowden (skip bowden move) +#filament_always_gripped: 0 # 1 = Filament is always trapped by MMU (most type-B designs), 0 = MMU can release filament +#has_bypass: 0 # 1 = Bypass gate available, 0 = No filament bypass possible + +# Uncomment to change the display name in UI's. Defaults to the vendor name +#display_name: My Precious + +homing_extruder: 1 # CAUTION: Normally this should be 1. 0 will disable the homing extruder capability + + +# FILAMENT DRIVE GEAR STEPPER(S) -------------------------------------------------------------------------------------- +# ██████╗ ███████╗ █████╗ ██████╗ +# ██╔════╝ ██╔════╝██╔══██╗██╔══██╗ +# ██║ ███╗█████╗ ███████║██████╔╝ +# ██║ ██║██╔══╝ ██╔══██║██╔══██╗ +# ╚██████╔╝███████╗██║ ██║██║ ██║ +# ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ +# Note that 'toolhead' & 'mmu_gear' endstops will automatically be added if a toolhead sensor or gate sensor is defined +# +# The default values are tested with the ERCF BOM NEMA14 motor. Please adapt these values to the motor you are using +# Example : for NEMA17 motors, you'll usually use higher current +# +[tmc2209 stepper_mmu_gear] +uart_pin: mmu:MMU_GEAR_UART +run_current: 1 # +hold_current: 0.4 # Recommend to be small if not using "touch" or move (TMC stallguard) +interpolate: False +sense_resistor: 0.110 # Usually 0.11, 0.15 for BTT TMC2226 +stealthchop_threshold: 0 # Spreadcycle has more torque and better at speed +# +# Uncomment two lines below if you have TMC and want the ability to use filament "touch" homing with gear stepper +#diag_pin: ^mmu:MMU_GEAR_DIAG # Set to MCU pin connected to TMC DIAG pin for gear stepper +#driver_SGTHRS: 60 # 255 is most sensitive value, 0 is least sensitive + + +[motor_constants 17he12-1204s] +resistance: 2.5 +inductance: 0.0033 +holding_torque: 0.26 +max_current: 1.20 +steps_per_revolution: 200 + +[autotune_tmc stepper_mmu_gear] +motor: 17he12-1204s +tuning_goal: performance + + + +[stepper_mmu_gear] +step_pin: mmu:MMU_GEAR_STEP +dir_pin: !mmu:MMU_GEAR_DIR +enable_pin: !mmu:MMU_GEAR_ENABLE +rotation_distance: 22.7316868 # Bondtech 5mm Drive Gears. Overridden by 'mmu_gear_rotation_distance' in mmu_vars.cfg +gear_ratio: 80:20 # E.g. ERCF 80:20, Tradrack 50:17 +microsteps: 16 # Recommend 16. Increase only if you "step compress" issues when syncing +full_steps_per_rotation: 200 # 200 for 1.8 degree, 400 for 0.9 degree +# +# Uncomment the two lines below to enable filament "touch" homing option with gear motor +#extra_endstop_pins: tmc2209_stepper_mmu_gear:virtual_endstop +#extra_endstop_names: mmu_gear_touch + + + +# SELECTOR STEPPER ---------------------------------------------------------------------------------------------------- +# ███████╗███████╗██╗ ███████╗ ██████╗████████╗ ██████╗ ██████╗ +# ██╔════╝██╔════╝██║ ██╔════╝██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗ +# ███████╗█████╗ ██║ █████╗ ██║ ██║ ██║ ██║██████╔╝ +# ╚════██║██╔══╝ ██║ ██╔══╝ ██║ ██║ ██║ ██║██╔══██╗ +# ███████║███████╗███████╗███████╗╚██████╗ ██║ ╚██████╔╝██║ ██║ +# ╚══════╝╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ +# Consult doc if you want to setup selector for "touch" homing instead or physical endstop +# +[tmc2209 stepper_mmu_selector] +uart_pin: mmu:MMU_SEL_UART +run_current: 0.4 # ERCF BOM NEMA17 motor +hold_current: 0.2 # Can be small if not using "touch" movement (TMC stallguard) +interpolate: True +sense_resistor: 0.110 +stealthchop_threshold: 100 # Stallguard "touch" movement (slower speeds) best done with stealthchop +# +# Uncomment two lines below if you have TMC and want to use selector "touch" movement +#diag_pin: ^mmu:MMU_SEL_DIAG # Set to MCU pin connected to TMC DIAG pin for selector stepper +#driver_SGTHRS: 75 # 255 is most sensitive value, 0 is least sensitive + +[stepper_mmu_selector] +step_pin: mmu:MMU_SEL_STEP +dir_pin: mmu:MMU_SEL_DIR +enable_pin: !mmu:MMU_SEL_ENABLE +rotation_distance: 40 +microsteps: 16 # Don't need high fidelity +full_steps_per_rotation: 200 # 200 for 1.8 degree, 400 for 0.9 degree +endstop_pin: ^mmu:MMU_SEL_ENDSTOP # Selector microswitch +endstop_name: mmu_sel_home +# Uncomment this line only if default endstop above is using stallguard +#homing_retract_dist: 0 +# +# Uncomment two lines below to give option of selector "touch" movement +#extra_endstop_pins: tmc2209_stepper_mmu_selector:virtual_endstop +#extra_endstop_names: mmu_sel_touch + + +# SERVOS --------------------------------------------------------------------------------------------------------------- +# ███████╗███████╗██████╗ ██╗ ██╗ ██████╗ ███████╗ +# ██╔════╝██╔════╝██╔══██╗██║ ██║██╔═══██╗██╔════╝ +# ███████╗█████╗ ██████╔╝██║ ██║██║ ██║███████╗ +# ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║ ██║╚════██║ +# ███████║███████╗██║ ██║ ╚████╔╝ ╚██████╔╝███████║ +# ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ +# Basic servo PWM setup. If these values are changed then the angles defined for different positions will also change +# +# SELECTOR SERVO ------------------------------------------------------------------------------------------------------- +# +[mmu_servo selector_servo] +pin: mmu:MMU_SEL_SERVO +maximum_servo_angle: 180 +minimum_pulse_width: 0.00085 +maximum_pulse_width: 0.00215 +# +# OPTIONAL GANTRY SERVO FOR TOOLHEAD FILAMENT CUTTER ------------------------------------------------------------------ +# +# (uncomment this section if you have a gantry servo for toolhead cutter pin) +#[mmu_servo mmu_gantry_servo] +#pin: +#maximum_servo_angle:180 +#minimum_pulse_width: 0.00075 +#maximum_pulse_width: 0.00225 +#initial_angle: 180 + + +# FILAMENT SENSORS ----------------------------------------------------------------------------------------------------- +# ███████╗███████╗███╗ ██╗███████╗ ██████╗ ██████╗ ███████╗ +# ██╔════╝██╔════╝████╗ ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝ +# ███████╗█████╗ ██╔██╗ ██║███████╗██║ ██║██████╔╝███████╗ +# ╚════██║██╔══╝ ██║╚██╗██║╚════██║██║ ██║██╔══██╗╚════██║ +# ███████║███████╗██║ ╚████║███████║╚██████╔╝██║ ██║███████║ +# ╚══════╝╚══════╝╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ +# Define the pins for optional sensors in the filament path. All but the pre-gate sensors will be automatically setup as +# both endstops (for homing) and sensors for visibility purposes. +# +# 'pre_gate_switch_pin_X' .. 'mmu_pre_gate_X' sensor detects filament at entry to MMU. X=gate number (0..N) +# 'gate_switch_pin' .. 'mmu_gate' shared sensor detects filament past the gate of the MMU +# or +# 'post_gear_switch_pin_X' .. 'mmu_gear_X' post gear sensor for each filament +# 'extruder_switch_pin' .. 'extruder' sensor detects filament just before the extruder entry +# 'toolhead_switch_pin' .. 'toolhead' sensor detects filament after extruder entry +# +# Sync motor feedback will typically have a tension switch (most important for syncing) or both tension and compression. +# Note that compression switch is useful for use as a endstop to detect hitting the extruder entrance +# 'sync_feedback_tension_pin' .. pin for switch activated when filament is under tension +# 'sync_feedback_compression_pin' .. pin for switch activated when filament is under compression +# +# Configuration is flexible: Simply define pins for any sensor you want to enable, if pin is not set (or the alias is empty) +# it will be ignored. You can also just comment out what you are not using. +# +[mmu_sensors] +pre_gate_switch_pin_0: ^mmu:MMU_PRE_GATE_0 +pre_gate_switch_pin_1: ^mmu:MMU_PRE_GATE_1 +pre_gate_switch_pin_2: ^mmu:MMU_PRE_GATE_2 +pre_gate_switch_pin_3: ^mmu:MMU_PRE_GATE_3 +pre_gate_switch_pin_4: ^mmu:MMU_PRE_GATE_4 +pre_gate_switch_pin_5: ^mmu:MMU_PRE_GATE_5 +pre_gate_switch_pin_6: ^mmu:MMU_PRE_GATE_6 +pre_gate_switch_pin_7: ^mmu:MMU_PRE_GATE_7 +pre_gate_switch_pin_8: ^mmu:MMU_PRE_GATE_8 +pre_gate_switch_pin_9: ^mmu:MMU_PRE_GATE_9 +pre_gate_switch_pin_10: ^mmu:MMU_PRE_GATE_10 +pre_gate_switch_pin_11: ^mmu:MMU_PRE_GATE_11 + +post_gear_switch_pin_0: ^mmu:MMU_POST_GEAR_0 +post_gear_switch_pin_1: ^mmu:MMU_POST_GEAR_1 +post_gear_switch_pin_2: ^mmu:MMU_POST_GEAR_2 +post_gear_switch_pin_3: ^mmu:MMU_POST_GEAR_3 +post_gear_switch_pin_4: ^mmu:MMU_POST_GEAR_4 +post_gear_switch_pin_5: ^mmu:MMU_POST_GEAR_5 +post_gear_switch_pin_6: ^mmu:MMU_POST_GEAR_6 +post_gear_switch_pin_7: ^mmu:MMU_POST_GEAR_7 +post_gear_switch_pin_8: ^mmu:MMU_POST_GEAR_8 +post_gear_switch_pin_9: ^mmu:MMU_POST_GEAR_9 +post_gear_switch_pin_10: ^mmu:MMU_POST_GEAR_10 +post_gear_switch_pin_11: ^mmu:MMU_POST_GEAR_11 + +# These sensors can be replicated in a multi-mmu, type-B setup (see num_gates comment). +# If so, then use a comma separated list of per-unit pins instead of single pin +gate_switch_pin: ^mmu:MMU_GATE_SENSOR +sync_feedback_tension_pin: +sync_feedback_compression_pin: + +# These sensors are on the toolhead and often controlled by the main printer mcu +extruder_switch_pin: ^EBBCan:gpio24 +toolhead_switch_pin: ^EBBCan:gpio22 + + +# ENCODER ------------------------------------------------------------------------------------------------------------- +# ███████╗███╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ +# ██╔════╝████╗ ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗ +# █████╗ ██╔██╗ ██║██║ ██║ ██║██║ ██║█████╗ ██████╔╝ +# ██╔══╝ ██║╚██╗██║██║ ██║ ██║██║ ██║██╔══╝ ██╔══██╗ +# ███████╗██║ ╚████║╚██████╗╚██████╔╝██████╔╝███████╗██║ ██║ +# ╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ +# Encoder measures distance, monitors for runout and clogging and constantly calculates % flow rate +# Note that the encoder_resolution set here is purely a default to get started. It will be correcly set after calibration +# with the value stored in mmu_vars.cfg +# +# The encoder resolution will be calibrated but it needs a default approximation +# If BMG gear based: +# resolution = bmg_circumfrance / (2 * teeth) +# 24 / (2 * 17) = 0.7059 for TRCT5000 based sensor +# 24 / (2 * 12) = 1.0 for Binky with 12 tooth disc +# +[mmu_encoder mmu_encoder] +encoder_pin: ^mmu:MMU_ENCODER +encoder_resolution: 1.0 # This is just a starter value. Overriden by calibrated 'mmu_encoder_resolution' in mmm_vars.cfg +desired_headroom: 5.0 # The clog/runout headroom that MMU attempts to maintain (closest point to triggering runout) +average_samples: 4 # The "damping" effect of last measurement (higher value means slower automatic clog_length reduction) +flowrate_samples: 20 # How many "movements" of the extruder to measure average flowrate over + + +# ESPOOLER (OPTIONAL) ------------------------------------------------------------------------------------------------- +# ███████╗███████╗██████╗ ██████╗ ██████╗ ██╗ ███████╗██████╗ +# ██╔════╝██╔════╝██╔══██╗██╔═══██╗██╔═══██╗██║ ██╔════╝██╔══██╗ +# █████╗ ███████╗██████╔╝██║ ██║██║ ██║██║ █████╗ ██████╔╝ +# ██╔══╝ ╚════██║██╔═══╝ ██║ ██║██║ ██║██║ ██╔══╝ ██╔══██╗ +# ███████╗███████║██║ ╚██████╔╝╚██████╔╝███████╗███████╗██║ ██║ +# ╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝ +# +# An espooler controls DC motors (typically N20) that are able to rewind a filament spool and optionally provide +# forward assist to overcome spooler rotation friction. This should define pins for each of the gates on your mmu +# starting with '_0'. +# An empty pin can be deleted, commented or simply left blank. If you mcu has a separate "enable" pin +# +#[mmu_espooler mmu_espooler] +#pwm: 1 # 1=PWM control (typical), 0=digital on/off control +#hardware_pwm: 0 # See klipper doc +#cycle_time: 0.100 # See klipper doc +#scale: 1 # Scales the PWM output range +#value: 0 # See klipper doc +#shutdown_value: 0 # See klipper doc + +#respool_motor_pin_0: mmu:MMU_ESPOOLER_RWD_0 # PWM (or digital) pin for rewind/respool movement +#assist_motor_pin_0: mmu:MMU_ESPOOLER_FWD_0 # PWM (or digital) pin for forward motor movement +#enable_motor_pin_0: mmu:MMU_ESPOOLER_EN_0 # Digital output for Afc mcu +#assist_trigger_pin_0: mmu:MMU_ESPOOLER_TRIG_0 # Trigger pin for sensing need to assist during print + +#respool_motor_pin_1: mmu:MMU_ESPOOLER_RWD_1 +#assist_motor_pin_1: mmu:MMU_ESPOOLER_FWD_1 +#enable_motor_pin_1: mmu:MMU_ESPOOLER_EN_1 +#assist_trigger_pin_1: mmu:MMU_ESPOOLER_TRIG_1 + +#respool_motor_pin_2: mmu:MMU_ESPOOLER_RWD_2 +#assist_motor_pin_2: mmu:MMU_ESPOOLER_FWD_2 +#enable_motor_pin_2: mmu:MMU_ESPOOLER_EN_2 +#assist_trigger_pin_2: mmu:MMU_ESPOOLER_TRIG_2 + +#respool_motor_pin_3: mmu:MMU_ESPOOLER_RWD_3 +#assist_motor_pin_3: mmu:MMU_ESPOOLER_FWD_3 +#enable_motor_pin_3: mmu:MMU_ESPOOLER_EN_3 +#assist_trigger_pin_3: mmu:MMU_ESPOOLER_TRIG_3 + + +# MMU OPTIONAL NEOPIXEL LED SUPPORT ------------------------------------------------------------------------------------ +# ██╗ ███████╗██████╗ ███████╗ +# ██║ ██╔════╝██╔══██╗██╔════╝ +# ██║ █████╗ ██║ ██║███████╗ +# ██║ ██╔══╝ ██║ ██║╚════██║ +# ███████╗███████╗██████╔╝███████║ +# ╚══════╝╚══════╝╚═════╝ ╚══════╝ +# Define the led connection, type and length +# +# (comment out this section if you don't have leds or have them defined elsewhere) +[neopixel mmu_leds] +pin: mmu:MMU_NEOPIXEL +chain_count: 18 # Need number gates x1 or x2 + status leds +color_order: GRB # Set based on your particular neopixel specification (can be comma separated list) + +# MMU LED EFFECT SEGMENTS ---------------------------------------------------------------------------------------------- +# Define neopixel LEDs for your MMU. The chain_count must be large enough for your desired ranges: +# exit .. this set of LEDs, one for every gate, usually would be mounted at the exit point of the gate +# entry .. this set of LEDs, one for every gate, could be mounted at the entry point of filament into the MMU/buffer +# status .. these LED. represents the status of the MMU (and selected filament). More than one status LED is possible +# logo .. these LEDs don't change during operation and are designed for driving a logo. More than one logo LED is possible +# +# Note that all sets are optional. You can opt to just have the 'exit' set for example. The advantage to having +# both entry and exit LEDs is, for example, so that 'entry' can display gate status while 'exit' displays the color +# +# The animation effects requires the installation of Julian Schill's awesome LED effect module otherwise the LEDs +# will be static: +# https://github.com/julianschill/klipper-led_effect +# +# LED's are indexed in the chain from 1..N. Thus to set up LED's on 'exit' and a single 'status' LED on a 4 gate MMU: +# +# exit_leds: neopixel:mmu_leds (1,2,3,4) +# status_leds: neopixel:mmu_leds (5) +# +# In this example no 'entry' set is configured. Note that constructs like "mmu_leds (1-3,4)" are also valid +# +# The range is completely flexible and can be comprised of different led strips, individual LEDs, or combinations of +# both on different pins. In addition, the ordering is flexible based on your wiring, thus (1-4) and (4-1) both represent +# the same LED range but mapped to increasing or decreasing gates respectively. E.g if you have two Box Turtle MMUs, one +# with a chain of LEDs wired in reverse order and another with individual LEDs, to define 8 exit LEDs: +# +# exit_leds: neopixel:bt_1 (4-1) +# neopixel:bt_2a +# neopixel:bt_2b +# neopixel:bt_2c +# neopixel:bt_2d +# +# Note the use of separate lines for each part of the definition, +# +# ADVANCED: Happy Hare provides a convenience wrapper [mmu_led_effect] that not only creates an effect on each of the +# [mmu_leds] specified segments as a whole but also each individual LED for atomic control. See mmu_leds.cfg for examples +# +# (comment out this whole section if you don't have/want leds; uncomment/edit LEDs fitted on your MMU) +[mmu_leds] +exit_leds: neopixel:mmu_leds (9-16) +entry_leds: neopixel:mmu_leds (8-1) +#status_leds: neopixel:mmu_leds (17) +#logo_leds: neopixel:mmu_leds (18) +frame_rate: 24 diff --git a/mmu/base/mmu_leds.cfg b/mmu/base/mmu_leds.cfg new file mode 120000 index 0000000..8c8c47f --- /dev/null +++ b/mmu/base/mmu_leds.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_leds.cfg \ No newline at end of file diff --git a/mmu/base/mmu_macro_vars.cfg b/mmu/base/mmu_macro_vars.cfg new file mode 100644 index 0000000..26cd830 --- /dev/null +++ b/mmu/base/mmu_macro_vars.cfg @@ -0,0 +1,536 @@ +######################################################################################################################## +# Happy Hare MMU Software +# +# EDIT THIS FILE BASED ON YOUR SETUP +# +# Copyright (C) 2022-2025 moggieuk#6538 (discord) +# moggieuk@hotmail.com +# This file may be distributed under the terms of the GNU GPLv3 license. +# +# Goal: Happy Hare supporting MACRO configuration +# +# (\_/) +# ( *,*) +# (")_(") Happy Hare Ready +# +# +# Supporting set of macros supplied with Happy Hare can be customized by editing the macro "variables" declared here. +# +# This configuration will automatically retained and upgraded between releases (a backup of previous config files will +# always be made for your reference). If you want to customize macros beyond what is possible through these variables +# it is highly recommended you copy the macro to a new name and change the callback macro name in 'mmu_parameters.cfg' +# That way the default macros can still be upgraded but your customization will be left intact +# + + +# PERSISTED STATE --------------------------------------------------------- +# Happy Hare stores configuration and state in the klipper variables file. +# Since klipper can only be a single 'save_variables' file, if you already +# have one you will need to merge the two and point this appropriately. +# +[save_variables] +filename: ~/printer_data/config/mmu/mmu_vars.cfg + + +# NECESSARY KLIPPER OVERRIDES --------------------------------------------- +# ██╗ ██╗██╗ ██╗██████╗ ██████╗ ███████╗██████╗ +# ██║ ██╔╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗ +# █████╔╝ ██║ ██║██████╔╝██████╔╝█████╗ ██████╔╝ +# ██╔═██╗ ██║ ██║██╔═══╝ ██╔═══╝ ██╔══╝ ██╔══██╗ +# ██║ ██╗███████╗██║██║ ██║ ███████╗██║ ██║ +# ╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ +# +# These supplemental settings essentially disable klipper's built in +# extrusion limits and is necessary when using an MMU +[extruder] +max_extrude_only_distance: 200 +max_extrude_cross_section: 50 + +# For dialog prompts and progress in Mainsail. Requires Mainsail version >= v2.9.0 +[respond] + +# Other Happy Hare prerequisites. Harmless if already defined elsewhere in user config +[display_status] +[pause_resume] +[virtual_sdcard] +path: ~/printer_data/gcodes +#on_error_gcode: CANCEL_PRINT + + +# PRINT START/END --------------------------------------------------------- +# ██████╗ ██████╗ ██╗███╗ ██╗████████╗ ███████╗████████╗ █████╗ ██████╗ ████████╗ +# ██╔══██╗██╔══██╗██║████╗ ██║╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ +# ██████╔╝██████╔╝██║██╔██╗ ██║ ██║ ███████╗ ██║ ███████║██████╔╝ ██║ +# ██╔═══╝ ██╔══██╗██║██║╚██╗██║ ██║ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ +# ██║ ██║ ██║██║██║ ╚████║ ██║ ███████║ ██║ ██║ ██║██║ ██║ ██║ +# ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ +# (base/mmu_software.cfg) +# +[gcode_macro _MMU_SOFTWARE_VARS] +description: Happy Hare optional configuration for print start/end checks +gcode: # Leave empty + +# These variables control the behavior of the MMU_START_SETUP and MMU_START_LOAD_INITIAL_TOOL macros +variable_user_pre_initialize_extension : 'G28' ; Executed at start of MMU_START_SETUP. Commonly G28 to home +variable_home_mmu : False ; True/False, Whether to home mmu before print starts +variable_check_gates : True ; True/False, Whether to check filament is loaded in all gates used +variable_load_initial_tool : True ; True/False, Whether to automatically load initial tool +# +# Automapping strategy to apply slicer tool map to find matching MMU gate (will adjust tool-to-gate map). Options are: +# 'none' - don't automap (i.e. don't update tool-to-gate map) +# 'filament_name' - exactly match on case insensitive filament name +# 'material' - exactly match on material +# 'color' - exactly match on color (with same material) +# 'closest_color' - match to closest available filament color (with same material) +# 'spool_id' - exactly match on spool_id [FUTURE] +variable_automap_strategy : "none" ; none|filament_name|material|color|closest_color|spool_id + +# These variables control the behavior of the MMU_END macro +variable_user_print_end_extension : 'PRINT_END_PARK' ; Executed at start of MMU_END. Good place to move off print +variable_unload_tool : True ; True/False, Whether to unload the tool at the end of the print +variable_reset_ttg : False ; True/False, Whether reset TTG map at end of print +variable_dump_stats : True ; True/False, Whether to display print stats at end of print + + +# STATE MACHINE CHANGES --------------------------------------------------- +# ███████╗████████╗ █████╗ ████████╗███████╗ ██████╗██╗ ██╗ █████╗ ███╗ ██╗ ██████╗ ███████╗ +# ██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝ ██╔════╝██║ ██║██╔══██╗████╗ ██║██╔════╝ ██╔════╝ +# ███████╗ ██║ ███████║ ██║ █████╗ ██║ ███████║███████║██╔██╗ ██║██║ ███╗█████╗ +# ╚════██║ ██║ ██╔══██║ ██║ ██╔══╝ ██║ ██╔══██║██╔══██║██║╚██╗██║██║ ██║██╔══╝ +# ███████║ ██║ ██║ ██║ ██║ ███████╗ ╚██████╗██║ ██║██║ ██║██║ ╚████║╚██████╔╝███████╗ +# ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ +# (base/mmu_state.cfg) +# +[gcode_macro _MMU_STATE_VARS] +description: Happy Hare configuration for state change hooks +gcode: # Leave empty + +# You can extend functionality to all Happy Hare state change or event +# macros by adding a command (or call to your gcode macro). +# E.g for additional LED logic or consumption counters +variable_user_action_changed_extension : '' ; Executed after default logic with duplicate params +variable_user_print_state_changed_extension : '' ; Executed after default logic with duplicate params +variable_user_mmu_event_extension : '' ; Executed after default logic with duplicate params + +# Maintenance warning limits (consumption counters) +variable_servo_down_limit : 5000 ; Set to -1 for no limit / disable warning +variable_cutter_blade_limit : 3000 ; Set to -1 for no limit / disable warning + + +# LED CONTROL ------------------------------------------------------------- +# ██╗ ███████╗██████╗ ███████╗ +# ██║ ██╔════╝██╔══██╗██╔════╝ +# ██║ █████╗ ██║ ██║███████╗ +# ██║ ██╔══╝ ██║ ██║╚════██║ +# ███████╗███████╗██████╔╝███████║ +# ╚══════╝╚══════╝╚═════╝ ╚══════╝ +# Only configure if you have LEDs installed. The led_effects option is +# automatically ignored if led-effects klipper module is not installed +# (base/mmu_led.cfg) +# +[gcode_macro _MMU_LED_VARS] +description: Happy Hare led macro configuration variables +gcode: # Leave empty + +# Default effects for LED segments when not providing action status +# 'off' - LED's off +# 'on' - LED's white +# 'gate_status' - indicate gate availability / status (printer.mmu.gate_status) +# 'filament_color' - display filament color defined in gate map (printer.mmu.gate_color_rgb) +# 'slicer_color' - display slicer defined set color for each gate (printer.mmu.slicer_color_rgb) +# 'r,g,b' - display static r,g,b color e.g. "0,0,0.3" for dim blue +# '_effect_' - display the named led effect +# +variable_led_enable : True ; True = LEDs are enabled at startup (MMU_LED can control), False = Disabled +variable_led_animation : True ; True = Use led-animation-effects, False = Static LEDs +variable_default_exit_effect : "gate_status" ; off|gate_status|filament_color|slicer_color|r,g,b|_effect_ +variable_default_entry_effect : "filament_color" ; off|gate_status|filament_color|slicer_color|r,g,b|_effect_ +variable_default_status_effect : "filament_color" ; on|off|gate_status|filament_color|slicer_color|r,g,b|_effect_ +variable_default_logo_effect : "0,0,.3" ; off |r,g,b|_effect_ +variable_white_light : (1, 1, 1) ; RGB color for static white light +variable_black_light : (.01, 0, .02) ; RGB color used to represent "black" (filament) +variable_empty_light : (0, 0, 0) ; RGB color used to represent empty gate + + +# SEQUENCE MACRO - PARKING MOVEMENT AND TOOLCHANGE CONTROL ---------------- +# ███╗ ███╗ ██████╗ ██╗ ██╗███████╗███╗ ███╗███████╗███╗ ██╗████████╗ +# ████╗ ████║██╔═══██╗██║ ██║██╔════╝████╗ ████║██╔════╝████╗ ██║╚══██╔══╝ +# ██╔████╔██║██║ ██║██║ ██║█████╗ ██╔████╔██║█████╗ ██╔██╗ ██║ ██║ +# ██║╚██╔╝██║██║ ██║╚██╗ ██╔╝██╔══╝ ██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║ +# ██║ ╚═╝ ██║╚██████╔╝ ╚████╔╝ ███████╗██║ ╚═╝ ██║███████╗██║ ╚████║ ██║ +# ╚═╝ ╚═╝ ╚═════╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝ +# Configure carefully if you 'enable_park: True' +# (base/mmu_sequence.cfg) +# +[gcode_macro _MMU_SEQUENCE_VARS] +description: Happy Hare sequence macro configuration variables +gcode: # Leave empty + +# Parking and movement controls: +# Happy Hare defines 7 operations that may require parking. You can specify +# whether to park for each of those operations both during a print and +# standalone (not printing) with Happy Hare or when HH is disabled: +# +# enable_park_printing +# This is a list of the operations that should result in toolhead parking +# while in a print. There are really two main starting points from which +# you can customize. If using the slicer to form tips (and toolchange is +# over the wipetower) you don't want to park on "toolchange" but you would +# want to on "runout" which is a forced toolchange unknown by the slicer. +# Typically you would also want to park at least on pause, cancel and +# complete if not done elsewhere +# +# enabled_park_standalone +# List of the operations that should result in toolhead parking when not +# printing, for example, just manipulating the MMU manually or via +# Klipperscreen. Really it is up to you to choose based on personal +# workflow preferences but this defaults to just 'pause,cancel' +# (i.e. disabled for toolchange) +# +# enabled_park_disabled +# List of the operations that should result in toolhead parking when MMU is +# disabled (MMU ENABLE=0) and using Happy Hare client macros. Note that only +# pause and cancel can occur in this mode and would typically be enabled +# +# The operations are as follows: +# toolchange - normal toolchange initiated with Tx or MMU_CHANGE_TOOL command +# runout - when a forced toolchange occurs as a result of runout +# load - individual MMU_LOAD operation +# unload - individual MMU_UNLOAD/MMU_EJECT operation +# complete - when print is complete (Happy Hare enabled) +# pause - a regular klipper PAUSE +# cancel - a regular klipper CANCEL_PRINT +# +# It is possible to call the parking macro manually in this form should you wish +# to include in your macros. +# +# _MMU_PARK FORCE_PARK=1 X=10 Y=10 Z_HOP=5 +# +# restore_xy_pos +# Controls where the toolhead (x,y) is returned to after an operation that +# invokes a parking move: +# last - return to original position before park (frequently the default) +# next - return to next print position if possible else last logic will be applied. +# In print this reduces dwell time at the last position reducing blobbing +# and unnecessary movement. Only applied to "toolchange" operation +# none - the toolhead is left wherever it ends up after change. In a print the +# next gcode command will restore toolhead x,y position +# +# Notes: +# - The starting z-height will always be restored, thus the different between 'next' +# and 'none' is the z-height at which the (x,y) move occurs and the location of +# of any un-retract +# - The default parking logic is a straight line move to the 'park_*' position. +# To implement fancy movement and control you can specify your own +# 'user_park_move_macro' to use instead of default straight line move +# - x,y parking coordinates can be negative if your printer can handle it +# +# Retraction can be used to optimize stringing and blobs that can occur when +# changing tools and are active only during a print. +# IMPORTANT: For toolchanging the config order would be: +# 1. In mmu_parameters.cfg configure extruder dimensions like +# 'toolhead_extruder_to_nozzle',etc. These are based on geometry. +# 2. In mmu_parameters.cfg tweak 'toolhead_ooze_reduction' only if necessary +# so that filament _just_ appears at the nozzle on load +# 3. Only then, adjust retraction to control stringing and blobs when +# changing tool in a print +variable_enable_park_printing : 'toolchange,runout,load,unload,complete,pause,cancel' ; Empty '' to disable parking +variable_enable_park_standalone : 'toolchange,load,unload,pause,cancel' ; Empty '' to disable parking +variable_enable_park_disabled : 'pause,cancel' ; Empty '' to disable parking + +variable_min_toolchange_z : 1.0 ; The absolute minimum safety floor (z-height) for ALL parking moves + +# These specify the parking location, z_hop and retraction for all enabled operation +# types. Each must be 5 values: +# x_coord, y_coord, z_hop(delta), z_hop_ramp, retraction length +# Use -999,-999 for no x,y move (you can just have z_hop). Use 0 for no z_hop +# The z_hop ramp is the horizontal distance in mm to travel during the lift. The +# direction is automatic and only applied if lifting the first time from print. +# This move is useful to help break the filament "string" +variable_park_toolchange : -999, -999, 1, 5, 2 ; x,y,z-hop,z_hop_ramp,retract for "toolchange" operations (toolchange,load,unload) +variable_park_runout : -999, -999, 1, 5, 2 ; x,y,z-hop,z_hop_ramp,retract +variable_park_pause : 50, 50, 5, 0, 2 ; x,y,z-hop,z_hop_ramp,retract (park position when mmu error occurs) +variable_park_cancel : -999, -999, 10, 0, 5 ; x,y,z-hop,z_hop_ramp,retract +variable_park_complete : 50, 50, 10, 0, 5 ; x,y,z-hop,z_hop_ramp,retract + +# For toolchange operations, this allows to you to specify additional parking moves +# at various stages of the toolchange. Each must have 3 values: +# x_coord, y_coord, z_hop(delta) +# Use -999,-999,0 for no movement at that stage (no-op). +# All movement will be at the established movement plane (z-height) +variable_pre_unload_position : -999, -999, 0 ; x,y,z-hop position before unloading starts +variable_post_form_tip_position : -999, -999, 0 ; x,y,z-hop position after form/cut tip on unload +variable_pre_load_position : -999, -999, 0 ; x,y,z-hop position before loading starts + +variable_restore_xy_pos : "last" ; last|next|none - What x,y position the toolhead should travel to after a "toolchange" + +variable_park_travel_speed : 200 ; Speed for any travel movement XY(Z) in mm/s +variable_park_lift_speed : 15 ; Z-only travel speed in mm/s +variable_retract_speed : 30 ; Speed of the retract move in mm/s +variable_unretract_speed : 30 ; Speed of the unretract move in mm/s + +# ADVANCED: Normally x,y moves default to 'G1 X Y' to park position. This allows +# you to create exotic movements. Macro will be provided the following parameters: +# YOUR_MOVE_MACRO X= Y= F= +# when restoring the from parked postion the same macro is called but passed a RESTORE=1 parameter, along with co-ordinates to restore to +# YOUR_MOVE_MACRO RESTORE=1 X= Y= F= +variable_user_park_move_macro : '' ; Executed instead of default 'G1 X Y move' to park position + +variable_auto_home : True ; True = automatically home if necessary, False = disable +variable_timelapse : False ; True = take frame snapshot after load, False = disable + +# Instead of completely defining your your own macros you can can extend functionality +# of default sequence macros by adding a command (or call to your gcode macro) +variable_user_mmu_error_extension : '' ; Executed after default logic when mmu error condition occurs +variable_user_pre_unload_extension : '' ; Executed after default logic +variable_user_post_form_tip_extension : '' ; Executed after default logic +variable_user_post_unload_extension : '' ; Executed after default logic +variable_user_pre_load_extension : '' ; Executed after default logic +variable_user_post_load_extension : '' ; Executed after default logic but before restoring toolhead position + + +# CUT_TIP ----------------------------------------------------------------- +# ██████╗██╗ ██╗████████╗ ████████╗██╗██████╗ +# ██╔════╝██║ ██║╚══██╔══╝ ╚══██╔══╝██║██╔══██╗ +# ██║ ██║ ██║ ██║ ██║ ██║██████╔╝ +# ██║ ██║ ██║ ██║ ██║ ██║██╔═══╝ +# ╚██████╗╚██████╔╝ ██║ ██║ ██║██║ +# ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ +# Don't need to configure if using tip forming +# (base/mmu_cut_tip.cfg) +# +[gcode_macro _MMU_CUT_TIP_VARS] +description: Happy Hare toolhead tip cutting macro configuration variables +gcode: # Leave empty + +# Whether the toolhead tip cutting macro will return toolhead to initial position +# after the cut is complete. If using parking logic it is better to disable this +variable_restore_position : False ; True = return to initial position, False = don't return + +# Distance from the internal nozzle tip to the cutting blade. This dimension +# is based on your toolhead and should not be used for tuning +# Note: If you have a toolhead sensor this variable can be automatically determined! +# Read https://github.com/moggieuk/Happy-Hare/wiki/Blobing-and-Stringing +variable_blade_pos : 37.5 ; TUNE ME: Distance in mm from internal nozzle tip + +# Distance to retract prior to making the cut, measured from the internal nozzle +# tip. This reduces wasted filament (left behind in extruder) but might cause a +# clog if set too large. This must be less than 'blade_pos' +# Note: the residual filament left in nozzle ('toolhead_ooze_reduction') is +# subtracted from this value so make sure toolhead is calibrated +variable_retract_length : 32.5 ; TUNE ME: 5mm less than 'blade_pos' is a good starting point + +# Whether to perform a simple tip forming move after the initial retraction +# Enabling this adds gives some additional cooling time of molten filament and +# may help avoid potential clogging on some hotends +variable_simple_tip_forming : True ; True = Perform simple tip forming, False = skip + +# Change to X and Y stepper current during the cut operation. Technically any stepper +# current can be modified by adding the stepper name to the list. Be careful not to +# overload your steppers but generally up to 150% is safe +variable_cut_axis_steppers : 'stepper_x, stepper_y' ; Comma separated list of stepper names to increase current for cutting +variable_cut_stepper_current : 100 ; % of stepper current to use for cutting motion (100 to disable) + +# This should be the position of the toolhead where the cutter arm just +# lightly touches the depressor pin +variable_cutting_axis : "x" ; "x" or "y". Determines cut direction (axis) during cut motion, used for park distance +variable_pin_loc_xy : 14, 250 ; x,y coordinates of depressor pin + +# This distance is added (or subtracted if negative) to "pin_loc_x" or "pin_loc_y" depending on the 'cutting_axis' +# This is used to determine the starting position and to create a small safety distance that aids in generating momentum. +# For example, Filametrix cuts along X axis towards Xmin requiring a positive value, whereas A4T-A4C cuts on Y axis towards +# Ymax requring a negative number +variable_pin_park_dist : 5.0 ; Distance in mm (+ve or -ve) from 'variable_pin_loc_xy' + +# Position of the toolhead when the cutter is fully compressed. Should leave a small headroom from the +# extremes of your printer edges (e.g. it should be a bit larger than 0, or whatever Xmin is) to avoid +# banging the toolhead or gantry. Typically x position will match x in pin_loc_xy if cutting in y direction +# or y position will match y in pin_loc_xy if cutting in x direction, but diagonal cuts are possible +variable_pin_loc_compressed_xy : 0.5, 250 ; x,y coordinates of fully depressed location + +# Retract length and speed after the cut so that the cutter blade doesn't +# get stuck on return to origin position +variable_rip_length : 1.0 ; Distance in mm to retract to aid lever decompression (>= 0) +variable_rip_speed : 3 ; Speed mm/s + +# Pushback of the remaining tip from the cold end into the hotend. This does +# not have to push back all the way, just sufficient to ensure filament fragment +# stays in hot end and the "nail head" of the cut is pushed back past the +# PTFE/metal junction so it cannot cause clogging problems on future loads. +# Cannot be larger than 'retract_length' - `toolhead_ooze_reduction` +variable_pushback_length : 15.0 ; TUNE ME: PTFE tube length + 3mm is good starting point +variable_pushback_dwell_time : 0 ; Time in ms to dwell after the pushback + +# Speed related settings for tip cutting +# Note that if the cut speed is too fast, the steppers can lose steps. +# Therefore, for a cut: +# - We first make a fast move to accumulate some momentum and get the cut +# blade to the initial contact with the filament +# - We then make a slow move for the actual cut to happen +variable_travel_speed : 150 ; Speed mm/s +variable_cut_fast_move_speed : 32 ; Speed mm/s +variable_cut_slow_move_speed : 8 ; Speed mm/s +variable_evacuate_speed : 150 ; Speed mm/s +variable_cut_dwell_time : 50 ; Time in ms to dwell at the cut point +variable_cut_fast_move_fraction : 1.0 ; Fraction of the move that uses fast move +variable_extruder_move_speed : 25 ; Speed mm/s for all extruder movement + +# Safety margin for fast vs slow travel. When traveling to the pin location +# we make a safer but longer move if we are closer to the pin than this +# specified margin. Usually setting these to the size of the toolhead +# (plus a small margin) should be good enough +variable_safe_margin_xy : 30, 30 ; Approx toolhead width +5mm, height +5mm) + +# If gantry servo option is installed, enable the servo and set up and down +# angle positions +variable_gantry_servo_enabled : False ; True = enabled, False = disabled +variable_gantry_servo_down_angle: 55 ; Angle for when pin is deployed +variable_gantry_servo_up_angle : 180 ; Angle for when pin is retracted + + +# FORM_TIP ---------------------------------------------------------------- +# ███████╗ ██████╗ ██████╗ ███╗ ███╗ ████████╗██╗██████╗ +# ██╔════╝██╔═══██╗██╔══██╗████╗ ████║ ╚══██╔══╝██║██╔══██╗ +# █████╗ ██║ ██║██████╔╝██╔████╔██║ ██║ ██║██████╔╝ +# ██╔══╝ ██║ ██║██╔══██╗██║╚██╔╝██║ ██║ ██║██╔═══╝ +# ██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║ ██║ ██║██║ +# ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ +# Don't need to configure if using tip cutting +# (base/mmu_form_tip.cfg) +# +[gcode_macro _MMU_FORM_TIP_VARS] +description: Happy Hare tip forming macro configuration variables +gcode: # Leave empty + +# Step 1 - Ramming +# Ramming is the initial squeeze of filament prior to cooling moves and is +# described in terms of total volume and progression of squeeze intensity +# printing/standalone. This can be separately controlled when printing or +# standalone +variable_ramming_volume : 0 ; Volume in mm^3, 0 = disabled (optionally let slicer do it) +variable_ramming_volume_standalone : 0 ; Volume in mm^3, 0 = disabled + +# Optionally set for temperature change (reduction). The wait will occur +# before nozzle separation if 'use_fast_skinnydip: False' else after cooling +# moves. Temperature will be restored after tip creation is complete +variable_toolchange_temp : 0 ; 0 = don't change temp, else temp to set +variable_toolchange_fan_assist : False ; Whether to use part cooling fan for quicker temp change +variable_toolchange_fan_name : '' ; Define the part fan name if not default [fan] e.g "fan_generic fan0" +variable_toolchange_fan_speed : 50 ; Fan speed % if using fan_assist enabled + +# Step 2 - Nozzle Separation +# The filament is then quickly separated from the meltzone by a fast movement +# before then slowing to travel the remaining distance to cooling tube. The +# initial fast movement should be as fast as extruder can comfortably perform. +# A good starting point# for slower move is unloading_speed_start/cooling_moves. +# Too fast a slower movement can lead to excessively long tips or hairs +variable_unloading_speed_start : 80 ; Speed in mm/s for initial fast movement +variable_unloading_speed : 18 ; Speed in mm/s for slow move to cooling zone + +# Step 3 - Cooling Moves +# The cooling move allows the filament to harden while constantly moving back +# and forth in the cooling tube portion of the extruder to prevent a bulbous +# tip forming. The cooling tube position is measured from the internal nozzle +# to just past the top of the heater block (often it is beneficial to add a +# couple of mm to ensure the tip is in the cooling section. The cooling tube +# length is then the distance from here to top of heatsink (this is the length +# length of the cooling moves). The final cooling move is a fast movement to +# break the string formed. +variable_cooling_tube_position : 35 ; Start of cooling tube. DragonST:35, DragonHF:30, Mosquito:30, Revo:35, RapidoHF:27 +variable_cooling_tube_length : 10 ; Movement length. DragonST:15, DragonHF:10, Mosquito:20, Revo:10, RapidoHF:10 +variable_initial_cooling_speed : 10 ; Initial slow movement (mm/s) to solidify tip and cool string if formed +variable_final_cooling_speed : 50 ; Fast movement (mm/s) Too fast: tip deformation on eject, Too Slow: long string/no separation +variable_cooling_moves : 4 ; Number of back and forth cooling moves to make (2-4 is a good start) + +# Step 4 - Skinnydip +# Skinnydip is an advanced final move that may have benefit with some +# material like PLA to burn off persistent very fine hairs. To work the +# depth of insertion is critical (start with it disabled and tune last) +# For reference the internal nozzle would be at a distance of +# cooling_tube_position + cooling_tube_length, the top of the heater +# block would be cooling_tube_length away. +variable_use_skinnydip : False ; True = enable skinnydip, False = skinnydip move disabled +variable_skinnydip_distance : 30 ; Distance to reinsert filament into hotend starting from end of cooling tube +variable_dip_insertion_speed : 30 ; Medium/Slow insertion speed mm/s - Just long enough to melt the fine hairs, too slow will pull up molten filament +variable_dip_extraction_speed : 70 ; Speed mm/s - Around 2x Insertion speed to prevents forming new hairs +variable_melt_zone_pause : 0 ; Pause if melt zone in ms. Default 0 +variable_cooling_zone_pause : 0 ; Pause if cooling zone after dip in ms. Default 0 +variable_use_fast_skinnydip : False ; False = Skip the toolhead temp change wait during skinnydip move + +# Step 5 - Parking +# Park filament ready to eject +variable_parking_distance : 0 ; Position mm to park the filament at end of tip forming, 0 = leave where filament ends up after tip forming +variable_extruder_eject_speed : 25 ; Speed mm/s used for parking_distance (and final_eject when testing) + + +# PURGE ------------------------------------------------------------------- +# ██████╗ ██╗ ██╗██████╗ ██████╗ ███████╗ +# ██╔══██╗██║ ██║██╔══██╗██╔════╝ ██╔════╝ +# ██████╔╝██║ ██║██████╔╝██║ ███╗█████╗ +# ██╔═══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝ +# ██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗ +# ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ +# +# Optional reference (bucket) purge. Blobifier if far better but this can be +# used as a basis for custom purge +# (base/mmu_purge.cfg) +# +[gcode_macro _MMU_PURGE_VARS] +description: Happy Hare reference purging macro configuration variables +gcode: # Leave empty + +# Set speed as fast as you can without the extruder skipping steps. Note that +# you can increase the extruder current for purging in mmu_parameters.cfg +variable_extruder_purge_speed : 2 ; Speed in mm/s for purging + + +# CLIENT MACROS ----------------------------------------------------------- +# ██████╗ █████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███████╗███████╗██╗ ██╗███╗ ███╗███████╗ +# ██╔══██╗██╔══██╗██║ ██║██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██║ ██║████╗ ████║██╔════╝ +# ██████╔╝███████║██║ ██║███████╗█████╗ ██████╔╝█████╗ ███████╗██║ ██║██╔████╔██║█████╗ +# ██╔═══╝ ██╔══██║██║ ██║╚════██║██╔══╝ ██╔══██╗██╔══╝ ╚════██║██║ ██║██║╚██╔╝██║██╔══╝ +# ██║ ██║ ██║╚██████╔╝███████║███████╗ ██║ ██║███████╗███████║╚██████╔╝██║ ╚═╝ ██║███████╗ +# ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ +# If using the recommended PAUSE/RESUME/CANCEL_PRINT macros shipped with +# Happy Hare these variables allow for customization and basic extension +# Note that most parameters are pulled from the "movement" (sequence) +# macro above and thus these are supplemental a +# (optional/client_macros.cfg) +# +[gcode_macro _MMU_CLIENT_VARS] +description: Happy Hare client macro configuration variables +gcode: # Leave empty + +variable_reset_ttg_on_cancel : False ; True/False, Whether reset TTG map if print is canceled +variable_unload_tool_on_cancel : False ; True/False, Whether to unload the tool on cancel + +# You can extend functionality by adding a command (or call to your gcode macro) +variable_user_pause_extension : '' ; Executed after the klipper base pause +variable_user_resume_extension : '' ; Executed before the klipper base resume +variable_user_cancel_extension : '' ; Executed before the klipper base cancel_print + + +########################################################################### +# Tool change macros +# This is automatically created on installation but you can increase or +# reduce this list to match your number of tools in operation +# Note: it is annoying to have to do this but interfaces like Mainsail rely +# on real macro definitions for tools to be visible in the UI +# +[gcode_macro T0] +gcode: MMU_CHANGE_TOOL TOOL=0 +[gcode_macro T1] +gcode: MMU_CHANGE_TOOL TOOL=1 +[gcode_macro T2] +gcode: MMU_CHANGE_TOOL TOOL=2 +[gcode_macro T3] +gcode: MMU_CHANGE_TOOL TOOL=3 +[gcode_macro T4] +gcode: MMU_CHANGE_TOOL TOOL=4 +[gcode_macro T5] +gcode: MMU_CHANGE_TOOL TOOL=5 +[gcode_macro T6] +gcode: MMU_CHANGE_TOOL TOOL=6 +[gcode_macro T7] +gcode: MMU_CHANGE_TOOL TOOL=7 + diff --git a/mmu/base/mmu_parameters.cfg b/mmu/base/mmu_parameters.cfg new file mode 100644 index 0000000..a65bd13 --- /dev/null +++ b/mmu/base/mmu_parameters.cfg @@ -0,0 +1,689 @@ +######################################################################################################################## +# Happy Hare MMU Software +# +# EDIT THIS FILE BASED ON YOUR SETUP +# +# Copyright (C) 2022-2025 moggieuk#6538 (discord) +# moggieuk@hotmail.com +# This file may be distributed under the terms of the GNU GPLv3 license. +# +# Goal: Main configuration parameters for the klipper module +# +# (\_/) +# ( *,*) +# (")_(") Happy Hare Ready +# +# Notes: +# Macro configuration is specified separately in 'mmu_macro_vars.cfg'. +# Full details in https://github.com/moggieuk/Happy-Hare/tree/main/doc/configuration.md +# +[mmu] +happy_hare_version: 3.2 # Don't mess, used for upgrade detection + +# MMU Hardware Limits -------------------------------------------------------------------------------------------------- +# ██╗ ██╗███╗ ███╗██╗████████╗███████╗ +# ██║ ██║████╗ ████║██║╚══██╔══╝██╔════╝ +# ██║ ██║██╔████╔██║██║ ██║ ███████╗ +# ██║ ██║██║╚██╔╝██║██║ ██║ ╚════██║ +# ███████╗██║██║ ╚═╝ ██║██║ ██║ ███████║ +# ╚══════╝╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ +# +# Define the physical limits of your MMU. These settings will be respected regardless of individual speed settings. +# +gear_max_velocity: 125 #300 # Never to be exceeded gear velocity regardless of specific parameters +gear_max_accel: 1500 # Never to be exceeded gear acceleration regardless of specific parameters +selector_max_velocity: 250 # Never to be exceeded selector velocity regardless of specific parameters +selector_max_accel: 1200 # Never to be exceeded selector acceleration regardless of specific parameters + + +# Servo configuration ------------------------------------------------------------------------------------------------- +# ███████╗███████╗██████╗ ██╗ ██╗ ██████╗ +# ██╔════╝██╔════╝██╔══██╗██║ ██║██╔═══██╗ +# ███████╗█████╗ ██████╔╝██║ ██║██║ ██║ +# ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║ ██║ +# ███████║███████╗██║ ██║ ╚████╔╝ ╚██████╔╝ +# ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═════╝ +# +# Angle of the servo in three named positions +# up = tool is selected and filament is allowed to freely move through gate +# down = to grip filament +# move = ready the servo for selector move (optional - defaults to up) +# V2.4.0 on: These positions are only for initial config they are replaced with calibrated servo positions in `mmu_vars.cfg` +# +# Note that leaving the servo active when down can stress the electronics and is not recommended with EASY-BRD or ERB board +# unless the 5v power supply has been improved and it is not necessary with standard ERCF builds +# Make sure your hardware is suitable for the job! +# +servo_up_angle: 30 # ERCF: MG90S: 30 ; SAVOX SH0255MG: 140 ; Tradrack: 145 +servo_down_angle: 140 # ERCF: MG90S: 140 ; SAVOX SH0255MG: 30 ; Tradrack: 1 +servo_move_angle: 30 # Optional angle used when selector is moved (defaults to up position) +servo_duration: 0.4 # Duration of PWM burst sent to servo (default non-active mode, automatically turns off) +servo_dwell: 0.5 # Minimum time given to servo to complete movement prior to next move +servo_always_active: 0 # CAUTION - WILL DAMAGE COMMON SERVOS, PLEASE USE AT YOUR OWN RISK: 1=Force servo to always stay active, 0=Release after movement +servo_active_down: 0 # CAUTION - WILL DAMAGE COMMON SERVOS, PLEASE USE AT YOUR OWN RISK: 1=Force servo to stay active when down only, 0=Release after movement +servo_buzz_gear_on_down: 1 # Whether to "buzz" the gear stepper on down to aid engagement + + +# Logging -------------------------------------------------------------------------------------------------------------- +# ██╗ ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ +# ██║ ██╔═══██╗██╔════╝ ██╔════╝ ██║████╗ ██║██╔════╝ +# ██║ ██║ ██║██║ ███╗██║ ███╗██║██╔██╗ ██║██║ ███╗ +# ██║ ██║ ██║██║ ██║██║ ██║██║██║╚██╗██║██║ ██║ +# ███████╗╚██████╔╝╚██████╔╝╚██████╔╝██║██║ ╚████║╚██████╔╝ +# ╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ +# +# log_level & logfile_level can be set to one of (0 = essential, 1 = info, 2 = debug, 3 = trace, 4 = stepper moves) +# Generally you can keep console logging to a minimal whilst still sending debug output to the mmu.log file +# Increasing the console log level is only really useful during initial setup to save having to constantly open the log file +# Note: that it is not recommended to keep logging at level greater that 2 (debug) if not debugging an issue because +# of the additional overhead +# +log_level: 1 +log_file_level: 2 # Can also be set to -1 to disable log file completely +log_statistics: 1 # 1 to log statistics on every toolchange (default), 0 to disable (but still recorded) +log_visual: 1 # 1 log visual representation of filament, 0 = disable +log_startup_status: 1 # Whether to log tool to gate status on startup, 1 = summary (default), 0 = disable +log_m117_messages: 1 # Whether send toolchange message via M117 to screen + + +# Movement speeds ------------------------------------------------------------------------------------------------------ +# ███████╗██████╗ ███████╗███████╗██████╗ ███████╗ +# ██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝ +# ███████╗██████╔╝█████╗ █████╗ ██║ ██║███████╗ +# ╚════██║██╔═══╝ ██╔══╝ ██╔══╝ ██║ ██║╚════██║ +# ███████║██║ ███████╗███████╗██████╔╝███████║ +# ╚══════╝╚═╝ ╚══════╝╚══════╝╚═════╝ ╚══════╝ +# +# Long moves are faster than the small ones and used for the bulk of the bowden movement. You can set two fast load speeds +# depending on whether pulling from the spool or filament buffer (if fitted and not the first time load). This can be helpful +# in allowing faster loading from buffer and slower when pulling from the spool because of the additional friction (prevents +# loosing steps). Unloading speed can be tuning if you have a rewinder system that imposes additional limits. +# NOTE: Encoder cannot keep up much above 450mm/s so make sure 'bowden_apply_correction' is off at very high speeds! +# +gear_from_spool_speed: 80 # mm/s Speed when loading from the spool (for the first time if has_filament_buffer: 1) +gear_from_spool_accel: 100 # Acceleration when loading from spool +gear_from_buffer_speed: 150 # mm/s Speed when loading filament from buffer. Conservative is 100mm/s, Max around 400mm/s +gear_from_buffer_accel: 400 # Normal acceleration when loading filament +gear_unload_speed: 80 # mm/s Use (lower) speed when unloading filament (defaults to "from spool" speed) +gear_unload_accel: 100 # Acceleration when unloading filament (defaults to "from spool" accel) +# +gear_short_move_speed: 80 # mm/s Speed when making short moves (like incremental retracts with encoder) +gear_short_move_accel: 600 # Usually the same as gear_from_buffer_accel (for short movements) +gear_short_move_threshold: 70 # Move distance that controls application of 'short_move' speed/accel +gear_homing_speed: 50 # mm/s Speed of gear stepper only homing moves (e.g. homing to gate or extruder) + +# Speeds of extruder movement. The 'sync' speeds will be used when gear and extruder steppers are moving in sync +# +extruder_load_speed: 16 # mm/s speed of load move inside extruder from homing position to meltzone +extruder_unload_speed: 16 # mm/s speed of unload moves inside of extruder (very initial move from meltzone is 50% of this) +extruder_sync_load_speed: 18 # mm/s speed of synchronized extruder load moves +extruder_sync_unload_speed: 18 # mm/s speed of synchronized extruder unload moves +extruder_homing_speed: 18 # mm/s speed of extruder only homing moves (e.g. to toolhead sensor) + +# Selector movement speeds. (Acceleration is defined by physical MMU limits set above and passed to selector stepper driver) +# +selector_move_speed: 200 # mm/s speed of selector movement (not touch) +selector_homing_speed: 60 # mm/s speed of initial selector homing move (not touch) +selector_touch_speed: 80 # mm/s speed of all touch selector moves (if stallguard configured) + +# Selector touch (stallguard) operation. If stallguard is configured, then this can be used to switch on touch movement which +# can detect blocked filament path and try to recover automatically but it is more difficult to set up +# +selector_touch_enable: 0 # If selector touch operation configured this can be used to disable it 1=enabled, 0=disabled + +# When Happy Hare calls out to a macro for user customization and for parking moves these settings are applied and the previous +# values automatically restored afterwards. This allows for deterministic movement speed regardless of the starting state. +# +macro_toolhead_max_accel: 0 # Default printer toolhead acceleration applied when macros are run. 0 = use printer max +macro_toolhead_min_cruise_ratio: 0.5 # Default printer cruise ratio applied when macros are run + + +# Gate loading/unloading ----------------------------------------------------------------------------------------------- +# ██████╗ █████╗ ████████╗███████╗ ██╗ ██████╗ █████╗ ██████╗ +# ██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝ ██║ ██╔═══██╗██╔══██╗██╔══██╗ +# ██║ ███╗███████║ ██║ █████╗ ██║ ██║ ██║███████║██║ ██║ +# ██║ ██║██╔══██║ ██║ ██╔══╝ ██║ ██║ ██║██╔══██║██║ ██║ +# ╚██████╔╝██║ ██║ ██║ ███████╗ ███████╗╚██████╔╝██║ ██║██████╔╝ +# ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ +# +# These settings control the loading and unloading filament at the gate which is the parking position inside the MMU. +# Typically this would be switch sensor but you can also use an encoder. Even with encoder the endstop can be a switch +# and the encoder used for move verifcation (see advanced 'gate_endstop_to_encoder' option). Note that the `encoder` +# method, due to the nature of its operation will overshoot a little. This is not a problem in practice because the +# overshoot will simply be compensated for in the subsequent move. A +ve parking distance moves towards the MMU, -ve +# moves back through the endstop towards the toolhead. If the MMU has multiple bowden tubes then it is possible to home +# at the extruder sensor and avoid long bowden moves! +# +# Possible gate_homing_endstop names: +# encoder - Detect filament position using movement of the encoder +# mmu_gate - Use gate endstop +# mmu_gear - Use individual per-gate endstop (type-B MMU's) +# extruder - Use extruder entry sensor (Only for some type-B designs, see [mmu_machine] require_bowden_move setting) +# +gate_homing_endstop: encoder # Name of gate endstop, "encoder" forces use of encoder for parking +gate_homing_max: 70 # Maximum move distance to home to the gate (or actual move distance for encoder parking) +gate_preload_homing_max: 70 # Maximum homing distance to the mmu_gear endstop (if MMU is fitted with one) +gate_unload_buffer: 50 # Amount to reduce the fast unload so that filament doesn't overshoot when parking +gate_load_retries: 2 # Number of times MMU will attempt to grab the filament on initial load (type-A designs) +gate_parking_distance: 10 # Parking position in the gate (distance back from homing point, -ve value means move forward) +gate_endstop_to_encoder: 10 # Distance between gate endstop and encoder (IF both fitted. +ve if encoder after endstop) +gate_autoload: 1 # If pre-gate sensor fitted this controls the automatic loading of the gate +gate_final_eject_distance: 0 # Distance to eject filament on MMU_EJECT (Ignored by MMU_UNLOAD) + + +# Bowden tube loading/unloading ---------------------------------------------------------------------------------------- +# ██████╗ ██████╗ ██╗ ██╗██████╗ ███████╗███╗ ██╗ ██╗ ██████╗ █████╗ ██████╗ +# ██╔══██╗██╔═══██╗██║ ██║██╔══██╗██╔════╝████╗ ██║ ██║ ██╔═══██╗██╔══██╗██╔══██╗ +# ██████╔╝██║ ██║██║ █╗ ██║██║ ██║█████╗ ██╔██╗ ██║ ██║ ██║ ██║███████║██║ ██║ +# ██╔══██╗██║ ██║██║███╗██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██╔══██║██║ ██║ +# ██████╔╝╚██████╔╝╚███╔███╔╝██████╔╝███████╗██║ ╚████║ ███████╗╚██████╔╝██║ ██║██████╔╝ +# ╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ +# +# In addition to different bowden loading speeds for buffer and non-buffered filament it is possible to detect missed +# steps caused by "jerking" on a heavy spool. If bowden correction is enabled the driver with "believe" the encoder +# reading and make correction moves to bring the filament to within the 'bowden_allowable_load_delta' of the end of +# bowden position (this does require a reliable encoder and is not recommended for very high speed loading >350mm/s) +# +bowden_apply_correction: 1 # 1 to enable, 0 disabled. Requires Encoder +bowden_allowable_load_delta: 20.0 # How close in mm the correction moves will attempt to get to target. Requires Encoder + +# This test verifies the filament is free of extruder before the fast bowden movement to reduce possibility of grinding filament +bowden_pre_unload_test: 1 # 1 to check for bowden movement before full pull (slower), 0 don't check (faster). Requires Encoder + +# ADVANCED: If pre-unload test is enabled, this controls the detection of successful bowden pre-unload test and represents +# the fraction of allowable mismatch between actual movement and that seen by encoder. Setting to 50% tolerance usually +# works well. Increasing will make test more tolerant. Value of 100% essentially disables error detection +bowden_pre_unload_error_tolerance: 50 + + +# Extruder homing ----------------------------------------------------------------------------------------------------- +# ███████╗██╗ ██╗████████╗ ██╗ ██╗ ██████╗ ███╗ ███╗██╗███╗ ██╗ ██████╗ +# ██╔════╝╚██╗██╔╝╚══██╔══╝ ██║ ██║██╔═══██╗████╗ ████║██║████╗ ██║██╔════╝ +# █████╗ ╚███╔╝ ██║ ███████║██║ ██║██╔████╔██║██║██╔██╗ ██║██║ ███╗ +# ██╔══╝ ██╔██╗ ██║ ██╔══██║██║ ██║██║╚██╔╝██║██║██║╚██╗██║██║ ██║ +# ███████╗██╔╝ ██╗ ██║██╗ ██║ ██║╚██████╔╝██║ ╚═╝ ██║██║██║ ╚████║╚██████╔╝ +# ╚══════╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ +# +# Happy Hare needs a reference "homing point" close to the extruder from which to accurately complete the loading of +# the toolhead. This homing operation takes place after the fast bowden load and it is anticipated that that load +# operation will leave the filament just shy of the homing point. If using a toolhead sensor this initial extruder +# homing is unnecessary (but can be forced) because the homing will occur inside the extruder for the optimum in accuracy. +# You still should set this homing method because it is also used for the determination and calibration of bowden length. +# +# In addition to an entry sensor "extruder" it is possible for Happy Hare to "feel" for the extruder gear entry +# by colliding with it. This can be done with encoder based collision detection, the compression of the sync-feedback +# (aka buffer) sensor or using "touch" (stallguard) on the gear stepper. Note that encoder collision detection is not +# completely deterministic and you will have to find the sweetspot for your setup by adjusting the TMC current reduction. +# Note that reduced current during collision detection can also prevent unecessary filament griding. +# +# Possible extruder_homing_endtop names: +# collision - Detect the collision with the extruder gear by monitoring encoder movement (Requires encoder) +# Fast bowden load will move to the extruder gears +# mmu_gear_touch - Use touch detection when the gear stepper hits the extruder (Requires stallguard) +# Fast bowden load will move to extruder_homing_buffer distance before extruder gear, then home +# extruder - If you have a "filament entry" endstop configured (Requires 'extruder' endstop) +# Fast bowden load will move to extruder_homing_buffer distance before sensor, then home +# filament_compression - If you have a "sync-feedback" sensor with compression switch configured +# Fast bowden load will move to extruder_homing_buffer distance before extruder gear, then home +# none - Don't attempt to home. Only possibiliy if lacking all sensor options +# Fast bowden load will move to the extruder gears. Option is fine if using toolhead sensor +# Note: The homing_endstop will be ignored ("none") if a toolhead sensor is available unless "extruder_force_homing: 1" +# +extruder_homing_max: 80 # Maximum distance to advance in order to attempt to home the extruder +extruder_homing_endstop: extruder # Filament homing method/endstop name (fallback if toolhead sensor not available) +extruder_homing_buffer: 25 # Amount to reduce the fast bowden load so filament doesn't overshoot the extruder homing point +extruder_collision_homing_current: 30 # % gear_stepper current (10%-100%) to use when homing to extruder homing (100 to disable) + +# If you have a toolhead sensor it will always be used as a homing point making the homing outside of the extruder +# potentially unnecessary. However you can still force this initial homing step by setting this option in which case +# the filament will home to the extruder and then home to the toolhead sensor in two steps +# +extruder_force_homing: 0 + + +# Toolhead loading and unloading -------------------------------------------------------------------------------------- +# ████████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗███████╗ █████╗ ██████╗ ██╗ ██████╗ █████╗ ██████╗ +# ╚══██╔══╝██╔═══██╗██╔═══██╗██║ ██║ ██║██╔════╝██╔══██╗██╔══██╗ ██║ ██╔═══██╗██╔══██╗██╔══██╗ +# ██║ ██║ ██║██║ ██║██║ ███████║█████╗ ███████║██║ ██║ ██║ ██║ ██║███████║██║ ██║ +# ██║ ██║ ██║██║ ██║██║ ██╔══██║██╔══╝ ██╔══██║██║ ██║ ██║ ██║ ██║██╔══██║██║ ██║ +# ██║ ╚██████╔╝╚██████╔╝███████╗██║ ██║███████╗██║ ██║██████╔╝ ███████╗╚██████╔╝██║ ██║██████╔╝ +# ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ +# +# It is possible to define highly customized loading and unloading sequences, however, unless you have a specialized +# setup it is probably easier to opt for the built-in toolhead loading and unloading sequence which already offers a +# high degree of customization. If you need even more control then edit the _MMU_LOAD_SEQUENCE and _MMU_UNLOAD_SEQUENCE +# macros in mmu_sequence.cfg - but be careful! +# +# An MMU must have a known point at the end of the bowden from which it can precisely load the extruder. Generally this +# will either be the extruder entrance (which is controlled with settings above) or by homing to toolhead sensor. If +# you have toolhead sensor it is past the extruder gear and the driver needs to know the max distance (from end of +# bowden move) to attempt homing +# +toolhead_homing_max: 40 # Maximum distance to advance in order to attempt to home to defined homing endstop + +# IMPORTANT: These next three settings are based on the physical dimensions of your toolhead +# Once a homing position is determined, Happy Hare needs to know the final move distance to the nozzle. There is only +# one correct value for your setup - use 'toolhead_ooze_reduction' (which corresponds to the residual filament left in +# your nozzle) to control excessive oozing on load. See doc for table of proposed values for common configurations. +# +# NOTE: If you have a toolhead sensor you can automate the calculation of these parameters! Read about the +# `MMU_CALIBRATE_TOOLHEAD` command (https://github.com/moggieuk/Happy-Hare/wiki/Blobbing-and-Stringing#---calibrating-toolhead) +# +#toolhead_extruder_to_nozzle: 99.38 # Distance from extruder gears (entrance) to nozzle +#toolhead_sensor_to_nozzle: 79.78 # Distance from toolhead sensor to nozzle (ignored if not fitted) +#toolhead_entry_to_extruder: 13.29 # Distance from extruder "entry" sensor to extruder gears (ignored if not fitted) + +toolhead_extruder_to_nozzle: 101.3 # (currently: 100.9) +toolhead_sensor_to_nozzle: 88.2 #(currently: 87.4) +toolhead_entry_to_extruder: 19.1 #(currently: 18.7) + +# This setting represents how much residual filament is left behind in the nozzle when filament is removed, it is thus +# used to reduce the extruder loading length and prevent excessive blobbing but also in the calculation of purge volume. +# Note that this value can also be measured with the `MMU_CALIBRATE_TOOLHEAD` procedure +# +toolhead_residual_filament: 0 # Reduction in extruder loading length because of residual filament left behind + +# TUNING: Finally, this is the last resort tuning value to fix blobbing. It is expected that this value is NEAR ZERO as +# it represents a further reduction in extruder load length to fix blobbing. If using a wipetower and you experience blobs +# on it, increase this value (reduce the quantity of filament loaded). If you experience gaps, decrease this value. If gaps +# and already at 0 then perhaps the 'toolhead_extruder_to_nozzle' or 'toolhead_residual_filament' settings are incorrect. +# Similarly a value >+5mm also suggests the four settings above are not correct. Also see 'retract' setting in +# 'mmu_macro_vars.cfg' for final in-print ooze tuning. +# +toolhead_ooze_reduction: 0 # Reduction in extruder loading length to prevent ooze (represents filament remaining) + +# Distance added to the extruder unload movement to ensure filament is free of extruder. This adds some degree of tolerance +# to slightly incorrect configuration or extruder slippage. However don't use as an excuse for incorrect toolhead settings +# +toolhead_unload_safety_margin: 10 # Extra movement safety margin (default: 10mm) + +# If not synchronizing gear and extruder and you experience a "false" clog detection immediately after the tool change +# it might be because of a long bowden and/or large internal diameter that causes slack in the filament. This optional +# move will tighten the filament after a load by % of current clog detection length. Gear stepper will run at 50% current +# +toolhead_post_load_tighten: 60 # % of clog detection length, 0 to disable. Ignored if 'sync_to_extruder: 1' + +# ADVANCED: Controls the detection of successful extruder load/unload movement and represents the fraction of allowable +# mismatch between actual movement and that seen by encoder. Setting to 100% tolerance effectively turns off checking. +# Some designs of extruder have a short move distance that may not be picked up by encoder and cause false errors. This +# allows masking of those errors. However the error often indicates that your extruder load speed is too high or the +# friction is too high on the filament and in that case masking the error is not a good idea. Try reducing friction +# and lowering speed first! +# +toolhead_move_error_tolerance: 60 + + +# Tip forming --------------------------------------------------------------------------------------------------------- +# ████████╗██╗██████╗ ███████╗ ██████╗ ██████╗ ███╗ ███╗██╗███╗ ██╗ ██████╗ +# ╚══██╔══╝██║██╔══██╗ ██╔════╝██╔═══██╗██╔══██╗████╗ ████║██║████╗ ██║██╔════╝ +# ██║ ██║██████╔╝ █████╗ ██║ ██║██████╔╝██╔████╔██║██║██╔██╗ ██║██║ ███╗ +# ██║ ██║██╔═══╝ ██╔══╝ ██║ ██║██╔══██╗██║╚██╔╝██║██║██║╚██╗██║██║ ██║ +# ██║ ██║██║ ██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║██║██║ ╚████║╚██████╔╝ +# ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ +# +# Tip forming responsibility can be split between slicer (in-print) and standalone macro (not in-print) or forced to always +# be done by Happy Hare's standalone macro. Since you always need the option to form tips without the slicer so it is +# generally easier to completely turn off the slicer, force "standalone" tip forming and tune only in Happy Hare. +# +# When Happy Hare is asked to form a tip it will run the referenced macro. Two are reference examples are provided but +# you can implement your own: +# _MMU_FORM_TIP .. default tip forming similar to popular slicers like Superslicer and Prusaslicer +# _MMU_CUT_TIP .. for Filametrix (originally ERCFv2) or similar style toolhead filament cutting system +# +# NOTE: For MMU located cutting like the optional EREC cutter you should set still this to _MMU_FORM_TIP to build a decent +# tip prior to extraction and cutting after the unload. +# +# Often it is useful to increase the extruder current for the rapid movement to ensure high torque and no skipped steps +# +# If opting for slicer tip forming you MUST configure where the slicer leaves the filament in the extruder since +# there is no way to determine this. This can be ignored if all tip forming is performed by Happy Hare +# +force_form_tip_standalone: 1 # 0 = Slicer in print else standalone, 1 = Always standalone tip forming (TURN SLICER OFF!) +form_tip_macro: _MMU_FORM_TIP # Name of macro to call to perform the tip forming (or cutting) operation +extruder_form_tip_current: 100 # % of extruder current (100%-150%) to use when forming tip (100 to disable) +slicer_tip_park_pos: 0 # This specifies the position of filament in extruder after slicer completes tip forming + + +# Purging ------------------------------------------------------------------------------------------------------------- +# ██████╗ ██╗ ██╗██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ +# ██╔══██╗██║ ██║██╔══██╗██╔════╝ ██║████╗ ██║██╔════╝ +# ██████╔╝██║ ██║██████╔╝██║ ███╗██║██╔██╗ ██║██║ ███╗ +# ██╔═══╝ ██║ ██║██╔══██╗██║ ██║██║██║╚██╗██║██║ ██║ +# ██║ ╚██████╔╝██║ ██║╚██████╔╝██║██║ ╚████║╚██████╔╝ +# ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ +# +# After a toolchange it is necessary to purge the old filament. Similar to tip forming this can be done by the slicer and/or +# by Happy Hare using an extension like Blobifer. If a purge_macro is defined it will be called when not printing or whenever +# the slicer isn't going to purge (like initial tool load). You can force it to always be called in a print by setting +# force_purge_standalone, but remember to turn off the slicer wipetower +# +# The default is for no (empty) macro so purging will not be done out of a print and thus wipetower. Two options are shipped with +# Happy Hare but you can also build your own custom one: +# _MMU_PURGE .. default purging that just dumps the desired amount of filament (setup correct parking before enabling this!) +# BLOBIFER .. for excellent Blobifer addon (https://github.com/Dendrowen/Blobifier) +# +# Often it is useful to increase the extruder current for the often rapid puring movement to ensure high torque and no skipped steps +# +force_purge_standalone: 0 # 0 = Slicer wipetower in print else standalone, 1 = Always standalone purging (TURN WIPETOWER OFF!) +purge_macro: '' # Name of macro to call to perform the standalone purging operation. E.g. BLOBIFIER, _MMU_PURGE +extruder_purge_current: 100 # % of extruder current (100%-150%) to use when purging (100 to disable) + + +# Synchronized gear/extruder movement ---------------------------------------------------------------------------------- +# ███╗ ███╗ ██████╗ ████████╗ ██████╗ ██████╗ ███████╗██╗ ██╗███╗ ██╗ ██████╗ +# ████╗ ████║██╔═══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ██╔════╝╚██╗ ██╔╝████╗ ██║██╔════╝ +# ██╔████╔██║██║ ██║ ██║ ██║ ██║██████╔╝ ███████╗ ╚████╔╝ ██╔██╗ ██║██║ +# ██║╚██╔╝██║██║ ██║ ██║ ██║ ██║██╔══██╗ ╚════██║ ╚██╔╝ ██║╚██╗██║██║ +# ██║ ╚═╝ ██║╚██████╔╝ ██║ ╚██████╔╝██║ ██║ ███████║ ██║ ██║ ╚████║╚██████╗ +# ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝ +# +# This controls whether the extruder and gear steppers are synchronized during printing operations +# If you normally run with maxed out gear stepper current consider reducing it with 'sync_gear_current' +# If equipped with TMC drivers the current of the gear and extruder motors can be controlled to optimize performance. +# This can be useful to control gear stepper temperature when printing with synchronized motor +# +sync_to_extruder: 1 # Gear motor is synchronized to extruder during print +sync_gear_current: 70 # % of gear_stepper current (10%-100%) to use when syncing with extruder during print +sync_form_tip: 0 # Synchronize during standalone tip formation (initial part of unload) +sync_purge: 0 # Synchronize during standalone purging (last part of load) + +# Optionally it is possible to leverage feedback for a "compression/expansion" sensor in the bowden path from MMU to +# extruder to ensure that the two motors are kept in sync as viewed by the filament (the signal feedback state can be +# binary supplied by one or two switches: -1 (expanded) and 1 (compressed) of proportional value between -1.0 and 1.0 +# Requires [mmu_sensors] setting +# +sync_feedback_enable: 0 # 0 = Turn off (even with fitted sensor), 1 = Turn on +sync_multiplier_high: 1.05 # Maximum factor to apply to gear stepper 'rotation_distance' +sync_multiplier_low: 0.95 # Minimum factor to apply + + +# ESpooler control ----------------------------------------------------------------------------------------------------- +# ███████╗███████╗██████╗ ██████╗ ██████╗ ██╗ ███████╗██████╗ +# ██╔════╝██╔════╝██╔══██╗██╔═══██╗██╔═══██╗██║ ██╔════╝██╔══██╗ +# █████╗ ███████╗██████╔╝██║ ██║██║ ██║██║ █████╗ ██████╔╝ +# ██╔══╝ ╚════██║██╔═══╝ ██║ ██║██║ ██║██║ ██╔══╝ ██╔══██╗ +# ███████╗███████║██║ ╚██████╔╝╚██████╔╝███████╗███████╗██║ ██║ +# ╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝ +# +# If your MMU has a dc motor (often N20) controlled respooler/assist then how it operates can be controlled with these +# settings. Typically the espooler will be controlled with PWM signal. This will be at the maximum at speeds equal or +# above 'espooler.max_stepper_speed'. The PWM signal will scale downwards towards 0 for slower speeds. The falloff being +# controlled by the 'espooler_speed_exponent' setting according to this formula and allows for non-linear characteristics +# the DC motor (0.5 is a good starting value). +# +# espooler_pwm = (stepper_speed / espooler_max_stepper_speed) ^ {espooler_speed_exponent} +# +# Regardless of h/w configuration you can enable/disable actions with the 'espooler_operations' list. E.g. remove 'play' to +# turn off operation while printing. Options are: +# +# rewind - when filament is being unloaded under MMU control (aka respool) +# assist - when filament is being loaded under MMU control (% of "rewind" speed but with minimum of "print" power) +# print - while printing. Generally set 'espooler_printing_power' to a low percentage just to allow motor to be turned +# freely or set to 0 to enable/allow "burst" assist movements +# +# If using a digitally controlled espooler motor (not PWM) then you should turn off the "print" mode and set +# 'espooler_min_stepper_speed' to prevent "over movement" +# +espooler_min_distance: 30 # Individual stepper movements less than this distance will not active espooler +espooler_max_stepper_speed: 300 # Gear stepper speed at which espooler will be at maximum power +espooler_min_stepper_speed: 0 # Gear stepper speed at which espooler will become inactive (useful for non PWM control) +espooler_speed_exponent: 0.5 # Controls non-linear espooler power relative to stepper speed (see notes) +espooler_assist_reduced_speed: 50 # Control the % of the rewind speed that is applied to assisting load (want rewind to be faster) +espooler_printing_power: 0 # If >0, fixes the % of PWM power while printing. 0=allows burst movement +espooler_operations: rewind, assist, print # List of operational modes (allows disabling even if h/w is configured) +# +# The following burst configuration is used only if 'print' operation is enabled and 'espooler_printing_power: 0' +# +espooler_assist_extruder_move_length: 100 # Distance (mm) extruder needs to move between each assist burst +espooler_assist_burst_power: 100 # The % power of the burst move +espooler_assist_burst_duration: 0.4 # The duration of the burst move is seconds +espooler_assist_burst_trigger: 0 # If trigger assist switch is fitted 0=disable, 1=enable +espooler_assist_burst_trigger_max: 3 # If trigger assist switch is fitted this limits the max number of back-to-back advances + + +# Filament Management Options ---------------------------------------------------------------------------------------- +# ███████╗██╗██╗ ███╗ ███╗ ██████╗ ███╗ ███╗████████╗ +# ██╔════╝██║██║ ████╗ ████║██╔════╝ ████╗ ████║╚══██╔══╝ +# █████╗ ██║██║ ██╔████╔██║██║ ███╗██╔████╔██║ ██║ +# ██╔══╝ ██║██║ ██║╚██╔╝██║██║ ██║██║╚██╔╝██║ ██║ +# ██║ ██║███████╗██╗ ██║ ╚═╝ ██║╚██████╔╝██║ ╚═╝ ██║ ██║ +# ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ +# +# - Clog detection is available when encoder is fitted and it can detect when filament is not moving and pause the print +# - EndlessSpool feature allows detection of runout on one spool and the automatic mapping of tool to an alternative +# gate (spool). Set to '1', this feature requires clog detection or gate sensor or pre-gate sensors. EndlessSpool +# functionality can optionally be extended to attempt to load an empty gate with 'endless_spool_on_load'. On some MMU +# designs (with linear selector) it can also be configured to eject filament remains to a designated gate rather than +# defaulting to current gate. A custom gate will disable pre-gate runout detection for EndlessSpool because filament +# end must completely pass through the gate for selector to move +# +enable_clog_detection: 2 # 0 = disable, 1 = static length clog detection, 2 = automatic length clog detection +enable_endless_spool: 1 # 0 = disable, 1 = enable endless spool +endless_spool_on_load: 0 # 0 = don't apply endless spool on load, 1 = run endless spool if gate is empty +endless_spool_eject_gate: -1 # Which gate to eject the filament remains. -1 = current gate +#endless_spool_groups: # Default EndlessSpool groups (see later in file) +# +# Spoolman support requires you to correctly enable spoolman with moonraker first. If enabled, the gate SpoolId will +# be used to load filament details and color from the spoolman database and Happy Hare will activate/deactivate +# spools as they are used. The enabled variation allows for either the local map or the spoolman map to be the +# source of truth as well as just fetching filament attributes. See this table for explanation: +# +# | Activate/ | Fetch filament attributes | Filament gate | Filament gate | +# spoolman_support | Deactivate | attributes from spoolman | assignment shown | assignment pulled | +# | spool? | based on spool_id? | in spoolman db? | from spoolman db? | +# -----------------+------------+---------------------------+------------------+-------------------+ +# off | no | no | no | no | +# readonly | yes | yes | no | no | +# push | yes | yes | yes | no | +# pull | yes | yes | yes | yes | +# +spoolman_support: off # off = disabled, readonly = enabled, push = local gate map, pull = remote gate map +pending_spool_id_timeout: 20 # Seconds after which this pending spool_id (set with rfid) is voided +# +# Mainsail/Fluid UI can visualize the color of filaments next to the extruder/tool chooser. The color is dynamic and +# can be customized to your choice: +# +# slicer - Color from slicer tool map (what the slicer expects) +# allgates - Color from all the tools in the gate map after running through the TTG map +# gatemap - As per gatemap but hide empty tools +# off - Turns off support +# +# Note: Happy Hare will also add the 'spool_id' variable to the Tx macro if spoolman is enabled +# +t_macro_color: slicer # 'slicer' = default | 'allgates' = mmu | 'gatemap' = mmu without empty gates | 'off' + + +# Print Statistics --------------------------------------------------------------------------------------------------- +# ███████╗████████╗ █████╗ ████████╗███████╗ +# ██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝ +# ███████╗ ██║ ███████║ ██║ ███████╗ +# ╚════██║ ██║ ██╔══██║ ██║ ╚════██║ +# ███████║ ██║ ██║ ██║ ██║ ███████║ +# ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ +# +# These parameters determine how print statistic data is shown in the console. This table can show a lot of data, +# probably more than you'd want to see. Below you can enable/disable options to your needs. +# +# +-----------+---------------------+----------------------+----------+ +# | 114(46) | unloading | loading | complete | +# | swaps | pre | - | post | pre | - | post | swap | +# +-----------+------+-------+------+------+-------+-------+----------+ +# | all time | 0:07 | 47:19 | 0:00 | 0:01 | 37:11 | 33:39 | 2:00:38 | +# | - avg | 0:00 | 0:24 | 0:00 | 0:00 | 0:19 | 0:17 | 1:03 | +# | this job | 0:00 | 10:27 | 0:00 | 0:00 | 8:29 | 8:30 | 28:02 | +# | - avg | 0:00 | 0:13 | 0:00 | 0:00 | 0:11 | 0:11 | 0:36 | +# | last | 0:00 | 0:12 | 0:00 | 0:00 | 0:10 | 0:14 | 0:39 | +# +-----------+------+-------+------+------+-------+-------+----------+ +# Note: Only formats correctly on Python3 +# +# Comma separated list of desired columns +# Options: pre_unload, form_tip, unload, post_unload, pre_load, load, purge, post_load, total +console_stat_columns: unload, load, post_load, total + +# Comma separated list of rows. The order determines the order in which they're shown. +# Options: total, total_average, job, job_average, last +console_stat_rows: total, total_average, job, job_average, last + +# How you'd want to see the state of the gates and how they're performing +# string - poor, good, perfect, etc.. +# percentage - rate of success +# emoticon - fun sad to happy faces (python3 only) +console_gate_stat: emoticon + +# Always display the full statistics table +console_always_output_full: 1 # 1 = Show full table, 0 = Only show totals out of print + + +# Miscellaneous, but you should review ------------------------------------------------------------------------------- +# ███╗ ███╗██╗███████╗ ██████╗ +# ████╗ ████║██║██╔════╝██╔════╝ +# ██╔████╔██║██║███████╗██║ +# ██║╚██╔╝██║██║╚════██║██║ +# ██║ ╚═╝ ██║██║███████║╚██████╗ +# ╚═╝ ╚═╝╚═╝╚══════╝ ╚═════╝ +# +# Important you verify these work for you setup/workflow. Temperature and timeouts +# +timeout_pause: 72000 # Idle time out (printer shuts down) in seconds used when in MMU pause state +disable_heater: 600 # Delay in seconds after which the hotend heater is disabled in the MMU_PAUSE state +default_extruder_temp: 200 # Default temperature for performing swaps and forming tips when not in print (overridden by gate map) +extruder_temp_variance: 2 # When waiting for extruder temperature this is the +/- permissible variance in degrees (>= 1) +# +# These are auto calibration/tuning settings. Once the gear rotation_distance and encoder are calibrated, enabling these options +# will lessen the initial calibration and will automatically tune bowden length and individual gate rotation_distance differences. +# Note: What can be tuned is based on "variable_rotation_distance" and "variable_bowden_lengths" settings in mmu_hardware.cfg +# E.g. with fixed bowden and multiple BMG gears and encoder like the ERCF, the bowden length is tuned on gate#0 and +# rotation_distance (MMU_CALIBRATE_GATE) is tuned for other gates. +# +autotune_bowden_length: 0 # Automated bowden length calibration/tuning. 1=automatic, 0=manual/off +autotune_rotation_distance: 1 # Automated gate calibration/tuning (requires encoder). 1=automatic, 0=manual/off +# +# Other workflow options +# +startup_home_if_unloaded: 0 # 1 = force mmu homing on startup if unloaded, 0 = do nothing +startup_reset_ttg_map: 0 # 1 = reset TTG map on startup, 0 = do nothing +show_error_dialog: 1 # 1 = show pop-up dialog in addition to console message, 0 = show error in console +preload_attempts: 5 # How many "grabbing" attempts are made to pick up the filament with preload feature +strict_filament_recovery: 0 # If enabled with MMU with toolhead sensor, this will cause filament position recovery to + # perform extra moves to look for filament trapped in the space after extruder but before sensor +filament_recovery_on_pause: 1 # 1 = Run a quick check to determine current filament position on pause/error, 0 = disable +retry_tool_change_on_error: 0 # Whether to automatically retry a failed tool change. If enabled Happy Hare will perform + # the equivalent of 'MMU_RECOVER' + 'Tx' commands which usually is all that is necessary + # to recover. Note that enabling this can mask problems with your MMU +bypass_autoload: 1 # If extruder sensor fitted this controls the automatic loading of extruder for bypass operation +has_filament_buffer: 1 # Whether the MMU has a filament buffer. Set to 0 if using Filamentalist or DC eSpooler, etc +# +# Advanced options. Don't mess unless you fully understand. Read documentation. +# +encoder_move_validation: 1 # ADVANCED: 1 = Normally Encoder validates move distances are within given tolerance + # 0 = Validation is disabled (eliminates slight pause between moves but less safe) +print_start_detection: 1 # ADVANCED: Enabled for Happy Hare to automatically detect start and end of print and call + # ADVANCED: MMU_PRINT_START and MMU_PRINT_END automatically. Harmless to leave enabled but can disable + # if you think it is causing problems and known START/END is covered in your macros +extruder: extruder # ADVANCED: Name of the toolhead extruder that MMU is using +gcode_load_sequence: 0 # VERY ADVANCED: Gcode loading sequence 1=enabled, 0=internal logic (default) +gcode_unload_sequence: 0 # VERY ADVANCED: Gcode unloading sequence, 1=enabled, 0=internal logic (default) + + +# ADVANCED: Klipper tuning ------------------------------------------------------------------------------------------- +# ██╗ ██╗██╗ ██╗██████╗ ██████╗ ███████╗██████╗ +# ██║ ██╔╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗ +# █████╔╝ ██║ ██║██████╔╝██████╔╝█████╗ ██████╔╝ +# ██╔═██╗ ██║ ██║██╔═══╝ ██╔═══╝ ██╔══╝ ██╔══██╗ +# ██║ ██╗███████╗██║██║ ██║ ███████╗██║ ██║ +# ╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ +# +# Timer too close is a catch all error, however it has been found to occur on some systems during homing and probing +# operations especially so with CANbus connected MCUs. Happy Hare uses many homing moves for reliable extruder loading +# and unloading and enabling this option affords klipper more tolerance and avoids this dreaded error +# +update_trsync: 0 # 1 = Increase TRSYNC_TIMEOUT, 0 = Leave the klipper default +# +# Some CANbus boards are prone to this but it have been seen on regular USB boards where a comms timeout will kill +# the print. Since it seems to occur only on homing moves they can be safely retried to workaround. This has been +# working well in practice +canbus_comms_retries: 3 # Number of retries. Recommend the default of 3. +# +# Older neopixels have very finicky timing and can generate lots of "Unable to obtain 'neopixel_result' response" +# errors in klippy.log. An often cited workaround is to increase BIT_MAX_TIME in neopixel.py. This option does that +# automatically for you to save dirtying klipper +update_bit_max_time: 1 # 1 = Increase BIT_MAX_TIME, 0 = Leave the klipper default + + +# ADVANCED: MMU macro overrides --- ONLY SET IF YOU'RE COMFORTABLE WITH KLIPPER MACROS ------------------------------- +# ███╗ ███╗ █████╗ ██████╗██████╗ ██████╗ ███████╗ +# ████╗ ████║██╔══██╗██╔════╝██╔══██╗██╔═══██╗██╔════╝ +# ██╔████╔██║███████║██║ ██████╔╝██║ ██║███████╗ +# ██║╚██╔╝██║██╔══██║██║ ██╔══██╗██║ ██║╚════██║ +# ██║ ╚═╝ ██║██║ ██║╚██████╗██║ ██║╚██████╔╝███████║ +# ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ +# +# 'pause_macro' defines what macro to call on MMU error (must put printer in paused state) +# Other macros are detailed in 'mmu_sequence.cfg' +# Also see form_tip_macro in Tip Forming section and purge_macro in Purging section +# +pause_macro: PAUSE # What macro to call to pause the print +action_changed_macro: _MMU_ACTION_CHANGED # Called when action (printer.mmu.action) changes +print_state_changed_macro: _MMU_PRINT_STATE_CHANGED # Called when print state (printer.mmu.print_state) changes +mmu_event_macro: _MMU_EVENT # Called on useful MMU events +pre_unload_macro: _MMU_PRE_UNLOAD # Called before starting the unload +post_form_tip_macro: _MMU_POST_FORM_TIP # Called immediately after tip forming +post_unload_macro: _MMU_POST_UNLOAD # Called after unload completes +pre_load_macro: _MMU_PRE_LOAD # Called before starting the load +post_load_macro: _MMU_POST_LOAD # Called after the load is complete +unload_sequence_macro: _MMU_UNLOAD_SEQUENCE # VERY ADVANCED: Optionally called based on 'gcode_unload_sequence' +load_sequence_macro: _MMU_LOAD_SEQUENCE # VERY ADVANCED: Optionally called based on 'gcode_load_sequence' + + +# ADVANCED: See documentation for use of these ----------------------------------------------------------------------- +# ██████╗ ███████╗███████╗███████╗████████╗ ██████╗ ███████╗███████╗███████╗ +# ██╔══██╗██╔════╝██╔════╝██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝██╔════╝██╔════╝ +# ██████╔╝█████╗ ███████╗█████╗ ██║ ██║ ██║█████╗ █████╗ ███████╗ +# ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██║ ██║ ██║██╔══╝ ██╔══╝ ╚════██║ +# ██║ ██║███████╗███████║███████╗ ██║ ██████╔╝███████╗██║ ███████║ +# ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚══════╝ +# +# These are the values that the various "RESET" commands will reset too rather than the built-in defaults. The lenght +# of the lists must match the number of gates on your MMU +# +# e.g. MMU_GATE_MAP RESET=1 - will use all the 'gate_XXX' values +# MMU_TTG_MAP RESET=1 - will use the 'tool_to_gate_map' +# MMU_ENDLESS_SPOOL_GROUPS RESET=1 - will use the 'endless_spool_groups' +# +# Gate: #0 #1 #2 #3 #4 #5 #6 #7 #8 +#gate_status: 1, 0, 1, 2, 2, -1, -1, 0, 1 +#gate_filament_name: one, two, three, four, five, six, seven, eight, nine +#gate_material: PLA, ABS, ABS, ABS+, PLA, PLA, PETG, TPU, ABS +#gate_color: red, black, yellow, green, blue, indigo, ffffff, grey, black +#gate_temperature: 210, 240, 235, 245, 210, 200, 215, 240, 240 +#gate_spool_id: 3, 2, 1, 4, 5, 6, 7, -1, 9 +#gate_speed_override: 100, 100, 100, 100, 100, 100, 100, 50, 100 +#endless_spool_groups: 0, 1, 2, 1, 0, 0, 3, 4, 1 +# +# Tool: T0 T1 T2 T3 T4 T5 T6 T7 T8 +#tool_to_gate_map: 0, 1, 2, 3, 4, 5, 6, 7, 8 + + +# ADVANCED/CUSTOM MMU: See documentation for use of these ------------------------------------------------------------ +# ██████╗██╗ ██╗███████╗████████╗ ██████╗ ███╗ ███╗ ███╗ ███╗███╗ ███╗██╗ ██╗ +# ██╔════╝██║ ██║██╔════╝╚══██╔══╝██╔═══██╗████╗ ████║ ████╗ ████║████╗ ████║██║ ██║ +# ██║ ██║ ██║███████╗ ██║ ██║ ██║██╔████╔██║ ██╔████╔██║██╔████╔██║██║ ██║ +# ██║ ██║ ██║╚════██║ ██║ ██║ ██║██║╚██╔╝██║ ██║╚██╔╝██║██║╚██╔╝██║██║ ██║ +# ╚██████╗╚██████╔╝███████║ ██║ ╚██████╔╝██║ ╚═╝ ██║ ██║ ╚═╝ ██║██║ ╚═╝ ██║╚██████╔╝ +# ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ +# +# Normally all these settings are set based on your choice of 'mmu_vendor' and 'mmu_version' in mmu_hardware.cfg, but they +# can be overridden. If you have selected a vendor of "Other" and your MMU has a selector you must set these CAD based +# dimensions else you will get arbitrary defaults. You may also need to set additional attributes in '[mmu_machine]' +# section of mmu_hardware.cfg. +# +#cad_gate0_pos: 4.2 # Approximate distance from endstop to first gate. Used for rough calibration only +#cad_gate_width: 21.0 # Width of each gate +#cad_bypass_offset: 0 # Distance from limit of travel back to the bypass (e.g. ERCF v2.0) +#cad_last_gate_offset: 2.0 # Distance from limit of travel back to last gate +#cad_selector_tolerance: 10.0 # How much extra selector movement to allow for calibration +#cad_gate_directions = [1, 1, 0, 0] # Directions of gear depending on gate (3DChameleon) +#cad_release_gates = [2, 3, 0, 1] # Gate to move to when releasing filament (3DChameleon) + +# SUPPLEMENTAL USER CONFIG retained after upgrade -------------------------------------------------------------------- +# diff --git a/mmu/base/mmu_purge.cfg b/mmu/base/mmu_purge.cfg new file mode 120000 index 0000000..50043c7 --- /dev/null +++ b/mmu/base/mmu_purge.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_purge.cfg \ No newline at end of file diff --git a/mmu/base/mmu_sequence.cfg b/mmu/base/mmu_sequence.cfg new file mode 120000 index 0000000..7f0ccb6 --- /dev/null +++ b/mmu/base/mmu_sequence.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_sequence.cfg \ No newline at end of file diff --git a/mmu/base/mmu_software.cfg b/mmu/base/mmu_software.cfg new file mode 120000 index 0000000..1265352 --- /dev/null +++ b/mmu/base/mmu_software.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_software.cfg \ No newline at end of file diff --git a/mmu/base/mmu_state.cfg b/mmu/base/mmu_state.cfg new file mode 120000 index 0000000..2200afc --- /dev/null +++ b/mmu/base/mmu_state.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/base/mmu_state.cfg \ No newline at end of file diff --git a/mmu/mmu_vars.cfg b/mmu/mmu_vars.cfg new file mode 100644 index 0000000..e5c6f2e --- /dev/null +++ b/mmu/mmu_vars.cfg @@ -0,0 +1,36 @@ +[Variables] +mmu__revision = 2859 +mmu_calibration_bowden_home = 'encoder' +mmu_calibration_bowden_lengths = [951.6, 951.6, 951.6, 951.6, 951.6, 951.6, 951.6, 951.6] +mmu_calibration_clog_length = 19.0 +mmu_encoder_resolution = 0.948992 +mmu_gear_rotation_distances = [22.845345, -1, 23.000827, -1, 23.065147, 22.682752, -1, 22.754847] +mmu_selector_bypass = 179.2 +mmu_selector_offsets = [4.0, 27.0, 49.9, 72.9, 95.9, 118.9, 141.8, 164.8] +mmu_servo_angles = {'down': 145, 'up': 30, 'move': 50} +mmu_state_enable_endless_spool = 0 +mmu_state_filament_pos = 0 +mmu_state_filament_remaining = 0 +mmu_state_filament_remaining_color = '' +mmu_state_gate_color = ['green', 'grey', 'black', '', 'cyan', '', '', '3d3846'] +mmu_state_gate_filament_name = ['', '', '', '', '', '', '', ''] +mmu_state_gate_material = ['ABS', 'ABS', 'ABS', '', 'ABS', '', '', 'PETG'] +mmu_state_gate_selected = -1 +mmu_state_gate_speed_override = [100, 100, 100, 100, 100, 100, 100, 100] +mmu_state_gate_spool_id = [-1, -1, -1, -1, -1, -1, -1, -1] +mmu_state_gate_status = [0, 0, 0, 0, 0, 0, 2, 1] +mmu_state_gate_temperature = [200, 200, 200, 200, 200, 200, 200, 200] +mmu_state_last_tool = 5 +mmu_state_tool_selected = -1 +mmu_state_tool_to_gate_map = [0, 1, 2, 3, 4, 5, 6, 7] +mmu_statistics_counters = {'servo_down': {'count': 599, 'limit': 5000, 'warning': 'Inspect servo arm for wear/damage', 'pause': False}, 'mmu_restarts': {'count': 93, 'limit': -1, 'warning': ''}, 'cutter_blade': {'count': 0, 'limit': 3000, 'warning': 'Inspect/replace filament cutting blade', 'pause': False}} +mmu_statistics_gate_0 = {'pauses': 0, 'loads': 8, 'load_distance': 11954.651, 'load_delta': 4653.767, 'unloads': 11, 'unload_distance': 5205.0, 'unload_delta': 92.747, 'load_failures': 4, 'unload_failures': 2, 'quality': 0.8198260180834479} +mmu_statistics_gate_1 = {'pauses': 2, 'loads': 10, 'load_distance': 15191.968, 'load_delta': 770.824, 'unloads': 11, 'unload_distance': 1720.0, 'unload_delta': -15.149, 'load_failures': 2, 'unload_failures': 0, 'quality': 0.9676574716286735} +mmu_statistics_gate_2 = {'pauses': 2, 'loads': 12, 'load_distance': 20421.388, 'load_delta': 8152.369, 'unloads': 17, 'unload_distance': 12115.0, 'unload_delta': 3336.452, 'load_failures': 9, 'unload_failures': 0, 'quality': 0.9635278810027199} +mmu_statistics_gate_3 = {'pauses': 0, 'loads': 0, 'load_distance': 0.0, 'load_delta': 0.0, 'unloads': 0, 'unload_distance': 0.0, 'unload_delta': 0.0, 'load_failures': 0, 'unload_failures': 0, 'quality': -1.0} +mmu_statistics_gate_4 = {'pauses': 1, 'loads': 8, 'load_distance': 13584.429, 'load_delta': 9464.65, 'unloads': 11, 'unload_distance': 3440.0, 'unload_delta': 3139.28, 'load_failures': 7, 'unload_failures': 2, 'quality': 0.7126287603755388} +mmu_statistics_gate_5 = {'pauses': 0, 'loads': 2, 'load_distance': 2852.423, 'load_delta': 423.003, 'unloads': 4, 'unload_distance': 2704.8, 'unload_delta': 149.164, 'load_failures': 1, 'unload_failures': 1, 'quality': 0.8392536837473988} +mmu_statistics_gate_6 = {'pauses': 4, 'loads': 3, 'load_distance': 3363.452, 'load_delta': 1694.174, 'unloads': 3, 'unload_distance': 901.6, 'unload_delta': 40.864, 'load_failures': 1, 'unload_failures': 1, 'quality': 0.2490142359175044} +mmu_statistics_gate_7 = {'pauses': 6, 'loads': 11, 'load_distance': 14499.488, 'load_delta': 6469.17, 'unloads': 26, 'unload_distance': 22111.2, 'unload_delta': 6092.289, 'load_failures': 7, 'unload_failures': 5, 'quality': 0.5589421641409617} +mmu_statistics_swaps = {'pre_load': 16.29, 'purge': 17.61, 'post_load': 27.17, 'load': 1499.55, 'pre_unload': 25.33, 'form_tip': 393.62, 'unload': 2817.46, 'post_unload': 22.04, 'total': 1578.64, 'total_swaps': 20, 'swaps_since_pause': 3, 'swaps_since_pause_record': 4, 'total_pauses': 16, 'pause': 1582.58} + diff --git a/mmu/optional/client_macros.cfg b/mmu/optional/client_macros.cfg new file mode 120000 index 0000000..c91c6cf --- /dev/null +++ b/mmu/optional/client_macros.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/optional/client_macros.cfg \ No newline at end of file diff --git a/mmu/optional/mmu_menu.cfg b/mmu/optional/mmu_menu.cfg new file mode 120000 index 0000000..af7f456 --- /dev/null +++ b/mmu/optional/mmu_menu.cfg @@ -0,0 +1 @@ +/home/biqu/Happy-Hare/config/optional/mmu_menu.cfg \ No newline at end of file diff --git a/mmu_klipperscreen.conf b/mmu_klipperscreen.conf new file mode 100644 index 0000000..7a8144e --- /dev/null +++ b/mmu_klipperscreen.conf @@ -0,0 +1,757 @@ +# Happy Hare KlipperScreen menus. Don't remove this line, installer needs it! +# +# Copyright (C) 2023-2025 moggieuk#6538 (discord) +# moggieuk@hotmail.com +# +# Menu options: +# name, icon, panel, method, confirm, enable, params, style, NEW: show_disabled, refresh_on +# +# Additional functionality added with this MMU Happy Hare fork: +# +# Options: +# show_disabled - True will cause 'enable' logic to show button disabled rather than not display it +# refresh_on - List of printer variables to monitor real time for 'show_disabled' +# +# Menu name: +# can specify multiple roots, e.g. [menu __main,__print mymenu] +# will duplicate on both __main and __print menus +# (no space after comman) +# +# Useful for custom single purpose use (like dedicated SpoolMan display on filament rack) +# you can make any panel "sticky" (never changes without navigation) by adding the following. +# Caution: only intended for monitoring panels - NO NAVIGATION +# [main] +# sticky_panel: +# + +[menu __main,__print mmu] +name: {{ gettext('MMU') }} +icon: mmu_carrot +panel: mmu_main +enable: {{ printer.mmu is defined and not klipperscreen.side_mmu_shortcut }} + +[menu __main,__print mmu ttg] +name: {{ gettext('Manage TTG...') }} +icon: mmu_ttg_map +panel: mmu_toolmap + +[menu __main,__print mmu filaments] +name: {{ gettext('Filaments...') }} +icon: mmu_filaments +panel: mmu_filaments + +[menu __main,__print mmu spoolman] +name: {{ gettext('Spoolman...') }} +icon: spoolman +panel: mmu_spoolman +enable: {{ moonraker.spoolman }} +show_disabled: True + +[menu __main,__print mmu tools] +name: {{ gettext('Load Tool...') }} +icon: extruder +enable: {{ printer.mmu.print_state != "printing" }} +show_disabled: True +refresh_on: printer.mmu.print_state + +# Generated menus for each tool/gate... +[menu __main,__print mmu tools T0] +name: {{ gettext('T0') }} +icon: mmu_t0 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=0 QUIET=1" } +enable: {{ (printer.mmu.tool != 0 or (printer.mmu.tool == 0 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[0] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T1] +name: {{ gettext('T1') }} +icon: mmu_t1 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=1 QUIET=1" } +enable: {{ (printer.mmu.tool != 1 or (printer.mmu.tool == 1 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[1] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T2] +name: {{ gettext('T2') }} +icon: mmu_t2 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=2 QUIET=1" } +enable: {{ (printer.mmu.tool != 2 or (printer.mmu.tool == 2 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[2] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T3] +name: {{ gettext('T3') }} +icon: mmu_t3 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=3 QUIET=1" } +enable: {{ (printer.mmu.tool != 3 or (printer.mmu.tool == 3 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[3] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T4] +name: {{ gettext('T4') }} +icon: mmu_t4 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=4 QUIET=1" } +enable: {{ (printer.mmu.tool != 4 or (printer.mmu.tool == 4 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[4] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T5] +name: {{ gettext('T5') }} +icon: mmu_t5 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=5 QUIET=1" } +enable: {{ (printer.mmu.tool != 5 or (printer.mmu.tool == 5 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[5] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T6] +name: {{ gettext('T6') }} +icon: mmu_t6 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=6 QUIET=1" } +enable: {{ (printer.mmu.tool != 6 or (printer.mmu.tool == 6 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[6] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action +[menu __main,__print mmu tools T7] +name: {{ gettext('T7') }} +icon: mmu_t7 +method: printer.gcode.script +params: { "script":"MMU_CHANGE_TOOL TOOL=7 QUIET=1" } +enable: {{ (printer.mmu.tool != 7 or (printer.mmu.tool == 7 and printer.mmu.filament != "Loaded")) and printer.mmu.gate_status[7] != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.tool, printer.mmu.gate_status, printer.mmu.filament, printer.mmu.action + +[menu __main,__print mmu preload_gates] +name: {{ gettext('Preload Gate...') }} +icon: mmu_reset +enable: {{ printer.mmu.print_state != "printing" }} +show_disabled: True +refresh_on: printer.mmu.print_state + +# Generated menus for each tool/gate... +[menu __main,__print mmu preload_gates PG0] +name: {{ gettext('Preload Gate #0') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=0" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG1] +name: {{ gettext('Preload Gate #1') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG2] +name: {{ gettext('Preload Gate #2') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=2" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG3] +name: {{ gettext('Preload Gate #3') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=3" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG4] +name: {{ gettext('Preload Gate #4') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=4" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG5] +name: {{ gettext('Preload Gate #5') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=5" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG6] +name: {{ gettext('Preload Gate #6') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=6" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu preload_gates PG7] +name: {{ gettext('Preload Gate #7') }} +icon: mmu_reset +method: printer.gcode.script +params: { "script":"MMU_PRELOAD GATE=7" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.action + +[menu __main,__print mmu eject_gates] +name: {{ gettext('Eject Gate...') }} +icon: mmu_eject +enable: {{ printer.mmu.print_state != "printing" }} +show_disabled: True +refresh_on: printer.mmu.print_state + +# Generated menus for each tool/gate... +[menu __main,__print mmu eject_gates G0] +name: {{ gettext('Eject Gate #0') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=0" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[0] != 0 and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G1] +name: {{ gettext('Eject Gate #1') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[1] != 0 and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G2] +name: {{ gettext('Eject Gate #2') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=2" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[2] != 0 and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G3] +name: {{ gettext('Eject Gate #3') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=3" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[3] != 0 and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G4] +name: {{ gettext('Eject Gate #4') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=4" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[4] != 0 and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G5] +name: {{ gettext('Eject Gate #5') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=5" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[5] != 0 and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G6] +name: {{ gettext('Eject Gate #6') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=6" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[6] != 0 and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main,__print mmu eject_gates G7] +name: {{ gettext('Eject Gate #7') }} +icon: mmu_eject +method: printer.gcode.script +params: { "script":"MMU_EJECT FORCE=1 GATE=7" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.gate_status[7] != 0 and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action + +[menu __main,__print mmu check_gates] +name: {{ gettext('Check Gate...') }} +icon: mmu_checkgates +enable: {{ printer.mmu.print_state != "printing" }} +show_disabled: True +refresh_on: printer.mmu.print_state + +# Generated menus for each tool/gate... +[menu __main,__print mmu check_gates CG0] +name: {{ gettext('Check Gate #0') }} +icon: mmu_checkgate0 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=0 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG1] +name: {{ gettext('Check Gate #1') }} +icon: mmu_checkgate1 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=1 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG2] +name: {{ gettext('Check Gate #2') }} +icon: mmu_checkgate2 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=2 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG3] +name: {{ gettext('Check Gate #3') }} +icon: mmu_checkgate3 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=3 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG4] +name: {{ gettext('Check Gate #4') }} +icon: mmu_checkgate4 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=4 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG5] +name: {{ gettext('Check Gate #5') }} +icon: mmu_checkgate5 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=5 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG6] +name: {{ gettext('Check Gate #6') }} +icon: mmu_checkgate6 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=6 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main,__print mmu check_gates CG7] +name: {{ gettext('Check Gate #7') }} +icon: mmu_checkgate7 +method: printer.gcode.script +params: { "script":"MMU_CHECK_GATE GATE=7 QUIET=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.action + +[menu __main,__print mmu select_gates] +name: {{ gettext('Select Gate...') }} +icon: mmu_select_gate +enable: {{ printer.mmu.print_state != "printing" }} +show_disabled: True +refresh_on: printer.mmu.print_state + +# Example: to just select the tool (not load) +#[menu __main,__print mmu select_tools] +#name: {{ gettext('Select Tool...') }} +#icon: extruder +#enable: {{ printer.mmu.print_state != "printing" }} +#show_disabled: True +#refresh_on: printer.mmu.print_state +# +#MMU_iter_select_tools + +[menu __main,__print mmu select_gates bypass}] +name: {{ gettext('Select Bypass') }} +icon: mmu_select_bypass +method: printer.gcode.script +params: {"script":"MMU_SELECT_BYPASS"} +enable: {{ printer.mmu.gate != -2 and printer.mmu.has_bypass }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.has_bypass + +# Generated menus for each tool/gate... +[menu __main,__print mmu select_gates G0] +name: {{ gettext('Select Gate #0') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=0" } +enable: {{ printer.mmu.gate != 0 and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G1] +name: {{ gettext('Select Gate #1') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=1" } +enable: {{ printer.mmu.gate != 1 and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G2] +name: {{ gettext('Select Gate #2') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=2" } +enable: {{ printer.mmu.gate != 2 and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G3] +name: {{ gettext('Select Gate #3') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=3" } +enable: {{ printer.mmu.gate != 3 and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G4] +name: {{ gettext('Select Gate #4') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=4" } +enable: {{ printer.mmu.gate != 4 and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G5] +name: {{ gettext('Select Gate #5') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=5" } +enable: {{ printer.mmu.gate != 5 and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G6] +name: {{ gettext('Select Gate #6') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=6" } +enable: {{ printer.mmu.gate != 6 and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.gate +[menu __main,__print mmu select_gates G7] +name: {{ gettext('Select Gate #7') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=7" } +enable: {{ printer.mmu.gate != 7 and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.gate + +[menu __main,__print mmu status] +name: {{ gettext('Display Status') }} +icon: info +method: printer.gcode.script +params: {"script":"MMU_STATUS"} +enable: {{ printer.mmu.action == "Idle" }} +show_disabled: True +refresh_on: printer.mmu.action + +[menu __main,__print mmu print] +name: {{ gettext('Print Stats') }} +icon: mmu_status +method: printer.gcode.script +params: {"script":"MMU_STATS"} +enable: {{ printer.mmu.action == "Idle" }} +show_disabled: True +refresh_on: printer.mmu.action + +[menu __main,__print mmu reset] +name: {{ gettext('Reset Stats') }} +icon: mmu_stats_reset +method: printer.gcode.script +confirm: Are you sure you want to reset MMU statistics? +params: {"script":"MMU_STATS RESET=1"} +enable: {{ printer.mmu.action == "Idle" }} +show_disabled: True +refresh_on: printer.mmu.action + +[menu __main,__print mmu enable_endless_spool] +name: {{ gettext('Enable E.Spool') }} +icon: mmu_enable_endless_spool +method: printer.gcode.script +params: {"script":"MMU_ENDLESS_SPOOL ENABLE=1"} +enable: {{ printer.mmu.endless_spool == 0 }} +show_disabled: True +refresh_on: printer.mmu.endless_spool + +[menu __main,__print mmu disable_endless_spool] +name: {{ gettext('Disable E.Spool') }} +icon: mmu_disable_endless_spool +method: printer.gcode.script +params: {"script":"MMU_ENDLESS_SPOOL ENABLE=0"} +enable: {{ printer.mmu.endless_spool == 1 }} +show_disabled: True +refresh_on: printer.mmu.endless_spool +[menu __main,__print mmu led_disable] + +name: {{ gettext('Disable LED') }} +icon: mmu_led_disable +method: printer.gcode.script +params: {"script":"MMU_LED ENABLE=0 QUIET=1"} +enable: {{ printer.mmu.enabled and not printer.mmu.print_state == "standby" }} +show_disabled: True +refresh_on: printer.mmu.enabled, printer.mmu.print_state + +[menu __main,__print mmu led_gate_status] +name: {{ gettext('LED Gate Status') }} +icon: mmu_led_gate_status +method: printer.gcode.script +params: {"script":"MMU_LED ENABLE=1 EXIT_EFFECT=gate_status QUIET=1"} +enable: {{ printer.mmu.enabled and not printer.mmu.print_state == "standby" }} +show_disabled: True +refresh_on: printer.mmu.enabled, printer.mmu.print_state + +[menu __main,__print mmu led_filament_color] +name: {{ gettext('LED Fil. Color') }} +icon: mmu_led_filament_color +method: printer.gcode.script +params: {"script":"MMU_LED ENABLE=1 EXIT_EFFECT=filament_color QUIET=1"} +enable: {{ printer.mmu.enabled and not printer.mmu.print_state == "standby" }} +show_disabled: True +refresh_on: printer.mmu.enabled, printer.mmu.print_state + +# Example: User added ... +[menu __main,__print mmu spare1] +name: {{ gettext('user def') }} +icon: mmu_carrot +enable: False +show_disabled: False + +# Examples: for basic management +#[menu __main,__print mmu home] +#name: {{ gettext('Home Selector') }} +#icon: home +#method: printer.gcode.script +#params: {"script":"MMU_HOME"} +# +#[menu __main,__print mmu servoup] +#name: {{ gettext('Servo UP') }} +#icon: arrow-up +#method: printer.gcode.script +#params: {"script":"MMU_SERVO POS=up"} +#enable: {{ printer.mmu.servo != "Up" }} +#show_disabled: True +#refresh_on: printer.mmu.servo +# +#[menu __main,__print mmu servodown] +#name: {{ gettext('Servo Down') }} +#icon: arrow-down +#method: printer.gcode.script +#params: {"script":"MMU_SERVO POS=down"} +#enable: {{ printer.mmu.servo != "Down" }} +#show_disabled: True +#refresh_on: printer.mmu.servo +# +#[menu __main,__print mmu motoroff] +#name: {{ gettext('Disable Motors') }} +#icon: motor-off +#method: printer.gcode.script +#confirm: "This will invalidate selector position and require rehoming. Are you sure?" +#params: {"script":"MMU_MOTORS_OFF"} +# +# ---------- MMU Manage submenu end + + +# ---------- MMU config/calibration menu +# +[menu __main more mmu_calib] +name: {{ gettext('MMU Setup') }} +icon: mmu_gear +enable: {{ printer.mmu is defined }} + +[menu __main more mmu_calib home] +name: {{ gettext('Home') }} +icon: home +method: printer.gcode.script +params: {"script":"MMU_HOME"} +enable: {{ printer.mmu.selector_type and printer.mmu.selector_type != "VirtualSelector" }} +show_disabled: True + +[menu __main more mmu_calib select_gates] +name: {{ gettext('Select Gate...') }} +icon: mmu_select_gate + +# Generated menus for each tool/gate... +[menu __main more mmu_calib select_gates G0] +name: {{ gettext('Select Gate #0') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=0" } +enable: {{ printer.mmu.gate != 0 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G1] +name: {{ gettext('Select Gate #1') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=1" } +enable: {{ printer.mmu.gate != 1 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G2] +name: {{ gettext('Select Gate #2') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=2" } +enable: {{ printer.mmu.gate != 2 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G3] +name: {{ gettext('Select Gate #3') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=3" } +enable: {{ printer.mmu.gate != 3 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G4] +name: {{ gettext('Select Gate #4') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=4" } +enable: {{ printer.mmu.gate != 4 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G5] +name: {{ gettext('Select Gate #5') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=5" } +enable: {{ printer.mmu.gate != 5 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G6] +name: {{ gettext('Select Gate #6') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=6" } +enable: {{ printer.mmu.gate != 6 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action +[menu __main more mmu_calib select_gates G7] +name: {{ gettext('Select Gate #7') }} +icon: mmu_select_gate +method: printer.gcode.script +params: { "script":"MMU_SELECT GATE=7" } +enable: {{ printer.mmu.gate != 7 and printer.mmu.action == "Idle" and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.gate, printer.mmu.action + +[menu __main more mmu_calib grip] +name: {{ gettext('Test Grip') }} +icon: mmu_grip +method: printer.gcode.script +params: {"script":"MMU_TEST_GRIP"} + +[menu __main more mmu_calib formtip] +name: {{ gettext('Form Tip') }} +icon: mmu_formtip +method: printer.gcode.script +params: {"script":"MMU_FORM_TIP"} + +[menu __main more mmu_calib servoup] +name: {{ gettext('Servo UP') }} +icon: arrow-up +method: printer.gcode.script +params: {"script":"MMU_SERVO POS=up"} +enable: {{ printer.mmu.selector_type and printer.mmu.selector_type != "VirtualSelector" and printer.mmu.servo != "Up" }} +show_disabled: True +refresh_on: printer.mmu.servo + +[menu __main more mmu_calib servomove] +name: {{ gettext('Servo MOVE') }} +icon: arrow-right +method: printer.gcode.script +params: {"script":"MMU_SERVO POS=move"} +enable: {{ printer.mmu.selector_type and printer.mmu.selector_type != "VirtualSelector" and printer.mmu.servo != "Move" }} +show_disabled: True +refresh_on: printer.mmu.servo + +[menu __main more mmu_calib servodown] +name: {{ gettext('Servo DOWN') }} +icon: arrow-down +method: printer.gcode.script +params: {"script":"MMU_SERVO POS=down"} +enable: {{ printer.mmu.selector_type and printer.mmu.selector_type != "VirtualSelector" and printer.mmu.servo != "Down" }} +show_disabled: True +refresh_on: printer.mmu.servo + +[menu __main more mmu_calib encoder] +name: {{ gettext('Cal. Encoder') }} +icon: mmu_encodercal +method: printer.gcode.script +params: {"script":"MMU_CALIBRATE_ENCODER"} + +[menu __main more mmu_calib all] +name: {{ gettext('Calibrate ALL') }} +icon: extruder +method: printer.gcode.script +confirm: This will calibrate all gates. Are you sure? +params: {"script":"MMU_CALIBRATE_GATES ALL=1"} + +[menu __main more mmu_calib gate] +name: {{ gettext('Cal. Gate...') }} +icon: mmu_calibrate + +# Generated menus for each tool/gate... +[menu __main more mmu_calib gate CG0] +name: {{ gettext('Calibrate #0') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=0" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 0 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG1] +name: {{ gettext('Calibrate #1') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=1" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 1 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG2] +name: {{ gettext('Calibrate #2') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=2" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 2 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG3] +name: {{ gettext('Calibrate #3') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=3" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 3 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG4] +name: {{ gettext('Calibrate #4') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=4" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 4 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG5] +name: {{ gettext('Calibrate #5') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=5" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 5 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG6] +name: {{ gettext('Calibrate #6') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=6" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 6 }} +show_disabled: True +refresh_on: printer.mmu.action +[menu __main more mmu_calib gate CG7] +name: {{ gettext('Calibrate #7') }} +icon: mmu_calibrate +method: printer.gcode.script +params: { "script":"MMU_CALIBRATE_GATES GATE=7" } +enable: {{ printer.mmu.action == "Idle" and printer.mmu.num_gates > 7 }} +show_disabled: True +refresh_on: printer.mmu.action +# +# ---------- MMU config/calibration end + diff --git a/moonraker.conf b/moonraker.conf new file mode 100644 index 0000000..f7b346d --- /dev/null +++ b/moonraker.conf @@ -0,0 +1,112 @@ +[server] +host: 0.0.0.0 +port: 7125 +klippy_uds_address: /home/biqu/printer_data/comms/klippy.sock + +[authorization] +trusted_clients: + 192.168.0.0/16 + 10.0.0.0/8 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.168.0.0/16 + FC00::/7 + FE80::/10 + ::1/128 +cors_domains: + *.lan + *.local + *://localhost + *://localhost:* + *://my.mainsail.xyz + *://app.fluidd.xyz + +[octoprint_compat] + +[history] + +[file_manager] +enable_object_processing: True + +[update_manager] +channel: dev +refresh_interval: 168 + +[timelapse] + +[update_manager mainsail] +path: /home/biqu/mainsail +repo: mainsail-crew/mainsail +channel: stable +type: web + +[update_manager mainsail-config] +managed_services: klipper +origin: https://github.com/mainsail-crew/mainsail-config.git +path: /home/biqu/mainsail-config +primary_branch: master +type: git_repo + +[update_manager KlipperScreen] +install_script: /home/biqu/KlipperScreen/scripts/KlipperScreen-install.sh +requirements: /home/biqu/KlipperScreen/scripts/KlipperScreen-requirements.txt +virtualenv: /home/biqu/.KlipperScreen-env +managed_services: KlipperScreen +origin: https://github.com/moggieuk/KlipperScreen-Happy-Hare-Edition.git +path: /home/biqu/KlipperScreen +type: git_repo + +# Crowsnest update_manager entry +[update_manager crowsnest] +type: git_repo +path: ~/crowsnest +origin: https://github.com/mainsail-crew/crowsnest.git +managed_services: crowsnest +install_script: tools/pkglist.sh + +# Sonar update_manager entry +[update_manager sonar] +type: git_repo +path: ~/sonar +origin: https://github.com/mainsail-crew/sonar.git +primary_branch: main +managed_services: sonar +system_dependencies: resources/system-dependencies.json + +[update_manager timelapse] +type: git_repo +primary_branch: main +path: ~/moonraker-timelapse +origin: https://github.com/mainsail-crew/moonraker-timelapse.git +managed_services: klipper moonraker + +[update_manager Klipper-Adaptive-Meshing-Purging] +type: git_repo +channel: dev +path: ~/Klipper-Adaptive-Meshing-Purging +origin: https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging.git +managed_services: klipper +primary_branch: main + +[update_manager klipper_tmc_autotune] +type: git_repo +channel: dev +path: ~/klipper_tmc_autotune +origin: https://github.com/andrewmcgr/klipper_tmc_autotune.git +managed_services: klipper +primary_branch: main +install_script: install.sh + +[update_manager happy-hare] +type: git_repo +path: ~/Happy-Hare +origin: https://github.com/moggieuk/Happy-Hare.git +primary_branch: main +managed_services: klipper + +[mmu_server] +enable_file_preprocessor: True +enable_toolchange_next_pos: True +update_spoolman_location: True + diff --git a/octopus_pro_1.1.cfg b/octopus_pro_1.1.cfg new file mode 100644 index 0000000..0cbd00c --- /dev/null +++ b/octopus_pro_1.1.cfg @@ -0,0 +1,235 @@ +[mcu] +canbus_uuid: afcf80281237 + +[temperature_sensor OctopusPro] +sensor_type: temperature_mcu + +[temperature_sensor Chamber] +sensor_type: ATC Semitec 104NT-4-R025H42G +sensor_pin: PF4 + +[output_pin ps_on] +pin: PE11 +value: 1 +shutdown_value: 1 + +##################################################################### +# X/Y Stepper Settings +##################################################################### + +## ldo-42sth48-2004mah + +## X Stepper on Motor0 (B Motor) +[stepper_x] +enable_pin: !PF14 +step_pin: PF13 +dir_pin: PF12 +microsteps: 64 +endstop_pin: tmc5160_stepper_x:virtual_endstop + +[tmc5160 stepper_x] +interpolate: True +cs_pin: PC4 +spi_software_sclk_pin: PA5 +spi_software_mosi_pin: PA7 +spi_software_miso_pin: PA6 +diag1_pin: ^!PG6 +driver_SGT: 1 #1-3 # -64 is most sensitive value, 63 is least sensitive +run_current: 1.25 #1.25 +stealthchop_threshold: 0 +#stealthchop_threshold: 999999 + +## Y Stepper on Motor2 (A Motor) +[stepper_y] +enable_pin: !PG5 +step_pin: PF11 +dir_pin: PG3 +microsteps: 64 +endstop_pin: tmc5160_stepper_y:virtual_endstop + +[tmc5160 stepper_y] +interpolate: True +cs_pin: PC6 +spi_software_sclk_pin: PA5 +spi_software_mosi_pin: PA7 +spi_software_miso_pin: PA6 +diag1_pin: ^!PG10 +driver_SGT: 0 #2-3 #range is -64 to +63 +run_current: 1.25 #1.25 +stealthchop_threshold: 0 +#stealthchop_threshold: 999999 + + +[autotune_tmc stepper_x] +motor: ldo-42sth48-2004mah +extra_hysteresis: 4 +sgt: 0 +[autotune_tmc stepper_y] +motor: ldo-42sth48-2004mah +extra_hysteresis: 4 +sgt: 0 + +##################################################################### +# Z Stepper Settings +##################################################################### + +## Z0 Stepper - Front Left on MOTOR4 +[stepper_z] +enable_pin: !PG2 +step_pin: PF9 +dir_pin: PF10 +microsteps: 128 #128 +endstop_pin: probe:z_virtual_endstop + +[tmc2209 stepper_z] +uart_pin: PF2 +interpolate: True +run_current: 1 +#sense_resistor: 0.110 +#stealthchop_threshold: 999999 + +## Z1 Stepper - Rear Left on Motor5 +[stepper_z1] +enable_pin: !PF1 +step_pin: PC13 +dir_pin: !PF0 +microsteps: 128 + +[tmc2209 stepper_z1] +uart_pin: PE4 +interpolate: True +run_current: 1 +#sense_resistor: 0.110 +#stealthchop_threshold: 999999 + +## Z2 Stepper - Rear Right on Motor6 +[stepper_z2] +enable_pin: !PD4 +step_pin: PE2 +dir_pin: PE3 +microsteps: 128 + +[tmc2209 stepper_z2] +uart_pin: PE1 +interpolate: True +run_current: 1 +#sense_resistor: 0.110 +#stealthchop_threshold: 999999 + +## Z3 Stepper - Fron Right on Motor7 +[stepper_z3] +enable_pin: !PE0 +step_pin: PE6 +dir_pin: !PA14 +microsteps: 128 + +[tmc2209 stepper_z3] +uart_pin: PD3 +interpolate: True +run_current: 1 +#sense_resistor: 0.110 +#stealthchop_threshold: 999999 + +[autotune_tmc stepper_z] +motor: ldo-42sth48-2004ac +[autotune_tmc stepper_z1] +motor: ldo-42sth48-2004ac +[autotune_tmc stepper_z2] +motor: ldo-42sth48-2004ac +[autotune_tmc stepper_z3] +motor: ldo-42sth48-2004ac + +##################################################################### +# Bed Heater +##################################################################### + +[heater_bed] +heater_pin: PA0 +sensor_type: Generic 3950 +sensor_pin: PF3 +#max_power: 0.6 + +##################################################################### +# Fans +##################################################################### + +[controller_fan stepper_drivers_fan] +pin: PA8 +stepper: stepper_x, stepper_y +idle_speed: 0 +fan_speed: 0.6 + +#[heater_fan Nevermore] +#pin: PE5 +#heater_temp: 90 +#max_power: 1.0 +#kick_start_time: 0.5 +#heater: heater_bed +#fan_speed: 1 + +[fan_generic Nevermore] +## Nevermore - FAN5 on Octopus +## Adjust if you use a different board or a different terminal. +pin: PE5 + +[fan] #CPAP +pin: PD15 +max_power: 0.8 +shutdown_speed: 0 +cycle_time: 0.005 +hardware_pwm: False +kick_start_time: 0.100 +off_below: 0.03 + +#[temperature_fan chamber] +#pin: PD14 +#max_power: 1.0 +#shutdown_speed: 0.0 +#kick_start_time: 5.0 +#cycle_time:0.01 +#off_below:0.1 +#hardware_pwm: True +#sensor_type: ATC Semitec 104NT-4-R025H42G +#sensor_pin: PF4 +#min_temp: 0 +#max_temp: 70 +#target_temp: 40 +#control: watermark +#gcode_id: C + +# this is the exhaust fan +# comment out it if you don't have exhaust fan +[fan_generic exhaust_fan] +pin: PD14 +cycle_time: 0.01 +hardware_pwm: false + +#[multi_pin soc_pin] +#pins: PD12, PD13 + + +#[fan_generic SoC] +#pin: multi_pin: soc_pin +#max_power: 1 + +[fan_generic SoC_Left] +pin: PD13 +max_power: 1 + +[fan_generic SoC_Right] +pin: PD12 +max_power: 1 + + +##################################################################### +# LED Control +##################################################################### + +[neopixel chamber_leds] +pin: PB10 +chain_count: 50 #50 +color_order: GRB +initial_RED: 1.0 +initial_GREEN: 1.0 +initial_BLUE: 1.0 +initial_WHITE: 0.0 diff --git a/printer.cfg b/printer.cfg new file mode 100644 index 0000000..5213eb6 --- /dev/null +++ b/printer.cfg @@ -0,0 +1,235 @@ + +[include mainsail.cfg] +[include timelapse.cfg] +#[include hbb.cfg] + +# Happy Hare +#[include mmu/base/*.cfg] +#[include mmu/optional/client_macros.cfg] +#[include mmu/addons/blobifier.cfg] +#[include mmu/addons/mmu_erec_cutter.cfg] + +[mcu host] +serial: /tmp/klipper_host_mcu + +[temperature_sensor BttPi2] +sensor_type: temperature_host + +[include octopus_pro_1.1.cfg] +[include toolhead_sb.cfg] +#[include toolhead_sht36v2.cfg] + +[printer] +kinematics: corexy +max_velocity: 500 +max_accel: 8000 #Max 4000 +max_z_velocity: 15 #Max 15 for 12V TMC Drivers, can increase for 24V +max_z_accel: 350 +square_corner_velocity: 5.0 + +[force_move] +enable_force_move: true + +[respond] +default_type: echo +default_prefix: echo: + +[exclude_object] + +[gcode_arcs] +resolution: 0.1 + +[skew_correction] + + +##################################################################### +# X/Y Stepper Settings +##################################################################### + +## X Stepper on Motor1(B Motor) +[stepper_x] +rotation_distance: 40 #39.8 +full_steps_per_rotation:400 +position_min: 0 +position_endstop: 355 #355 +position_max: 355 #355 +homing_speed: 80 #25 #Max 100 +#homing_retract_dist: 10 +homing_retract_dist: 0 +homing_positive_dir: true + +## Y Stepper on Motor2 (A Motor) +[stepper_y] +full_steps_per_rotation:400 +rotation_distance: 40 #39.8 +position_min: 0 +position_endstop: 355 +position_max: 355 +homing_speed: 100 #25 #Max 100 +#homing_retract_dist: 5 +homing_retract_dist: 0 +homing_positive_dir: true + + +##################################################################### +# Z Stepper Settings +##################################################################### + +## Z0 Stepper - Front Left on MOTOR3_A +[stepper_z] +rotation_distance: 40 +gear_ratio: 80:16 +position_max: 300 +position_min: -20 +homing_speed: 15 +second_homing_speed: 3 +homing_retract_dist: 3 + +[stepper_z1] +rotation_distance: 40 +gear_ratio: 80:16 + +[stepper_z2] +rotation_distance: 40 +gear_ratio: 80:16 + +[stepper_z3] +rotation_distance: 40 +gear_ratio: 80:16 + + +##################################################################### +# Heater +##################################################################### + +[verify_heater heater_bed] +max_error: 120 +check_gain_time: 60 +hysteresis: 5 +heating_gain: 2 + +[verify_heater extruder] +#max_error: 120 +check_gain_time: 30 +#hysteresis: 5 +#heating_gain: 2 + + +##################################################################### +# Bed Heater +##################################################################### + +[heater_bed] +min_temp: 0 +max_temp: 120 +control: pid +pid_kp: 55.796 +pid_ki: 2.797 +pid_kd: 278.281 + + +##################################################################### +# Probe +##################################################################### + +[probe] +x_offset: 0 +y_offset: 0 +#z_offset: -0.890 +lift_speed: 15 #10 +speed: 3.0 #5 +samples: 3 +samples_result: median +sample_retract_dist: 3 +samples_tolerance: 0.005 +samples_tolerance_retries: 6 +activate_gcode: + {% set PROBE_TEMP = 150 %} + {% set MAX_TEMP = PROBE_TEMP + 5 %} + {% set ACTUAL_TEMP = printer.extruder.temperature %} + {% set TARGET_TEMP = printer.extruder.target %} + + {% if TARGET_TEMP > PROBE_TEMP %} + { action_respond_info('Extruder temperature target of %.1fC is too high, lowering to %.1fC' % (TARGET_TEMP, PROBE_TEMP)) } + M109 S{ PROBE_TEMP } + {% else %} + # Temperature target is already low enough, but nozzle may still be too hot. + {% if ACTUAL_TEMP > MAX_TEMP %} + { action_respond_info('Extruder temperature %.1fC is still too high, waiting until below %.1fC' % (ACTUAL_TEMP, MAX_TEMP)) } + TEMPERATURE_WAIT SENSOR=extruder MAXIMUM={ MAX_TEMP } + {% endif %} + {% endif %} + +##################################################################### +# Homing and Gantry Adjustment Routines +##################################################################### + +[idle_timeout] +timeout: 600 +gcode: + _SET_IDLE_MODE + #_CHAMBER_LED_OFF + +[quad_gantry_level] +gantry_corners: + -60,10 + 410,420 +points: + #50,50 + #50,300 + #300,300 + #300,50 + 50,50 + 50,300 + 300,300 + 300,50 +speed: 500 +horizontal_move_z: 6 +retries: 10 +retry_tolerance: 0.0075 +max_adjust: 15 + +[bed_mesh] +speed: 450 +horizontal_move_z: 5 +#mesh_min: 40, 40 +#mesh_max: 310,310 +mesh_min: 30, 30 +mesh_max: 325,325 +fade_start: 0.6 +fade_end: 10.0 +probe_count: 5,5 # Values should be odd, so one point is directly at bed center +algorithm: bicubic +#relative_reference_index: 12 #40 #12 # Update when changing probe_count, to ((x points * y points) - 1) / 2. (the center point) +adaptive_margin: 5 + + +[include macros/main.cfg] + +#*# <---------------------- SAVE_CONFIG ----------------------> +#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated. +#*# +#*# [skew_correction default] +#*# xy_skew = -0.002542020467517966 +#*# xz_skew = 0.0 +#*# yz_skew = 0.0 +#*# +#*# [bed_mesh default] +#*# version = 1 +#*# points = +#*# 0.047812, 0.011875, 0.018437, 0.068750 +#*# 0.045312, 0.025312, 0.030625, 0.085937 +#*# 0.057500, 0.017812, 0.029375, 0.089062 +#*# x_count = 4 +#*# y_count = 3 +#*# mesh_x_pps = 2 +#*# mesh_y_pps = 2 +#*# algo = lagrange +#*# tension = 0.2 +#*# min_x = 99.89129999999997 +#*# max_x = 270.62129999999996 +#*# min_y = 264.187 +#*# max_y = 283.447 +#*# +#*# [probe] +#*# z_offset = -0.830 diff --git a/rapido_ace.cfg b/rapido_ace.cfg new file mode 100644 index 0000000..602ae37 --- /dev/null +++ b/rapido_ace.cfg @@ -0,0 +1,17 @@ +[extruder] +#Classic Ziegler-Nichols PID parameters: +#pid_kp: 41.785 +#pid_ki: 25.323 +#pid_kd: 17.237 +##Pessen Integral Rule PID parameters: +#pid_kp: 48.749 +#pid_ki: 36.930 +#pid_kd: 24.131 +#Some Overshoot PID parameters: +#pid_kp: 22.982 +#№pid_ki: 13.928 +#pid_kd: 25.027 +#No Overshoot PID parameters: +pid_kp: 13.928 +pid_ki: 8.441 +pid_kd: 15.168 diff --git a/rapido_v2.cfg b/rapido_v2.cfg new file mode 100644 index 0000000..59ecabc --- /dev/null +++ b/rapido_v2.cfg @@ -0,0 +1,5 @@ +[extruder] +control: pid +pid_Kp: 26.171 +pid_Ki: 2.684 +pid_Kd: 63.793 \ No newline at end of file diff --git a/sonar.conf b/sonar.conf new file mode 100644 index 0000000..c4b60d2 --- /dev/null +++ b/sonar.conf @@ -0,0 +1,17 @@ +#### Sonar - A WiFi Keepalive daemon +#### +#### Written by Stephan Wendel aka KwadFan +#### Copyright 2022 +#### https://github.com/mainsail-crew/sonar +#### +#### This File is distributed under GPLv3 +#### + +[sonar] +enable: false # false to disable till next reboot (will stop again if not set to true) +debug_log: false # if set to true, sonar will log every ping with triptime and date/time +persistent_log: false # If true logs in /var/log/sonar.log, false logs to systemd +target: auto # IP Address, URL or auto as ping target +count: 3 # How often should be pinged? +interval: 60 # Ping again after X seconds +restart_threshold: 10 # If failed, restart WiFi after X seconds diff --git a/toolhead_sb.cfg b/toolhead_sb.cfg new file mode 100644 index 0000000..d8ff907 --- /dev/null +++ b/toolhead_sb.cfg @@ -0,0 +1,174 @@ +# SB RapidoV2 G2E + +[include rapido_v2.cfg] + +[mcu EBBCan] +canbus_uuid: d7e70bd38059 + +[firmware_retraction] +retract_length: 0.3 +# The length of filament (in mm) to retract when G10 is activated, +# and to unretract when G11 is activated (but see +# unretract_extra_length below). The default is 0 mm. +retract_speed: 35 +# The speed of retraction, in mm/s. The default is 20 mm/s. +#unretract_extra_length: 0 +# The length (in mm) of *additional* filament to add when +# unretracting. +unretract_speed: 35 +# The speed of unretraction, in mm/s. The default is 10 mm/s. + +[adxl345] +cs_pin: EBBCan:gpio1 +spi_software_sclk_pin: EBBCan:gpio2 +spi_software_mosi_pin: EBBCan:gpio0 +spi_software_miso_pin: EBBCan:gpio3 +axes_map: z,-y,x + +[resonance_tester] +probe_points: 177.5, 177.5, 50 +accel_chip: adxl345 +min_freq: 15 +max_freq: 120 +accel_per_hz: 125 +hz_per_sec: 1 + +[input_shaper] +#max 4000 +shaper_type_x:mzv +shaper_freq_x:53.400 +shaper_type_y:mzv +shaper_freq_y:42.200 + +[temperature_sensor SB2209] +sensor_type: temperature_mcu +sensor_mcu: EBBCan + +[temperature_sensor Ebb] +sensor_type: Generic 3950 +sensor_pin: EBBCan:gpio28 + + +##################################################################### +# Extruder +##################################################################### + +[extruder] +step_pin: EBBCan:gpio18 +dir_pin: EBBCan:gpio19 +enable_pin: !EBBCan:gpio17 +microsteps: 16 +rotation_distance: 46.64 #G2E +gear_ratio: 9:1 #G2E +full_steps_per_rotation: 200 #200 for 1.8 degree, 400 for 0.9 degree +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: EBBCan:gpio7 + +#sensor_type: ATC Semitec 104NT-4-R025H42G +#sensor_pin: EBBCan:gpio27 + +#sensor_type: PT1000 +#sensor_pin: EBBCan:gpio27 + +#pullup_resistor: 1000 + +sensor_type: MAX31865 +sensor_pin: EBBCan:gpio9 +spi_software_sclk_pin: EBBCan:gpio10 +spi_software_mosi_pin: EBBCan:gpio8 +spi_software_miso_pin: EBBCan:gpio11 +rtd_nominal_r: 1000 +rtd_reference_r: 4300 +rtd_num_of_wires: 2 + +min_temp: 20 +max_temp: 350 +max_power: 1.0 +max_extrude_only_distance: 300 +max_extrude_cross_section: 5 +min_extrude_temp: 20 + +control: pid +pid_Kp: 26.171 +pid_Ki: 2.684 +pid_Kd: 63.793 + + + +[tmc2209 extruder] +uart_pin: EBBCan:gpio20 +interpolate: false +run_current: 0.65 #0.6 +#sense_resistor: 0.110 +#stealthchop_threshold: 0 # 999999 + +[autotune_tmc extruder] +motor: ldo-36sth20-1004ahg-9T + + + +[filament_switch_sensor G2E] +pause_on_runout: True +runout_gcode: + UNLOAD_FILAMENT +insert_gcode: + LOAD_FILAMENT +switch_pin: ^EBBCan:gpio24 + + +##################################################################### +# Probe +##################################################################### + +[probe] +pin: ^!EBBCan:gpio21 + +##################################################################### +# Fan Control +##################################################################### + +[fan] +#hardware_pwm: False +#pin: EBBCan:gpio13 #gpio15 +#off_below: 0.05 +#cycle_time: 0.00008 + +# Время (в секундах), необходимое для запуска вентилятора на полной скорости при первом включении +# или увеличении ее более чем на 50% (помогает запустить вентилятор). Значение по умолчанию равно 0,100 секунды. +#kick_start_time: 0.150 +# Время (в секундах), затрачиваемое на каждый цикл подачи питания на вентилятор с помощью ШИМ. +# Рекомендуется, чтобы это значение составляло 10 миллисекунд или более при использовании программного управления ШИМ. +# Значение по умолчанию равно 0,010 секунды. +#cycle_time: 0.01 +#tachometer_pin: EBBCan:gpio12 +#tachometer_poll_interval: 0.0005 #0.0005 +#tachometer_ppr: 1 + +[heater_fan hotend_fan] +## Hotend Fan - CNC_FAN1 +pin: EBBCan:gpio14 +#max_power: 1.0 +#kick_start_time: 0.5 +heater: extruder +## If you are experiencing back flow, you can reduce fan_speed +#fan_speed: 1.0 + +#[temperature_fan EbbFan] +#pin: EBBCan:gpio6 +#max_power: 1.0 +#shutdown_speed: 0.0 +#sensor_type: Generic 3950 +#sensor_pin: EBBCan:gpio28 +#min_temp: 0 +#max_temp: 100 +#target_temp: 60.0 +#control: watermark + + +##################################################################### +# LED Control +##################################################################### + +[neopixel sb_leds] +pin: EBBCan:gpio16 \ No newline at end of file diff --git a/toolhead_sht36v2.cfg b/toolhead_sht36v2.cfg new file mode 100644 index 0000000..f617bc0 --- /dev/null +++ b/toolhead_sht36v2.cfg @@ -0,0 +1,104 @@ +[mcu sht] +canbus_uuid: 8ce295109ef0 + +[firmware_retraction] +retract_length: 0.4 +retract_speed: 30 +unretract_speed: 30 + +[adxl345] +cs_pin: sht:PA9 +spi_bus: spi2 +#axes_map: z,-y,x + +[resonance_tester] +probe_points: 177.5, 177.5, 50 +accel_chip: adxl345 +min_freq: 15 +max_freq: 120 +accel_per_hz: 125 +hz_per_sec: 1 + +[input_shaper] +shaper_type_x: mzv +shaper_freq_x: 51 +shaper_type_y: mzv +shaper_freq_y: 41.6 + +[temperature_sensor sht36_v2] +sensor_type: temperature_mcu +sensor_mcu: sht + + + +##################################################################### +# Extruder +##################################################################### + +[extruder] +step_pin: sht:PB4 +dir_pin: sht:PB3 +enable_pin: !sht:PA15 +microsteps: 16 +rotation_distance: 53.494165 +gear_ratio: 44:10, 37:17 +full_steps_per_rotation: 200 #200 for 1.8 degree, 400 for 0.9 degree +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: sht:PA8 +sensor_type: PT1000 +sensor_pin: sht:PA3 +pullup_resistor: 1100 +min_temp: 20 +max_temp: 350 +max_power: 1.0 +max_extrude_only_distance: 300 +max_extrude_cross_section: 5 +min_extrude_temp: 20 +control: pid +pid_Kp: 26.171 +pid_Ki: 2.684 +pid_Kd: 63.793 + + +[tmc2209 extruder] +uart_pin: sht:PB5 +#diag_pin: sht:PB6 +interpolate: false +run_current: 0.65 #0.6 +#sense_resistor: 0.110 +#stealthchop_threshold: 0 # 999999 + +[autotune_tmc extruder] +motor: ldo-36sth20-1004ahg + +##################################################################### +# Probe +##################################################################### + +[probe] +pin: ^!sht:PA2 + +##################################################################### +# Fan Control +##################################################################### + +[fan] +#hardware_pwm: True +#kick_start_time: 0.25 +#cycle_time: 0.15 +off_below: 0.05 +pin: sht:PB11 + +[heater_fan hotend_fan] +pin: sht:PB10 +heater: extruder + + + +##################################################################### +# LED Control +##################################################################### + +[neopixel sb_leds] +pin: sht:PB0 \ No newline at end of file