From fd7f74260141ae5338535ddc7fb818308ffd4d7c Mon Sep 17 00:00:00 2001 From: Surion79 <102791900+Surion79@users.noreply.github.com> Date: Sat, 2 Dec 2023 23:43:50 +0100 Subject: [PATCH 01/79] Fysetc Catalyst Config --- .../main/Fysetc_Catalyst_v1.x.cfg | 20 ++++++++++ .../main/Fysetc_Catalyst_v1.x.cfg | 37 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 config/mcu_definitions/main/Fysetc_Catalyst_v1.x.cfg create mode 100644 user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg diff --git a/config/mcu_definitions/main/Fysetc_Catalyst_v1.x.cfg b/config/mcu_definitions/main/Fysetc_Catalyst_v1.x.cfg new file mode 100644 index 000000000..8b5dc9b64 --- /dev/null +++ b/config/mcu_definitions/main/Fysetc_Catalyst_v1.x.cfg @@ -0,0 +1,20 @@ +[board_pins mcu_manufacturer] +aliases: + MCU_A_MOT_STEP=PC15 , MCU_A_MOT_DIR=PC13 , MCU_A_MOT_ENABLE=PA10 , MCU_A_MOT_CS_PDN=PC14 , MCU_A_MOD_DIAG=PA9 , + MCU_B_MOT_STEP=PC12 , MCU_B_MOT_DIR=PC10 , MCU_B_MOT_ENABLE=PD2 , MCU_B_MOT_CS_PDN=PC11 , MCU_B_MOD_DIAG=PB3 , + MCU_Z_MOT_STEP=PB2 , MCU_Z_MOT_DIR=PC5 , MCU_Z_MOT_ENABLE=PB10 , MCU_Z_MOT_CS_PDN=PC4 , + MCU_E_MOT_STEP=PB6 , MCU_E_MOT_DIR=PB4 , MCU_E_MOT_ENABLE=PB7 , MCU_E_MOT_CS_PDN=PB5 , + MCU_SPI_MOSI=PA7 , MCU_SPI_MISO=PA6 , MCU_SPI_SCK=PA5 , + + MCU_FAN0=PA13 , MCU_FAN1=PA14 , MCU_FAN2=PA8 , + MCU_NEOPIXEL=PC9 , + + MCU_PROBE=PC3 , # aka MCU_IO3 + + MCU_IO0=PA0 , MCU_IO1=PA1 , MCU_IO2=PA2 , MCU_IO3=PC3 , + + MCU_HEAT=PC7 , + + MCU_BED=PC8 , + + MCU_T0=PC0 , MCU_T1=PB0 , MCU_T2=PB1 , diff --git a/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg b/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg new file mode 100644 index 000000000..3af3f85d4 --- /dev/null +++ b/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg @@ -0,0 +1,37 @@ + +#---------------------------------------------# +#### Fysetc Catalyst v1.x MCU definition ###### +#---------------------------------------------# + +[mcu] +##-------------------------------------------------------------------- +# This board work by using a serial connection by default. If you +# want to use CAN, invert the commented lines and use canbus_uuid. + +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/Fysetc_Catalyst_v1.x.cfg] # Do not remove this line +[board_pins catalyst_mcu] +mcu: mcu +aliases: + X_STEP=MCU_B_MOT_STEP , X_DIR=MCU_B_MOT_DIR , X_ENABLE=MCU_B_MOT_ENABLE , X_TMCUART=MCU_B_MOT_CS_PDN , + Y_STEP=MCU_A_MOT_STEP , Y_DIR=MCU_A_MOT_DIR , Y_ENABLE=MCU_A_MOT_ENABLE , Y_TMCUART=MCU_A_MOT_CS_PDN , + Z_STEP=MCU_Z_MOT_STEP , Z_DIR=MCU_Z_MOT_DIR , Z_ENABLE=MCU_Z_MOT_ENABLE , Z_TMCUART=MCU_Z_MOT_CS_PDN , + E_STEP=MCU_E_MOT_STEP , E_DIR=MCU_E_MOT_DIR , E_ENABLE=MCU_E_MOT_ENABLE , E_TMCUART=MCU_E_MOT_CS_PDN , + + DRIVER_SPI_MOSI=MCU_SPI_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MISO=MCU_SPI_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_SCK=MCU_SPI_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 + + PROBE_INPUT=MCU_PROBE , + + E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_T0 , + BED_HEATER=MCU_BED , BED_TEMPERATURE=MCU_T1 , + + PART_FAN=MCU_FAN1 , E_FAN=MCU_FAN0 , + CONTROLLER_FAN=MCU_FAN2 , + + LIGHT_NEOPIXEL=MCU_NEOPIXEL , + \ No newline at end of file From 68ab265ddf47db11dcd6b73c9b58b497119a0b60 Mon Sep 17 00:00:00 2001 From: Surion79 <102791900+Surion79@users.noreply.github.com> Date: Thu, 7 Dec 2023 22:02:13 +0100 Subject: [PATCH 02/79] added respond on idle_timeout --- config/machine.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/machine.cfg b/config/machine.cfg index 87d0de761..93d0d1d73 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -15,6 +15,8 @@ on_error_gcode: [idle_timeout] timeout: 1800 +gcode: + RESPOND MSG="Idle timeout reached" [pause_resume] From 32344ff29bb97e82022218158fe73022aaba5ac5 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:12:25 +0100 Subject: [PATCH 03/79] sherpa mini config (#385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Boisselier --- config/hardware/extruder/sherpa_mini.cfg | 28 ++++++++++++++++++++++++ user_templates/printer.cfg | 1 + 2 files changed, 29 insertions(+) create mode 100644 config/hardware/extruder/sherpa_mini.cfg diff --git a/config/hardware/extruder/sherpa_mini.cfg b/config/hardware/extruder/sherpa_mini.cfg new file mode 100644 index 000000000..853b1f4da --- /dev/null +++ b/config/hardware/extruder/sherpa_mini.cfg @@ -0,0 +1,28 @@ +[gcode_macro _USER_VARIABLES] +variable_extruder_enabled: True +gcode: + + +[extruder] +# Sherpa mini Gear Ratio +# new_rd = previous_rd * mesured_distance / requested_distance +rotation_distance: 22.67895 +gear_ratio: 50:8 +microsteps: 32 +full_steps_per_rotation: 200 + +nozzle_diameter: 0.400 +filament_diameter: 1.75 +max_extrude_only_distance: 110 +max_extrude_cross_section: 5 +sensor_type: ATC Semitec 104NT-4-R025H42G +min_temp: 10 +max_temp: 290 +max_power: 1.0 +min_extrude_temp: 172 +pressure_advance: 0.0475 +pressure_advance_smooth_time: 0.040 + +# We also include the default wiring and low thermal hotend patch +[include default_wiring.cfg] +[include ../../../macros/helpers/hotend_heater_ctrl.cfg] diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index e790e3cc0..2f3378dd2 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -72,6 +72,7 @@ # [include config/hardware/extruder/lgx_heavy.cfg] # [include config/hardware/extruder/lgx_lite.cfg] # [include config/hardware/extruder/orbiter2.0.cfg] +# [include config/hardware/extruder/sherpa_mini.cfg] # [include config/hardware/extruder/vz_hextrudort.cfg] # ---------------------------------------------------------------------------------------- From 67980a7df9fb089a92ec2e5b4ed8e2b66e0f394b Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Fri, 15 Dec 2023 11:20:59 +0100 Subject: [PATCH 04/79] switch moonraker update management to dev channel (#390) --- moonraker/base.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/moonraker/base.conf b/moonraker/base.conf index 7e3286715..c30cb2419 100644 --- a/moonraker/base.conf +++ b/moonraker/base.conf @@ -38,7 +38,6 @@ enable_auto_refresh: True [update_manager Klippain] type: git_repo path: ~/klippain_config -channel: beta origin: https://github.com/Frix-x/klippain.git primary_branch: main managed_services: moonraker klipper From a20763997ef134cb24b401cb071eac245126f724 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 18 Dec 2023 09:24:27 -0500 Subject: [PATCH 05/79] Update orbiter2.0.cfg (#405) Add comment about required current. At the default of 0.45 on the Orbiter 2 motor, very poor performance will occur including significant underextrusion on infill, etc. --- config/hardware/extruder/orbiter2.0.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/hardware/extruder/orbiter2.0.cfg b/config/hardware/extruder/orbiter2.0.cfg index 98ab31ff1..78841f875 100644 --- a/config/hardware/extruder/orbiter2.0.cfg +++ b/config/hardware/extruder/orbiter2.0.cfg @@ -22,6 +22,9 @@ min_extrude_temp: 172 pressure_advance: 0.0475 pressure_advance_smooth_time: 0.040 +# Orbiter 2 motor will not be happy with 0.45 for run current. Recommended value in overrides.cfg is 0.85 depending on driver. +# https://www.orbiterprojects.com/orbiter-v2-0/ for more details + # We also include the default wiring and low thermal hotend patch [include default_wiring.cfg] [include ../../../macros/helpers/hotend_heater_ctrl.cfg] From c95c6c70121b9e02b2213f5074315d0e9f159017 Mon Sep 17 00:00:00 2001 From: Devon Hazelett Date: Tue, 9 Jan 2024 07:28:41 -0800 Subject: [PATCH 06/79] chore(mcu): properly label CAN H/L (#418) TX and RX are not helpful, looking at the back of the m8p v2 shows that RX is high, and TX is low. --- config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg b/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg index 3e3be9d02..490be0899 100644 --- a/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg +++ b/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg @@ -32,7 +32,7 @@ aliases: MCU_SPI2_MOSI=PC12 , MCU_SPI2_MISO=PC11 , MCU_SPI2_SCK=PC10 , MCU_SPI2_CS=PA15 , # TX RX - MCU_CAN_TRANSMIT=PD1 , MCU_CAN_RECIEVE=PD0 , + MCU_CAN_LOW=PD1 , MCU_CAN_HIGH=PD0 , MCU_FWS1=PC0 , MCU_FWS=PF10 , From 38e51d901be478cabc091c75fce796594369607f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Tue, 16 Jan 2024 13:26:55 +0000 Subject: [PATCH 07/79] added back the proper idle timeout behavior --- config/machine.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/machine.cfg b/config/machine.cfg index 93d0d1d73..835c6b101 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -17,6 +17,8 @@ on_error_gcode: timeout: 1800 gcode: RESPOND MSG="Idle timeout reached" + TURN_OFF_HEATERS + M84 [pause_resume] From c384eb263afe2627d17f9b8f233f6d26874214ad Mon Sep 17 00:00:00 2001 From: Gustavo Ribeiro Alves <145077902+gralves2@users.noreply.github.com> Date: Thu, 25 Jan 2024 06:36:18 -0300 Subject: [PATCH 08/79] BTT S2DW V1.0 and similar RP2040 + lis2dw boards (#439) --- .../accelerometers/lis2dw_usb_rp2040_spi1.cfg | 26 +++++++++++++++++++ user_templates/printer.cfg | 2 ++ 2 files changed, 28 insertions(+) create mode 100644 config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg diff --git a/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg b/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg new file mode 100644 index 000000000..a9063b3fa --- /dev/null +++ b/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg @@ -0,0 +1,26 @@ +# This LIS2DW file is dedicated to be used with USB RP2040 boards where the LIS2DW +# is connected to SPI1 + +# This include BTT S2DW V1.0, ... + + +# You need to set the proper serial in your overrides.cfg file +[mcu lis2dw_mcu] +serial: /dev/serial/by-id/xxx + +[lis2dw] +cs_pin: lis2dw_mcu:gpio9 +spi_bus: spi1a +axes_map: -y,x,-z + +[resonance_tester] +accel_chip: lis2dw +probe_points: + -1,-1,-1 + + +# Include the IS calibration macros to unlock them when +# an accelerometer is installed on the machine +[include ../../../macros/helpers/resonance_override.cfg] +[include ../../../macros/calibration/IS_shaper_calibrate.cfg] +[include ../../../macros/calibration/IS_vibrations_measurement.cfg] diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 2f3378dd2..e7f50e614 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -178,6 +178,8 @@ # [include config/hardware/accelerometers/adxl345_ebb.cfg] # For ADXL plugged in BTT EBB36 or EBB42 boards # [include config/hardware/accelerometers/adxl345_sht.cfg] # For ADXL plugged in Mellow SHT36 or SHT42 boards # [include config/hardware/accelerometers/adxl345_BTT_SB22xx.cfg] # For ADXL plugged in BTT SB2209 or SB2240 boards + +# [include config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg] # For BTT S2DW V1.0, ... # ---------------------------------------------------------------------------------------- From 81236b64ccf67b534c68e3317cfcfc17bf8b69c4 Mon Sep 17 00:00:00 2001 From: Andrew Wickham Date: Thu, 25 Jan 2024 08:47:10 -0500 Subject: [PATCH 09/79] Add Octopus Pro 1.0 MCU definition as duplicate of Octopus MCU --- .../main/BTT_Octopus_Pro_v1.0.cfg | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 user_templates/mcu_defaults/main/BTT_Octopus_Pro_v1.0.cfg diff --git a/user_templates/mcu_defaults/main/BTT_Octopus_Pro_v1.0.cfg b/user_templates/mcu_defaults/main/BTT_Octopus_Pro_v1.0.cfg new file mode 100644 index 000000000..e6cae3e7d --- /dev/null +++ b/user_templates/mcu_defaults/main/BTT_Octopus_Pro_v1.0.cfg @@ -0,0 +1,53 @@ + +#--------------------------------------# +#### BTT Octopus MCU definition ######## +#--------------------------------------# + +[mcu] +##-------------------------------------------------------------------- +# This board work by using a serial connection by default. If you +# want to use CAN, invert the commented lines and use canbus_uuid. + +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/BTT_Octopus.cfg] # Do not remove this line +[board_pins octopus_mcu] +mcu: mcu +aliases: + X_STEP=MCU_MOTOR0_STEP , X_DIR=MCU_MOTOR0_DIR , X_ENABLE=MCU_MOTOR0_ENABLE , X_TMCUART=MCU_MOTOR0_UART , + Y_STEP=MCU_MOTOR1_STEP , Y_DIR=MCU_MOTOR1_DIR , Y_ENABLE=MCU_MOTOR1_ENABLE , Y_TMCUART=MCU_MOTOR1_UART , + + Z_STEP=MCU_MOTOR2_1_STEP , Z_DIR=MCU_MOTOR2_1_DIR , Z_ENABLE=MCU_MOTOR2_1_ENABLE , Z_TMCUART=MCU_MOTOR2_1_UART , + Z1_STEP=MCU_MOTOR3_STEP , Z1_DIR=MCU_MOTOR3_DIR , Z1_ENABLE=MCU_MOTOR3_ENABLE , Z1_TMCUART=MCU_MOTOR3_UART , + Z2_STEP=MCU_MOTOR4_STEP , Z2_DIR=MCU_MOTOR4_DIR , Z2_ENABLE=MCU_MOTOR4_ENABLE , Z2_TMCUART=MCU_MOTOR4_UART , + Z3_STEP=MCU_MOTOR5_STEP , Z3_DIR=MCU_MOTOR5_DIR , Z3_ENABLE=MCU_MOTOR5_ENABLE , Z3_TMCUART=MCU_MOTOR5_UART , + + E_STEP=MCU_MOTOR6_STEP , E_DIR=MCU_MOTOR6_DIR , E_ENABLE=MCU_MOTOR6_ENABLE , E_TMCUART=MCU_MOTOR6_UART , + + # DRIVER_SPI_MOSI=EXP2_6 , # Used in case of SPI drivers such as TMC2240 or TMC5160 + # DRIVER_SPI_MISO=EXP2_1 , # Used in case of SPI drivers such as TMC2240 or TMC5160 + # DRIVER_SPI_SCK=EXP2_2 , # Used in case of SPI drivers such as TMC2240 or TMC5160 + + X_STOP=MCU_STOP0 , Y_STOP=MCU_STOP1 , Z_STOP=MCU_STOP2 , + PROBE_INPUT=MCU_STOP7 , + RUNOUT_SENSOR=MCU_STOP3 , + + E_HEATER=MCU_HE0 , E_TEMPERATURE=MCU_T0 , + BED_HEATER=MCU_HE1 , BED_TEMPERATURE=MCU_TB , + + PART_FAN=MCU_FAN0 , E_FAN=MCU_FAN1 , + CONTROLLER_FAN=MCU_FAN2 , + EXHAUST_FAN=MCU_FAN3 , + FILTER_FAN=MCU_FAN4 , + HOST_CONTROLLER_FAN=MCU_FAN5 , + + CHAMBER_TEMPERATURE=MCU_T1 , ELECTRICAL_CABINET_TEMPERATURE=MCU_T2 , + + LIGHT_OUTPUT=MCU_HE2 , + LIGHT_NEOPIXEL=MCU_STOP5 , + STATUS_NEOPIXEL=MCU_NEOPIXEL , + + SERVO_PIN=MCU_SERVOS , + From a1e72145a5f89e51c49a04c1068680b017ca767d Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Fri, 9 Feb 2024 09:47:50 +0100 Subject: [PATCH 10/79] fix typo in BTT_Octopus_Pro_v1.1.cfg (#460) --- config/mcu_definitions/main/BTT_Octopus_Pro_v1.1.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/mcu_definitions/main/BTT_Octopus_Pro_v1.1.cfg b/config/mcu_definitions/main/BTT_Octopus_Pro_v1.1.cfg index 3caa46142..45b078573 100644 --- a/config/mcu_definitions/main/BTT_Octopus_Pro_v1.1.cfg +++ b/config/mcu_definitions/main/BTT_Octopus_Pro_v1.1.cfg @@ -14,7 +14,7 @@ aliases: MCU_PROBE=PB7 , MCU_SERVOS=PB6 , - MCU_HE0=PA0 , MCU_HE1=PA3 , MCU_HE2=PB00 , MCU_HE3=PB11 , + MCU_HE0=PA0 , MCU_HE1=PA3 , MCU_HE2=PB0 , MCU_HE3=PB11 , MCU_BED0=PA1 , From d4bbd748fd33afadfea906fd0f489af4823335f4 Mon Sep 17 00:00:00 2001 From: tehniemer Date: Wed, 13 Dec 2023 03:34:07 -0600 Subject: [PATCH 11/79] Turn on filter only if it was used during printing. (#380) Co-authored-by: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> --- macros/base/end_print.cfg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index 4f1a5f23f..614d63c6a 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -12,6 +12,7 @@ gcode: {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} + {% set filter_speed = printer["gcode_macro START_PRINT"].material.filter_speed|default(0)|int %} PARK @@ -45,9 +46,9 @@ gcode: {% endif %} - # If a filter is connected, filter the air at full power + # If a filter is connected, and used during the print, continue filtering the air # for a couple of min before stopping everything - {% if filter_enabled %} + {% if filter_enabled and filter_speed > 0 %} {% set FILTER_TIME = params.FILTER_TIME|default(filter_default_time)|int %} START_FILTER SPEED=1 UPDATE_DELAYED_GCODE ID=_STOP_FILTER_DELAYED DURATION={FILTER_TIME} From 59ff255c22120b64dd23c8eaede32274bd02427a Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:39:40 +0100 Subject: [PATCH 12/79] added parameters to park (#391) --- macros/base/park.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/macros/base/park.cfg b/macros/base/park.cfg index e042afd7d..6e70e1d34 100644 --- a/macros/base/park.cfg +++ b/macros/base/park.cfg @@ -4,6 +4,10 @@ gcode: {% set E = params.E|default(1.7)|float %} {% set Px, Py = printer["gcode_macro _USER_VARIABLES"].park_position_xy|map('float') %} + + {% set Px = params.X|default(Px)|float %} + {% set Py = params.Y|default(Py)|float %} + {% set park_lift_z = printer["gcode_macro _USER_VARIABLES"].park_lift_z %} {% set firmware_retraction_enabled = printer["gcode_macro _USER_VARIABLES"].firmware_retraction_enabled %} From 6c78e149eb0f53a32e1f412dfbebcfface107a70 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:56:24 +0100 Subject: [PATCH 13/79] M8P v2.0 SPI fix (#389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Boisselier --- config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg | 3 ++- user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg b/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg index 490be0899..eb15b6d25 100644 --- a/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg +++ b/config/mcu_definitions/main/BTT_Manta_M8P_v2.0.cfg @@ -29,7 +29,8 @@ aliases: MCU_PROBE1=PD13 , MCU_PROBE2=PD12 , MCU_IND_PROBE=PD8 , - MCU_SPI2_MOSI=PC12 , MCU_SPI2_MISO=PC11 , MCU_SPI2_SCK=PC10 , MCU_SPI2_CS=PA15 , + MCU_SPI_MOSI=PC12 , MCU_SPI_MISO=PC11 , MCU_SPI_SCK=PC10 , MCU_SPI_CS=PA15 , + MCU_M_SPI_MOSI=PG6, MCU_M_SPI_MISO=PG7, MCU_M_SPI_SCK=PG8, # TX RX MCU_CAN_LOW=PD1 , MCU_CAN_HIGH=PD0 , diff --git a/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg b/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg index a91c6a0eb..5386782fd 100644 --- a/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg +++ b/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg @@ -26,9 +26,9 @@ aliases: E_STEP=MCU_M7_STEP , E_DIR=MCU_M7_DIR , E_ENABLE=MCU_M7_EN , E_TMCUART=MCU_M7_CS , - DRIVER_SPI_MOSI=MCU_SPI2_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 - DRIVER_SPI_MISO=MCU_SPI2_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 - DRIVER_SPI_SCK=MCU_SPI2_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MOSI=MCU_M_SPI_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MISO=MCU_M_SPI_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_SCK=MCU_M_SPI_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 X_STOP=MCU_M1_STOP , Y_STOP=MCU_M2_STOP , Z_STOP=MCU_M3_STOP , PROBE_INPUT=MCU_PROBE2 , From ea69a8b3d13413516432ff536da46d8c84ffed47 Mon Sep 17 00:00:00 2001 From: tehniemer Date: Fri, 15 Dec 2023 04:50:40 -0600 Subject: [PATCH 14/79] Add per material filament sensor management (#381) --- macros/base/start_print.cfg | 5 +++++ macros/helpers/filament_swap.cfg | 9 ++++++--- macros/helpers/nozzle_cleaning.cfg | 3 ++- macros/helpers/prime_line.cfg | 3 ++- user_templates/variables.cfg | 21 +++++++++++++++++---- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index e49cc2cfd..1023319c4 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -46,6 +46,7 @@ gcode: {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set firmware_retraction_enabled = printer["gcode_macro _USER_VARIABLES"].firmware_retraction_enabled %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} + {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} {% if MATERIAL not in printer["gcode_macro _USER_VARIABLES"].material_parameters %} RESPOND MSG="Material '{MATERIAL}' is unknown!" @@ -153,6 +154,10 @@ gcode: START_FILTER SPEED={material.filter_speed / 100} {% endif %} + {% if filament_sensor_enabled and not material.filament_sensor %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% endif %} + # And.... Goooo! {% if status_leds_enabled %} STATUS_LEDS COLOR="PRINTING" diff --git a/macros/helpers/filament_swap.cfg b/macros/helpers/filament_swap.cfg index bccab66af..99f08431e 100644 --- a/macros/helpers/filament_swap.cfg +++ b/macros/helpers/filament_swap.cfg @@ -18,6 +18,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% if filament_sensor_enabled %} @@ -52,7 +53,7 @@ gcode: RESTORE_GCODE_STATE NAME=UNLOAD_FILAMENT_state - {% if filament_sensor_enabled %} + {% if filament_sensor_enabled and material_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% if verbose %} RESPOND MSG="Filament unloaded, runout sensor reactivated" @@ -79,6 +80,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% if filament_sensor_enabled %} @@ -112,7 +114,7 @@ gcode: G92 E0 RESTORE_GCODE_STATE NAME=LOAD_FILAMENT_state - {% if filament_sensor_enabled %} + {% if filament_sensor_enabled and material_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% if verbose %} RESPOND MSG="Filament loaded, runout sensor reactivated" @@ -138,6 +140,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% if filament_sensor_enabled %} @@ -182,7 +185,7 @@ gcode: RESTORE_GCODE_STATE NAME=TIP_SHAPING_state - {% if filament_sensor_enabled %} + {% if filament_sensor_enabled and material_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% if verbose %} RESPOND MSG="Filament tip shaping done, runout sensor reactivated" diff --git a/macros/helpers/nozzle_cleaning.cfg b/macros/helpers/nozzle_cleaning.cfg index aa7c599b9..8bbd548f0 100644 --- a/macros/helpers/nozzle_cleaning.cfg +++ b/macros/helpers/nozzle_cleaning.cfg @@ -77,6 +77,7 @@ gcode: {% set purgeclean_servo_enabled = printer["gcode_macro _USER_VARIABLES"].purgeclean_servo_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% if purge_and_brush_enabled %} @@ -114,7 +115,7 @@ gcode: # No M400 needed here since G4 is also flushing Klipper's buffer G4 P{OOZE_TIME * 1000} - {% if filament_sensor_enabled %} + {% if filament_sensor_enabled and material_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% endif %} diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index fef104b69..ed936f94b 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -15,6 +15,7 @@ gcode: {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set max_extrude_cross_section = printer["configfile"].config["extruder"]["max_extrude_cross_section"]|float %} {% set filament_diameter = printer["configfile"].config["extruder"]["filament_diameter"]|float %} @@ -114,6 +115,6 @@ gcode: {% endif %} {% endif %} - {% if filament_sensor_enabled %} + {% if filament_sensor_enabled and material_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% endif %} diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index c6f0468ed..c9c67dc09 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -140,7 +140,7 @@ variable_print_default_material: "XXX" ## Material configuration parameters applied during START_PRINT by using the slicer MATERIAL variable ## FYI, retract paramaters are used only if firmware retraction is enabled, filter speed (in %) is used if -## there is a filter installed on the machine, etc... +## there is a filter installed on the machine, filament sensor is on or off if installed, etc... ## If you are using another material, just extend the list bellow with a new material and everything should work :) variable_material_parameters: { 'PLA': { @@ -150,7 +150,8 @@ variable_material_parameters: { 'retract_speed': 40, 'unretract_speed': 30, 'filter_speed': 0, - 'additional_z_offset': 0 + 'additional_z_offset': 0, + 'filament_sensor': 1 }, 'PET': { 'pressure_advance': 0.0650, @@ -159,7 +160,8 @@ variable_material_parameters: { 'retract_speed': 30, 'unretract_speed': 20, 'filter_speed': 0, - 'additional_z_offset': 0.020 + 'additional_z_offset': 0.020, + 'filament_sensor': 1 }, 'ABS': { 'pressure_advance': 0.0480, @@ -168,7 +170,18 @@ variable_material_parameters: { 'retract_speed': 40, 'unretract_speed': 30, 'filter_speed': 80, - 'additional_z_offset': 0 + 'additional_z_offset': 0, + 'filament_sensor': 1 + }, + 'TPU': { + 'pressure_advance': 0.0500, + 'retract_length': 0.2, + 'unretract_extra_length': 0, + 'retract_speed': 5, + 'unretract_speed': 5, + 'filter_speed': 0, + 'additional_z_offset': 0.040, + 'filament_sensor': 0 } } From e88cf7944534c0a768a9d82809e16b8777a2cf48 Mon Sep 17 00:00:00 2001 From: tehniemer Date: Fri, 15 Dec 2023 04:57:53 -0600 Subject: [PATCH 15/79] Remove _TIP_SHAPING from End/cancel print macros (#357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Co-authored-by: Félix Boisselier --- macros/base/cancel_print.cfg | 2 +- macros/base/end_print.cfg | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index d61f699b5..aa5a9f1f0 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -20,7 +20,7 @@ gcode: {% endif %} {% else %} # pull back the filament a little bit - _TIP_SHAPING + G92 E0 G1 E-10 F2100 {% endif %} diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index 614d63c6a..3158b46c3 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -23,7 +23,6 @@ gcode: {% endif %} {% else %} # pull back the filament a little bit - _TIP_SHAPING G92 E0 G1 E-10 F2100 {% endif %} From 26b9bb11cac11962267acd0a7d8234a607f4c2b5 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:02:08 +0100 Subject: [PATCH 16/79] Klipper SET_PRINT_STATS_INFO compatibility (#392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Boisselier --- docs/configuration.md | 10 +++++++--- macros/base/start_print.cfg | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9b2e03867..181fce681 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -33,12 +33,16 @@ Before your first print, **carefully check all features to prevent issues on you Next, ensure the mechanical probe (if used) can be attached/detached, verify that QGL/Z_TILT works, and confirm correct coordinates for all components (purge bucket, physical Z endstop, etc.). Check your first layer calibration (and the `switch_offset` parameter of the automatic Z calibration plugin, if used), etc. -Finally, add custom print start G-code to your slicer. Here's an example for SuperSlicer: +Then, add this custom print start G-code to your slicer (example for SuperSlicer): ``` -START_PRINT EXTRUDER_TEMP={first_layer_temperature[initial_extruder] + extruder_temperature_offset[initial_extruder]} BED_TEMP=[first_layer_bed_temperature] MATERIAL=[filament_type] CHAMBER=[chamber_temperature] SIZE={first_layer_print_min[0]}_{first_layer_print_min[1]}_{first_layer_print_max[0]}_{first_layer_print_max[1]} INITIAL_TOOL={initial_extruder} +START_PRINT EXTRUDER_TEMP={first_layer_temperature[initial_extruder] + extruder_temperature_offset[initial_extruder]} BED_TEMP=[first_layer_bed_temperature] MATERIAL=[filament_type] SIZE={first_layer_print_min[0]}_{first_layer_print_min[1]}_{first_layer_print_max[0]}_{first_layer_print_max[1]} INITIAL_TOOL={initial_extruder} ``` -Also, add custom print end G-code to your slicer: +There is also a couple of other optionnal parameters that are supported in Klippain (they need to be added on the same one line following the other parameters): + - `CHAMBER=[chamber_temperature]` to be able to specify a target heatsoak temperature for the START_PRINT sequence + - `TOTAL_LAYER=[total_layer_count]` to be able to set the PRINT_STATS_INFOS in Klipper. If using this, you will need to add on your slicer custom layer change gcode the appropriate `SET_PRINT_STATS_INFO CURRENT_LAYER={layer_num}` + +Finally, add custom print end G-code to your slicer: ``` END_PRINT ``` diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 1023319c4..401eb1eb0 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -10,6 +10,7 @@ variable_initial_tool: 0 variable_material: "XXX" variable_fl_size: "0_0_0_0" variable_bed_mesh_profile: "" +variable_total_layer: 0 gcode: # Get all the parameters passed from the slicer {% set BED_TEMP = params.BED_TEMP|default(printer["gcode_macro _USER_VARIABLES"].print_default_bed_temp)|float %} # Bed temperature @@ -33,6 +34,11 @@ gcode: SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=material VALUE='"{MATERIAL}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=fl_size VALUE='"{FL_SIZE}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_mesh_profile VALUE='"{BED_MESH_PROFILE}"' + + {% if params.TOTAL_LAYER %} # total layers count (if provided by the slicer) + SET_PRINT_STATS_INFO TOTAL_LAYER={params.TOTAL_LAYER|int} + SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=total_layer VALUE={params.TOTAL_LAYER|int} + {% endif %} # Get all the config options and configurations for this macro {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} From b5422baa9c88cd04e9bbe2ed0e74616331d52a96 Mon Sep 17 00:00:00 2001 From: tehniemer Date: Tue, 19 Dec 2023 04:43:54 -0600 Subject: [PATCH 17/79] Fix error with turning on filter only if it was used during printing. (#406) Fix issue discovered after merging https://github.com/Frix-x/klippain/pull/380 --- macros/base/cancel_print.cfg | 9 ++++++++- macros/base/end_print.cfg | 11 ++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index aa5a9f1f0..00514a448 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -10,6 +10,7 @@ gcode: {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} + {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} PARK @@ -41,8 +42,14 @@ gcode: SDCARD_RESET_FILE + # If a filter is connected, and used during the print, continue filtering the air + # for a couple of min before stopping everything {% if filter_enabled %} - STOP_FILTER + {% if printer['fan_generic filter'].speed > 0 %} + {% set FILTER_TIME = params.FILTER_TIME|default(filter_default_time)|int %} + START_FILTER SPEED=1 + UPDATE_DELAYED_GCODE ID=_STOP_FILTER_DELAYED DURATION={FILTER_TIME} + {% endif %} {% endif %} {% if light_enabled %} diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index 3158b46c3..4e9c62db2 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -12,7 +12,6 @@ gcode: {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} - {% set filter_speed = printer["gcode_macro START_PRINT"].material.filter_speed|default(0)|int %} PARK @@ -47,10 +46,12 @@ gcode: # If a filter is connected, and used during the print, continue filtering the air # for a couple of min before stopping everything - {% if filter_enabled and filter_speed > 0 %} - {% set FILTER_TIME = params.FILTER_TIME|default(filter_default_time)|int %} - START_FILTER SPEED=1 - UPDATE_DELAYED_GCODE ID=_STOP_FILTER_DELAYED DURATION={FILTER_TIME} + {% if filter_enabled %} + {% if printer['fan_generic filter'].speed > 0 %} + {% set FILTER_TIME = params.FILTER_TIME|default(filter_default_time)|int %} + START_FILTER SPEED=1 + UPDATE_DELAYED_GCODE ID=_STOP_FILTER_DELAYED DURATION={FILTER_TIME} + {% endif %} {% endif %} {% if light_enabled %} From fe82709bc53d0389ace8e5cd32099375cf271ab8 Mon Sep 17 00:00:00 2001 From: tehniemer Date: Tue, 19 Dec 2023 04:46:29 -0600 Subject: [PATCH 18/79] fix missing variable to cancel_print (#408) --- macros/base/cancel_print.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index 00514a448..2d4c29efe 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -4,6 +4,7 @@ description: Cancel the print, retract 10mm of filament and park gcode: {% set turn_off_heaters_in_end_print = printer["gcode_macro _USER_VARIABLES"].turn_off_heaters_in_end_print %} {% set safe_extruder_temp = printer["gcode_macro _USER_VARIABLES"].safe_extruder_temp|float %} + {% set light_intensity_end_print = printer["gcode_macro _USER_VARIABLES"].light_intensity_end_print %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% set ercf_unload_on_cancel_print = printer["gcode_macro _USER_VARIABLES"].ercf_unload_on_cancel_print %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} From 6e845ec126c99e28f95b03fb03d4108cd47aa0c1 Mon Sep 17 00:00:00 2001 From: tehniemer Date: Wed, 20 Dec 2023 08:13:56 -0600 Subject: [PATCH 19/79] filament sensor status checks universal (#411) --- macros/base/cancel_print.cfg | 6 +++++ macros/base/end_print.cfg | 6 +++++ macros/helpers/filament_swap.cfg | 39 ++++++++++++++++++------------ macros/helpers/nozzle_cleaning.cfg | 9 ++++--- macros/helpers/prime_line.cfg | 9 ++++--- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index 2d4c29efe..6f62b8717 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -11,6 +11,7 @@ gcode: {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} + {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} PARK @@ -60,4 +61,9 @@ gcode: STATUS_LEDS COLOR="OFF" {% endif %} + # If a filament sensor is connected, re-enable it in case it was disabled during printing + {% if filament_sensor_enabled %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 + {% endif %} + BASE_CANCEL_PRINT diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index 4e9c62db2..45241d99b 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -12,6 +12,7 @@ gcode: {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} + {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} PARK @@ -60,3 +61,8 @@ gcode: {% if status_leds_enabled %} STATUS_LEDS COLOR="OFF" {% endif %} + + # If a filament sensor is connected, re-enable it in case it was disabled during printing + {% if filament_sensor_enabled %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 + {% endif %} \ No newline at end of file diff --git a/macros/helpers/filament_swap.cfg b/macros/helpers/filament_swap.cfg index 99f08431e..4c258ede2 100644 --- a/macros/helpers/filament_swap.cfg +++ b/macros/helpers/filament_swap.cfg @@ -18,13 +18,16 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} + {% set re_enable_filament_sensor = 0 %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% if filament_sensor_enabled %} - SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 - {% if verbose %} - RESPOND MSG="Runout sensor deactivated to unload filament" + {% if (printer['filament_motion_sensor runout_sensor'] is defined and printer['filament_motion_sensor runout_sensor'].enabled) or (printer['filament_switch_sensor runout_sensor'] is defined and printer['filament_switch_sensor runout_sensor'].enabled) %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% set re_enable_filament_sensor = 1 %} + {% if verbose %} + RESPOND MSG="Runout sensor deactivated to unload filament" + {% endif %} {% endif %} {% endif %} @@ -53,7 +56,7 @@ gcode: RESTORE_GCODE_STATE NAME=UNLOAD_FILAMENT_state - {% if filament_sensor_enabled and material_filament_sensor %} + {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% if verbose %} RESPOND MSG="Filament unloaded, runout sensor reactivated" @@ -80,13 +83,16 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} + {% set re_enable_filament_sensor = 0 %} {% if filament_sensor_enabled %} - SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 - {% if verbose %} - RESPOND MSG="Runout sensor deactivated to load filament" + {% if (printer['filament_motion_sensor runout_sensor'] is defined and printer['filament_motion_sensor runout_sensor'].enabled) or (printer['filament_switch_sensor runout_sensor'] is defined and printer['filament_switch_sensor runout_sensor'].enabled) %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% set re_enable_filament_sensor = 1 %} + {% if verbose %} + RESPOND MSG="Runout sensor deactivated to load filament" + {% endif %} {% endif %} {% endif %} @@ -114,7 +120,7 @@ gcode: G92 E0 RESTORE_GCODE_STATE NAME=LOAD_FILAMENT_state - {% if filament_sensor_enabled and material_filament_sensor %} + {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% if verbose %} RESPOND MSG="Filament loaded, runout sensor reactivated" @@ -140,13 +146,16 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} + {% set re_enable_filament_sensor = 0 %} {% if filament_sensor_enabled %} - SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 - {% if verbose %} - RESPOND MSG="Runout sensor deactivated for filament tip shaping" + {% if (printer['filament_motion_sensor runout_sensor'] is defined and printer['filament_motion_sensor runout_sensor'].enabled) or (printer['filament_switch_sensor runout_sensor'] is defined and printer['filament_switch_sensor runout_sensor'].enabled) %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% set re_enable_filament_sensor = 1 %} + {% if verbose %} + RESPOND MSG="Runout sensor deactivated for filament tip shaping" + {% endif %} {% endif %} {% endif %} @@ -185,7 +194,7 @@ gcode: RESTORE_GCODE_STATE NAME=TIP_SHAPING_state - {% if filament_sensor_enabled and material_filament_sensor %} + {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% if verbose %} RESPOND MSG="Filament tip shaping done, runout sensor reactivated" diff --git a/macros/helpers/nozzle_cleaning.cfg b/macros/helpers/nozzle_cleaning.cfg index 8bbd548f0..8cb799f28 100644 --- a/macros/helpers/nozzle_cleaning.cfg +++ b/macros/helpers/nozzle_cleaning.cfg @@ -77,7 +77,7 @@ gcode: {% set purgeclean_servo_enabled = printer["gcode_macro _USER_VARIABLES"].purgeclean_servo_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} + {% set re_enable_filament_sensor = 0 %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% if purge_and_brush_enabled %} @@ -93,7 +93,10 @@ gcode: {% endif %} {% if filament_sensor_enabled %} - SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% if (printer['filament_motion_sensor runout_sensor'] is defined and printer['filament_motion_sensor runout_sensor'].enabled) or (printer['filament_switch_sensor runout_sensor'] is defined and printer['filament_switch_sensor runout_sensor'].enabled) %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% set re_enable_filament_sensor = 1 %} + {% endif %} {% endif %} G90 @@ -115,7 +118,7 @@ gcode: # No M400 needed here since G4 is also flushing Klipper's buffer G4 P{OOZE_TIME * 1000} - {% if filament_sensor_enabled and material_filament_sensor %} + {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% endif %} diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index ed936f94b..dfb872384 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -15,7 +15,7 @@ gcode: {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set material_filament_sensor = printer["gcode_macro START_PRINT"].material.filament_sensor|default(1) %} + {% set re_enable_filament_sensor = 0 %} {% set max_extrude_cross_section = printer["configfile"].config["extruder"]["max_extrude_cross_section"]|float %} {% set filament_diameter = printer["configfile"].config["extruder"]["filament_diameter"]|float %} @@ -67,7 +67,10 @@ gcode: {% endif %} {% if filament_sensor_enabled %} - SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% if (printer['filament_motion_sensor runout_sensor'] is defined and printer['filament_motion_sensor runout_sensor'].enabled) or (printer['filament_switch_sensor runout_sensor'] is defined and printer['filament_switch_sensor runout_sensor'].enabled) %} + SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=0 + {% set re_enable_filament_sensor = 1 %} + {% endif %} {% endif %} G91 @@ -115,6 +118,6 @@ gcode: {% endif %} {% endif %} - {% if filament_sensor_enabled and material_filament_sensor %} + {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% endif %} From a46d2188921b2938f85a0e059eedd5a0b435def0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Mon, 8 Jan 2024 00:33:38 +0100 Subject: [PATCH 20/79] proper Shake&Tune integration in Klippain --- .gitignore | 1 + .../hardware/accelerometers/adxl345_rpi.cfg | 3 +- .../hardware/accelerometers/adxl345_usb.cfg | 3 +- .../accelerometers/adxl345_usb_rampon.cfg | 3 +- .../adxl345_usb_rp2040_spi1.cfg | 3 +- .../generics/adxl345_hardware_spi1.cfg | 3 +- .../generics/adxl345_hardware_ssp1.cfg | 3 +- .../generics/adxl345_software_spi.cfg | 3 +- config/machine.cfg | 1 + config/software/shaketune.cfg | 7 + install.sh | 6 +- macros/calibration/IS_shaper_calibrate.cfg | 97 --- .../calibration/IS_vibrations_measurement.cfg | 191 ------ moonraker/base.conf | 10 + scripts/is_workflow/graph_belts.py | 638 ------------------ scripts/is_workflow/graph_shaper.py | 395 ----------- scripts/is_workflow/graph_vibrations.py | 439 ------------ scripts/is_workflow/is_workflow.py | 231 ------- scripts/is_workflow/is_workflow_cmd.cfg | 4 - scripts/is_workflow/klippain.png | Bin 621954 -> 0 bytes scripts/shell_commands.cfg | 2 - 21 files changed, 29 insertions(+), 2014 deletions(-) create mode 100644 config/software/shaketune.cfg delete mode 100644 macros/calibration/IS_shaper_calibrate.cfg delete mode 100644 macros/calibration/IS_vibrations_measurement.cfg delete mode 100755 scripts/is_workflow/graph_belts.py delete mode 100755 scripts/is_workflow/graph_shaper.py delete mode 100755 scripts/is_workflow/graph_vibrations.py delete mode 100755 scripts/is_workflow/is_workflow.py delete mode 100644 scripts/is_workflow/is_workflow_cmd.cfg delete mode 100644 scripts/is_workflow/klippain.png diff --git a/.gitignore b/.gitignore index 1c963e1f2..344064f33 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /*.cfg /*.conf /.VERSION +/scripts/K-ShakeTune # ------------------------------------------------------------------- diff --git a/config/hardware/accelerometers/adxl345_rpi.cfg b/config/hardware/accelerometers/adxl345_rpi.cfg index e5b26a1c9..172ff2980 100644 --- a/config/hardware/accelerometers/adxl345_rpi.cfg +++ b/config/hardware/accelerometers/adxl345_rpi.cfg @@ -21,5 +21,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/hardware/accelerometers/adxl345_usb.cfg b/config/hardware/accelerometers/adxl345_usb.cfg index f3ac0f1e7..b73e4043f 100644 --- a/config/hardware/accelerometers/adxl345_usb.cfg +++ b/config/hardware/accelerometers/adxl345_usb.cfg @@ -22,5 +22,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/hardware/accelerometers/adxl345_usb_rampon.cfg b/config/hardware/accelerometers/adxl345_usb_rampon.cfg index a91c95b03..20947d46f 100644 --- a/config/hardware/accelerometers/adxl345_usb_rampon.cfg +++ b/config/hardware/accelerometers/adxl345_usb_rampon.cfg @@ -21,5 +21,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg b/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg index 67c924515..2eb968368 100644 --- a/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg +++ b/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg @@ -25,5 +25,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg b/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg index f0746898e..f1906ee06 100644 --- a/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg +++ b/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg @@ -21,5 +21,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../../macros/helpers/resonance_override.cfg] -[include ../../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg b/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg index 165c905b1..c5bf2a71f 100644 --- a/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg +++ b/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg @@ -18,5 +18,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../../macros/helpers/resonance_override.cfg] -[include ../../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/hardware/accelerometers/generics/adxl345_software_spi.cfg b/config/hardware/accelerometers/generics/adxl345_software_spi.cfg index 480c21349..2c279e581 100644 --- a/config/hardware/accelerometers/generics/adxl345_software_spi.cfg +++ b/config/hardware/accelerometers/generics/adxl345_software_spi.cfg @@ -22,5 +22,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../../macros/helpers/resonance_override.cfg] -[include ../../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../../scripts/K-ShakeTune/*.cfg] diff --git a/config/machine.cfg b/config/machine.cfg index 835c6b101..dbe821047 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -51,3 +51,4 @@ resolution: 0.1 [include ../macros/miscs/startup.cfg] [include ../scripts/*.cfg] +[include software/shaketune.cfg] diff --git a/config/software/shaketune.cfg b/config/software/shaketune.cfg new file mode 100644 index 000000000..c422e16ec --- /dev/null +++ b/config/software/shaketune.cfg @@ -0,0 +1,7 @@ +# This is an automatic override for the Shake&Tune entrypoint. This will allow it +# to work correctly in the full Klippain environement (within the scripts folder). + +[gcode_shell_command shaketune] +command: ~/printer_data/config/scripts/K-ShakeTune/scripts/shaketune.sh +timeout: 600.0 +verbose: True diff --git a/install.sh b/install.sh index 7fe9053b6..46a3ceb0c 100755 --- a/install.sh +++ b/install.sh @@ -6,6 +6,7 @@ # @version: 1.3 # CHANGELOG: +# v1.4: added Shake&Tune install call # v1.3: - added a warning on first install to be sure the user wants to install klippain and fixed a bug # where some artefacts of the old user config where still present after the install (harmless bug but not clean) # - automated the install of the Gcode shell commands plugin @@ -129,9 +130,6 @@ function install_config { # CHMOD the scripts to be sure they are all executables (Git should keep the modes on files but it's to be sure) chmod +x ${FRIX_CONFIG_PATH}/install.sh chmod +x ${FRIX_CONFIG_PATH}/uninstall.sh - for file in is_workflow.py graph_vibrations.py graph_shaper.py graph_belts.py; do - chmod +x ${FRIX_CONFIG_PATH}/scripts/is_workflow/$file - done # Symlink the gcode_shell_command.py file in the correct Klipper folder (erased to always get the last version) ln -fsn ${FRIX_CONFIG_PATH}/scripts/gcode_shell_command.py ${KLIPPER_PATH}/klippy/extras @@ -258,5 +256,7 @@ backup_config install_config restart_klipper +wget -O - https://raw.githubusercontent.com/Frix-x/klippain-shaketune/main/install.sh | bash + echo "[POST-INSTALL] Everything is ok, Klippain installed and up to date!" echo "[POST-INSTALL] Be sure to check the breaking changes on the release page: https://github.com/Frix-x/klippain/releases" diff --git a/macros/calibration/IS_shaper_calibrate.cfg b/macros/calibration/IS_shaper_calibrate.cfg deleted file mode 100644 index 04aeaf432..000000000 --- a/macros/calibration/IS_shaper_calibrate.cfg +++ /dev/null @@ -1,97 +0,0 @@ -################################################ -###### STANDARD INPUT_SHAPER CALIBRATIONS ###### -################################################ -# Written by Frix_x#0161 # -# @version: 1.4 - -# CHANGELOG: -# v1.4: added possibility to only run one axis at a time for the axes shaper calibration -# v1.3: added possibility to override the default parameters -# v1.2: added EXCITATE_AXIS_AT_FREQ to hold a specific excitating frequency on an axis and diagnose mechanical problems -# v1.1: added M400 to validate that the files are correctly saved to disk -# v1.0: first version of the automatic input shaper workflow - - -### What is it ? ### -# This macro helps you to configure the input shaper algorithm of Klipper by running the tests sequencially and calling an automatic script -# that generate the graphs, manage the files and so on. It's basically a fully automatic input shaper calibration workflow. -# Results can be found in your config folder using FLuidd/Maisail file manager. - -# The goal is to make it easy to set, share and use it. - -# Usage: -# 1. Call the AXES_SHAPER_CALIBRATION macro, wait for it to end and compute the graphs. Then look for the results in the results folder. -# 2. Call the BELTS_SHAPER_CALIBRATION macro, wait for it to end and compute the graphs. Then look for the results in the results folder. -# 3. If you find out some strange noise, you can use the EXCITATE_AXIS_AT_FREQ macro to diagnose the origin - - -[gcode_macro AXES_SHAPER_CALIBRATION] -description: Run standard input shaper test for all axes -gcode: - {% set verbose = params.VERBOSE|default(true) %} - {% set min_freq = params.FREQ_START|default(5)|float %} - {% set max_freq = params.FREQ_END|default(133.3)|float %} - {% set hz_per_sec = params.HZ_PER_SEC|default(1)|float %} - {% set axis = params.AXIS|default("all")|string|lower %} - - {% set X, Y = False, False %} - - {% if axis == "all" %} - {% set X, Y = True, True %} - {% elif axis == "x" %} - {% set X = True %} - {% elif axis == "y" %} - {% set Y = True %} - {% else %} - { action_raise_error("AXIS selection invalid. Should be either all, x or y!") } - {% endif %} - - {% if X %} - TEST_RESONANCES AXIS=X OUTPUT=raw_data NAME=x FREQ_START={min_freq} FREQ_END={max_freq} HZ_PER_SEC={hz_per_sec} - M400 - - {% if verbose %} - RESPOND MSG="X axis shaper graphs generation..." - {% endif %} - RUN_SHELL_COMMAND CMD=plot_graph PARAMS=SHAPER - {% endif %} - - {% if Y %} - TEST_RESONANCES AXIS=Y OUTPUT=raw_data NAME=y FREQ_START={min_freq} FREQ_END={max_freq} HZ_PER_SEC={hz_per_sec} - M400 - - {% if verbose %} - RESPOND MSG="Y axis shaper graphs generation..." - {% endif %} - RUN_SHELL_COMMAND CMD=plot_graph PARAMS=SHAPER - {% endif %} - - -[gcode_macro BELTS_SHAPER_CALIBRATION] -description: Run custom demi-axe test to analyze belts on CoreXY printers -gcode: - {% set verbose = params.VERBOSE|default(true) %} - {% set min_freq = params.FREQ_START|default(5)|float %} - {% set max_freq = params.FREQ_END|default(133.33)|float %} - {% set hz_per_sec = params.HZ_PER_SEC|default(1)|float %} - - TEST_RESONANCES AXIS=1,1 OUTPUT=raw_data NAME=b FREQ_START={min_freq} FREQ_END={max_freq} HZ_PER_SEC={hz_per_sec} - M400 - TEST_RESONANCES AXIS=1,-1 OUTPUT=raw_data NAME=a FREQ_START={min_freq} FREQ_END={max_freq} HZ_PER_SEC={hz_per_sec} - M400 - - {% if verbose %} - RESPOND MSG="Belts graphs generation..." - {% endif %} - RUN_SHELL_COMMAND CMD=plot_graph PARAMS=BELTS - - -[gcode_macro EXCITATE_AXIS_AT_FREQ] -description: Maintain a specified input shaper excitating frequency for some time to diagnose vibrations -gcode: - {% set FREQUENCY = params.FREQUENCY|default(25)|int %} - {% set TIME = params.TIME|default(10)|int %} - {% set AXIS = params.AXIS|default("x")|string|lower %} - - TEST_RESONANCES OUTPUT=raw_data AXIS={AXIS} FREQ_START={FREQUENCY-1} FREQ_END={FREQUENCY+1} HZ_PER_SEC={1/(TIME/3)} - M400 diff --git a/macros/calibration/IS_vibrations_measurement.cfg b/macros/calibration/IS_vibrations_measurement.cfg deleted file mode 100644 index 40af7707d..000000000 --- a/macros/calibration/IS_vibrations_measurement.cfg +++ /dev/null @@ -1,191 +0,0 @@ -################################################ -###### VIBRATIONS AND SPEED OPTIMIZATIONS ###### -################################################ -# Written by Frix_x#0161 # -# @version: 2.1 - -# CHANGELOG: -# v2.1: allow decimal entries for speed and increment and added the E axis as an option to be neasured -# v2.0: added the possibility to measure mutliple axis -# v1.0: first speed and vibrations optimization macro - - -### What is it ? ### -# This macro helps you to identify the speed settings that exacerbate the vibrations of the machine (ie. where the frame resonate badly). -# It also helps to find the clean speed ranges where the machine is silent. -# I had some strong vibrations at very specific speeds on my machine (52mm/s for example) and I wanted to find all these problematic speeds -# to avoid them in my slicer profile and finally get the silent machine I was dreaming! - -# It works by moving the toolhead at different speed settings while recording the vibrations using the ADXL chip. Then the macro call a custom script -# to compute and find the best speed settings. The results can be found in your config folder using Fluidd/Mainsail file manager. - -# 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. - -# Usage: -# 1. DO YOUR INPUT SHAPER CALIBRATION FIRST !!! This macro should not be used before as it would be useless and the results invalid. -# 2. Call the VIBRATIONS_CALIBRATION macro with the speed range you want to measure (default 20 to 200mm/s with 2mm/s increment). -# Be carefull about the Z_HEIGHT variable that default to 20mm -> if your ADXL is under the nozzle, increase it to avoid a crash of the ADXL on the bed of the machine. -# 3. Wait for it to finish all the measurement and compute the graph. Then look at it in the results folder. - - -[gcode_macro VIBRATIONS_CALIBRATION] -gcode: - # - # PARAMETERS - # - {% set size = params.SIZE|default(60)|int %} # size of the area where the movements are done - {% set direction = params.DIRECTION|default('XY') %} # can be set to either XY, AB, ABXY, A, B, X, Y, Z - {% set z_height = params.Z_HEIGHT|default(20)|int %} # z height to put the toolhead before starting the movements - {% set verbose = params.VERBOSE|default(true) %} # Wether to log the current speed in the console - - {% set min_speed = params.MIN_SPEED|default(20)|float * 60 %} # minimum feedrate for the movements - {% set max_speed = params.MAX_SPEED|default(200)|float * 60 %} # maximum feedrate for the movements - {% set speed_increment = params.SPEED_INCREMENT|default(2)|float * 60 %} # feedrate increment between each move - {% set feedrate_travel = params.TRAVEL_SPEED|default(200)|int * 60 %} # travel feedrate between moves - - {% set accel_chip = params.ACCEL_CHIP|default("adxl345") %} # ADXL chip name in the config - - # - # COMPUTED VALUES - # - {% set mid_x = printer.toolhead.axis_maximum.x|float / 2 %} - {% set mid_y = printer.toolhead.axis_maximum.y|float / 2 %} - {% set nb_samples = ((max_speed - min_speed) / speed_increment + 1) | int %} - - {% set direction_factor = { - 'XY' : { - 'start' : {'x': -0.5, 'y': -0.5 }, - 'move_factors' : { - '0' : {'x': 0.5, 'y': -0.5, 'z': 0.0 }, - '1' : {'x': 0.5, 'y': 0.5, 'z': 0.0 }, - '2' : {'x': -0.5, 'y': 0.5, 'z': 0.0 }, - '3' : {'x': -0.5, 'y': -0.5, 'z': 0.0 } - } - }, - 'AB' : { - 'start' : {'x': 0.0, 'y': 0.0 }, - 'move_factors' : { - '0' : {'x': 0.5, 'y': -0.5, 'z': 0.0 }, - '1' : {'x': -0.5, 'y': 0.5, 'z': 0.0 }, - '2' : {'x': 0.0, 'y': 0.0, 'z': 0.0 }, - '3' : {'x': 0.5, 'y': 0.5, 'z': 0.0 }, - '4' : {'x': -0.5, 'y': -0.5, 'z': 0.0 }, - '5' : {'x': 0.0, 'y': 0.0, 'z': 0.0 } - } - }, - 'ABXY' : { - 'start' : {'x': -0.5, 'y': 0.5 }, - 'move_factors' : { - '0' : {'x': -0.5, 'y': -0.5, 'z': 0.0 }, - '1' : {'x': 0.5, 'y': -0.5, 'z': 0.0 }, - '2' : {'x': -0.5, 'y': 0.5, 'z': 0.0 }, - '3' : {'x': 0.5, 'y': 0.5, 'z': 0.0 }, - '4' : {'x': -0.5, 'y': -0.5, 'z': 0.0 }, - '5' : {'x': -0.5, 'y': 0.5, 'z': 0.0 } - } - }, - 'B' : { - 'start' : {'x': 0.5, 'y': 0.5 }, - 'move_factors' : { - '0' : {'x': -0.5, 'y': -0.5, 'z': 0.0 }, - '1' : {'x': 0.5, 'y': 0.5, 'z': 0.0 } - } - }, - 'A' : { - 'start' : {'x': -0.5, 'y': 0.5 }, - 'move_factors' : { - '0' : {'x': 0.5, 'y': -0.5, 'z': 0.0 }, - '1' : {'x': -0.5, 'y': 0.5, 'z': 0.0 } - } - }, - 'X' : { - 'start' : {'x': -0.5, 'y': 0.0 }, - 'move_factors' : { - '0' : {'x': 0.5, 'y': 0.0, 'z': 0.0 }, - '1' : {'x': -0.5, 'y': 0.0, 'z': 0.0 } - } - }, - 'Y' : { - 'start' : {'x': 0.0, 'y': 0.5 }, - 'move_factors' : { - '0' : {'x': 0.0, 'y': -0.5, 'z': 0.0 }, - '1' : {'x': 0.0, 'y': 0.5, 'z': 0.0 } - } - }, - 'Z' : { - 'start' : {'x': 0.0, 'y': 0.0 }, - 'move_factors' : { - '0' : {'x': 0.0, 'y': 0.0, 'z': 1.0 }, - '1' : {'x': 0.0, 'y': 0.0, 'z': 0.0 } - } - }, - 'E' : { - 'start' : {'x': 0.0, 'y': 0.0 }, - 'move_factor' : 0.05 - } - } - %} - - # - # STARTING... - # - {% if not 'xyz' in printer.toolhead.homed_axes %} - { action_raise_error("Must Home printer first!") } - {% endif %} - - {% if params.SPEED_INCREMENT|default(2)|float * 100 != (params.SPEED_INCREMENT|default(2)|float * 100)|int %} - { action_raise_error("Only 2 decimal digits are allowed for SPEED_INCREMENT") } - {% endif %} - - {% if (size / (max_speed / 60)) < 0.25 and direction != 'E' %} - { action_raise_error("SIZE is too small for this MAX_SPEED. Increase SIZE or decrease MAX_SPEED!") } - {% endif %} - - {% if not (direction in direction_factor) %} - { action_raise_error("DIRECTION is not valid. Only XY, AB, ABXY, A, B, X, Y, Z or E is allowed!") } - {% endif %} - - {action_respond_info("")} - {action_respond_info("Starting speed and vibration calibration")} - {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("")} - - SAVE_GCODE_STATE NAME=STATE_VIBRATIONS_CALIBRATION - - M83 - G90 - - # Going to the start position - G1 Z{z_height} - G1 X{mid_x + (size * direction_factor[direction].start.x) } Y{mid_y + (size * direction_factor[direction].start.y)} F{feedrate_travel} - - # vibration pattern for each frequency - {% for curr_sample in range(0, nb_samples) %} - {% set curr_speed = min_speed + curr_sample * speed_increment %} - {% if verbose %} - RESPOND MSG="{"Current speed: %.2f mm/s" % (curr_speed / 60)|float}" - {% endif %} - - ACCELEROMETER_MEASURE CHIP={accel_chip} - {% if direction == 'E' %} - G0 E{curr_speed*direction_factor[direction].move_factor} F{curr_speed} - {% else %} - {% for key, factor in direction_factor[direction].move_factors|dictsort %} - G1 X{mid_x + (size * factor.x) } Y{mid_y + (size * factor.y)} Z{z_height + (size * factor.z)} F{curr_speed} - {% endfor %} - {% endif %} - ACCELEROMETER_MEASURE CHIP={accel_chip} NAME=sp{("%.2f" % (curr_speed / 60)|float)|replace('.','_')}n1 - - G4 P300 - M400 - {% endfor %} - - {% if verbose %} - RESPOND MSG="Graphs generation... Please wait a minute or two and look in the configured folder." - {% endif %} - RUN_SHELL_COMMAND CMD=plot_graph PARAMS="VIBRATIONS {direction}" - - RESTORE_GCODE_STATE NAME=STATE_VIBRATIONS_CALIBRATION diff --git a/moonraker/base.conf b/moonraker/base.conf index c30cb2419..b6140e15d 100644 --- a/moonraker/base.conf +++ b/moonraker/base.conf @@ -35,6 +35,7 @@ trusted_clients: [update_manager] enable_auto_refresh: True + [update_manager Klippain] type: git_repo path: ~/klippain_config @@ -42,3 +43,12 @@ origin: https://github.com/Frix-x/klippain.git primary_branch: main managed_services: moonraker klipper install_script: install.sh + +[update_manager Klippain-ShakeTune] +type: git_repo +path: ~/klippain_shaketune +channel: beta +origin: https://github.com/Frix-x/klippain-shaketune.git +primary_branch: main +managed_services: klipper +install_script: install.sh diff --git a/scripts/is_workflow/graph_belts.py b/scripts/is_workflow/graph_belts.py deleted file mode 100755 index 4c31f8fd2..000000000 --- a/scripts/is_workflow/graph_belts.py +++ /dev/null @@ -1,638 +0,0 @@ -#!/usr/bin/env python3 - -################################################# -######## CoreXY BELTS CALIBRATION SCRIPT ######## -################################################# -# Written by Frix_x#0161 # -# @version: 2.1 - -# CHANGELOG: -# v2.1: replaced the TwoSlopNorm by a custom made norm to allow the script to work on older versions of matplotlib -# v2.0: updated the script to align it to the new K-Shake&Tune module -# v1.0: first version of this tool for enhanced vizualisation of belt graphs - - -# Be sure to make this script executable using SSH: type 'chmod +x ./graph_belts.py' when in the folder! - -##################################################################### -################ !!! DO NOT EDIT BELOW THIS LINE !!! ################ -##################################################################### - -import optparse, matplotlib, sys, importlib, os -from textwrap import wrap -from collections import namedtuple -import numpy as np -import matplotlib.pyplot, matplotlib.dates, matplotlib.font_manager -import matplotlib.ticker, matplotlib.gridspec, matplotlib.colors -import matplotlib.patches -import locale -from datetime import datetime - -matplotlib.use('Agg') - - -ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" # For paired peaks names - -PEAKS_DETECTION_THRESHOLD = 0.20 -CURVE_SIMILARITY_SIGMOID_K = 0.6 -DC_GRAIN_OF_SALT_FACTOR = 0.75 -DC_THRESHOLD_METRIC = 1.5e9 -DC_MAX_UNPAIRED_PEAKS_ALLOWED = 4 - -# Define the SignalData namedtuple -SignalData = namedtuple('CalibrationData', ['freqs', 'psd', 'peaks', 'paired_peaks', 'unpaired_peaks']) - -KLIPPAIN_COLORS = { - "purple": "#70088C", - "orange": "#FF8D32", - "dark_purple": "#150140", - "dark_orange": "#F24130", - "red_pink": "#F2055C" -} - - -# Set the best locale for time and date formating (generation of the titles) -try: - locale.setlocale(locale.LC_TIME, locale.getdefaultlocale()) -except locale.Error: - locale.setlocale(locale.LC_TIME, 'C') - -# Override the built-in print function to avoid problem in Klipper due to locale settings -original_print = print -def print_with_c_locale(*args, **kwargs): - original_locale = locale.setlocale(locale.LC_ALL, None) - locale.setlocale(locale.LC_ALL, 'C') - original_print(*args, **kwargs) - locale.setlocale(locale.LC_ALL, original_locale) -print = print_with_c_locale - - -###################################################################### -# Computation of the PSD graph -###################################################################### - -# Calculate estimated "power spectral density" using existing Klipper tools -def calc_freq_response(data): - helper = shaper_calibrate.ShaperCalibrate(printer=None) - return helper.process_accelerometer_data(data) - - -# Calculate or estimate a "similarity" factor between two PSD curves and scale it to a percentage. This is -# used here to quantify how close the two belts path behavior and responses are close together. -def compute_curve_similarity_factor(signal1, signal2): - freqs1 = signal1.freqs - psd1 = signal1.psd - freqs2 = signal2.freqs - psd2 = signal2.psd - - # Interpolate PSDs to match the same frequency bins and do a cross-correlation - psd2_interp = np.interp(freqs1, freqs2, psd2) - cross_corr = np.correlate(psd1, psd2_interp, mode='full') - - # Find the peak of the cross-correlation and compute a similarity normalized by the energy of the signals - peak_value = np.max(cross_corr) - similarity = peak_value / (np.sqrt(np.sum(psd1**2) * np.sum(psd2_interp**2))) - - # Apply sigmoid scaling to get better numbers and get a final percentage value - scaled_similarity = sigmoid_scale(-np.log(1 - similarity), CURVE_SIMILARITY_SIGMOID_K) - - return scaled_similarity - - -# This find all the peaks in a curve by looking at when the derivative term goes from positive to negative -# Then only the peaks found above a threshold are kept to avoid capturing peaks in the low amplitude noise of a signal -def detect_peaks(psd, freqs, window_size=5, vicinity=3): - # Smooth the curve using a moving average to avoid catching peaks everywhere in noisy signals - kernel = np.ones(window_size) / window_size - smoothed_psd = np.convolve(psd, kernel, mode='valid') - mean_pad = [np.mean(psd[:window_size])] * (window_size // 2) - smoothed_psd = np.concatenate((mean_pad, smoothed_psd)) - - # Find peaks on the smoothed curve - smoothed_peaks = np.where((smoothed_psd[:-2] < smoothed_psd[1:-1]) & (smoothed_psd[1:-1] > smoothed_psd[2:]))[0] + 1 - detection_threshold = PEAKS_DETECTION_THRESHOLD * psd.max() - smoothed_peaks = smoothed_peaks[smoothed_psd[smoothed_peaks] > detection_threshold] - - # Refine peak positions on the original curve - refined_peaks = [] - for peak in smoothed_peaks: - local_max = peak + np.argmax(psd[max(0, peak-vicinity):min(len(psd), peak+vicinity+1)]) - vicinity - refined_peaks.append(local_max) - - return np.array(refined_peaks), freqs[refined_peaks] - - -# This function create pairs of peaks that are close in frequency on two curves (that are known -# to be resonances points and must be similar on both belts on a CoreXY kinematic) -def pair_peaks(peaks1, freqs1, psd1, peaks2, freqs2, psd2): - # Compute a dynamic detection threshold to filter and pair peaks efficiently - # even if the signal is very noisy (this get clipped to a maximum of 10Hz diff) - distances = [] - for p1 in peaks1: - for p2 in peaks2: - distances.append(abs(freqs1[p1] - freqs2[p2])) - distances = np.array(distances) - - median_distance = np.median(distances) - iqr = np.percentile(distances, 75) - np.percentile(distances, 25) - - threshold = median_distance + 1.5 * iqr - threshold = min(threshold, 10) - - # Pair the peaks using the dynamic thresold - paired_peaks = [] - unpaired_peaks1 = list(peaks1) - unpaired_peaks2 = list(peaks2) - - while unpaired_peaks1 and unpaired_peaks2: - min_distance = threshold + 1 - pair = None - - for p1 in unpaired_peaks1: - for p2 in unpaired_peaks2: - distance = abs(freqs1[p1] - freqs2[p2]) - if distance < min_distance: - min_distance = distance - pair = (p1, p2) - - if pair is None: # No more pairs below the threshold - break - - p1, p2 = pair - paired_peaks.append(((p1, freqs1[p1], psd1[p1]), (p2, freqs2[p2], psd2[p2]))) - unpaired_peaks1.remove(p1) - unpaired_peaks2.remove(p2) - - return paired_peaks, unpaired_peaks1, unpaired_peaks2 - - -###################################################################### -# Computation of a basic signal spectrogram -###################################################################### - -def compute_spectrogram(data): - N = data.shape[0] - Fs = N / (data[-1,0] - data[0,0]) - # Round up to a power of 2 for faster FFT - M = 1 << int(.5 * Fs - 1).bit_length() - window = np.kaiser(M, 6.) - def _specgram(x): - return matplotlib.mlab.specgram( - x, Fs=Fs, NFFT=M, noverlap=M//2, window=window, - mode='psd', detrend='mean', scale_by_freq=False) - - d = {'x': data[:,1], 'y': data[:,2], 'z': data[:,3]} - pdata, bins, t = _specgram(d['x']) - for ax in 'yz': - pdata += _specgram(d[ax])[0] - return pdata, bins, t - - -###################################################################### -# Computation of the differential spectrogram -###################################################################### - -# Performs a standard bilinear interpolation for a given x, y point based on surrounding input grid values. This function -# is part of the logic to re-align both belts spectrogram in order to combine them in the differential spectrogram. -def bilinear_interpolate(x, y, points, values): - x1, x2 = points[0] - y1, y2 = points[1] - - f11, f12 = values[0] - f21, f22 = values[1] - - interpolated_value = ( - (f11 * (x2 - x) * (y2 - y) + - f21 * (x - x1) * (y2 - y) + - f12 * (x2 - x) * (y - y1) + - f22 * (x - x1) * (y - y1)) / ((x2 - x1) * (y2 - y1)) - ) - - return interpolated_value - - -# Interpolate source_data (2D) to match target_x and target_y in order to interpolate and -# get similar time and frequency dimensions for the differential spectrogram -def interpolate_2d(target_x, target_y, source_x, source_y, source_data): - interpolated_data = np.zeros((len(target_y), len(target_x))) - - for i, y in enumerate(target_y): - for j, x in enumerate(target_x): - # Find indices of surrounding points in source data - # and ensure we don't exceed array bounds - x_indices = np.searchsorted(source_x, x) - 1 - y_indices = np.searchsorted(source_y, y) - 1 - x_indices = max(0, min(len(source_x) - 1, x_indices)) - y_indices = max(0, min(len(source_y) - 1, y_indices)) - - if x_indices == len(source_x) - 2: - x_indices -= 1 - if y_indices == len(source_y) - 2: - y_indices -= 1 - - x1, x2 = source_x[x_indices], source_x[x_indices + 1] - y1, y2 = source_y[y_indices], source_y[y_indices + 1] - - f11 = source_data[y_indices, x_indices] - f12 = source_data[y_indices, x_indices + 1] - f21 = source_data[y_indices + 1, x_indices] - f22 = source_data[y_indices + 1, x_indices + 1] - - interpolated_data[i, j] = bilinear_interpolate(x, y, ((x1, x2), (y1, y2)), ((f11, f12), (f21, f22))) - - return interpolated_data - - -# This function identifies a "ridge" of high gradient magnitude in a spectrogram (pdata) - ie. a resonance diagonal line. Starting from -# the maximum value in the first column, it iteratively follows the direction of the highest gradient in the vicinity (window configured using -# the n_average parameter). The result is a sequence of indices that traces the resonance line across the original spectrogram. -def detect_ridge(pdata, n_average=3): - grad_y, grad_x = np.gradient(pdata) - magnitude = np.sqrt(grad_x**2 + grad_y**2) - - # Start at the maximum value in the first column - start_idx = np.argmax(pdata[:, 0]) - path = [start_idx] - - # Walk through the spectrogram following the path of the ridge - for j in range(1, pdata.shape[1]): - # Look in the vicinity of the previous point - vicinity = magnitude[max(0, path[-1]-n_average):min(pdata.shape[0], path[-1]+n_average+1), j] - # Take an average of top few points - sorted_indices = np.argsort(vicinity) - top_indices = sorted_indices[-n_average:] - next_idx = int(np.mean(top_indices) + max(0, path[-1]-n_average)) - path.append(next_idx) - - return np.array(path) - - -# This function calculates the time offset between two resonances lines (ridge1 and ridge2) using cross-correlation in -# the frequency domain (using FFT). The result provides the lag (or offset) at which the two sequences are most similar. -# This is used to re-align both belts spectrograms on their resonances lines in order to create the combined spectrogram. -def compute_cross_correlation_offset(ridge1, ridge2): - # Ensure that the two arrays have the same shape - if len(ridge1) < len(ridge2): - ridge1 = np.pad(ridge1, (0, len(ridge2) - len(ridge1))) - elif len(ridge1) > len(ridge2): - ridge2 = np.pad(ridge2, (0, len(ridge1) - len(ridge2))) - - cross_corr = np.fft.fftshift(np.fft.ifft(np.fft.fft(ridge1) * np.conj(np.fft.fft(ridge2)))) - return np.argmax(np.abs(cross_corr)) - len(ridge1) // 2 - - -# This function shifts data along its second dimension - ie. time here - by a specified shift_amount -def shift_data_in_time(data, shift_amount): - if shift_amount > 0: - return np.pad(data, ((0, 0), (shift_amount, 0)), mode='constant')[:, :-shift_amount] - elif shift_amount < 0: - return np.pad(data, ((0, 0), (0, -shift_amount)), mode='constant')[:, -shift_amount:] - else: - return data - - -# Main logic function to combine two similar spectrogram - ie. from both belts paths - by detecting similarities (ridges), computing -# the time lag and realigning them. Finally this function combine (by substracting signals) the aligned spectrograms in a new one. -# This result of a mostly zero-ed new spectrogram with some colored zones highlighting differences in the belts paths. -def combined_spectrogram(data1, data2): - pdata1, bins1, t1 = compute_spectrogram(data1) - pdata2, _, _ = compute_spectrogram(data2) - - # Detect ridges - ridge1 = detect_ridge(pdata1) - ridge2 = detect_ridge(pdata2) - - # Compute offset using cross-correlation and shit/align and interpolate the spectrograms - offset = compute_cross_correlation_offset(ridge1, ridge2) - pdata2_aligned = shift_data_in_time(pdata2, offset) - pdata2_interpolated = interpolate_2d(t1, bins1, t1, bins1, pdata2_aligned) - - # Combine the spectrograms - combined_data = np.abs(pdata1 - pdata2_interpolated) - return combined_data, bins1, t1 - - -# Compute a composite and highly subjective value indicating the "mechanical health of the printer (0 to 100%)" that represent the -# likelihood of mechanical issues on the printer. It is based on the differential spectrogram sum of gradient, salted with a bit -# of the estimated similarity cross-correlation from compute_curve_similarity_factor() and with a bit of the number of unpaired peaks. -# This result in a percentage value quantifying the machine behavior around the main resonances that give an hint if only touching belt tension -# will give good graphs or if there is a chance of mechanical issues in the background (above 50% should be considered as probably problematic) -def compute_mhi(combined_data, similarity_coefficient, num_unpaired_peaks): - filtered_data = combined_data[combined_data > 100] - - # First compute a "total variability metric" based on the sum of the gradient that sum the magnitude of will emphasize regions of the - # spectrogram where there are rapid changes in magnitude (like the edges of resonance peaks). - total_variability_metric = np.sum(np.abs(np.gradient(filtered_data))) - # Scale the metric to a percentage using the threshold (found empirically on a large number of user data shared to me) - base_percentage = (np.log1p(total_variability_metric) / np.log1p(DC_THRESHOLD_METRIC)) * 100 - - # Adjust the percentage based on the similarity_coefficient to add a grain of salt - adjusted_percentage = base_percentage * (1 - DC_GRAIN_OF_SALT_FACTOR * (similarity_coefficient / 100)) - - # Adjust the percentage again based on the number of unpaired peaks to add a second grain of salt - peak_confidence = num_unpaired_peaks / DC_MAX_UNPAIRED_PEAKS_ALLOWED - final_percentage = (1 - peak_confidence) * adjusted_percentage + peak_confidence * 100 - - # Ensure the result lies between 0 and 100 by clipping the computed value - final_percentage = np.clip(final_percentage, 0, 100) - - return final_percentage, mhi_lut(final_percentage) - - -# LUT to transform the MHI into a textual value easy to understand for the users of the script -def mhi_lut(mhi): - if 0 <= mhi <= 30: - return "Excellent mechanical health" - elif 30 < mhi <= 45: - return "Good mechanical health" - elif 45 < mhi <= 55: - return "Acceptable mechanical health" - elif 55 < mhi <= 70: - return "Potential signs of a mechanical issue" - elif 70 < mhi <= 85: - return "Likely a mechanical issue" - elif 85 < mhi <= 100: - return "Mechanical issue detected" - - -###################################################################### -# Graphing -###################################################################### - -def plot_compare_frequency(ax, lognames, signal1, signal2, max_freq): - # Get the belt name for the legend to avoid putting the full file name - signal1_belt = (lognames[0].split('/')[-1]).split('_')[-1][0] - signal2_belt = (lognames[1].split('/')[-1]).split('_')[-1][0] - - if signal1_belt == 'A' and signal2_belt == 'B': - signal1_belt += " (axis 1,-1)" - signal2_belt += " (axis 1, 1)" - elif signal1_belt == 'B' and signal2_belt == 'A': - signal1_belt += " (axis 1, 1)" - signal2_belt += " (axis 1,-1)" - else: - print("Warning: belts doesn't seem to have the correct name A and B (extracted from the filename.csv)") - - # Plot the two belts PSD signals - ax.plot(signal1.freqs, signal1.psd, label="Belt " + signal1_belt, color=KLIPPAIN_COLORS['purple']) - ax.plot(signal2.freqs, signal2.psd, label="Belt " + signal2_belt, color=KLIPPAIN_COLORS['orange']) - - # Trace the "relax region" (also used as a threshold to filter and detect the peaks) - psd_lowest_max = min(signal1.psd.max(), signal2.psd.max()) - peaks_warning_threshold = PEAKS_DETECTION_THRESHOLD * psd_lowest_max - ax.axhline(y=peaks_warning_threshold, color='black', linestyle='--', linewidth=0.5) - ax.fill_between(signal1.freqs, 0, peaks_warning_threshold, color='green', alpha=0.15, label='Relax Region') - - # Trace and annotate the peaks on the graph - paired_peak_count = 0 - unpaired_peak_count = 0 - offsets_table_data = [] - - for _, (peak1, peak2) in enumerate(signal1.paired_peaks): - label = ALPHABET[paired_peak_count] - amplitude_offset = abs(((signal2.psd[peak2[0]] - signal1.psd[peak1[0]]) / max(signal1.psd[peak1[0]], signal2.psd[peak2[0]])) * 100) - frequency_offset = abs(signal2.freqs[peak2[0]] - signal1.freqs[peak1[0]]) - offsets_table_data.append([f"Peaks {label}", f"{frequency_offset:.1f} Hz", f"{amplitude_offset:.1f} %"]) - - ax.plot(signal1.freqs[peak1[0]], signal1.psd[peak1[0]], "x", color='black') - ax.plot(signal2.freqs[peak2[0]], signal2.psd[peak2[0]], "x", color='black') - ax.plot([signal1.freqs[peak1[0]], signal2.freqs[peak2[0]]], [signal1.psd[peak1[0]], signal2.psd[peak2[0]]], ":", color='gray') - - ax.annotate(label + "1", (signal1.freqs[peak1[0]], signal1.psd[peak1[0]]), - textcoords="offset points", xytext=(8, 5), - ha='left', fontsize=13, color='black') - ax.annotate(label + "2", (signal2.freqs[peak2[0]], signal2.psd[peak2[0]]), - textcoords="offset points", xytext=(8, 5), - ha='left', fontsize=13, color='black') - paired_peak_count += 1 - - for peak in signal1.unpaired_peaks: - ax.plot(signal1.freqs[peak], signal1.psd[peak], "x", color='black') - ax.annotate(str(unpaired_peak_count + 1), (signal1.freqs[peak], signal1.psd[peak]), - textcoords="offset points", xytext=(8, 5), - ha='left', fontsize=13, color='red', weight='bold') - unpaired_peak_count += 1 - - for peak in signal2.unpaired_peaks: - ax.plot(signal2.freqs[peak], signal2.psd[peak], "x", color='black') - ax.annotate(str(unpaired_peak_count + 1), (signal2.freqs[peak], signal2.psd[peak]), - textcoords="offset points", xytext=(8, 5), - ha='left', fontsize=13, color='red', weight='bold') - unpaired_peak_count += 1 - - # Compute the similarity (using cross-correlation of the PSD signals) - ax2 = ax.twinx() # To split the legends in two box - ax2.yaxis.set_visible(False) - similarity_factor = compute_curve_similarity_factor(signal1, signal2) - ax2.plot([], [], ' ', label=f'Estimated similarity: {similarity_factor:.1f}%') - ax2.plot([], [], ' ', label=f'Number of unpaired peaks: {unpaired_peak_count}') - print(f"Belts estimated similarity: {similarity_factor:.1f}%") - - # Setting axis parameters, grid and graph title - ax.set_xlabel('Frequency (Hz)') - ax.set_xlim([0, max_freq]) - ax.set_ylabel('Power spectral density') - psd_highest_max = max(signal1.psd.max(), signal2.psd.max()) - ax.set_ylim([0, psd_highest_max + psd_highest_max * 0.05]) - - ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) - ax.yaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) - ax.ticklabel_format(axis='y', style='scientific', scilimits=(0,0)) - ax.grid(which='major', color='grey') - ax.grid(which='minor', color='lightgrey') - fontP = matplotlib.font_manager.FontProperties() - fontP.set_size('small') - ax.set_title('Belts Frequency Profiles (estimated similarity: {:.1f}%)'.format(similarity_factor), fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold') - - # Print the table of offsets ontop of the graph below the original legend (upper right) - if len(offsets_table_data) > 0: - columns = ["", "Frequency delta", "Amplitude delta", ] - offset_table = ax.table(cellText=offsets_table_data, colLabels=columns, bbox=[0.66, 0.75, 0.33, 0.15], loc='upper right', cellLoc='center') - offset_table.auto_set_font_size(False) - offset_table.set_fontsize(8) - offset_table.auto_set_column_width([0, 1, 2]) - offset_table.set_zorder(100) - cells = [key for key in offset_table.get_celld().keys()] - for cell in cells: - offset_table[cell].set_facecolor('white') - offset_table[cell].set_alpha(0.6) - - ax.legend(loc='upper left', prop=fontP) - ax2.legend(loc='upper right', prop=fontP) - - return similarity_factor, unpaired_peak_count - - -def plot_difference_spectrogram(ax, data1, data2, signal1, signal2, similarity_factor, max_freq): - combined_data, bins, t = combined_spectrogram(data1, data2) - - # Compute the MHI value from the differential spectrogram sum of gradient, salted with - # the similarity factor and the number or unpaired peaks from the belts frequency profile - # Be careful, this value is highly opinionated and is pretty experimental! - mhi, textual_mhi = compute_mhi(combined_data, similarity_factor, len(signal1.unpaired_peaks) + len(signal2.unpaired_peaks)) - print(f"[experimental] Mechanical Health Indicator: {textual_mhi.lower()} ({mhi:.1f}%)") - ax.set_title(f"Differential Spectrogram", fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold') - ax.plot([], [], ' ', label=f'{textual_mhi} (experimental)') - - # Draw the differential spectrogram with a specific custom norm to get white or light orange zero values and red for max values - colors = ['white', 'bisque', 'red', 'black'] - n_bins = [0, 0.12, 0.9, 1] # These values where found experimentaly to get a good higlhlighting of the differences only - cm = matplotlib.colors.LinearSegmentedColormap.from_list('WhiteToRed', list(zip(n_bins, colors))) - norm = matplotlib.colors.Normalize(vmin=np.min(combined_data), vmax=np.max(combined_data)) - ax.pcolormesh(bins, t, combined_data.T, cmap=cm, norm=norm, shading='gouraud') - - ax.set_xlabel('Frequency (hz)') - ax.set_xlim([0., max_freq]) - ax.set_ylabel('Time (s)') - ax.set_ylim([0, t[-1]]) - - fontP = matplotlib.font_manager.FontProperties() - fontP.set_size('medium') - ax.legend(loc='best', prop=fontP) - - # Plot vertical lines for unpaired peaks - unpaired_peak_count = 0 - for _, peak in enumerate(signal1.unpaired_peaks): - ax.axvline(signal1.freqs[peak], color='red', linestyle='dotted', linewidth=1.5) - ax.annotate(f"Peak {unpaired_peak_count + 1}", (signal1.freqs[peak], t[-1]*0.05), - textcoords="data", color='red', rotation=90, fontsize=10, - verticalalignment='bottom', horizontalalignment='right') - unpaired_peak_count +=1 - - for _, peak in enumerate(signal2.unpaired_peaks): - ax.axvline(signal2.freqs[peak], color='red', linestyle='dotted', linewidth=1.5) - ax.annotate(f"Peak {unpaired_peak_count + 1}", (signal2.freqs[peak], t[-1]*0.05), - textcoords="data", color='red', rotation=90, fontsize=10, - verticalalignment='bottom', horizontalalignment='right') - unpaired_peak_count +=1 - - # Plot vertical lines and zones for paired peaks - for idx, (peak1, peak2) in enumerate(signal1.paired_peaks): - label = ALPHABET[idx] - x_min = min(peak1[1], peak2[1]) - x_max = max(peak1[1], peak2[1]) - ax.axvline(x_min, color=KLIPPAIN_COLORS['purple'], linestyle='dotted', linewidth=1.5) - ax.axvline(x_max, color=KLIPPAIN_COLORS['purple'], linestyle='dotted', linewidth=1.5) - ax.fill_between([x_min, x_max], 0, np.max(combined_data), color=KLIPPAIN_COLORS['purple'], alpha=0.3) - ax.annotate(f"Peaks {label}", (x_min, t[-1]*0.05), - textcoords="data", color=KLIPPAIN_COLORS['purple'], rotation=90, fontsize=10, - verticalalignment='bottom', horizontalalignment='right') - - return - - -###################################################################### -# Custom tools -###################################################################### - -# Simple helper to compute a sigmoid scalling (from 0 to 100%) -def sigmoid_scale(x, k=1): - return 1 / (1 + np.exp(-k * x)) * 100 - -# Original Klipper function to get the PSD data of a raw accelerometer signal -def compute_signal_data(data, max_freq): - calibration_data = calc_freq_response(data) - freqs = calibration_data.freq_bins[calibration_data.freq_bins <= max_freq] - psd = calibration_data.get_psd('all')[calibration_data.freq_bins <= max_freq] - peaks, _ = detect_peaks(psd, freqs) - return SignalData(freqs=freqs, psd=psd, peaks=peaks, paired_peaks=None, unpaired_peaks=None) - - -###################################################################### -# Startup and main routines -###################################################################### - -def parse_log(logname): - with open(logname) as f: - for header in f: - if not header.startswith('#'): - break - if not header.startswith('freq,psd_x,psd_y,psd_z,psd_xyz'): - # Raw accelerometer data - return np.loadtxt(logname, comments='#', delimiter=',') - # Power spectral density data or shaper calibration data - raise ValueError("File %s does not contain raw accelerometer data and therefore " - "is not supported by this script. Please use the official Klipper " - "graph_accelerometer.py script to process it instead." % (logname,)) - - -def setup_klipper_import(kdir): - global shaper_calibrate - kdir = os.path.expanduser(kdir) - sys.path.append(os.path.join(kdir, 'klippy')) - shaper_calibrate = importlib.import_module('.shaper_calibrate', 'extras') - - -def belts_calibration(lognames, klipperdir="~/klipper", max_freq=200.): - setup_klipper_import(klipperdir) - - # Parse data - datas = [parse_log(fn) for fn in lognames] - if len(datas) > 2: - raise ValueError("Incorrect number of .csv files used (this function needs two files to compare them)") - - # Compute calibration data for the two datasets with automatic peaks detection - signal1 = compute_signal_data(datas[0], max_freq) - signal2 = compute_signal_data(datas[1], max_freq) - - # Pair the peaks across the two datasets - paired_peaks, unpaired_peaks1, unpaired_peaks2 = pair_peaks(signal1.peaks, signal1.freqs, signal1.psd, - signal2.peaks, signal2.freqs, signal2.psd) - signal1 = signal1._replace(paired_peaks=paired_peaks, unpaired_peaks=unpaired_peaks1) - signal2 = signal2._replace(paired_peaks=paired_peaks, unpaired_peaks=unpaired_peaks2) - - fig = matplotlib.pyplot.figure() - gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[4, 3]) - ax1 = fig.add_subplot(gs[0]) - ax2 = fig.add_subplot(gs[1]) - - # Add title - title_line1 = "RELATIVE BELT CALIBRATION TOOL" - fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold') - try: - filename = lognames[0].split('/')[-1] - dt = datetime.strptime(f"{filename.split('_')[1]} {filename.split('_')[2]}", "%Y%m%d %H%M%S") - title_line2 = dt.strftime('%x %X') - except: - print("Warning: CSV filenames look to be different than expected (%s , %s)" % (lognames[0], lognames[1])) - title_line2 = lognames[0].split('/')[-1] + " / " + lognames[1].split('/')[-1] - fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple']) - - # Plot the graphs - similarity_factor, _ = plot_compare_frequency(ax1, lognames, signal1, signal2, max_freq) - plot_difference_spectrogram(ax2, datas[0], datas[1], signal1, signal2, similarity_factor, max_freq) - - fig.set_size_inches(8.3, 11.6) - fig.tight_layout() - fig.subplots_adjust(top=0.89) - - # Adding a small Klippain logo to the top left corner of the figure - ax_logo = fig.add_axes([0.001, 0.899, 0.1, 0.1], anchor='NW', zorder=-1) - ax_logo.imshow(matplotlib.pyplot.imread(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'klippain.png'))) - ax_logo.axis('off') - - return fig - - -def main(): - # Parse command-line arguments - usage = "%prog [options] " - opts = optparse.OptionParser(usage) - opts.add_option("-o", "--output", type="string", dest="output", - default=None, help="filename of output graph") - opts.add_option("-f", "--max_freq", type="float", default=200., - help="maximum frequency to graph") - opts.add_option("-k", "--klipper_dir", type="string", dest="klipperdir", - default="~/klipper", help="main klipper directory") - options, args = opts.parse_args() - if len(args) < 1: - opts.error("Incorrect number of arguments") - if options.output is None: - opts.error("You must specify an output file.png to use the script (option -o)") - - fig = belts_calibration(args, options.klipperdir, options.max_freq) - fig.savefig(options.output) - - -if __name__ == '__main__': - main() diff --git a/scripts/is_workflow/graph_shaper.py b/scripts/is_workflow/graph_shaper.py deleted file mode 100755 index fdada5fa3..000000000 --- a/scripts/is_workflow/graph_shaper.py +++ /dev/null @@ -1,395 +0,0 @@ -#!/usr/bin/env python3 - -################################################# -######## INPUT SHAPER CALIBRATION SCRIPT ######## -################################################# -# Derived from the calibrate_shaper.py official Klipper script -# Copyright (C) 2020 Dmitry Butyugin -# Copyright (C) 2020 Kevin O'Connor -# -# Written by Frix_x#0161 # -# @version: 2.0 - -# CHANGELOG: -# v2.0: updated the script to align it to the new K-Shake&Tune module -# v1.1: - improved the damping ratio computation with linear approximation for more precision -# - reworked the top graph to add more information to it with colored zones, -# automated peak detection, etc... -# - added a full spectrogram of the signal on the bottom to allow deeper analysis -# v1.0: first version of this script inspired from the official Klipper -# shaper calibration script to add an automatic damping ratio estimation to it - - -# Be sure to make this script executable using SSH: type 'chmod +x ./graph_shaper.py' when in the folder! - -##################################################################### -################ !!! DO NOT EDIT BELOW THIS LINE !!! ################ -##################################################################### - -import optparse, matplotlib, sys, importlib, os, math -from textwrap import wrap -import numpy as np -import matplotlib.pyplot, matplotlib.dates, matplotlib.font_manager -import matplotlib.ticker, matplotlib.gridspec -import locale -from datetime import datetime - -matplotlib.use('Agg') - - -PEAKS_DETECTION_THRESHOLD = 0.05 -PEAKS_EFFECT_THRESHOLD = 0.12 -SPECTROGRAM_LOW_PERCENTILE_FILTER = 5 -MAX_SMOOTHING = 0.1 - -KLIPPAIN_COLORS = { - "purple": "#70088C", - "dark_purple": "#150140", - "dark_orange": "#F24130" -} - - -# Set the best locale for time and date formating (generation of the titles) -try: - locale.setlocale(locale.LC_TIME, locale.getdefaultlocale()) -except locale.Error: - locale.setlocale(locale.LC_TIME, 'C') - -# Override the built-in print function to avoid problem in Klipper due to locale settings -original_print = print -def print_with_c_locale(*args, **kwargs): - original_locale = locale.setlocale(locale.LC_ALL, None) - locale.setlocale(locale.LC_ALL, 'C') - original_print(*args, **kwargs) - locale.setlocale(locale.LC_ALL, original_locale) -print = print_with_c_locale - - -###################################################################### -# Computation -###################################################################### - -# Find the best shaper parameters using Klipper's official algorithm selection -def calibrate_shaper_with_damping(datas, max_smoothing): - helper = shaper_calibrate.ShaperCalibrate(printer=None) - - calibration_data = helper.process_accelerometer_data(datas[0]) - for data in datas[1:]: - calibration_data.add_data(helper.process_accelerometer_data(data)) - - calibration_data.normalize_to_frequencies() - - shaper, all_shapers = helper.find_best_shaper(calibration_data, max_smoothing, print) - - freqs = calibration_data.freq_bins - psd = calibration_data.psd_sum - fr, zeta = compute_damping_ratio(psd, freqs) - - print("Recommended shaper is %s @ %.1f Hz" % (shaper.name, shaper.freq)) - print("Axis has a main resonant frequency at %.1fHz with an estimated damping ratio of %.3f" % (fr, zeta)) - - return shaper.name, all_shapers, calibration_data, fr, zeta - - -# Compute damping ratio by using the half power bandwidth method with interpolated frequencies -def compute_damping_ratio(psd, freqs): - max_power_index = np.argmax(psd) - fr = freqs[max_power_index] - max_power = psd[max_power_index] - - half_power = max_power / math.sqrt(2) - idx_below = np.where(psd[:max_power_index] <= half_power)[0][-1] - idx_above = np.where(psd[max_power_index:] <= half_power)[0][0] + max_power_index - freq_below_half_power = freqs[idx_below] + (half_power - psd[idx_below]) * (freqs[idx_below + 1] - freqs[idx_below]) / (psd[idx_below + 1] - psd[idx_below]) - freq_above_half_power = freqs[idx_above - 1] + (half_power - psd[idx_above - 1]) * (freqs[idx_above] - freqs[idx_above - 1]) / (psd[idx_above] - psd[idx_above - 1]) - - bandwidth = freq_above_half_power - freq_below_half_power - zeta = bandwidth / (2 * fr) - - return fr, zeta - - -def compute_spectrogram(data): - N = data.shape[0] - Fs = N / (data[-1,0] - data[0,0]) - # Round up to a power of 2 for faster FFT - M = 1 << int(.5 * Fs - 1).bit_length() - window = np.kaiser(M, 6.) - def _specgram(x): - return matplotlib.mlab.specgram( - x, Fs=Fs, NFFT=M, noverlap=M//2, window=window, - mode='psd', detrend='mean', scale_by_freq=False) - - d = {'x': data[:,1], 'y': data[:,2], 'z': data[:,3]} - pdata, bins, t = _specgram(d['x']) - for ax in 'yz': - pdata += _specgram(d[ax])[0] - return pdata, bins, t - - -# This find all the peaks in a curve by looking at when the derivative term goes from positive to negative -# Then only the peaks found above a threshold are kept to avoid capturing peaks in the low amplitude noise of a signal -# An added "virtual" threshold allow me to quantify in an opiniated way the peaks that "could have" effect on the printer -# behavior and are likely known to produce or contribute to the ringing/ghosting in printed parts -def detect_peaks(psd, freqs, window_size=5, vicinity=3): - # Smooth the curve using a moving average to avoid catching peaks everywhere in noisy signals - kernel = np.ones(window_size) / window_size - smoothed_psd = np.convolve(psd, kernel, mode='valid') - mean_pad = [np.mean(psd[:window_size])] * (window_size // 2) - smoothed_psd = np.concatenate((mean_pad, smoothed_psd)) - - # Find peaks on the smoothed curve - smoothed_peaks = np.where((smoothed_psd[:-2] < smoothed_psd[1:-1]) & (smoothed_psd[1:-1] > smoothed_psd[2:]))[0] + 1 - detection_threshold = PEAKS_DETECTION_THRESHOLD * psd.max() - effect_threshold = PEAKS_EFFECT_THRESHOLD * psd.max() - smoothed_peaks = smoothed_peaks[smoothed_psd[smoothed_peaks] > detection_threshold] - - # Refine peak positions on the original curve - refined_peaks = [] - for peak in smoothed_peaks: - local_max = peak + np.argmax(psd[max(0, peak-vicinity):min(len(psd), peak+vicinity+1)]) - vicinity - refined_peaks.append(local_max) - - peak_freqs = ["{:.1f}".format(f) for f in freqs[refined_peaks]] - - num_peaks = len(refined_peaks) - num_peaks_above_effect_threshold = np.sum(psd[refined_peaks] > effect_threshold) - - print("Peaks detected on the graph: %d @ %s Hz (%d above effect threshold)" % (num_peaks, ", ".join(map(str, peak_freqs)), num_peaks_above_effect_threshold)) - - return np.array(refined_peaks), num_peaks, num_peaks_above_effect_threshold - - -###################################################################### -# Graphing -###################################################################### - -def plot_freq_response_with_damping(ax, calibration_data, shapers, performance_shaper, fr, zeta, max_freq): - freqs = calibration_data.freq_bins - psd = calibration_data.psd_sum[freqs <= max_freq] - px = calibration_data.psd_x[freqs <= max_freq] - py = calibration_data.psd_y[freqs <= max_freq] - pz = calibration_data.psd_z[freqs <= max_freq] - freqs = freqs[freqs <= max_freq] - - fontP = matplotlib.font_manager.FontProperties() - fontP.set_size('x-small') - - ax.set_xlabel('Frequency (Hz)') - ax.set_xlim([0, max_freq]) - ax.set_ylabel('Power spectral density') - ax.set_ylim([0, psd.max() + psd.max() * 0.05]) - - ax.plot(freqs, psd, label='X+Y+Z', color='purple') - ax.plot(freqs, px, label='X', color='red') - ax.plot(freqs, py, label='Y', color='green') - ax.plot(freqs, pz, label='Z', color='blue') - - ax.xaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(5)) - ax.yaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) - ax.ticklabel_format(axis='y', style='scientific', scilimits=(0,0)) - ax.grid(which='major', color='grey') - ax.grid(which='minor', color='lightgrey') - - ax2 = ax.twinx() - ax2.yaxis.set_visible(False) - - lowvib_shaper_vibrs = float('inf') - lowvib_shaper = None - lowvib_shaper_freq = None - lowvib_shaper_accel = 0 - - # Draw the shappers curves and add their specific parameters in the legend - # This adds also a way to find the best shaper with a low level of vibrations (with a resonable level of smoothing) - for shaper in shapers: - shaper_max_accel = round(shaper.max_accel / 100.) * 100. - label = "%s (%.1f Hz, vibr=%.1f%%, sm~=%.2f, accel<=%.f)" % ( - shaper.name.upper(), shaper.freq, - shaper.vibrs * 100., shaper.smoothing, - shaper_max_accel) - ax2.plot(freqs, shaper.vals, label=label, linestyle='dotted') - - # Get the performance shaper - if shaper.name == performance_shaper: - performance_shaper_freq = shaper.freq - performance_shaper_vibr = shaper.vibrs * 100. - performance_shaper_vals = shaper.vals - - # Get the low vibration shaper - if (shaper.vibrs * 100 < lowvib_shaper_vibrs or (shaper.vibrs * 100 == lowvib_shaper_vibrs and shaper_max_accel > lowvib_shaper_accel)) and shaper.smoothing < MAX_SMOOTHING: - lowvib_shaper_accel = shaper_max_accel - lowvib_shaper = shaper.name - lowvib_shaper_freq = shaper.freq - lowvib_shaper_vibrs = shaper.vibrs * 100 - lowvib_shaper_vals = shaper.vals - - # User recommendations are added to the legend: one is Klipper's original suggestion that is usually good for performances - # and the other one is the custom "low vibration" recommendation that looks for a suitable shaper that doesn't have excessive - # smoothing and that have a lower vibration level. If both recommendation are the same shaper, or if no suitable "low - # vibration" shaper is found, then only a single line as the "best shaper" recommendation is added to the legend - if lowvib_shaper != None and lowvib_shaper != performance_shaper and lowvib_shaper_vibrs <= performance_shaper_vibr: - ax2.plot([], [], ' ', label="Recommended performance shaper: %s @ %.1f Hz" % (performance_shaper.upper(), performance_shaper_freq)) - ax.plot(freqs, psd * performance_shaper_vals, label='With %s applied' % (performance_shaper.upper()), color='cyan') - ax2.plot([], [], ' ', label="Recommended low vibrations shaper: %s @ %.1f Hz" % (lowvib_shaper.upper(), lowvib_shaper_freq)) - ax.plot(freqs, psd * lowvib_shaper_vals, label='With %s applied' % (lowvib_shaper.upper()), color='lime') - else: - ax2.plot([], [], ' ', label="Recommended best shaper: %s @ %.1f Hz" % (performance_shaper.upper(), performance_shaper_freq)) - ax.plot(freqs, psd * performance_shaper_vals, label='With %s applied' % (performance_shaper.upper()), color='cyan') - - # And the estimated damping ratio is finally added at the end of the legend - ax2.plot([], [], ' ', label="Estimated damping ratio (ζ): %.3f" % (zeta)) - - # Draw the detected peaks and name them - # This also draw the detection threshold and warning threshold (aka "effect zone") - peaks, _, _ = detect_peaks(psd, freqs) - peaks_warning_threshold = PEAKS_DETECTION_THRESHOLD * psd.max() - peaks_effect_threshold = PEAKS_EFFECT_THRESHOLD * psd.max() - - ax.plot(freqs[peaks], psd[peaks], "x", color='black', markersize=8) - for idx, peak in enumerate(peaks): - if psd[peak] > peaks_effect_threshold: - fontcolor = 'red' - fontweight = 'bold' - else: - fontcolor = 'black' - fontweight = 'normal' - ax.annotate(f"{idx+1}", (freqs[peak], psd[peak]), - textcoords="offset points", xytext=(8, 5), - ha='left', fontsize=13, color=fontcolor, weight=fontweight) - ax.axhline(y=peaks_warning_threshold, color='black', linestyle='--', linewidth=0.5) - ax.axhline(y=peaks_effect_threshold, color='black', linestyle='--', linewidth=0.5) - ax.fill_between(freqs, 0, peaks_warning_threshold, color='green', alpha=0.15, label='Relax Region') - ax.fill_between(freqs, peaks_warning_threshold, peaks_effect_threshold, color='orange', alpha=0.2, label='Warning Region') - - - # Add the main resonant frequency and damping ratio of the axis to the graph title - ax.set_title("Axis Frequency Profile (ω0=%.1fHz, ζ=%.3f)" % (fr, zeta), fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold') - ax.legend(loc='upper left', prop=fontP) - ax2.legend(loc='upper right', prop=fontP) - - return freqs[peaks] - - -# Plot a time-frequency spectrogram to see how the system respond over time during the -# resonnance test. This can highlight hidden spots from the standard PSD graph from other harmonics -def plot_spectrogram(ax, data, peaks, max_freq): - pdata, bins, t = compute_spectrogram(data) - - # We need to normalize the data to get a proper signal on the spectrogram - # However, while using "LogNorm" provide too much background noise, using - # "Normalize" make only the resonnance appearing and hide interesting elements - # So we need to filter out the lower part of the data (ie. find the proper vmin for LogNorm) - vmin_value = np.percentile(pdata, SPECTROGRAM_LOW_PERCENTILE_FILTER) - - ax.set_title("Time-Frequency Spectrogram", fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold') - ax.pcolormesh(bins, t, pdata.T, norm=matplotlib.colors.LogNorm(vmin=vmin_value), - cmap='inferno', shading='gouraud') - - # Add peaks lines in the spectrogram to get hint from peaks found in the first graph - if peaks is not None: - for idx, peak in enumerate(peaks): - ax.axvline(peak, color='cyan', linestyle='dotted', linewidth=0.75) - ax.annotate(f"Peak {idx+1}", (peak, t[-1]*0.9), - textcoords="data", color='cyan', rotation=90, fontsize=10, - verticalalignment='top', horizontalalignment='right') - - ax.set_xlim([0., max_freq]) - ax.set_ylabel('Time (s)') - ax.set_xlabel('Frequency (Hz)') - - return - - -###################################################################### -# Startup and main routines -###################################################################### - -def parse_log(logname): - with open(logname) as f: - for header in f: - if not header.startswith('#'): - break - if not header.startswith('freq,psd_x,psd_y,psd_z,psd_xyz'): - # Raw accelerometer data - return np.loadtxt(logname, comments='#', delimiter=',') - # Power spectral density data or shaper calibration data - raise ValueError("File %s does not contain raw accelerometer data and therefore " - "is not supported by this script. Please use the official Klipper " - "calibrate_shaper.py script to process it instead." % (logname,)) - - -def setup_klipper_import(kdir): - global shaper_calibrate - kdir = os.path.expanduser(kdir) - sys.path.append(os.path.join(kdir, 'klippy')) - shaper_calibrate = importlib.import_module('.shaper_calibrate', 'extras') - - -def shaper_calibration(lognames, klipperdir="~/klipper", max_smoothing=None, max_freq=200.): - setup_klipper_import(klipperdir) - - # Parse data - datas = [parse_log(fn) for fn in lognames] - - # Calibrate shaper and generate outputs - performance_shaper, shapers, calibration_data, fr, zeta = calibrate_shaper_with_damping(datas, max_smoothing) - - fig = matplotlib.pyplot.figure() - gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[4, 3]) - ax1 = fig.add_subplot(gs[0]) - ax2 = fig.add_subplot(gs[1]) - - # Add title - title_line1 = "INPUT SHAPER CALIBRATION TOOL" - fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold') - try: - filename_parts = (lognames[0].split('/')[-1]).split('_') - dt = datetime.strptime(f"{filename_parts[1]} {filename_parts[2]}", "%Y%m%d %H%M%S") - title_line2 = dt.strftime('%x %X') + ' -- ' + filename_parts[3].upper().split('.')[0] + ' axis' - except: - print("Warning: CSV filename look to be different than expected (%s)" % (lognames[0])) - title_line2 = lognames[0].split('/')[-1] - fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple']) - - # Plot the graphs - peaks = plot_freq_response_with_damping(ax1, calibration_data, shapers, performance_shaper, fr, zeta, max_freq) - plot_spectrogram(ax2, datas[0], peaks, max_freq) - - fig.set_size_inches(8.3, 11.6) - fig.tight_layout() - fig.subplots_adjust(top=0.89) - - # Adding a small Klippain logo to the top left corner of the figure - ax_logo = fig.add_axes([0.001, 0.899, 0.1, 0.1], anchor='NW', zorder=-1) - ax_logo.imshow(matplotlib.pyplot.imread(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'klippain.png'))) - ax_logo.axis('off') - - return fig - - -def main(): - # Parse command-line arguments - usage = "%prog [options] " - opts = optparse.OptionParser(usage) - opts.add_option("-o", "--output", type="string", dest="output", - default=None, help="filename of output graph") - opts.add_option("-f", "--max_freq", type="float", default=200., - help="maximum frequency to graph") - opts.add_option("-s", "--max_smoothing", type="float", default=None, - help="maximum shaper smoothing to allow") - opts.add_option("-k", "--klipper_dir", type="string", dest="klipperdir", - default="~/klipper", help="main klipper directory") - options, args = opts.parse_args() - if len(args) < 1: - opts.error("Incorrect number of arguments") - if options.output is None: - opts.error("You must specify an output file.png to use the script (option -o)") - if options.max_smoothing is not None and options.max_smoothing < 0.05: - opts.error("Too small max_smoothing specified (must be at least 0.05)") - - fig = shaper_calibration(args, options.klipperdir, options.max_smoothing, options.max_freq) - fig.savefig(options.output) - - -if __name__ == '__main__': - main() diff --git a/scripts/is_workflow/graph_vibrations.py b/scripts/is_workflow/graph_vibrations.py deleted file mode 100755 index 0ba6a632c..000000000 --- a/scripts/is_workflow/graph_vibrations.py +++ /dev/null @@ -1,439 +0,0 @@ -#!/usr/bin/env python3 - -################################################## -###### SPEED AND VIBRATIONS PLOTTING SCRIPT ###### -################################################## -# Written by Frix_x#0161 # -# @version: 2.0 - -# CHANGELOG: -# v2.0: - updated the script to align it to the new K-Shake&Tune module -# - new features for peaks detection and advised speed zones -# v1.2: fixed a bug that could happen when username is not "pi" (thanks @spikeygg) -# v1.1: better graph formatting -# v1.0: first version of the script - - -# Be sure to make this script executable using SSH: type 'chmod +x ./graph_vibrations.py' when in the folder ! - -##################################################################### -################ !!! DO NOT EDIT BELOW THIS LINE !!! ################ -##################################################################### - -import optparse, matplotlib, re, sys, importlib, os, operator -from collections import OrderedDict -import numpy as np -import matplotlib.pyplot, matplotlib.dates, matplotlib.font_manager -import matplotlib.ticker, matplotlib.gridspec -import locale -from datetime import datetime - -matplotlib.use('Agg') - - -PEAKS_DETECTION_THRESHOLD = 0.05 -PEAKS_RELATIVE_HEIGHT_THRESHOLD = 0.04 -VALLEY_DETECTION_THRESHOLD = 0.1 # Lower is more sensitive - -KLIPPAIN_COLORS = { - "purple": "#70088C", - "dark_purple": "#150140", - "dark_orange": "#F24130" -} - - -# Set the best locale for time and date formating (generation of the titles) -try: - locale.setlocale(locale.LC_TIME, locale.getdefaultlocale()) -except locale.Error: - locale.setlocale(locale.LC_TIME, 'C') - -# Override the built-in print function to avoid problem in Klipper due to locale settings -original_print = print -def print_with_c_locale(*args, **kwargs): - original_locale = locale.setlocale(locale.LC_ALL, None) - locale.setlocale(locale.LC_ALL, 'C') - original_print(*args, **kwargs) - locale.setlocale(locale.LC_ALL, original_locale) -print = print_with_c_locale - - -###################################################################### -# Computation -###################################################################### - -def calc_freq_response(data): - # Use Klipper standard input shaper objects to do the computation - helper = shaper_calibrate.ShaperCalibrate(printer=None) - return helper.process_accelerometer_data(data) - - -def calc_psd(datas, group, max_freq): - psd_list = [] - first_freqs = None - signal_axes = ['x', 'y', 'z', 'all'] - - for i in range(0, len(datas), group): - - # Round up to the nearest power of 2 for faster FFT - N = datas[i].shape[0] - T = datas[i][-1,0] - datas[i][0,0] - M = 1 << int((N/T) * 0.5 - 1).bit_length() - if N <= M: - # If there is not enough lines in the array to be able to round up to the - # nearest power of 2, we need to pad some zeros at the end of the array to - # avoid entering a blocking state from Klipper shaper_calibrate.py - datas[i] = np.pad(datas[i], [(0, (M-N)+1), (0, 0)], mode='constant', constant_values=0) - - freqrsp = calc_freq_response(datas[i]) - for n in range(group - 1): - data = datas[i + n + 1] - - # Round up to the nearest power of 2 for faster FFT - N = data.shape[0] - T = data[-1,0] - data[0,0] - M = 1 << int((N/T) * 0.5 - 1).bit_length() - if N <= M: - # If there is not enough lines in the array to be able to round up to the - # nearest power of 2, we need to pad some zeros at the end of the array to - # avoid entering a blocking state from Klipper shaper_calibrate.py - data = np.pad(data, [(0, (M-N)+1), (0, 0)], mode='constant', constant_values=0) - - freqrsp.add_data(calc_freq_response(data)) - - if not psd_list: - # First group, just put it in the result list - first_freqs = freqrsp.freq_bins - psd = freqrsp.psd_sum[first_freqs <= max_freq] - px = freqrsp.psd_x[first_freqs <= max_freq] - py = freqrsp.psd_y[first_freqs <= max_freq] - pz = freqrsp.psd_z[first_freqs <= max_freq] - psd_list.append([psd, px, py, pz]) - else: - # Not the first group, we need to interpolate every new signals - # to the first one to equalize the frequency_bins between them - signal_normalized = dict() - freqs = freqrsp.freq_bins - for axe in signal_axes: - signal = freqrsp.get_psd(axe) - signal_normalized[axe] = np.interp(first_freqs, freqs, signal) - - # Remove data above max_freq on all axes and add to the result list - psd = signal_normalized['all'][first_freqs <= max_freq] - px = signal_normalized['x'][first_freqs <= max_freq] - py = signal_normalized['y'][first_freqs <= max_freq] - pz = signal_normalized['z'][first_freqs <= max_freq] - psd_list.append([psd, px, py, pz]) - - return first_freqs[first_freqs <= max_freq], psd_list - - -def calc_powertot(psd_list, freqs): - pwrtot_sum = [] - pwrtot_x = [] - pwrtot_y = [] - pwrtot_z = [] - - for psd in psd_list: - pwrtot_sum.append(np.trapz(psd[0], freqs)) - pwrtot_x.append(np.trapz(psd[1], freqs)) - pwrtot_y.append(np.trapz(psd[2], freqs)) - pwrtot_z.append(np.trapz(psd[3], freqs)) - - return [pwrtot_sum, pwrtot_x, pwrtot_y, pwrtot_z] - - -# This find all the peaks in a curve by looking at when the derivative term goes from positive to negative -# Then only the peaks found above a threshold are kept to avoid capturing peaks in the low amplitude noise of a signal -# Additionaly, we validate that a peak is a real peak based of its neighbors as we can have pretty flat zones in vibration -# graphs with a lot of false positive due to small "noise" in these flat zones -def detect_peaks(power_total, speeds, window_size=10, vicinity=10): - # Smooth the curve using a moving average to avoid catching peaks everywhere in noisy signals - kernel = np.ones(window_size) / window_size - smoothed_psd = np.convolve(power_total, kernel, mode='valid') - mean_pad = [np.mean(power_total[:window_size])] * (window_size // 2) - smoothed_psd = np.concatenate((mean_pad, smoothed_psd)) - - # Find peaks on the smoothed curve (and excluding the last value of the serie often detected when in a flat zone) - smoothed_peaks = np.where((smoothed_psd[:-3] < smoothed_psd[1:-2]) & (smoothed_psd[1:-2] > smoothed_psd[2:-1]))[0] + 1 - detection_threshold = PEAKS_DETECTION_THRESHOLD * power_total.max() - - valid_peaks = [] - for peak in smoothed_peaks: - peak_height = smoothed_psd[peak] - np.min(smoothed_psd[max(0, peak-vicinity):min(len(smoothed_psd), peak+vicinity+1)]) - if peak_height > PEAKS_RELATIVE_HEIGHT_THRESHOLD * smoothed_psd[peak] and smoothed_psd[peak] > detection_threshold: - valid_peaks.append(peak) - - # Refine peak positions on the original curve - refined_peaks = [] - for peak in valid_peaks: - local_max = peak + np.argmax(power_total[max(0, peak-vicinity):min(len(power_total), peak+vicinity+1)]) - vicinity - refined_peaks.append(local_max) - - peak_speeds = ["{:.1f}".format(speeds[i]) for i in refined_peaks] - num_peaks = len(refined_peaks) - print("Vibrations peaks detected: %d @ %s mm/s (avoid running these speeds in your slicer profile)" % (num_peaks, ", ".join(map(str, peak_speeds)))) - - return np.array(refined_peaks), num_peaks - - -# The goal is to find zone outside of peaks (flat low energy zones) to advise them as good speeds range to use in the slicer -def identify_low_energy_zones(power_total): - valleys = [] - - # Calculate the mean and standard deviation of the entire power_total - mean_energy = np.mean(power_total) - std_energy = np.std(power_total) - - # Define a threshold value as mean minus a certain number of standard deviations - threshold_value = mean_energy - VALLEY_DETECTION_THRESHOLD * std_energy - - # Find valleys in power_total based on the threshold - in_valley = False - start_idx = 0 - for i, value in enumerate(power_total): - if not in_valley and value < threshold_value: - in_valley = True - start_idx = i - elif in_valley and value >= threshold_value: - in_valley = False - valleys.append((start_idx, i)) - - # If the last point is still in a valley, close the valley - if in_valley: - valleys.append((start_idx, len(power_total) - 1)) - - max_signal = np.max(power_total) - - # Calculate mean energy for each valley as a percentage of the maximum of the signal - valley_means_percentage = [] - for start, end in valleys: - if not np.isnan(np.mean(power_total[start:end])): - valley_means_percentage.append((start, end, (np.mean(power_total[start:end]) / max_signal) * 100)) - - # Sort valleys based on mean percentage values - sorted_valleys = sorted(valley_means_percentage, key=lambda x: x[2]) - - return sorted_valleys - - -# Resample the signal to achieve denser data points in order to get more precise valley placing and -# avoid having to use the original sampling of the signal (that is equal to the speed increment used for the test) -def resample_signal(speeds, power_total, new_spacing=0.1): - new_speeds = np.arange(speeds[0], speeds[-1] + new_spacing, new_spacing) - new_power_total = np.interp(new_speeds, speeds, power_total) - return new_speeds, new_power_total - - -###################################################################### -# Graphing -###################################################################### - -def plot_total_power(ax, speeds, power_total): - resampled_speeds, resampled_power_total = resample_signal(speeds, power_total[0]) - - ax.set_title("Vibrations decomposition", fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold') - ax.set_xlabel('Speed (mm/s)') - ax.set_ylabel('Energy') - - ax2 = ax.twinx() - ax2.yaxis.set_visible(False) - - power_total_sum = np.array(resampled_power_total) - speed_array = np.array(resampled_speeds) - max_y = power_total_sum.max() + power_total_sum.max() * 0.05 - ax.set_xlim([speed_array.min(), speed_array.max()]) - ax.set_ylim([0, max_y]) - ax2.set_ylim([0, max_y]) - - ax.plot(resampled_speeds, resampled_power_total, label="X+Y+Z", color='purple') - ax.plot(speeds, power_total[1], label="X", color='red') - ax.plot(speeds, power_total[2], label="Y", color='green') - ax.plot(speeds, power_total[3], label="Z", color='blue') - - peaks, num_peaks = detect_peaks(resampled_power_total, resampled_speeds) - low_energy_zones = identify_low_energy_zones(resampled_power_total) - - if peaks.size: - ax.plot(speed_array[peaks], power_total_sum[peaks], "x", color='black', markersize=8) - for idx, peak in enumerate(peaks): - fontcolor = 'red' - fontweight = 'bold' - ax.annotate(f"{idx+1}", (speed_array[peak], power_total_sum[peak]), - textcoords="offset points", xytext=(8, 5), - ha='left', fontsize=13, color=fontcolor, weight=fontweight) - ax2.plot([], [], ' ', label=f'Number of peaks: {num_peaks}') - else: - ax2.plot([], [], ' ', label=f'No peaks detected') - - for idx, (start, end, energy) in enumerate(low_energy_zones): - ax.axvline(speed_array[start], color='red', linestyle='dotted', linewidth=1.5) - ax.axvline(speed_array[end], color='red', linestyle='dotted', linewidth=1.5) - ax2.fill_between(speed_array[start:end], 0, power_total_sum[start:end], color='green', alpha=0.2, label=f'Zone {idx+1}: {speed_array[start]:.1f} to {speed_array[end]:.1f} mm/s (mean energy: {energy:.2f}%)') - - ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) - ax.yaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator()) - ax.grid(which='major', color='grey') - ax.grid(which='minor', color='lightgrey') - fontP = matplotlib.font_manager.FontProperties() - fontP.set_size('small') - ax.legend(loc='upper left', prop=fontP) - ax2.legend(loc='upper right', prop=fontP) - - if peaks.size: - return speed_array[peaks] - else: - return None - - -def plot_spectrogram(ax, speeds, freqs, power_spectral_densities, peaks, max_freq): - spectrum = np.empty([len(freqs), len(speeds)]) - - for i in range(len(speeds)): - for j in range(len(freqs)): - spectrum[j, i] = power_spectral_densities[i][0][j] - - ax.set_title("Vibrations spectrogram", fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold') - ax.pcolormesh(speeds, freqs, spectrum, norm=matplotlib.colors.LogNorm(), - cmap='inferno', shading='gouraud') - - # Add peaks lines in the spectrogram to get hint from peaks found in the first graph - if peaks is not None: - for idx, peak in enumerate(peaks): - ax.axvline(peak, color='cyan', linestyle='dotted', linewidth=0.75) - ax.annotate(f"Peak {idx+1}", (peak, freqs[-1]*0.9), - textcoords="data", color='cyan', rotation=90, fontsize=10, - verticalalignment='top', horizontalalignment='right') - - ax.set_ylim([0., max_freq]) - ax.set_ylabel('Frequency (hz)') - ax.set_xlabel('Speed (mm/s)') - - return - - -###################################################################### -# Startup and main routines -###################################################################### - -def parse_log(logname): - with open(logname) as f: - for header in f: - if not header.startswith('#'): - break - if not header.startswith('freq,psd_x,psd_y,psd_z,psd_xyz'): - # Raw accelerometer data - return np.loadtxt(logname, comments='#', delimiter=',') - # Power spectral density data or shaper calibration data - raise ValueError("File %s does not contain raw accelerometer data and therefore " - "is not supported by graph_vibrations.py script. Please use " - "calibrate_shaper.py script to process it instead." % (logname,)) - - -def extract_speed(logname): - try: - speed = re.search('sp(.+?)n', os.path.basename(logname)).group(1).replace('_','.') - except AttributeError: - raise ValueError("File %s does not contain speed in its name and therefore " - "is not supported by graph_vibrations.py script." % (logname,)) - return float(speed) - - -def sort_and_slice(raw_speeds, raw_datas, remove): - # Sort to get the speeds and their datas aligned and in ascending order - raw_speeds, raw_datas = zip(*sorted(zip(raw_speeds, raw_datas), key=operator.itemgetter(0))) - - # Remove beginning and end of the datas for each file to get only - # constant speed data and remove the start/stop phase of the movements - datas = [] - for data in raw_datas: - sliced = round((len(data) * remove / 100) / 2) - datas.append(data[sliced:len(data)-sliced]) - - return raw_speeds, datas - - -def setup_klipper_import(kdir): - global shaper_calibrate - kdir = os.path.expanduser(kdir) - sys.path.append(os.path.join(kdir, 'klippy')) - shaper_calibrate = importlib.import_module('.shaper_calibrate', 'extras') - - -def vibrations_calibration(lognames, klipperdir="~/klipper", axisname=None, max_freq=1000., remove=0): - setup_klipper_import(klipperdir) - - # Parse the raw data and get them ready for analysis - raw_datas = [parse_log(filename) for filename in lognames] - raw_speeds = [extract_speed(filename) for filename in lognames] - speeds, datas = sort_and_slice(raw_speeds, raw_datas, remove) - - # As we assume that we have the same number of file for each speeds. We can group - # the PSD results by this number (to combine vibrations at given speed on all movements) - group_by = speeds.count(speeds[0]) - # Compute psd and total power of the signal - freqs, power_spectral_densities = calc_psd(datas, group_by, max_freq) - power_total = calc_powertot(power_spectral_densities, freqs) - - fig = matplotlib.pyplot.figure() - gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[4, 3]) - ax1 = fig.add_subplot(gs[0]) - ax2 = fig.add_subplot(gs[1]) - - title_line1 = "VIBRATIONS MEASUREMENT TOOL" - fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold') - try: - filename_parts = (lognames[0].split('/')[-1]).split('_') - dt = datetime.strptime(f"{filename_parts[1]} {filename_parts[2].split('-')[0]}", "%Y%m%d %H%M%S") - title_line2 = dt.strftime('%x %X') + ' -- ' + axisname.upper() + ' axis' - except: - print("Warning: CSV filename look to be different than expected (%s)" % (lognames[0])) - title_line2 = lognames[0].split('/')[-1] - fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple']) - - # Remove speeds duplicates and graph the processed datas - speeds = list(OrderedDict((x, True) for x in speeds).keys()) - - peaks = plot_total_power(ax1, speeds, power_total) - plot_spectrogram(ax2, speeds, freqs, power_spectral_densities, peaks, max_freq) - - fig.set_size_inches(8.3, 11.6) - fig.tight_layout() - fig.subplots_adjust(top=0.89) - - # Adding a small Klippain logo to the top left corner of the figure - ax_logo = fig.add_axes([0.001, 0.899, 0.1, 0.1], anchor='NW', zorder=-1) - ax_logo.imshow(matplotlib.pyplot.imread(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'klippain.png'))) - ax_logo.axis('off') - - return fig - - -def main(): - # Parse command-line arguments - usage = "%prog [options] " - opts = optparse.OptionParser(usage) - opts.add_option("-o", "--output", type="string", dest="output", - default=None, help="filename of output graph") - opts.add_option("-a", "--axis", type="string", dest="axisname", - default=None, help="axis name to be shown on the side of the graph") - opts.add_option("-f", "--max_freq", type="float", default=1000., - help="maximum frequency to graph") - opts.add_option("-r", "--remove", type="int", default=0, - help="percentage of data removed at start/end of each files") - opts.add_option("-k", "--klipper_dir", type="string", dest="klipperdir", - default="~/klipper", help="main klipper directory") - options, args = opts.parse_args() - if len(args) < 1: - opts.error("No CSV file(s) to analyse") - if options.output is None: - opts.error("You must specify an output file.png to use the script (option -o)") - if options.remove > 50 or options.remove < 0: - opts.error("You must specify a correct percentage (option -r) in the 0-50 range") - - fig = vibrations_calibration(args, options.klipperdir, options.axisname, options.max_freq, options.remove) - fig.savefig(options.output) - - -if __name__ == '__main__': - main() diff --git a/scripts/is_workflow/is_workflow.py b/scripts/is_workflow/is_workflow.py deleted file mode 100755 index be38addb2..000000000 --- a/scripts/is_workflow/is_workflow.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python3 -############################################ -###### INPUT SHAPER KLIPPAIN WORKFLOW ###### -############################################ -# Written by Frix_x#0161 # -# @version: 2.0 - -# CHANGELOG: -# v2.0: new version of this as a Python script (to replace the old bash script) and implement the newer and improved shaper plotting scripts -# v1.7: updated the handling of shaper files to account for the new analysis scripts as we are now using raw data directly -# v1.6: - updated the handling of shaper graph files to be able to optionnaly account for added positions in the filenames and remove them -# - fixed a bug in the belt graph on slow SD card or Pi clones (Klipper was still writing in the file while we were already reading it) -# v1.5: fixed klipper unnexpected fail at the end of the execution, even if graphs were correctly generated (unicode decode error fixed) -# v1.4: added the ~/klipper dir parameter to the call of graph_vibrations.py for a better user handling (in case user is not "pi") -# v1.3: some documentation improvement regarding the line endings that needs to be LF for this file -# v1.2: added the movement name to be transfered to the Python script in vibration calibration (to print it on the result graphs) -# v1.1: multiple fixes and tweaks (mainly to avoid having empty files read by the python scripts after the mv command) -# v1.0: first version of the script based on a Zellneralex script - -# Usage: -# This script was designed to be used with gcode_shell_commands directly from Klipper -# Parameters availables: -# BELTS - To generate belts diagrams after calling the Klipper TEST_RESONANCES AXIS=1,(-)1 OUTPUT=raw_data -# SHAPER - To generate input shaper diagrams after calling the Klipper TEST_RESONANCES AXIS=X/Y OUTPUT=raw_data -# VIBRATIONS - To generate vibration diagram after calling the custom (Frix_x#0161) VIBRATIONS_CALIBRATION macro - - - -import os -import time -import glob -import sys -import shutil -import tarfile -from datetime import datetime - -################################################################################################################# -RESULTS_FOLDER = os.path.expanduser('~/printer_data/config/K-ShakeTune_results') -KLIPPER_FOLDER = os.path.expanduser('~/klipper') -STORE_RESULTS = 3 -################################################################################################################# - -from graph_belts import belts_calibration -from graph_shaper import shaper_calibration -from graph_vibrations import vibrations_calibration - -RESULTS_SUBFOLDERS = ['belts', 'inputshaper', 'vibrations'] - - -def is_file_open(filepath): - for proc in os.listdir('/proc'): - if proc.isdigit(): - for fd in glob.glob(f'/proc/{proc}/fd/*'): - try: - if os.path.samefile(fd, filepath): - return True - except FileNotFoundError: - pass - return False - - -def get_belts_graph(): - current_date = datetime.now().strftime('%Y%m%d_%H%M%S') - lognames = [] - - globbed_files = glob.glob('/tmp/raw_data_axis*.csv') - if not globbed_files: - print("No CSV files found in the /tmp folder to create the belt graphs!") - sys.exit(1) - if len(globbed_files) < 2: - print("Not enough CSV files found in the /tmp folder. Two files are required for the belt graphs!") - sys.exit(1) - sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True) - - for filename in sorted_files[:2]: - # Wait for the file handler to be released by Klipper - while is_file_open(filename): - time.sleep(3) - - # Extract the tested belt from the filename and rename/move the CSV file to the result folder - belt = os.path.basename(filename).split('_')[3].split('.')[0].upper() - new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belt_{current_date}_{belt}.csv') - shutil.move(filename, new_file) - - # Save the file path for later - lognames.append(new_file) - - # Generate the belts graph and its name - fig = belts_calibration(lognames, KLIPPER_FOLDER) - png_filename = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belts_{current_date}.png') - - return fig, png_filename - - -def get_shaper_graph(): - current_date = datetime.now().strftime('%Y%m%d_%H%M%S') - - # Get all the files and sort them based on last modified time to select the most recent one - globbed_files = glob.glob('/tmp/raw_data*.csv') - if not globbed_files: - print("No CSV files found in the /tmp folder to create the input shaper graphs!") - sys.exit(1) - sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True) - filename = sorted_files[0] - - # Wait for the file handler to be released by Klipper - while is_file_open(filename): - time.sleep(3) - - # Extract the tested axis from the filename and rename/move the CSV file to the result folder - axis = os.path.basename(filename).split('_')[3].split('.')[0].upper() - new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], f'resonances_{current_date}_{axis}.csv') - shutil.move(filename, new_file) - - # Generate the shaper graph and its name - fig = shaper_calibration([new_file], KLIPPER_FOLDER) - png_filename = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], f'resonances_{current_date}_{axis}.png') - - return fig, png_filename - - -def get_vibrations_graph(axis_name): - current_date = datetime.now().strftime('%Y%m%d_%H%M%S') - lognames = [] - - globbed_files = glob.glob('/tmp/adxl345-*.csv') - if not globbed_files: - print("No CSV files found in the /tmp folder to create the vibration graphs!") - sys.exit(1) - if len(globbed_files) < 3: - print("Not enough CSV files found in the /tmp folder. At least 3 files are required for the vibration graphs!") - sys.exit(1) - - for filename in globbed_files: - # Wait for the file handler to be released by Klipper - while is_file_open(filename): - time.sleep(3) - - # Cleanup of the filename and moving it in the result folder - cleanfilename = os.path.basename(filename).replace('adxl345', f'vibr_{current_date}') - new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], cleanfilename) - shutil.move(filename, new_file) - - # Save the file path for later - lognames.append(new_file) - - # Sync filesystem to avoid problems as there is a lot of file copied - os.sync() - - # Generate the vibration graph and its name - fig = vibrations_calibration(lognames, KLIPPER_FOLDER, axis_name) - png_filename = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], f'vibrations_{current_date}_{axis_name}.png') - - # Archive all the csv files in a tarball and remove them to clean up the results folder - with tarfile.open(os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], f'vibrations_{current_date}_{axis_name}.tar.gz'), 'w:gz') as tar: - for csv_file in glob.glob(os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], f'vibr_{current_date}*.csv')): - tar.add(csv_file, recursive=False) - os.remove(csv_file) - - return fig, png_filename - - -# Utility function to get old files based on their modification time -def get_old_files(folder, extension, limit): - files = [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith(extension)] - files.sort(key=lambda x: os.path.getmtime(x), reverse=True) - return files[limit:] - -def clean_files(): - # Define limits based on STORE_RESULTS - keep1 = STORE_RESULTS + 1 - keep2 = 2 * STORE_RESULTS + 1 - - # Find old files in each directory - old_belts_files = get_old_files(os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0]), '.png', keep1) - old_inputshaper_files = get_old_files(os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1]), '.png', keep2) - old_vibrations_files = get_old_files(os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2]), '.png', keep1) - - # Remove the old belt files - for old_file in old_belts_files: - file_date = "_".join(os.path.splitext(os.path.basename(old_file))[0].split('_')[1:3]) - for suffix in ['A', 'B']: - csv_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belt_{file_date}_{suffix}.csv') - if os.path.exists(csv_file): - os.remove(csv_file) - os.remove(old_file) - - # Remove the old shaper files - for old_file in old_inputshaper_files: - csv_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], os.path.splitext(os.path.basename(old_file))[0] + ".csv") - if os.path.exists(csv_file): - os.remove(csv_file) - os.remove(old_file) - - # Remove the old vibrations files - for old_file in old_vibrations_files: - os.remove(old_file) - tar_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[2], os.path.splitext(os.path.basename(old_file))[0] + ".tar.gz") - if os.path.exists(tar_file): - os.remove(tar_file) - - -def main(): - # Check if results folders are there or create them - for result_subfolder in RESULTS_SUBFOLDERS: - folder = os.path.join(RESULTS_FOLDER, result_subfolder) - if not os.path.exists(folder): - os.makedirs(folder) - - if len(sys.argv) < 2: - print("Usage: plot_graphs.py [SHAPER|BELTS|VIBRATIONS]") - sys.exit(1) - - if sys.argv[1].lower() == 'belts': - fig, png_filename = get_belts_graph() - elif sys.argv[1].lower() == 'shaper': - fig, png_filename = get_shaper_graph() - elif sys.argv[1].lower() == 'vibrations': - fig, png_filename = get_vibrations_graph(axis_name=sys.argv[2]) - else: - print("Usage: plot_graphs.py [SHAPER|BELTS|VIBRATIONS]") - sys.exit(1) - - fig.savefig(png_filename) - - clean_files() - print(f"Graphs created. You will find the results in {RESULTS_FOLDER}") - - -if __name__ == '__main__': - main() diff --git a/scripts/is_workflow/is_workflow_cmd.cfg b/scripts/is_workflow/is_workflow_cmd.cfg deleted file mode 100644 index be19f8a8e..000000000 --- a/scripts/is_workflow/is_workflow_cmd.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[gcode_shell_command plot_graph] -command: ~/printer_data/config/scripts/is_workflow/is_workflow.py -timeout: 600.0 -verbose: True diff --git a/scripts/is_workflow/klippain.png b/scripts/is_workflow/klippain.png deleted file mode 100644 index 7b8ce84a98d60233d92692f36d15d404791c05af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 621954 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%0ARA(Z#;B|yrg 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�DKA?M8T8xURMuJltGfjIXVk>wJ-A+VWEXsPd z*ILe+Q!|3i7WliE8FMO4fY&y5Myi5NLBE)M&#V z9k02C+qb*XYpX@HlZC2@wQp&1>=Y+^77_%qXp;j0ml-|_w{;S{^wkI$>JZWMx+^)Y ztX0h@?^HEm)zBOQSNT5;T>GFTjmyek>tNv0pi9_+odDO)O zt@8*{=k5b8*T{3==F~Gn11{&7vtb+iYgCW?F>+X_OJHW{AvlTGD;6yQAi2){u$8cI zQ3qVN0<7e{k#(}2gn1BEsD17Stz=BD1NV^xE(w@=^w4U&GmeGy!sTip>EH+t;lrwi z;fc*$hR8T+#;Yg1h(o+I`?UhIRv|cw5H`GlFh)3$9*1MZfxd&FB_Ps(*hqpH6_-fw zLkRK1TM0OXn{0yBNP^d}7Q{yo?6L?#1TV2riJz5Nx)eAORK!9R9nqtv0!h-`7s~EJ zcxZ=$r!YZDng+enyhi{FsOChbO(Rq>t^6Jmt5rseng$4E;&T-gVB-E{y#h1Y4`C}h zVyOZtKc7!8_Yoc0qktl^M1AyplbLH*AkfYtnk$G zd#bP^T<(B>5x=ntR=UdgjEV?RxvbDEU?nQwj>r-_!HfAw4#BF>iFiKqhsDy=Xh*Ds zFuj=h%p88}GxUfTutG<;iY(^6o9{+^3Gdk~E4(vJ*t5Wfy;Q7#_bjgq*G#gYCM}=e zrHo>*|65GHpWg*8im)YPEDCT5*w0TX#EBF1ctV1S&NUF^2w4k_1T7ujpD)AS=<(6w z8ho&*5+5(A#Anp!`O+N7sVKh^Ulz*1&gJ;Bs7&drqEZz+R5`PAy1PQ+TUBBY0cuZG z5qfJS3_~&3ab8z~J}&n&-|Ax}xtEn>8I!PIU(99cH7ITmV#(q>^K$XS4VVd0RzjBY zzbaBztB9)r5jO#giq#h?KdexFu2Q6d5Y<9J60m9`U`h0MnQ!NOyFeD9sf+5-nhaGB z!=;N5U&iT*#mW(0X*I!WbuOZ7nC1{3M|5Zj;xgvs(Y4sSx)$%(8}L|>9+!KZOzPu-MiLyBg;ln13jmKNec z(*%*qg#S+{2?T>_u=GDfgY7e^!P5Wd>APTcu=W=K*(r-*EnkNB-;nVV`4{R(-)r08 zzxO0W@BT63gsbqQKSu1)V+l>`5P$He=-YBABKI7H@D9S&y%OMbIj3t8y8AE$w{o3~ zhq$Q&AZW#RO2AU_^J1-6VC!xzm}z7)GySd05ES1oLRNIka%JfX-`R!e9V`_7*aTd` z8sTr9_{3g{w{mju$>KunEvbZ;AF=>f&`_Whwac&z6^Mzosj&v}c0xsCm9k(-z)>G1 z{#-EvR&-qx*E7Q;T=f&K!Yl3k*c^yU55sjV$hr*(614Vs2sRS#p_|(*WhS_ig=2>a z{x;TxUHkwg!h4S$yPIpd4FSkn%a5L!EP+Rw0Ha*D+g`4E6b4k!KxxioZJuD%-@EDV??R&PTe;mYsO16?d|t=x_|*8?ZnCh(#zN3$Kz|Lv&t+FZVM7kq+>LecvlbdNIT0@4w4x3lnYytoJC`-- z5(1J~vjqwcd`}J#fkApqjb`n6tTe%;^F12~TnfMjijX3;ZE05I?^xT*F<+*tk`ZmoP4cT~TK&89bTR>6a48g&V51T6tB z=cx1G8co0&bvB&YqH|y$eFk(Rjzw-}7iO?_sR2?2k0s46T0qGIz=+qY0hIP_94HO8 zqzP5+hu1Dc^+f0 zScZ|21SDxDB;*7MFafa$r4k0R326kCpg5otRKf%@e;VPAfFq9WfedM8Y*auL&XRp< z&g|hVg58i-#78Ydi0~C2O0XJ2uu79{cpa(SPr6v*y3{_RLkM{p(xfPZPd5{Y8VOKx z>`uh8mmLzwgO9QLHOVmHt8E6#t)V|~T*{G7kPo$kc*d?p{3xe@!tQ3$N@ zz*o!fk$@#osnHTgC~7Mci7ZbS)HK`K^Q5C0rJ{PS69%O#vG z6bqOOyQWnW%B%{qVmXAhg(4@#dp(=q>|9Rg^V;Y0c`ay$cOgM?uABR6Kx9!n-e25~ zAB%rwY7xfrUDJ#qG8%yfRSK;5-u^vF94~izF*eO{;^jqF4Y(E<@WBEdK3G_TPbAJ& zUM)V!ufnGUtk0H|@F)+maE<>0j+ZEE-zI* z1$(Ons*2$^a9USLpeiI><*RuK#SkzRqu-DZFZ1hwh55I+kn_yLIUli?F#jS<*$NQ0 z=Obk0yo33=yO1hC+*3qxUL4-txyz!$iex16K!v8YSX%p~LOvu4^#3E`%kmu!mhK0O8QypHE1BS6Y5y~|AGoN4ua!#H zkhC%2igDu~?m{pi)~y&KU%Z6ACoe?!fuACL_c}x$_z?m-4nyprV-VbNBq8i*M7JM- z_&rCefTa-vS6HCxzO_uhmeV7Y^(sW*if>y==n}{IWq<@S-9nfW*t)X^@w?X`vR!Lp z3~pqhv8kKsxUY@vh+Jm{uB5JJ#(9(;Z{{w>2RZrpqNosk6|51}l_1C(QOs6`7-1`9 z(VXUEZLDE7uqNuPB!tu|ibUB}~q&!t^l)jLIm(NWMdo zHyj9D8f0mbW%*r$m3`?3(FCTOKzI}1Q3*Dx&t8Y)@~^^K#oKYc?giXj_GesQ@HDo& zKE!W}9zxT|OJE<7fGruwdW`5C*v6cJx{)WMAnOp!Bw#2%t%T)CftG4^(PCq1z?HaW z1y%w_2g8;~11`xc#BwkxtrSyuebdt{n4RfSO{E&lX@gd4z;&PmxFr0BjG6bdp+>wv zmhdv~5EZOcdL;H|^Vy7VL39G4YOFM&iC-4eOzJ^o0%2shX3+{{c@WBO1}5-3%M#x# zg3BQygA&rD1!dE&A`%$d$5WFHoTM0PL1S1dOiN_h*MtIVG3kj4FR>YxQ zKui3s1ipd=vaYRAjzmDuIxIsAAP{4Ro3nG>NR52A#scxfY{ z%8Zx-ELO~x@ZJ%k!i!j`TFeSz4%05MAf8_j-+bm1xgPiz6U>Sl5L`rXUR00JOley5 zAhx6t-pO@{%;WsR79h71-YHH5=kOWMYJzt*A$MLY0y7(c#k|)G+Hl7>BXsFSe0OB{ z9xX7nyr+_X|0CcUm(Ze=0-Q3%ipLib9Hf`wf;wf{`Z%{19}8^d)!iEs>Dt|fp~7r-lU#eCVPCsYxz1g`vM zfh$f;`3aw^LM{`k2v zgGH;Lq|#Ja%nG(N8xppp$*_Z9)kz>DbV+bh71lvQI;w_Z z#HEC*%Tg?==};sVtv{w%30fB1%;{}>-!>AqHm5lWTzojvBzCa5QkgT81^E9dsdG6< zgQfey`u}g>(qOBS&$SX+DU0E#U4!@D`i!s@N6h;ff`7RMz6XDf&;v&!_T;`gBPF_DHXl zD(%CT9x7og;fc@{byXqasX~a;06*|pQw;*rq}a~Pt(!p8S_NM_L2M1-XPE>)b!t5i zTL?)lT)$LX7n1ZHtfjWOEWWkjgah=@xMuZhsd zb;_B&)rR;o7KnC&PKyIxTP=Y|&)QWp`Uy|n|Dn=ZQSu9M)DW6pNwnd5eJ^@?%flIDy zz%?`7;J~H*t^rv&0jmP@hk8&k{wFZb_!SlmZQ}X_aH)GJ>AnkG)A&uw5G=Akt$AJc-_hQHi59rVY`N%>=McU|bi$Oqv>{*^ZJPgu@6eqXn7> zF~bGCC<2#Qu)+ka2;oDf-ZX+hT7&9AC=eDI)un(eD!yImd|wG#QL#P|g1jjW+&6(p z#ATmYnFNxC^1Lz=kj3?pOoCNj`d%dTJ)PNrN3!a%CCi2l!|b>r%ZeL@yYc%h3oaOH#&4;U zGOO{kAr<)fFdcq2tPaOy)=<^>X;uw>IZbA~j^|=PE8E`H^ zYM~1Of>peLa5~S1=n?|eJS#zr&vKTXAV$C}_7Jx0{N07{LW1-JR{SOt+7>kdi{eiYC*GRVj-QRFL{8$p64;mbNZ#pz zW%Tz+%IHrHk3xbI6>T6KiPO7`U#O}H`QmMJR4?SdXVGcSUe zUWXt-EY#UTuwrK2=;Zluzb#GZD=sC_5z=IxSjO5K5HQptA{MbmH~LF?uWF2lQPA7) zPIVhr4*O?-i?G3bKp@>-xfWl%zY8H>1P|_f5|ue^ta&G_D| zdP;n(49cl}1~a*->OIzBAt9iB(kVE*`fgn9{4-82Byf$m1S;gixN`|wXQF1*3CPb{ zj+xBd#P@Wp6iVD)bCVF?EDf@f(yUtpEL@@lTpa*fB9%suRL1ign8ojju;tGr1WAz7 z$^0fp@i`L?BAH?>YCY12^MjAA?FuxI-kq)Ih~i#TrST`$xA4o zY4VkIXGuyi3aE0bE~N;j)O^^f&a@I7$-MB?Oe4}O$iLAIybt6I$3(eOEM1sI!Pu zadt1DWSYkcvh*rkqTouL+tEZoY9t6L>lL@*R05I4+X-(iOhd`M_+u%bENL<%P$_jK zKuaRQOWdsGoR@*4R}$L9ij@dZD!y4Ufvm&I5kHK1{;E>=SMplh&3Ij>$BqS6xNbr@ z&P-cEz{AFyb7-mH1^{NQkL40@weK=LOrunh{^q zfL=!h{PlI*zr@rMXLl2i$N6^Fa9b^`VG+{m&CDDKKP}8CJ2>rPhFZ^KnFu>eo8YtS znW3=8%ykj75%ES3zTvg>nG9`EM2cpVxioCnM3)1V)FJW8?; z#jMnN9$$RHG>DSvzHapiVETR~uA6DUAGpd@tS$kkqLDpln0qPO7i>bqylXIz5Tn7C zz?FP^vhCo&CHwf%5Ch)GCO}PQWn&^MAA~FasAh!5w!tqU9%QH;O6H>@S`eGC6!DQ_ zL24l6cn}-ef#~Q?s!KH|#q708k<&zG1OSjkK?_UcR?FuyqGGW zmZ)PcWbR>CF| z&}O%CneaBJ4SOf?+nvVB-V_hwvspx0p0AWjW>mYEMmk_2TWP>yt5|*5Wh`EcDFP2h+ShEODDqKT8D~tp$ zfvRQ#SE~S(fECjbtfC!MrvOzE^J1Ost@6nnJv5XKVF|&FWYoQ%ha9yIO zVeHU6R>!Og_%!dvFThvy;dHr?8^;>vR)NOEYl2 zo}i`2@0c&0!%CpQ*2RRXO9)k$QkN0Nt|W9_$N3vlZMac^mIJq?x(Hb=Y)o-tGj$i| zx1|!a(ww-PQ-Q4qnI=VLED3r(SOW|6f4}5-gK4m|KU9P5S2S4K|4i)%uEDNTOw8pN z$&Br)3pc5riSeip(Jx;_V8`-6bhXS-+TbOKg{;i%oh}5OZUiNWsnNh1DAQXAV~ve!=$>8W#fa9s z5z-52)ga#F!rsy%1Zwo~7ZU<24M2M*UaxJ%vZ0GHg9X|@YvF1#9Enff`6_{1K&Ru! z`!e?AJE;6kl$A?-x5QyS=`?>ZZ0(n_a!CjYrWMQ9Bo-_a(s@qe*OgX>ar{ksQqN3x zAfE+$)tIBPBy$--%L5rmU;M0OXcGY_fuG5$5SD^gu4y1}9lT6Qngm$whor#Mpv3*G028Kq8)dRXuzezY&beyoV6FDIz0~y2vswv$tjC? zA967@tq4;xiZNMylQ=&qwUE!8>-Y{%ArMU=Sc#_cUQgvcpO(;c-gguXHc+@Gd5@V&#tO_l`FqJdeK-#DcTLZ>t`C6ZxAo6;9_j zIl&3c!u_#8e6of>?SSCtq}rxM?mSK-@=a;iiN z<4{!s88*kKBD$9-xC%<(WitUrdKH?)DLx-T3!zCI-DTJu>tbcWif}&SA`CSYX+Btl zt$0%*MR*d6Rx^KZ5fRc_3101lC21l|G!shGV60o4#wFrAVJb?f5@|t6#o@g``DH=% zHq6yP>k#IBYgjp7u1D{33%=|$;(d=9kL6Wk*j-A(Yihq|A7fXfe21TL*WmW=aY4J^?Awb~B?2Wqgi|J6Vx!Rm)d zeDsDBwsgfUc=Pplv=TG$CHnt-69PMbirD=U{((?+pZIP42=NDgg5C`))pBUtVOlT6 zt%o9T?-2;xeJFu!E&S5skYE+u!rJprX)DcXl8`#ka3O><*^8 zi5bp%uG`X0Fk6ZE4a~&8sy8W1|vB!f=d;cFwrQNG$T*4TI~2e)r_BHrv# z{#8*Y!LHGUeiK2Epd}9O0fP=<8$pV26mDTbNoeXTC`H)C4AsVM8ko@d;TcnpjAhc>YepqK((rSPx$f_h%MgE&`a5;AeLbL~RIG@R)=z>75uA84QRM z*uqur!-Q=dds_!Er&quxlJ!X# z<1}%c{Q;S!P}yI=sB={XZ337Q>khsyt#BS#P|LL^3v$i*Jqb`!XluYF(txXRA8=hx z;A%|lgXev~e)mfQu38PaG7NZE9OI>Tp+tip+CVrGplVj}w3Gwl2|Wl*VHanxf)=CC==bo$#k{ z8?j`G#Y$PTnpCgCkboDVsy|i0Oe|gm!i*k7(|fpW7XsN!(KoCMyT+};I}=vmt`Utm zXOtZ)hg6|}kTNr69>HJ{?^7=Ce?BGFsib9!_g38xc`rES^VoO46gX+mP43lx$+FzP z{Yu``eb1C>_QP@Vd2939GZAU;&A_}fS>9-1BKy?d3wg#fdET=KVT*Z9M!xr}h7{uB zku`W|j0taywc_h39u2DI)+0RCh1hftr~G#3G!e8K5t~hL9q&YF9P@^me3n!AOeYh* zCV8-T9P^DCOhb^0&g8wG=tAFE<|~uy;b-~)K`S|?5ZiJO3*9Kh`I`8 z;p*qSPcI=H2wRq7R{CVvoIC{WOAv4@M#!1V%3~fYq30-K}y9p>q1U1VY=U^*zkuGJ1$Fc5VUOjtXem6+grH)cCO!$ z=ETNS7d8>3?&S0?0@ro|*WCoJd$~?P>p@N*=DJ6z$EXBwX@&X!Iq{f$Ar8?0mGk(| zQ!>-|=Ol%bjA>V)e7DX&^J;j#5>-Bm=$9{{_klAJe(+c|$aM6c!x6gs2!wVXj_7?y zW6$Ol2yS1C*u6(1_V7;;fA}W|6UzFwELDS6OSp&l&gBHG9^n2}gs%?7?p}_-24>tF znE4BMaT?jurDAYJ#JY7SwJL~w-mm^fK^&pHAsKlbxYbrsg#mo=Wp$3!QZ7YGd)r4pZ zfv(kxK36sR32J+-1hS>|=;uCtge*~5Vrea9&9aSv)1*1X#|Tehw;r)pGkPV{k=}$J z6Srlp)UH>}bpew!*AcV`HZhNduvLLxLj|G)u9(HdOr{Y5yI8Jj)ih$VA!4?3zi#ZR zuHp8~Y`Glo?uJ)yK(LO$*We}q68daBZ<7^%y$QQZN(o~Q_-pDAQp1o~;VZ31u#&K8 zv>;|OzwnlVc3&K> zG&yH!!V>Fl~w;`v}!!Rg5 zSwl3RErBnuSimyHdL^JmkP_(Pe3)<*AJ(HlEW-7{RDu`Ri(|YfEbApaLzXl@O0Pn~ zSvo;$=yH5LtQ+r*?#6wi8*$Na3)W?nz?`~RL5Wzgq`7WfS`o&lm+(H8QkoTN|9ud+ zO5Xb)s)75__I2R%{T@jgRi-4%mE`;Y9gtpIC&$!!q>6Q|5OetMmoe{b<~5!?ycQeB zSnPBk1cH)SsV49npXxz;dJAHc8WA2(D4W!z6qw)!=J&u)xC%{e z;C6087w`R~dPF98;2p)hVJf#HaQVhK&_Bk8y>r`f$FvrhGb)s&PrkRoVC#VENN7C2 zp|O1Lr0KP3NGa}I=)|i_YVdAuB|gln!N&#F_@uB>1Fnh+?2#}JH4>bZ`DPuLYl;b9 z((6zxTjdBa-wa5AX?s2^flCl{tdjt>dHezqQ4WeBAo>Ya~fY>g80f3M8zNLkTS@4hOw1}h^^+7AQtMZK!3X#-?q8& zuFHW}EKWR7WWmi-s&LJON}Q8fNWdy2R8`{ilsd|S(+EeW6OK+-Qvw!YN^}P2&*D^^ z;m=RA;35K;G#g$cFi6TAbd&-!@Tqa=mB^=kMZlJK;(! zTlaE4Y0-K_ftCkPP)}0-1+M=v4Gvb{Cy8++Vj+#&A+TdD{5uatWZN1oaOpj(5hq;5cCc{R z%tB#13k3pKLWq#%cUQyLs6)8JhJZwLH`icy zC2MXCoR@f7El%`XYv8Xp5dtffle(|E5-|rs%fNlO%{)(T?=&IoATSxZ&ssv2nNUdZ ziaMFWS{z(&CD0M*HMI!o?TA*gc3rGT)a=2ti%eLa zA%&#?m%zy12d)ejs_l-S;fs&IP2d*LY(7dgA!>tE6Do$(;?*ZU$J;M|jw6&R47h<^@ zN~ju6$P$07k)4FAE(8f;GC*`}GAlI_oHT>aoS+rW7Uy&p;=>6}BREe8i)L{qye*;^hgYRkLSswhn z|F@ETs{P7!Nb@Dno9ksdhSxWS---+_?MTVTFNf)H(+CS*n`FngQ=ACT<~<$DiVuM+ zG{($lN5C5ECUiByH=214r$MoDO(cL#X+(T3ftCOk8s}y@CxTR%faV|LhHnJ(i17`G zPHlpJRy$sq*^Xm})nJkMq49kFS>O^M$Z>q{q-k+6&-v_GPCS!m!<+eac(+i84~up9 zw6qRimDLfrSP^A@(OX-My)~>f>X--1Akq4A$S^xW3-eiwNz>+|vXH&mp`t!JaL8=9pq}daoWy96n_BsO84TPqfsGF%d5M6qbGV34sCZ*N8D78Vqo53O%izf03% z=vEd8x3OkT$>7wulAv*F1KuInd^*1neM`#WEi6NSDL?j_ay9%zNX8R%R3a!oRubJ^ zng(0VtQFZcU#wRi4CP}@O&s3+gt72)W^&vQ zIte0OcK8Wa0T0ty33i;y_=T}%X*wi0*>tKWVx&!a8Cq4`s{qe0WZ>}{9NdnXY_kgi z@xda9?X9aqu)&Ea;VEiohHEmara!;g#+n}sR6XI$=0G3eC}d|Qt24vTb+P6)1Zz!% zG&_2$35K2q1Pho6mFN+wVVXK_S1BPPSYUFSa1Eido|(JJg0P9OSy6{@Ew8Dm1^rdL zUxc+lHSbr236UZL;$=LB-i6l--B^{Gs{vQK6f9Ce{yhs<4!WGbz?UEIB5KJvP&|a` zC}r7_Fb>j#YU+?0Jp15V>bF2|7&l+J1G?gFj2TjZ(JYk34{Ji2o~j!JxJ3VY;2OLD z7bOdCiL_siDZKWnypA~;4Jey%1S%#TiCO7RuB*m0{+{$9Dj;x)4_Di~+u@n>2Le|! zuV4Jsr0GaZ3>! z)y4Jgge_KNGMgd6OI1uQ2?-%%8%lE`fy*mFOqnJsF|N`j1{Vu<0+VuXm(UFaDSs*p z@TB8=W~Z`tNi(A~CrVSK_;Lw|c{wiuM)!>F!7IZWaq}<}ew_?lH|48M~x>EfU-R<8oo zrI+A@q2<^*!GsSNw4!%1pU*gclcS7?60G7=q-oKO$W#LLv^My~FKZ0*FRqiO!^nhs z1!VE5Er?HK1&gp1pVmQGBP4TP()5mH-m+*Z?wnc=J&!FG*MU|pWtF7{yB@j!nro0W zN0y>_conXkX2iDHdfYp|4v*v*@IsLtFBe+zT9E~>7n$*9nFSx!+VPprf-iJNe5*HN zuUSU1Fv4ro!^gZZTyH>xd2yh=T8+dJZDF3rX}nEF+~Bpha9u0msg2WiR%$zCSTt7j zx|!#8*CEtdiy+rYPw@U`6M7r1_{MF;-&}TlWHRIRN&}wB*W-Sk2nED7Z9ejUWOLR z%y}~|PPO7vuKzvPUzzH_)!a@w!gDH4@V8O|S?jsHfz!>@ot(dm+D6??-NSX_41Zsm z23ZfLIq|T-7MCCA^vP5=o+5BPL(qCYq5lHcf0zb`tHCveFX1R=jK#B?@z>{*V<&YYk>!UjKIcah~G>2+O`If9fv{&rVecEL3m>~uyZw{ zGF;C+gsvS+;osE8bjuLg%z|O3)+J*%(}t+{Hty>NW<;0U zfJ++jSwkh>n3apK78Ii|uL%9ch45Eb5g$*p*qD)2uvTVNO@@6I z9)mz7QQIXPM8APRrQ`4BI>dWeN}9kZUW#0;iY zVs8h17V^PKcNM>A``E)V*2JRgf4p^_RE`8`BP3YiFdCc+m1DJ&K+0#{T)nThv+ zu%x#kQbh=3ns8Gad}Yk|3aSw@bJ<`gXu04m*CANNW0v!Nl@l&ma}60B=q=T89hb|j z=$lu97{M)Cq{jzkEm%7=A2X#lSeisamx4tK&hH1V&V9heKfXsz<|J^*VE4?_Gb{1z zLw}Vxy8HfK<2$#u>r~91V8%$khhvyd9N}f0#UyZvuT~PK4g@dG|BHcZe?hGk-bt&} zOrBHG@a1q!KNB6fSDk*f!aTk0$cjOl*LEG{4R9(o{&G z7I4buH$8>l;EdBt8hGZN_GuSAFabV z;|%!yWFu~wXUEpXF5J7=fyWA5c)G}mrwi2L<)&fxcT zW~%fsG~;ZpmjR^DXZi~%ae5cOtV_Aw??qg`JdMXqv#I!5e@t_z-iEhu{x(k6r#J~& zT5rQU2~~Gdnl;OToeH$sg1*QL+ zz%{4_OZ#69)L>vWxL63VRy{mr2~PUSh3MVoWf2%gZ0}nLK5#Z-JB~*Dz9SS|#ka5H z^5KXPzWN2O2wH)ys}b5JfVCRfv4+6Zh1mAx@NFVI5w@aRx`2CDA+&`x=Q~-u-oVEAWSUcn`PW?Zu1n;p}{Tn^T0| zynF-|Y}LSLCBT>nFimy@>In@E2JA7H!RxLg)Y!S6VB{iT5QM@_tXUGO#9u2w(DJ%! znU0XfbTW8!d}$-T))n)28~nB!f|m_JYYn1qGvbXd$S^tRaAB`Rvv+X+Ob6*@$m7dU zJpQ^G1TCz+iEoy}f-phQ?=UFG__&+vJPz)UP*huusDl6{&4>+dLJ`l=!dh(&Va+CC z8_bB=-G~_-i0Q?r$^>r(YmHWB&a72RP*O?XTUd^$jkR1+wVCkb#GbMm^j8z|9K3&J zb%F*8PX2J_+!yB>jJdRyasJ^uR-O6qcJVb#54k26_}PPeq0IQntKsi=idhR z+{+FCF6jX$;Hvp-?U!^05I9-HeVsL|0Ur+UKxo`@1SJTmSf@CRjajNJR?$)23bq2` ztEHUdTj9%S3 zo+Oa4@Rwe5iJo&Ba1G4E<-RAM!9OGI9sI7eW=Rc>wfTL|n8*EBN&_wtuP;rYQhL2= zkf{aE)hZ=&4%#ypD^jU~85?y{rXG(@>%ceD`HUyaFink!jAh<1hI!aHC;CRP!bs2x zjA9-!(uOc$D?HYNs5Bu?;4_-o41YHBhRJ*`V+dW73C{vzi`QWNoHkSpDTlIAdrb&Kg>P z(>Z@y`eK}xmW$H}>%UGZBq$Z(6z=1`;1N^j=zG|;kRBc=IgIh1dfShIF;s`WT@DE}J0QAED_D<}*<8VapA!I#t6d`F9qFdJ>bk`~bx359$zI6mGPPZMxG;6uO zM-9UhzM})NyOt@7R+PXMxwA|4L=11^^q%F)S1Wu6p=)D1;wltGhiW<$i&sq6Zzg;Z z&Z0LEfUYHMoaMns6$SWk?h<^yr~rHOOW-RiL8!J0-%9U90*&8XqozT(K#n++bJ}E8 zepy}z!Ku-TKusz9#tIevJ!F+Ztlik{s6wQ}L$D&SI0+{n?!&=ari%dLvLfW+c4i&o zPVS3v*KZ&wwYm_p*CEQ^q_<(PiM7-QJK~*91Sg51)r5YY+pe-A9^ZsmCo@AU0m|c4 z;1zZ;tz80~+7UKNvmk4-wY4h3yO+QfakG%DA>dgEMue(>QHJkvDNu?Ls>DyLuZ)1F zCnW0Zge9H_6|J%&Qe#KN)`$QB%2#cHSFBkk?t=gp%o%ds#`9GvCdso_*IZY}d3n1O4+wHV7hzrr`4 z?^O^bf9>|4FrCDgGVuM=VY&d+v)j-dY>~2Jc6Rd{v zn;E8Aq$1)JpGBC;nS_0ia1Y@O>47LPB|Q(t0@jK^s;uim zFr@`iu8Z<_-_S0+!DFq@Zo+YyMuOH7OsAxW;r>`xrF=eRN-6*+uR~MveHr|j{2(cC z_`bYPdydK8ivyqSp!@n?YX9}ga?$Z}(8c_c>%(IS$s;`42m}*Z znVr&(Hwj!lL$xMc`9=iv*NGr{fg65DVhEz%|_6&5wvWC zEE~=y=$u2qIiFB-9^vdf!qNqtUc~j6P?s`|#LM~v_j5V7zmoG;bKTXPUdv^HEE#s^ zCT@320<<;|l9Ikz;{3ji``%6|(Bkx7{(c{i@c`#FXLu)J%Sp)6nhu}fx+l`ycv3YZ zI`JpYKa)z>O0CE9tQ7q@q35~$U*P(GR0n1{|5*DngM{QG%Sy??j}G}Y_U!J}O1-|1 zu=n8$5qUsDK^%_w!#_fJ=b;E~UXD0H%O^3iwk(HVtX!LyA$HFi$he6ifh_5rcsn!w zJA2?=-=dlmqjxa_m!`svEIed+Bf;u60?G|63~pzQ`?dxIZf!t(J!^ZLS;OAYf%w&C z;POU%zN`{|oi`VsEXc>Vd8P1{R3KPd4u4ezA*BXEX-;$zTnJjygeN@#Lxw5>4&kKT zflvcsquq%}mj{6so0_7F$0d~Qkzl1Q4g~adh_7gc*G>Q<5CyBb4~c12Z&4Ps7{MuE ztwD%@6*3c02wstT8~S;SU3KLMJ6RL0tVT$p#J4rVYcZf#S4B8$RPkye^=_W01@V?f zgl%Sml!^PX0#;_Ab_or^^EMF9q#03XL7>WjsFh%6CP3NU1Sejjkx*Dxr+_J9kRgCb zGDFYdwb!^2F6VDWdcECm^xaA(JY`;WO!!&YV1}PB>MuV zevbye;DY!d$vUwHNZ0zg>24GcKOBxpXQOr66=^^#=$d;i zs>UC!fNP2Zu1W=5()5@&av3~xFGI`1o8g#u4(4Tg6a=UySp{5TyOO3Qxj8UZ5+OA|NIa>f6xA{eL#B6;F+A$8p2V zC{8INXyx(#6!MxSK2MrH%wW>2T>F7b?(e>5JJ`Pd z1yX==(7FSpjxXmS--^7qgr9V=zzWdkqln+j&oaw#?+7zKAYknt$vj2iYlId4G5jv2 zxo|x56V68nSdp;}2#;^pG>*@34D-z~P4JE5@)Ut{R>r1v;hZrJEa5Yll)-z#`yls5 z?$N+=O`f|*S?k0C$@f@(lgfiRT}QyuVFk5ZsgCn?SVhoUML=4ePOu_ui4ILOV=cjD zErDqr!ANvCmyaa09Gzyxk2n<_lV-tBx&AoLAJ6qCP$w!8rnpY5RVNZ|eo39Aq`}oG z1fNqW3Ds~Kp(yF-ekOkt3zo8CF>O+3bNO5X(gg&ei$q*^aT-C3FmxF~=Q2(&=l-wY z`l|?P*Kn#0w`0Q%l!SD+iIS#6)!UE~|ExRHT-Zv0+D`2tH0|W_&NL_P;Xd!<^g*T* zsb)j|{s{FLrTnxATTgQ;`V;jG^=zt}^58kKY!S3xP-^6S<9~tc|5XhJRexWJjDR1O zWb)E2f6~wbJh0=*gmo*5$Olg#aM#a(`;LPD&ZP)#S%J`230S&@(6to4+gYRDx_-s(~W-DU*q zt;#wTYjGpuG!l|1H^IhZLZ7V~K93Q*&6NmpeMrVCY;q#r#q;5IUPA>!O)kP!9rr_c zQNC3U%F6voGn|o-MX+i15b6kFHZ5JmN%0twMmKuP2|8A$tF1;{Pw?{aJj^_nz?I8} zZ_A4bPXso-L4|?nudYGN;ZjyDU$qYYk}BoM9@E(oB`}37F6^x}@LWBJn>>h_8wr^b zSIeoaSN@VZ9eu^manW z5i5R$x8C?b!PBya69`6nLWMLb))2U=@Z3Xh?T0Oy?gKAUSUj4T2fqAd56=Jf^(bH5 zit$+$7{Nk*3=0D-;3?n#e*jnqD+yW$ON)Z9S+!;{1J27@4#T*U&^-P3%A(aa=^C_8 zq$Y8G3MIfbM}X@`n85;PY67^X5InFn$un*!GFaBHtU*bsL&vbiu+*c$YSA1I>fiDn)j?mO(*jHEg*Dtram6TYw4oxLk@!J(0N{O}V&=frm z6RQ<}JA&{3k)jkMj!H4%M+qIx)Kc5n(_lucMtXO|gvJkSY3bMo( zORQMea4MFpKN9$EL@6hDPVc0)5VE!sl6DZB#F{0Lbq~Sn zUh00Xm+0^hbKN6MCwi26j1tfihxn(JQ@ntdn}FrU^OTyVCSWV20WT)>Qp$gU>;G8| z4po0o`#-SBEVzd8gKx1Pg3mwIqJzhLpTqmqRS0Z84Dox{Au0h(cdkX`u2qQN!|B%L zh!DaAtU?<*l)qMd+cLyH|2)BzeeOzL5U1)$D*SbRK0aJfpn&UZDp*;Ia77KgRh0xChXz0d zC7(@tDH3>`dh{CQHyh%1JOqLGg=Vq(loF~8*sCi?UrhrPbLKgQ~?LeT!OxUszz*ytWDMz%H>naGa zl{SP+d9HP=5$6*iE8I%`b1M+5Y(OxdKsaBANP!Hr%X?SNV^ntGs)>4(r4{kL5$KY4 zNBmU=G@Xb9D5Mt8OglYgA)4(+>^|A_IX-tPt~fO>2he@#hK45FX76%ZM(-Mzj&Mnv^rV zILZey`MnV4A|tvHAG-p6f>?m(9F~|^LpY_xKTC%05ztamEJh5~pk6Xp}ph7h{k4?-Ah)>F>#l#^5vY~{r z49%+Z&m8ODCGA?}yAf%?C6;3GH58x5F={H~I2Pip;U+vYt^r?+cH=94Gog{pyC$}& zro-M$8-l6{(T$+2AIE1&$O=s$ERShLa2zYLV_FDj?fBc|9-J}EgheSOJf64%$TuPH z;DB?Jd1~PIAopo3za@E23wTa0&WiD;mVE;)F#5# zCIwh7Y@t-lEKWsY(b|#bCTO{FAJ;2!oxqkfABsgQ30b1YsVAtX_?!4>J);22wGXz$ zPfMgZ$q$6B2E0uD7r6c()!paaGa$l@-%9v!5nkF|KsRB?Nq~{@3ti&lRE?mqPKA(& z>N%|>NO8M>+k$|xmM~=?uyK2f0saODf}Dn&76jdPgba1uhYkJGRN3T2$isPkErMo& zJ1w$%pN_ERFsqnWaSv;zR-V6EubL;l;z;k{IT#EG*6I*Xoy*uZBQpsVAKAd@FfQl{_cHRLtIpK50&@lXzRT2vzbJ1h1HZ z+ZBqnipxcM#A9n$O>6RdYKh zplioFi|TQBRyh_j6BcNYz@Mt-%#2wwZ?PyS;Ntrw7Ke%HHONTGMP=?v6wmI#v`h=8 zrU`IWYZk73z;$rDq5v0ROQvzI-_Kl#bJfl}AIFN;V=;fCiSKT?Dum_ugIl#z3n$loK=V1zOEu52V)4&g&jh%{r;YoP>*n@T_})oJCFuk*I=v2K(!@tm>mj&q zNIA9+GvNJf@#}J9?@$MNM|lWUgyu=iOULtBj%MX(R3m(2`OGJ@!8=m?x!MV1P4H2n zv7NYgd^@Zem8=X%TrRl|0lNX`tgdB$6Rgb3H41PEP)l#qDsHzT!-&K9?FwLNmMW71 zte>f-K?{zjPM`#;P9pf6oX{!!uEc@;*G&5x>NL)u&Z!Lce3mHPjI#+{=Mca|Vx>Bl zAS61UFeG4g0U=7_UtP%GL=vK5Ur$0x28aFwbs2R9(_O{i1+M-`-N1^@jfAHg2~pyQ zB}44oN=Xx;IK4|V;YJbDZQ`=l%TRo?9N5b36l4*QBpSRxmQtFBkmbPxoEMAMLj*9< z!(4upN;VxPwI8;m*-!w>r65bfK4{MI9tB)U*h&J|OHB743tZm?4o&~twEqeXb}Z3g zX+?vj{o&F+E~%}KNLd1XaXa34?L8K0EZxF;5Pju#1n>E|3S=7DwhDe3Vu#b{&O-=N zYY-Ng+PMP3+uMNcs}oN0J<7@zzJt&uKz0W+@r@n8wxx(}Y6rG-BD#UVb_X;0^-YLy zK71SDim(;Gr3vx%+}CENztw~Im36>{HhkGojkjj!;%{?{uq&qofwEeJ#aXRU%|3Jk&c7lb(Pk!bh`*P-a!m?J_h@(4a@u zAP(a-h_CE|M{(^&{!cESz! z?c?up8^MV%7?DWs1i_HoiJ0^}SkMwj(C-vdVR;*I}sI1b<;QVrK5A zM6*bYCYnciCB?d%loP;bl{5l7AGhL{{3e*zFN-Xd$k%;mvbn|q8k@q;C zKv!W`)~t}I!iK1mkX%e)E91Uvn-I)1A*N#{UT8yLZY|>ZP6Xx?J_{taj|Ki5GyIjU zcx18-hYTqt92Bq+EMbhSc%>l7fo`3^VPi%wWg! z{hOLujb|TvBf(kn-$39>E)Q5Ivje~@GVQxmYL7j(43K0#wq%aphDHa+$ zr)1$K@4gh~+R#7(T1L!CZ$QcL!(g9y8k#0wqyd(|)&v2rE73ZMnnLiJawS@(Ud8Fv zXrY=XU5k#{1g^1S;W87nsxXBRCB83H_-#$$v1EL{DZC$7wQEcO0RQw!L_t(?PqcXr zSSIj(O=MaLB_K^VGB9{O&+(SwE%3dpJV9f6Rx##f zbDEKlX?#9YC~a`;N=!)?|3T@zArcFk_P!-8MjB8KRPx$os-@BV%`~6LacSaAUrWf5 zV^^y28rNjh;4VVdTLi8zviO}3b)i3#c?jj@avvegKbjRTLRVlMpWV;~_=jh&M-d;uo29$R%)TmPrEFKuAoSZ?Zf{0@pYJE=rn@^Qq1Z6OPCb-zy`I<2Unj zzVAOLTxpK%3Ck6w0E_xfLi?KmHAx7D-%%2V;aqMnI$vNap^FGwNr^MNCaw3Ngl9-L z3#z6;&L?{jUd{Pysic$p4b)B4ttk?^!I6+1>j_s1vJ_xRye!T6eGB163*{ir?^*=- zyA!&HaC9$qAN4>&G6atVD}9vU^(f~>j}f+>;IbCtL3$l((yUtbiEs~Yf|LU<@b~BV zEk2*xs4QDAq&4Bi)F!-|(#+rMDH~p9e)(VE`Zs8>V~GY!D;g~A50h5Y*J?D?ED-Z> z#)+4puh++-%#YZv*Aac@V)ShwSnW6*!7Zy0+bMCjRw78C3dx|;_pVmWiT>M}d2d}# zAR|OcT&+!A1TDgq49~Nk8UG#BrdId`qBgf9bZb4L(gSfLx1-|x4dSnLTMJ^h5xkf_ zaL;IcOkDU--KuZA&$#IPEp+q@BAvnstA!qgjBI`vFUZvRWrxuECZ_U~7^% z$ZMe0I+c>?SN9-(yC%iWL9A*jB8|lpb_> zDwfn}o>#KTaKDoNTQaYK(%*$GB@MXtS(y^nNM%LheGm(lSg&S{F=5F}4-ADpIJENw zoPNR|uh?@XY;)U3Wgd{Y598)IAWMW!3yWY`H) z1g_!r@Q-Rj-^hCG9m#xW6rbmqPV^3OVQ+?;Fvbekh<1E4stb1xt4EyxE}xftdjqdG zsU&PAVNnK^AIs+^m6LgVHf|RFM-Q>#I0DztQw%sh)r4OVmVTLLQ9T7u;k*jPK*-TT zF-S9@m2f4I+X+@&R!xCi7D-@HWvSve(hR8iSlJU(8!n?{OhSp~E|T7ZS`R|2a&EsS zRcj*rBe%Vt5(jq)*KiA`;^eM@mJN4spW=fhfTbXd-~47u0P8MlD*KB1 z4X`xG@({2*c!(0nQlQ28$Eha?M=}hL^gMi$>;FXH5=&N666WDK>d#Ck65x87XN}6NT9>gx}tZ$O9)JdiPO??KqOav>ef$s}b3`QVr7+CQQY-9NV%KxNkK=cXlDX zu>*0gk4ewOTM17RU4Bb9aF+~J-Ac%6Lwq9(1%g*Z0PGeI!nd&oemgS;LRjn${x0Js z-ogUra%oO%#%Jv{_{)L?_-IZZb}uSMe||aq1(gVw)*x6`O+d0KAFi;K;A7MyR8J_f zn+P&Bh*+%Xt*9dC5ZsJrgdBt@tAt>%AtJ#;WdP@fMtH>+%w$5u<%GXZ!Y5b}5|9%o z_eMeop{lp48b0Z*XeQhkOz7vf0hh$~B0Taq5i>zZwlg^hRfH9bT{RU3eq$WaPP;>Ir5nTnS2nS|_}P2E@gJRmSTn zB7hODqQ)jQ703$Ly0}dPdh=@#t#A^q2!J}?-#o%wp%pQ68~lW?$Rb|jygI~k31&qE z&Js7GMNY~ERJOxE%Ye`V-p7Rmzxjl(`GnJ1Cd3!Xm~K4ol1}vHcH)h~WjJM2HEL4} zF`LjJ@rP6lBxcewc(ej6!q${@0WO2mlyuX63s+VRo_%56&p*0M0WYeWaW9K8(w%oY`_G%&P91FVb&oQQcd|A=VKD)VR)yC#}(&%D7zaU6Si&~ z=0RJ!bc~QDM9m^3u=HKv`uj>k#&_2XcuAf^kmLSG@!H2_maFE$vW2Z!)pi0dKX)@8 z-tjtK`qO*p-y29g^yHs3HT!|kw}AIEVAs2dzw;!54_u2c&sc+Rd&0w3d#E*`XRt2nv^P|e$;W_WvEZDz-3uH{;)>8m*K=$ znf2H`tO4H)bzzrSx<<&d2f@+p=pRl9W4gW6o}tay&G+b~>^8Kg$@rXd{Dg(=Abkh8 zMAY|lr}bDa(qIE(jWQVUeB~LPNC=~uG1h(8ys4O(itcL zEM>tGz@ijj5p=du0$8FQ1f;t~1fBaR8EPjf&5|XMRZqauB#@;5i=gyWLdjuxR2(fX zKSw>wv`MR$7FSDPOOs~7643G}y~6p|c)VA64__N)#76}V^e$h9_~}Rg7r6c%8tho2 z!P1HbOZ(4CHLdVt5=~{MKP)8|E1HkRH(&48@-+X)=)LbW_%^Npb{>Y{mNkgnw^qSc zgg_PAz5cO5;QCg?#eZufYs?Y?;gXjik^aQN< zrgnl@JAWgr5X6G(8wpw9z!h%zj(6aVl03XSFBgBCmyg~>B?vAlBa{%7 zYQ-YuKuCHia$cGQWjGvxtdLHJu$@pvXhI_k7`+L7)p|s&EW|1a6E%dUS^|VXR~?sK z1Qjb`OK(8L$?XKPj7Bw_jts98l6Cb?1k7gmY!<}2Tj6sPdZby>O|a7IxlJ?SsgdVJ z!1A;Z@CZY8f+gY3mtU%)#s|d;*VK%@@*0HAPV|)#8g+y?JWrV{eOt(mf*b=TUC)5@( zZ3RKCg3qAbO<*M`mJ!4jnBkv6*vzpaSi;)!d_vo7-j`g$Z)FeqW)TFdm%^V@4_^-V zQ^Dt%&+{K|fp-$`{o-zXFufT!j&@>cMl}jji&*QICKss{i$%+*0au1**;3Z63^S$; zvGDg=OdVQ_XCHn0hXYsQPkgyveC#9Kzy2NEf7`owYU>wx{LW8t^5NH^bY6#Ylol(2 z1X`6LtE5S91~b~6tW~HT`AfLRpNp1>e?T+gs&V`kXrh`YTuEK=gMq6m0bJ7#0xkt$ z{N^OQgh;GxV)c@Ng>zVtwxsKDVWty*nYa?)jP1s^L&QI;8&Pp)Cs;`@!yqBapTUYj zMm+*t=gnx+niQ$n$mI&S#IhApgGjflVR&S0L>YQVnjHnie1tHWmtd#C^hU&#uNRM% z#fndMC*GT|6c>#aD@X-qv2YdZocJ&aBuQ_z{opXrVznP8zE2WBQ#B*XJ}7Z$mma2L zGs-b-Of9Mk+Hu&@Q*gxvoAA=JAHdh2c)0ui_;N%8h==QP-4j$MR1xl zvJ7 z4H=BPLRs$)zDGX@xClq%Q>7Wygt4hIGD8WB)J0h~JfGc+j|ozr5x~D1S&zQ#dh8{5 z?a6LL|HxMK4r?J~HQ`%PW)r-_+wkd_9{gsg8znp^c{kOuljo7pV8A8kqOGsM63(y4 zu;F;>m;AO*;ro7Sngzd3wcvCD*I8*coK5gKmpV^Ci$Ely7%rg%u*7PDdM3XMc<=Z45&P z;mUy>TuwF>s@{dvz1+wB%ojut60jcPZx3<$@BqnR(i&*VIEUKsJ4wh=maKt*m70v9 zMagnPs@agz{IePfS_EP0c`iSf=ECbEop^tV6MI*80_PqETyz9*_7VRDu78IHJC_|8KBLX~$@C;U5>A-F@r zLUh4Tu=3v4OxS8i{O&dI6R7%cZ&KkLd^fSM-XP%~2x647TFLazb_8y5BbxBr3f|&D zoa;bE?_|NTh3U3*0NgLGbOD#P;FI=p{AGR)K3PzJy-UjB&#P3x6{@I%w@m!9Z0IW~ zC%jk*PIU;I%!t_tECeS3uD;R=HB3(2;YMGL9{ojCfUAXIMUXOD5N~8Hu!g{9B$!xT z_%^=;ezS#;!)*v)@HE0#S&hAwJeG~e;JgGV4OxxKS-wxleH!Y3W)_GQIt0piTqA+T z=zv#-*D-rkgm^ht)ak*lvN8n4AB->t!dZWnf#>RguSAb{r5%CXT0{k~3JHf*E(9v< z*juPWf4K$zc~#2S%3s3sNLaUGwY;DD2KdUX2v_o$`E`g?^S+h{j1dfV%?h}JxxA(& zcI=r|O>i=ye~}S^LKh;XjRdt8#20fu*A0~Mxh-%Ywx}MFCC%{7<$iJr#4{Y|pXI_g zlX#8A9f&XFHnUpc9p{2?Dhs>WJ$L{WLF&GIj0@*x)es* z)N})3iyC6W^dVy5s>QTnIz0c_JO6Xw5)0R3ALD`b?<(NB@78zm;Q9~nG{Nhp3!Xx| z`4^Zo%Eouxh?&e-7p8Zha`-W*pLj0Xrd&ywx(ZF>E<@u4fv(FGcr_8WWcq`EYu14l zE(r@EK}{zs-?3!HM!-v(E@8p$Nw35ySr+UV-GUFtcA;;0i?U#Ov-q84X#q@S{6iUh zTAbWN%IejCehF48VIT-sKCxOcZHSN+9m?qt!V_UEp4kasYNKjW)T~||3cmcz2)rnWeb>P%YD@s$uIbQs#bjm_04&eiVL6cSpYf7w>X2L{M;lb%-BmlAW zD8DSGnV79Z?wm#}Yd#*AU2r>I_|w}6`x6h8e_GcG{)@&C4-m2fpCb0jZb&4gyb|2mj{d5j?XAdsh`;mt!iw&l!Mw0lsJ`$JPAK%7@NoKDk%{j@H~K&1eH) zXP-1{kDRkKY0ALtzdZUP^zS8X$+>*-40>-Q)LvW(TwKONuojVD6d-a)4zRocSgVI` zjRh~bYjEk}JamkikKBwLKIyeNUL1HntIiaG+Tp1`G305&77 z6qd9yTrkv(Cx_MJ?Myd58Ro)Qgs{)j4A{+gX-{@5c4al;o2&+WP2l=G(}S-w>+#vJ zHf$Qx!S_zAy>ecOX2k?#4b(p1QdYVIG;*8S{H7aOX*zC*ov>vjXc_REROwBqMQ{I| zz!rh(eCk5N%_W4J-&2=S3bGQqn&09zoLcM7$(w)>@Tqn(gTlu@PU{O1`tO1sj(xSeLq-Wv%JWtUBT>l`Kwcw&0J7TlYdr6P{1!K1N#c*IXxd z_pAWU_z`gVk$lhAAoi=n5nXlEe}U`Yp}~$N8Z517u(bcI#Ggf)H>4mC=hV6-O?cy_ zzp4xdv2PK2^A7m89gf(JLlE55jqpwha=HpJ852=_w|1@|AoU=8XE%JeG$KMEi)`*d zbW5iSRw{m5u?@`3Z}cE=qnp1IzBacayq-1dJDL!a*jt-g5xt`s@l6DvTb&4RYC?1a zbt7TxYC^|J_4rG9F5aB87@sdF#GXYZ@a2{h6e6OOKT9WvmqqDSssF8g%QDW zLXS&)zoh9;!axvO>ckPAU{uZY76-x1jvyf~?h>n1t%?dS0Y$^LgetuYefd>9A3}@C zi73~_>RbpDu=)!KZWV+uy&EwL3&s*70gL+((9(H$oi)m86{?i&Tnegs=Lv8c;4R>_ z=n0C8D+zdJ^cB{@Uuxnt@|wyCOQjlYNxFW*ne;e}|4a}1rdiQH#Y!k!0Uv8* zf$4<|1DB@vaPQ4;<4@bZ#G{)&#))gLLD`g5C>pvBwy~$9ar}j78hZ&vz#4xgng~=) z69u-Cx_qBn_?t-iZzX)V+9oIBZ%w&opAXkS;1Ua$0GIf2N#Q*)0bSB0vm~_~&WvjO zJky9RV_NY(&+Dt~X7p!?<*FWj<)g*Qjf8I)E=`H`T4ed5t>{g2E8yx&Pe50CBLd<8 zPY?@;IIp726THOACA}4c5>rbxEpj~}%%9c_e|8u4j$4kmhqvO-quO!XFguP+uRsCM zPtH>cS+PbysIn9#r?>A$7sxla6;MhR$TRAA0zGn|IC_{|Ad;7<>~ z4e##nKJ<7j#Amu2vHp*MU2h`%)&mH>bQAm!{sw`a$0GXpsfg@6ffcl$!S`!^U#;`u zw@yRUJ{u8tEcV8 zoV%n5p6vNp$cn7^H)@XZa-RfpG_X>`Q;F3r0bI#^eg8dALKr^L@41P1Igs#*Q zT%2vkV_9~*ljX$685Vq$X2B;zoP?`Je4W*ZF9=*;3~j`xnRa|W)Q!)EHsh5Moj4}L zjF~*1HmuTq;7ayR92~f`=PHA-*QD3t2=4QgR3lDH(G#{zDs+SRY003^8f>q)5fCX~UVr5E8oDZp~z5uS@unv7|fhy{goX+`@#)cqPP zo#^}aDgIl-nJN70r{|(~uV%}SfBR?n?)@c#w|66c*J}80XJJaPifvsAY+Z)P#ty<2 z!RoFa$iUNmHxXR!AWRXSA{$va$asjH3Uv8zt|weE)4z#@{_PTHs|k^tJ%lb6>KmE< zjs{>0Yx0|05Z&622*E3Og&w%F6`!>-^O}>3_vaPitA(Wq71hC;Q;Kl40fAyd7vady zc`qR-N_avG0nQ`s>OQ6bEq`)I5xtQ4PF5*3Efa815@kOc0q?5{u(3t1p3?rCIVd8=0d!_1wMhU zGD15Ci(Gokt1gogNNdu}JLRx+u0n$cTbHHEgAY?If*EMK0igro=L)Eg~p!U7*;?ZJgYfOM@~K3*i#3Cve5edAx-L!!q9U z90$Vr9{3kp5GiVaFW-*-ie`k1o2WMInMtr*)QrFkYEC1fm8%e##{FjV-pINI?eI^j z=YCeI!E$}WT`bfch>q@nm+;^l(F*VMWw?2y8D%W+rV_ZOv-T}f*r$n=ixS|HLT5UG z>xC!&b-;DstyCj&Fvyz&n!gBh7@v2u@i|@Uo!vWj3LY1*MNL)Hj6BX-Fe>vmodva0z7X zW#%8?)W@1}WLO)w_aMl^G|YYYSjY-=Nl(S-@E-KaP&^}+WB17A_~{h62|JsNeqmlC8^piAIO zAV=P%D%jxCn4MO@!Q!21;| z7iXp#@LK|x>TO7!Pv8>Rx>y01=J>8TyW11~Ski1L&4&(LN07Omx{>p@rnzuC;YdJB zELO^DMTimINeNtSA?V!2^;?-n088L%pZIO;BtU7Q8tN1B;C@Q{uO8;~5&kZEjPsB0 zlNP?=aeiMip5fyJp(l7QPbMTi4W;Q&3+bSZb11--jGrZ-_2NDWXlbzZQYrx}wN*74 zzDm8G(n{zO*y46sR=hUVijS)r(SOu3#Lrm`T)Kv^brfP}9uEJZtk{+>#ka#)$tIlj z|0hJ69|#)*HCS5F4@vv4&<{D@U};6k8rnb&mQM8DeTq}FbPZ;WX?QudZ+Zxkuyp&1 zApGVQcsH&gOcAaKRpC235Zfl99NGv>ZHNneZSDf@T#DGH4q(Sp#J7q6R)^|=7`%gp z^oC{?DINr`=e2w_h6uD24t2rRb}+SYTs>j_7fI}kae9&eQr zw&oP!>)dMW&8t>G6t1X4)JO;_t5y!`5h~umf~s1FsE0LvodLlb1L6dr-K7$`fskdk zs3t{ap|TNF3n^p;jI0~e68B5EKM+3Qu)pX@j0X+Xp#)+Rzy zVU_aL3Ol%taMwrZ+gr}_YT~t8SU^@75ivIq>P(2$*x{?Q!>eQAsORLL! zXoPQ`6@j^gF|laP zH@}O=Zu<&nuDBZwlP^RwL91iJRa%&b30IEut%L+S9nC^{Y-T0qPPSl0>+#H6o`QF;IJ#?p(o~2D6^kJ* zpymAx(T^TQ`1RWnc$#dy(JiDRY~U_t6a=4;Y(QiFyA^S=a4$n_;9V3}UcN@p>0XF2ikea|5( z=coQc2)(`)zN?x4onK1WDpQJG#7f`AC5T^E$%3*H!Jp+IymT?*U3oxHE~g8DW%4%7j8JhvAp6L*klJZDc@DK5#V z#Y00(cs0|Gw^;FcZ-^5gW;h90PQ0IC$A?)Kd`uwwl)&``;r_mnZD`~3o|htidg4;D zAG%~J+GpXC^W$??7B;nBLYkb7?fBT@K;Xwcz*$EE7aofEMTa1I z>N-SL9D&}V7JNO%f?d2nUNyXy3|8O%U*P)R>W3U}u(YBBKE#9uODFp7J~iMP!H?EZ z)`555`Bcke!e1fy>}7~=KLo*z?F6qT1h%#ybXSXNE);8(Sh2zqHGTsNiCYOtged_k zW#J-dDcBMV*RAyc=OecgDpZ`UCd9-^{&o-Igsd2UkFV!%ge_@ij7uCYahAWN8M{{N z@$SMLd^WQXU(YMW-rOqqiggHJcPZ#W*hmKl?eqYYC52&2^?`#H=0Y&F3-e2xXN7 z&>DhCz6m};lfTr4Ai*k3#cBvTWo|^u2yTn@=*yAN7j{I79Eex&UKR8F2x7imy%syG z*rmca#5vuwutr(80)>PxLkqn51U4O?Ls=8T`Ak>BLVJz@(Q-oHB0^^+f1A%Vh0O>p zA=s7o5UvP|vzoAXybXO5dF}#T69{cH3B@xAk&8O9X98hueka0H`5uh)pnrr%1zZeH zl!26atZc&c$QIn2ZAT3Y1PSIjHMK4QTsll;;W8sb0-ti4UH88SuE#&d{RaV;Si0`L znY!s+JWk*`YsEcintBnM$NmBBgsN6TRf_=ELHeHnSBn7G%xew;F3mAn3V*R~%}go9 zAEtKW>k;D2u7zia4DW!%#1bDZ9}AIiRtsVhyp%A8k(~;>WZXn)R`d;NP;t2WGu#9) z&T|`oW-Gqp{8yv8@WSv$JU*rw_l#}B&Dl-3EV}_`4zuH@88Xmt2@EXkmk_RI@q3q^ zhvG{$n&+kk6V;m9lFfqu9B|1vnzh_k1Fq2ou93XP(aNG_#fpv-uyw;@2o7+77mP`w z3?f0qdp||!!^aT%>+SG9ayp`q{~Gb9PDA{;v*CaIB!r(jiSTtQ;xAo*_+7t%_s6yP z#xRlJ^K`&4gPM(gTOpp-Rb%bA#VSy!Y9>n)-!riU@mj>n#p@F*;r2EKxK`>)}@K#%zOB?;gncwJPC=*2};G4Ok?J5QYG z^AYY@gjnZ7#5)!t+OYuf?i^qxD{;$hc(AS#M^9LQ+VotWXBpoMt(j2rVwr09^`8JP zk-!io&9&20^3j$dy%#OGKf{dY(oA?Q-Hf+}*ziuegRewM<(@Ax<#;|#vq5L{B~(;X@9Ex3m?z zGR^REyS=D^+S#~SX$9{K16D;bfN?IshOw6x+M|7&pqoJ zc)jAa8b;*nXR&+dPZ8S0THO{IvS&Gh+gS)~YlmNaueSCezGE5UTe}b!i`FIr*lmpp zswCt?Y>R|+AY4h$L;)-Tsf{v3Pph(YMQ-sRO6ZCUlnH2YK5~nj0LJC(oWSKy#7?cp zr}|QSGB+Q)=9Z#wQ6)lUW`qbrp>hMlHJq=rB5LDy4TKp^;ciBMX*K)=rhtyWQ9i;{ zSRB>~PoX*s{52LttOP`p2Z3@EBGQCc%zYM{;4d)%jUDit90(DnBG!6%r8&_c4(={Q zR3vvjLJk&mCYR=?Wo$sWn)5}3y&6Ij6{>Zjzubs$9U;isN|@q2fhts4Pf+4{RW=Z^ zj65GgPZ7b002ZpKN1%+LL|F1KlCTg?1jXT<>m^h}sF+Y!M$nr>@Z&U6!~N#){7c>F z&Cw%V)r>$suaiI)E%hKsm7W~sVU%C=~vw07uH(^h<1%a78@Ux%~ zOyK)5sT;oG+&`f!FscokGYzO@L8d~Fr06h>&^0wpddG^zOV7fv7BfZ=xSsssPV@0( zScqr>xNd*@K-jwFZRN+MEL^vKLEyR@Ed;KXahIWeynvJDFn_S5$?%5**R|-FaSbYx zz{PJ&bDXbYfmTUXU^b!Wk_j#Nc60|K1f_lzwte@ZbRr#=b-1XiUoQ{ZbCSvA!@L3D-NL3Y<+KuxP$q<9Ys>+_u4TIR5tGx7xW%J2gUxe*84{UfqT8x#GK3 zj`#(Yh+o9{iwIp8mmnrqE(({{Aa({Tglpy@)IJAjCwO%byxJFYJ`Y$*9a4#RJvF#^ zb`e@L3kW;KgkOOjiNnVGELK9E*Fe}(&w(14zl&s@CT)1AIegA5_&r^lB?BcJ@p8Ha zf61`puNe-!mFmE|1h4lpop>+9g^vkbAC73j?IY?@$79amdmtS-wEgaHZcQFX^WoCY zMZGJObSx-l+I5*${3hM1fa}~8vx)?NNvim5*_GecRRpXgY$g4)lD!RY;qtA7oZBdI zfS0DjBy4S`c5qp9b{FeaJ?=e70$UGI52iFIJ*4IdS)5Av1}%hxNA)a}@C{E=PjTH- zoIbNpS};=4vpfeGYDb&yZ!%0mmP`j)vtA}lDRG~#?vo3zQ?Kxzyfngu*QYu0S$PNg zo4bG$4h7CR1h{Yw;%BWz?ASxl*WQI)`3=~`eAJiDe43RmUs{9m)7+cx!CvMOeFQFV zddGi(>wl{sa=gLPiUu1_Vz6|g1NW(Ir@B86uf|i4zNj)9Ryh%T?RxmOtwu;3;O|_4 z@P=;m5vIZfEdOn+l}kWU8FV_~nr$bXKuyW{Va|)0qxl3MtiCJq-EaSea#Zu)UEY%^%sXv$SQ^Ufwmg!3Pdx>5B z9?7*LIGfkKfKXUMXk1`IXt5Rk`9?%I4V4n&2xpPXMtJAcBAjn0H0cp7CaCeZP+Gkvi@-av9x)QwD?%wP1gd3-WwBB- zgzq6U>*x?xN`~+`5W?c=d>6PJ7}1H|5ncFdcst%3(S&=mOt^WJ17{4g;;_s*SkuZ- znpTP&feJ#_OcsQ4tm*u=#fm6S)*3{yAeC>PQXOR|EgqPx(=04f=&ORC+p2f-CEB+`HM#hS!(ccD$ezRZvgMR_~Pkn(fiDW z2t0BE@YKl&Ja~fY5$(VKI7A3pp+}EJ=*eFq^5C(|7gnNobv}02PD8kME?`)Im}xQk zY$bTKx)dFw7GiG7;si{}yCu*i9fGPbpZCX>U4zr6cj9rwS-9SGHmXO}Lj_wEYYne= zgyez4DzWp)^ke9LAbM&OEeHC^eVXO|Hs~20O(a*|KID`P1b!kD_M7Uci+usEgrOJ(c%sT3Iu{foCpaaf+Rpf zg1fY(P)ealaSKV-9=GrNJ#+U-HX%^@|Ml1R-}mi?!@bXyxi)j=GiT16;j^UjTb|@m ziw9Zeo_DRmA6e=D#iI@HxwYYaLf89*uD=q%{zmBf*s}$@{kzf6;}dwU0GEXSaE{iT zEE;gh{b^t>z$MnT1irTc&stpJA(KbTWYG<{mB1zOwIuX|j7VHg_;6ab4uMt&Hc~bb zv^KeEPVrj_Fw%wiD8Xq5%DX%G! z&<$E3(${$(V!2XQtO=;nrrJ65`*7bZiJK)BEy9(n1Sjpn+dSq^e7<+wTk!6bCVUV{ zu+8km-ZtvO)8_$K90Odo2)ODPI4(a1=93n(KIw-(whMdtt%f~2l#iB<_a@<9#yxv6 z%JM%dlg7J?d%+wWV598+D&YFZfN@BUcC5%hbL_ugq&0e^L%gOef9XAI`!&##f+Ypa z(HB5FlKvzzX@Jy+lF@7*0;g9tPZx-1R=3*ZRk=_xNu>k(7^p$>lhZR7_YQWJz2p0*;knC4Nm(3#Q6uHUFSarobUY8H*c$nl6mySHeI*8!xL@{#)ZR0#ZgS z63mQ6Jh#3FrlLlmg{|FULR3K`TiG+!yoH7WLJPr4S5OOEGoM|i;HhXQ*zulnYGEkh zHH+DT$>lla1e6@6OR=O8E~^MO)vQA=q&3$=YgeX4u3~r|~Fmc^p zK!{4=edhP!Kx`AQKL?f=0v};(JciF3MHr6jgCU%t7sI>|NI=dy0p^4O$`H(9ypI^> ziMV;tc@q*NhLn}d94J%I48ZC?8;`ixqRcf%b*n|Of)?P4o>)$2r6Bn+p1}3iD<5h3 zPuW0}9Yp>5xjzlKxWdEVQeBFKs|_Dg2wDPMN$4js2biDuziNg(5T?7atp%NhD%IwgjcQw%{Ug+O$te=o-T30htfzJW07 zNw^|Z**pZaX2ZsotbGd09+m9Ask8A;_*`rb=*BJnZ8+1r7QL>8s3u(Hva*v3FM^e| zRLa3D+rfkk>EaXXjtcZj7?R+#;uNk$b7%RNZK4me)5vL@!L!8#%CWArY8Ozc83xHV)ah~l#c!d=J&S3^4>a(Jbeue zdoG1;_xZ5BdNmv`Q0F{zAso;B26*W_7olza@=hQd-61AFBR0#_Pg zs{*@9DlzDnggBQBK9knaRQZeVTt>#$OsT|`@%?zd;(UDHwG{6+-iMPzk0am+ED|30 zUIZxIU6OI)f(x<#hY{YnmG?~Gl4tn#_ZVBX2-ce`30tLvu5#FKDTnRWGB_kWgjl+k zOo&*#?$Ej%O{b^8GMEJGKsuo-ozRu8fXgrRjAEn zs4ZpGp#Yb}%jzXm%~Fo=f8;iStao|byRL0~zm0f5xB;J~w&FWBuJwxuS?8SsTyg?o zYd&FXE^KEV58K>hVXWxGzOY6dpuW_3P^VJ|m?iv+hs<-@3mrjgT*ccPqzozRmeFgF z+xz|tT>oBin*S$@voQX$d)D?l3oZ)~3%IXKDsH=BC3NFjccSI<=b_tvChQN-hl9{% z+As^24Q!E9qQ zQN(YRLr_a?fhCdWM^(X|)&^ZnE$rnBVMr&aB@uYzxj%v5AhQpaEEf8t0q6r-U`-%Y zCJn)n!OA9_-zm$DGHs6nptUW52tzI^xb^I;0@SD_7Tga}K( zY&`7MfKmlqGOyqv;EHjnV#Qa@e94xwUk(2J#^0r$=ATq`;#@6Ok)MYy1zc(c_|r>Y zsKBRA;CgZcL5s5M{`c|Z`VUl>;`NK3MBnr~&=+zqfs4Qtra{yHOa#7`sn}e-F?XXR z@MOeD=nIxJ&BCPt*K~qWI%R1fTdjff;E>P_KKy=D`e5~D<7Eopum1`7-hUB33|xfg zrVe1)ls25|S&2sX93;7?GBSipA11bS5k;+NyhhR%p zy1b?mez!ovN}#d|6(Z8N41KMq;F+Co9{f}au4LWG%r-L|roFIy^D05>evIzC2xCuP z1k-a@!urCM(C@hj_Sdc@Y+V5J&QoB0f>x6Px@x(MI5s^TZkcsK7NL@>{N{8teQmp@eb?U}t-@;6^tI1yO&{ z!sP@miL>Pl`=EtfO)9Os+}$4Mu{(lG}kSzR~~(uz?p0@)NcN)<%S zg2|I$Y5W!!&zJ(XE2_VpIy z)3{9RPbninl*61wfXbIr5=1e}^q=t>Ag`E`UPLW``| z6Y%nDVJhb{mh#>!I${P~T9HiB3UAt;$G;<{c!7vUz4?;x)g`Yh?5 zB&3#g!O_U~O7JqJ3xp9kvv^#bM3E=tq!Ylh2r+rQUxJo3rvu~hm4rzGZ(%P%i_e-Y zlT#BKOJ>25&-BU&I|&jYz7wW|2A(5n6KD$wNi&);5?T&x3b#c!5$sr)(+J4<3t)=x zfj+JWW3dFOtVM9dabF-|F>x-e!2(=!VDxK;F`9}ZdI;vIA?QNc8k@%FOgRp==>)Nm zKInZ2rc?NBr_Cam9ZRqn!UnHe6w5q|Y9eQ`KnQfn)FM>`5t&}60x{l|*tp^`?B6>o znUH^y8J#uuPyZbbTw>w+IpF#RHypc10at(MQUzQCVJnY-r+;1sWGVA5Ml8jw>Gz<- z|3t)ypBgKq$=!+)QC{M2tqGOjrbDo?W$T!>05$^F0q;5Z)^8Es3S5X4e1{iKYeuJg z1=3t30BIhg`0h04d#2|mQzca%wVY4Z0SATe`saabGIaeIwp69d>jv|>A+9yl8Re8B zWW~1PmTOjE_G5B~`qbI5J$oLkd(MRUp?R=9b27}ke+~PdD=~IPCH9s2vk?;pM|CXAa1splx%ho) z5$5=(AfEb5VhC!Jfmf=oxl-?PEJ>M%FIp}G+OMNNSc1Rjtir1BThQjQfXCGFUCBI} zV$Caohf5MpTyPN%>=)~nGsoFs+xH%ZH=PCZ;&M0^i*<{D<&-4^uO+e+5#VyJi=`_c zxV;pn3$kIJlS1H1gMBdVFyNB#5f1U`T2KL9c`|xuESwVM2?GMp6T|e!c9KSZ1B`$k6SHXbZf$!uB`;E7Q#d`A)+3CbZ^FU zK0P?zqY?>Xxtfrl0xsDuu%(1~I+({M5xN$7G~ybMRxBpO9SK}AD$yA!e*Hn<63dpr zR{Ozl56Zg5I#C^B@2P`30vp0 zv2fxXnEU6kZX#5L&BPc%SLQ-B`AUcv!WH4k=y@m1Jm%*~_I6~9_ zO!v=(MWBno<=Dnn`GbRMjzjy#S+IzOYYTzv{%(NqWtO;Fn|lF5mqoe=H_znx?W!wL z{ocY#_<=51*Rhi3cFS4<7QxH0f#9;b8J0V0;JA~O^+n9kl?8;YattR@8KsrMKrs`% z?8Qw4m>$*rXR07bWt0(E8ZlNVj`1A?r$&rqm&4XQh_Ui|!jw$g(+yiiGwg&cTa|Pz z5nV@8CVur8lf<*$67Kwv90kLN;#tC}HiWZEPG_bYZ zPH>V5pap6gfoeW~aSN=?eD<VMeV4Z4PAN@ zECeu10`E7AP+P(ZJ&!O|FbgAz1V-`IiX?0%F^%+oLKB}et^;GC4NP-B!HUqFe;mf6 zxIbw&tdabVGv>n>)embRua$5->`{cn@L3q2LZFQ$gvT#{E{I_3%lFP>Y%xqHVhGl7 zDx0Z%ufEJD5y#*`?*imBMTt60Pg{xJ%X*xtGw`*-{XmbdSO?WJqr*mE`< zJ5Pb>i4$RYg70HH;q$R$V19HS8)5^{ol}JGE5lf}!&q*o19kCi(B$CHmDM;oC=9AQ=9z5&Q3Cd0b4OQn9yWbmD}lZp2B}ErG3DD9X~MS-BiM z&vbkWtb>Fu0+uFD3ztYHu#j*zPzqyC1%~5V@y3iHoaI}GG}l7DcX9R?Uo=9F2*1PO zz{T&xZ+j$gsqF+$@fTd=UWKI|wRqI62D{xF@B#trH3HEauFZIp046~3`zf8c(yIyC zYSMWvK&)mt`zhd>d=Ju9UW68p8eHhnhQ&;GiCZ&na~0sy9OebMWJIDwj~5><0WOIW zFTkb2)tuNs!t_Alk#Fz?N9FoFcF_8MI!cyhJcjBJ13*bt7t`rrMzh zY{@h`0$O6>60nl)!9!h&PM@td{LzC@O1<@G-+KHdq#hr#5xcLt3;LOTur4BCopU^J z!Le{$I2ZP_`Y7{ZJ@HsrW-f%GjCIe9F6;|v#t)usY-m%!Wx1z{z*P<0F%t)ds_7(V%Hp=H3c^z-Y?TD4(iWhR03qDy|9;dLNC+e)ONE4+y#4OCkzCu@sdV0ccDz7V`=DyF29b@MzCYr z=2{-d<8754uvBneEL3G|<;Wz^`Mh2&0kf(D!xBe}pk*j*A?Wda6>8QkT?v=jyqEGm z*ot`FqE1+3(r5yfK9O*k)rueD2#a}C@&qM&Za3_NCVLtotFTW&m??vRHG|JWs4{2p zyx3ZpbEpW?3428>urru`Hs2u?gn_VT=DD_9ZcpKJXRy%D=p;n7z&wKxm_W#i;kQZ} zgkd`2GLeNnjNc}X#|846MfbxL(@(gX10$iz5<@1Fs#7a#ZU%~d>t1$d=6TW}^cQC$sE6gun59=$}z_j}U z7@oNT=3QsOvSk6R4-Ubx`vh2b5c0PV!uI%l;E@F|UQv$y^+C`VO=lTOW*JX{y)_*l zHI(Dx$Xq15=J45SsmGcK7qy7zJDV5MikBPNSnR$Y_Nwz(p0B`%nYUt--@UljYdr=% zuSb%5J0jfqEeNmSuC;J?NyYJVFT@Xfht;!K6*TfOM!v^^P3J?uqzd+%3*fjpk3dB@ zx$y}>%lSRS1OtY-Xy@9Euu2D~3ti!U<87mE%1u72RSV}Vl^ z0_V;HE~Q*Vcsgq~Y^NUw`&>2>I_E%N(1QchTd~)#8Q;4!!{8|vDuR?Jb*aaI3hQ8Y z=ep}G=sgKr5)#IZ>n^j@cB5NA_w_?ZATvy|aLGjUGLl&!Ot$|A1D7boAIs5?{l7sp zWqUOFXYN_{g^I9%1h7C)_btbpFMOc2P%U3V_xfEhY+e96LCZj}vdLVC>$u$5Pk0(2 zJh6f%Tp8E3E8i{arkN^QylH(K>@q5muw~)8V~hB637E0MCtO+96A0EcD~pzu@MYn; zO`z-nrn80>_ubWS+)4Pjt_z=4=Hrv_RE)$H!g0KVW z6$-#)RH0EUU3CO5?sv2hLUwniOn#kv|u!Y+tLY@IfSPii5Sm9o6PT$ zJ`>}Sbr_H5x5${y^Vw=j7=S*Qih+P-3?=x*4MHE*4MT7ztdUd#A$$)>ge$_Aeg^M7 zjL#G{2-8#^AH;8-cr468yib4Le;9!-?L_DaTK4GqF#A%Ou+?nwC$NRj!$z+<6cM<@ z!B#9>3KpcoBXEVY1s>sEO#qYf$NbD~-UN?8w;~)jbP-;9>MiI-Crz-YRfh-H?2~}& z?U%m5o(HuE^BQnzvTHq|YyJCpanskh<>Y5D5PKK;LziKQpfwP2Gz-^+)4a@=co=YT zJ#48O*(g3+{ZY%%8+{KtB5y%;@I}b*p2KIW=CiS!@p+_-2^i?k7#All1fkWkC6)Ppp!C1z)MEmY4MVNx_tjgct1yjts{X; zgDepZxWtbri1!f4eLe)5ps8gz_tabP-RD}@8!QgkNL$i@r~#K94&8S!eXtw*cU=el z3yWcT<1W}eY(P?u~eY;PnjUMXtXr(B;;M*9c)-{bpi--+MZb597BE=erTu zn+#hL%k0O%C3&nI3B0%C-J5ZPTN`e56{mTLE-zh*9fYn2 zMUkm_B&ezCP88Up>?ROB<=R8o>LG0PXkCZ|B>^t!K757SULk0Syhc!Yo$?yD$tc8E zd5k6!>YIdT54IEL!geh4Y(K%Mwi5@E*)R`o!LYw$>>A772*U<{T z$YF*4-ypyI9t5nM{o|8Gl>RSGVHy>O#5iZ{G3bxms=$~U9!+w ze*(V#dar0t*uH%U#+?_#xOqP84-=|nl%ZI$?q}t_t{aX`;;%KRCY&~`YlH1U?iZ^S zMYp<YOUBHj`oY_R^n@Py2fib@YHo_Fjdoh|qI4Wb>5;LomuvNgyBa0AKIuoWW0%u7# z>=K}qa3vNkOCcdKlK?2dB~~hdtekej7-6((4xx$fy^yfO!foR|Q&tDenLIYN4dxkq z=jmb{Ylc0K1(Zu$VISXH11t#yuNi#L1*|j*=fW&e<6}Fa^W(k%zQ6Q^JdWR%irqY| z9hL~fRCpg835y6_{0>w`Rzj3<`VdBgx?v39yG}k4=I|jN$7B6_V2xcw7(O1lP%4EW zw&1*Z&%T6kZz>WWzJsvY&_&M2de52(;3`zW6~(e97B1-~lL?JgSDC<yaXF8I@s&V_ZtMKWEU#c!2?N6Z=|F3HK2_bO3{5gS3;&3@FT$;5@3k~rBf$Li= zIfcL#f43TaI5+`ZT3Cn4z@-6|6SxK<C}ewHT?a$daY8L$HkGQno8=n5s~nel$|KY2q9? z=CpP>f$PV*K(4R7&&i_Ag{XD^I7KSsL!hPo)c-jq0gJ7y~@IaaU&nwthoX*A0WL8OMj)szi=M;-1w1IS*Mq1$e~D>txYxsK&foDCJ8wf$0T|2PVwH@0%B<7Y(B;AfZgs$Cc*{*>V zAxlK8SueX$2sAREp+tz6k%!`+B_iu@5X|1>F>lBu(4Osh!@Cu4v0?MBe=|M}@5C3; z9r*iQ@#j=emL>LY7P_Z|6 zL%I+NU3LPPmB8lM)CtF0Lc-lOu;0@N+|-ZHYxD8<>De%(RKplw1WQIaL4y!On3C95 z`ZB^xO*?c2H7d@PO~Nk_j8v$Hs%C-~)03d0GRGjnY_zBzmKp+KAzLGaG*fjeMsm4L zfUC9(-y{{VW!Vh_&(r7g8pQ;+Dgt747e>;{2x}}br7b+a5ymVT;m7l`xt><5f{W@? z31Ma;x zq#~0p9|0#BQ5UITN)rvXCX2IzJ+h)bLI+I9k+3DA&4oA_sx&zgxHLuaz7pneH3^3KZRSP zo=1<*m4ucy?VET=c#A@UWIEQbd;})b1VpM4iVm3n_7wC>nU^KV>0$w_iEhM$@-x6C zRxW2;E)^!C6pky3VOf~Q3Y;=8lc1%EX6+(~$@U?F<)R|k+S$OILERVCiXRdOu{ojx ztsWBoqmaNQGd1v=s`^W-H#94k^P4(>%UM^5m9Fn@TRq8bIRd1!Vo#-08h*y-Jj-Ch)r zR_t+a!_!Q6w`Vh+^lVhJTSiWLG~rnS;IkeLc$wQ?_Nc?_?hSa8+urctH}z`7ADG5l z9xeD2(|L>XC#LZhxBuCv8GoMIgg+5{-XlzX5Zs3MgIl?5!N=k4_#&YjUuSjUd)5OZ zY&h#X3G{vQfuRM!LIT!tCjj&K`pAm7ng)3>l8LjJ=qW?aES<9$+1T6 zbH>}!yUtXQB^EAO>IjtrTr%Oj^4*fIMpx--U!9@-}V4OU}Fnx_Y)k{=)_K5gTS`D0oFU~ z;kcKua$yfX%E-p&u|?PyT>xWZ5y3*jK**>)0#0QM;fW9+;TkHK7GcX+!1L=Q+(R=g z+^)}WfibfM=CU3N3r8gjL@gnsc7Vq*6U(us?S!rx=o{F&;BQMUm*t(XHnKHS$onIV zS;~3;CA>~0VXA^~Qpx?Lgo}I@zD$BsG4D5n;FQN>2v~-k77V8o0>!eG#Wc!hLc%>* z@;jgx1)A3mRI!yKK}^#Kh1p#yWP?4E_Z(lXoZ5{9Fd2Pl$rGP47F+?c0v5Vt0w00P z!gGunyob~_jK{O}UBJT1-=@L==o9#El9^^C!8Mbup*VrUE&?l|D3S1-!tWW*bJZM( zR4%b|U<#W_s3Jgf-5SXjS}ZHW@Ilz8GM$*YFcHKIzTFrnXi4{>Lo8asycV~agZc

0{|q%l8Ids!Mh`=t(5Ki8>bs%}*8x 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

}h28l-d8*yAaeUE2?p$FG!e`|Q&8r=T4jX%v zx7SmVug@98F}o~kJi$Q;KL2|$gPuFuv>*7t0rZZ3yq)KK^P<^@00b4uq@&|Hcp2h5 zkt%xNS2BGtVa<2&y-OgMX{TG`vD&&Ptk1KN-mAkZ_oIGE8g(fNWJJN2U|$_Rjinuu zGg8GF_Tkuw2Oaab9qpz$*V=!n+jk@u<0(=6w&IpTUbwqNmC9~AeuV-60qjMN+hs06hh0S9tv8LhHCo@ z|DI>I0Elqqw;sdT6CVY(02U~p3`bzEQ*B%_A{1a18Wx49Q-x#R4pWUr)jPzP4x%dC zV8)NI{Vr>QZX(Taa=7vLjMg^{p6vf!e-Ut1aq#U$9G|@1P6T8%`(Nn~-z83^e`yxj zlb?}a%Iq&$)*HPD7kceJ%y@q?$1`X}!k0Xx=~Hf&&0MO!$(E$u1X1yl_$R%78%CD% zqHkyB1MIAcdap#twsfYV!*Cdh(r$tH`VV|s;BkPiDO={G-W&!iTLZ+LDAhe8&C1=Y|OHi?j#i`h;AC8i6MAclp2r<#|%+K zOru!4X|lS{>QQ%NhZV=$tqEllgzDRiE*0_DkG8AX+rXy!OzKX4$fDaik1!D~pD|~w z+Dp}X?U29MQWvv=ITt5sIT!oCC@+o#5c`9lO((g$nsV7*YE{w^hvNyDMY&PH#Pfx) zA*)KLq3E<4d@O+O=er2GcCXsF`lYLH(EvyPfhuqkd^FhdeC|9E4lZIOw7N}HJR#E= z<9%)rvd+ON$%nEAr|GO2hpUQQo;h)vC~2-3u&&0NnozT%&N zRAfDlF1SJ0oeCJXi6%eu_@RHIfFHg=PV0FGAd}+aTho~7!W7Z1jER<(;Vq3O^-?>=gN z$=8TmH`PjFE>e-hh?-#V<;jv5oO1`#Ir=)rWUER{wPy=}*xGFlIlMEE8`oGHjaVb| z%Uo+6gt2q1lg=C+JjB&c0eMW?;_4B%J)RF|hxZ0ZJWiZ>S<=p${L4@oh&f-bX#`-^ zupiw@?qVzLV(WS~3$sz1Qkne^QA*CAv*22HQ+B4`l9r6WI?dkywqVfowo0w<%vy7B4u$wlavWYJG=MRYx>rhpR$B+QKnVl5DS`~CZ) z8!kkgL*DEniy=nXr-$eN|ESI62F^FG%*)#UBOZJ$pr~R4P7}|m4!0r zhLi-jY1~ubWBPP6`LqllTIXSgfG<3Rnbc)^>zY&eO)4zynimGlJ}Hv%c^d17_A*)$ zBS@*`GMk6JBW!Xd&OH({^OkeQR%B6<6n=kCZ@5=*Pd0mVM(xxyu+tJ%0r@89u9(l+wEXXgQt$F_@s>qUh7$BO-Asj!RI3eaWZv4MPb@tyjXb#JI_iIsgeI=l& zQ{QgGa9vRt2($;%wD?VE^d*1Hct4@^E!ywAX)ddEE{srQgc&ZqAvQszW5X9hq+CMM zPUi@+trzP?5y!+0bK5QOvQAcSd~mjpZ8T!60W#JAMe8!PkxQ4b#>1m0UdY(Jk2M42 z_TK0Acosvj9+fY&`ow~S^@3D5yc`a?esv(O^Y=yi`iUpB?iC8#iFMO0Ti*M$OJl2* zL!WUXEZ*f2`;cDlD2;=tA=&dz%0vyv4e5zc z0W?$Hw+_ErX?=Pq0PT3_X73JUxF=A}yq6jHNTC=iFw+mOTsVMO@uKTB$QG7`5jciW zqVuBc*LA}N zel*0zPA%YCVhDZGcDA(9a|^C@L|H#~)C&_x@lg(6p1EXb01?j>g7}mS(+uhv&CLJsO^T*gNCw%)JxJ#- zKj+h6YWxTTZZ)LQXa3j^hjp(K73B2UTqqj{zdI_zWL~(L{!3D*E9`gnNZNV0_tgq8 zoAq_uN_1~_%MAB&4dQMWrMV^d!>k4X3C`W-{OM?3)n(lvZ*eqI2%Yg#*!AMpY z^MbyKw0K2vLaRNCOgwFUjdt{D$k(qEG~<5(-V=ZmO8R0~5`RHhNU;8KY2l&hupyrza$U19>q`+`b{Y`0S{o zXqc+x2-kdaCV=s&VDRMKCH?Q2EZhvuDLvP8C2sjXv{TIv3KbKVGj&g|we4ieyRbjB zEaV_Lk>X|A0-fjGJ9Jw(v=Emn0(@nnnCUtALrI*oxSk{i#S4dQHIwOvY#q?^kmQ+U zkDS{wPbl9DGjYY_Tp^S(GQoxg!C!L%8qIcpg9zlRkr_@iuX1Q=Awcj{y185-xAe0x zN_(dH2UoPNau|15deHM*K+c-5$0t0fT4NfCZwih93X%*>f3ntUj~_mD0JW%kzWq`= zVK#gDa`>v^XO8ObtYPd;dPD+0e?n;~5JQGgbpzIAakU z2h@LX-Vj5 z#A>uISCN2jeiyK2D3`KV;L-ur+xy=nG+eSVwTAh{oC)4@c}&;l>_UWfIm_X72Sz(| zw>lpvFA~#MVYswo{!pTawhfhhg~OPOXr)IQ`x^2zqS zOX&R_?3x1YL?${iAJr+hh_b=52rlw+yL4OjTXhUdsVUx>7@T$ zFx!MEr~OkOyuJAM)=lcUOF{8(YnJ&d8=j}t4x8&v!Mq-55-T)Kja=PR;JJeHf;1cz zHo3<3aaW=K3cv@aD&=FMB?v7w2lLpPZ@^Ay72l^_p>mr-QLqGrLbH7*{RO!qn@=C3 z>Un5MMCafp^evxA))= z-T<1ndrwp_T-sJ8H6$rcyxgr(S+~ngqUK;N4Q&LRZaY#W`6*cftzUp&LaK+C4Lf{+ z11(|J0#?xK=O|m2wJ{V$$^g$wZZGJu6nwST32F4{D10=-XsA$LN{}~kcx1pd z(6_7I`mmGJ=bR9LF4qVW0So$c6EQ(#FRtCxOxa-pU=u(%xa5 zx?_YeUbLb0zCx*=xi^@zip34-tk{+_B{VW#ajEV~Phq%-$mP+tt)d+01^Aw|uMk%h z)^`=hX+K#z9>D7ewP1|fs3KO+xM=hYKHWk#bg4*+~iocCk2{+`Xz#+oJ;(9hcbm!3# zab8>iY~^wb>^4ct+>FVfTIB6`QyY-|^+#)39HWEJ0f*4UwH61%Sq@_zT-1X7+wh;8 za_>=@t4q4Ldl!@s9w!^5xNHdYWdtM>bDWv<3wFk+qrzdY=GZ@@^_df&?FCrTC66EP zml4TFsuuuZV#uQ1`y{kH6h#bguv$Kk$xNIBC8GyN)p52nZT)(+BRu%)Z~q6;2p#e_ zqEJNr>R+!^bohnFx-})lE^=47F1`ZY5T!=o*WBc78?Fbl!b=__Q#Q7lKymWR3)-|a z#XK<#3U6pIYtSJRpYp46g`g(sxyBYSZJ{6Z`^vYvjTGhf>GvNM4 zsMyEh+(d2fNQ8_OW8cr-!^Eu#V#{SRk-c7~g}&8QG9;^2NSS+j#3L7$;EQfC0jocY zKM0WJ#(eU{JPDukrauB2mPg$7l?KOr>vjxptxqj({S&0kQ->Q;s008e5w_J;K7U|40kmF=>pyH9Lgz>6)|`VSKa*FGdolBoVeS5;Q+HCm=+aL4bHo2 zJE8w#J{DaD_-+zE?Aqk0lB*%X%u8&W!(`vqeooAgEX7AjKz$W_!s zE!YiR3*dfbLeypM7{6zQSN-2cNQoMZ6bmXBPj&BrgLB*3LtO0*QGyI}F40#Kr68EW zp{fL5m;f%Y8=$3i%-%fgOAq-KkOMF`fi~hnEjc>%{EG*R|FPgD0otvQb-t*t&nOif zk+wti0cdE7X|*=A9RM4oLhg0?!@M;Xc*Cj*#;$m{`* zO@A&m)2z*?HfWR-VoS=KHx}E#d^wS0xF@FJy2Q()X_0mVDNDhbH%aiViqXZh=*chI zuqau1oeWi(MD@A?QG%cPuT>oHhGC?N$;ZNSsRJ4CF(QD8#Gr^t6CaRz$)0VaJmp&- zE-pE`ppgIh?O3$h{HU{>>7_L*#7Fkh>eA9;I78_2MZIKcZ)Ugb0kM(klDsH{P;qPw zkVoBV-zx`Keu2(ccYbOqm=?ORO)K>LTb~EXa$1y;!U)aEKiEOrS0_YU zOy1P-(1EX=eovp6OI%p}1h3Rel?4@AEGMx1!gUBw4A59)54+JKF5^PZ zyOe}S%UC{(c9_2K;l;gvzmlAU49ZlmO>>$P_kfNL>!ARa?G-erbQ5SvGvO2(LPTi`pSuVOcVar zErMtiAQWjc=)RcT3QhQ0gKcXa2}cKm#4Nh2R79n{52-2ficp(7ajn%vfa#5?izYczs z>Jwa+uuWdd?g{HAI})IX@z2czMOe(H2ohc2=d6!f0&w z$?bIrFlCJ&K*horreMqfs=Ju^6}0W?Mpkjs*HU@n*{sIq-K@4nQQJ?;mXL~LL!`iE zfMQI86YUpP)fQBP?S<5c{R?c8sQQT9FOhXPWrTy+s13Afu~zt!UF}N|S%PZL#`T~$ zHuZ(`ej&Vbx!}16VP{oG!1hxV$w*?0Iv=0<=jDYmRrglcs&Q{ABjRw(Hs#5@^hnnQ z!#?+($?Ct`lv13*uCBqU(Iz4nDrt#k^cE~qbD(`iKVSgZt$$V0LbuaIxZSs`B}agP z0o^*0iU-{~^&qZ(d`kpn9c1Ryx+e{#)L8lvu;10lAu$oXbSfa~9TGR#QlXIj$&zLmX;8JonY1Wlu zjNnuI*hM9XmXpXk4<4qPy+xEWj|Y7Fb3eYum-bFW1E%~tI05+*qxNu`=&M8dT&S&9 z2jIj?`(c#5m2)Kcl`(6j%>F@7a{vz+u6)`=DZ#jaYh?V9L@3hy0ANzE>f5 zSM8Z53ae(b+DHNLcE%sB!!9A&t0;u6m9 zL37t^1~e6Wo8WK#yhN*|`mcFJv(~1+OsbjFZ1Wyq2m#h%fJRHK?p&+-c@B@LSjL<^E(p1|#E4^#xgKyqdoP8d!E6ipEWKY*99qG62B=~lDdX{^)X4eWS+Qo*EET_V+n z4???vVgUS$yCt*>#JVV|U3wRyC5&Z_HOUX5MfLLSzSeU~lv(nSkb{T!^YnW(jncaH z_?C*pl(v|x#m_c(*m*mDQN{%=5JQ`+1wF(sgE2Ve`HZyoJIuyb#8f&|o{ZoqKfI6> zG4?r;V8BOkU_Je<*$w8!a5`Sb5dOgobnIeXG2o(+kr37}(nPd-W?#K(EjqY|sfqwDn@LJkpal`d$PG6lsOk+m z6l8}h$z@ew#}L1ZDHc;zs93j|H5DO`hY&&J)>?~WcWdj_nuBmKM{J$r348%oL?Cu& zUK=APvn-MCpa;DaEaatvsW&y!p76`x03Y4Iyb8cmTGKV$#si1Merx$-p>aqTcmU`tRQ9}Qbgf3iI*BjMSN2-I%4KsH6$HEe|A&1`> z3get*2~TkwElGd`HwCg&I94M*#0lk4+IT6&l+xVz9m-f<17uTn&&y|yijMXCIG%Z` zyCpChKqm$-wy*#?yFdWIHs5bkdcEHGgcn-R>0*R0fbDPaSp`QDW~cz0g(@nL54@i9 zw7MNG;ESl9yM&e>*zs>|C-dGHzz>wD73+H7alcHFK>@oDFtU4#)L(1T>R`{a{098( zvh!AMqS}u-2`|+v<&NJr09;nvhh^R3LJNl%G1fF)Y33!YqQoR81dh&svo$Uxf$dk! zlcxwMU>ZT(`RzS8^Qn|9y?_>Ug59LthVvTsN|sqru&=}ey7J^a+Mjs~fskEF!`Kkl z;C}5u2|)XrmN|`IT1Y<3!dH2+UWps2Bq~lAFm&&x@YXh)a1!*GR06arIUCrjQo+}^ z8H>p_6+wa?UrQAR;y~!wDP5bjiY4!2D3`#|l%MgfWY5Fx@2=6Pn|UOjw~YC`3Uzof zzJAhpO8~`(AX=GpMA^EE%2Bh(fUi+}PDABC;j2Hbr=2|u6M-)Q4MTI)=`VK!93ylXFHq-CkCLZ|!pRUX51tq|#9U`odhXl5 zj&1^RpOFgm(1TgBd(QBX!mcjE5jn8#0aYVy?V z3(vCn)P73}Pz-_Bhfp=qKvwPLjl?4?8NcvodFUbFy5>|H99kkm#6R@~qNp$du}xIZ zmxw0+<$_p1fiG2UnbNRZ@PJ_`nPmT~x0gKTczsSjvpmexz#rEjfS2fXeElLdzS}Tv5t`8cG`K<8F^|bI7HlJFMt(^+eEgAbLqKz^KNaM00H)#QGn%Q7@fL3kd%RTWp-`K}>6dV@~{&o-^Y zcX7#<^7IoWWl0HT`;oIUA~&k(9NN_SSB4DJ-eL<3s(j+D{ot=3C=gXV~Uhb8-DecQP8Ye&86DJo}b@p>RQr-L;qE zPeblOrMjc#6&tMn_g7f|AxrHC9}TB>)?5W8d6UR9quDv&?(i)N%{TK>py&09Yl4#emU&+V2t|pfM$3#rKRb^%;uk+?Wwb8Z z$qgmctHQ;3h&s0=k@h-8q(72Z3cA_0H@BZVA~puHz;EnQjRd~%uU>Xd&O{$%eh#Yp zGaA%|Id1#uTr!Z6Orq$?3B8+oD)x+QD#@s{bo3KJcOiunIO^1sfftvX-#{Pqb23eX1!ESa=ew8Uwzbm1B%s`u8p@x(aLiIz z-FNz}W}MSJ%BfJt5I%Z7@SsuU&nz%Xd}=oxSWwhwUIjGaip%IKWmT2um6%<28=7MY z%UjJn0W<(i>CK^vFQujd53S{Kf@0(502+z&HnpQWS`gWmQ`c+GxUcSxhi_A1E?;!_ zIf^Q~@9AC++F>q*cI+en-jd?n?o{9?5Z|)e$#J>%?00#lx8sD;&*f$8N=?4z0y^QH zJsy4{0mJLsumr*FLDZd1&mfC+s#*mG)%s~)7^l;98<)W<^JE3@U$gO1{Z79^5NjM1 zry6D&u%Jt`hT9bpX*hgU!s?WypkDSsja&C|D?jtUL|D&1OJWb5Br`YaHCS6`%;;FX zuk>2fEyy$%K=9MR zmsWn>E$$Ou;Gblo$)62ZpxzVvWAcL3uyaVcR~Zgp$H;2$LK<*ql;3wr1=`J-oTgevSJz|4v=kPF=L<6 zdm1wVCbg(noh7z3w$YPVgihwDEp6#-olV3*Jku;%a0 zn}{h|IrUz4(e}jFK%YLf>tec;6WSOwVOiJO{n&c2y<=rI#<69aT7vP^(7o}(n_7OF z0TafJKg}0c@BV2s-oLBf&wCwe5%D0ehiD#nZ2$Lf@O|dQBl(>Wf8;OP+kzM0B?j;A zL@)lXM+oUX-kcsh&zC=!pPy`Q{k^^utj2i%L-Zm>??G+gZh`nt*D-isIUI!^~XGcJv@7MoUTW6{jvG-pWdUV)fMI=TB)b7Q-vU}r?NIH&Od zd(t3AtQ0#N%Fne>6HLi^oZp#oQ38e`2;I%hz^<^siLQfcrf`#pn-B9-qEGkEA%~U= zT_19s2V!n-9{C5K2I`rV=9%iPXvRKK{1JNI)8F`OMI7*$C0d(BOp-Gz@`gO48|{;&`&&X7}Bpz+$zk%Cvn zgV!-3=Nx(_X4J5u93Z)5Jm-mDDG^i@_WQl}r1#)GSIBkZ;55EQ{k-hs^V_lYM}8*B zGx6FPNnX{ih8&OaD133Gd1LlZjs6sD$4ZWm!&C*tw%q6`6acx6<%QTFVVwjhONDWj zX*0inh+;h$J_b(O0lzer=s<6mR&K|-8IZMo_5IEwYJz=bkj=qB=6& z^eLX;NajNJXm~UE;vdr!=c&{q4-dUT?OOA8P0f|EjS7=?{4Vm+kqd2G-g*Fabn$Ik zdyd5_5V4*E^5Ih6ugxm-Y@+#)N~+RHmRW1jsZ z$kCO*!D&$yW_C5YD5*}^498#`q-r6EfS)kJ$OaiS1_ z%^}L&VR(|toItqf*=J@->%d9p8&oDv*q->!q&G5l{l1dxb=GOv5!b~K_;or%3{&Rk zwFIEeJ=pvVVCyr;uPGPn_XYp$7hX}6luYx2m*=ITT&5A*H>CqqSEHfsXK)0o@AmO> z=A1o*SSVs)RnDaKm?noLmVR{e zh`I>V)7Q$r|4PFDYSFV z2&EpVKfjLHGXJ{o$U^E=-crD}hMn@Yg35UVVLR{hzuCocyIj(@c`3W?6ORzI5_{;n;-wPe0cS(Z$N zl7iBzhupcZYDkMQB3u_F8>%r~5YgBN-g+OeM~|0IYzy%7t+VmJ&m&Zit}dw+L^U+1 zt>KD#xo#9`*o*H>Q0Te&8+O2;PNVeh08`#;0ixTD=%A{f}S6m5>Ups!VpJU^ehzP z5^VdnwWCU7+wSgn9fbeE&M#&P_zJ?r~DmTYt|Z z8=eGA{%=+lAjA1>Yh7_4ZZ!@^(1&|{YYD|9D>ekRb#aXhSw^8#Wp1hgx>1^~*vpLAG|i^=ii@C z?@l5l`_pb7STE&+mOfR7bVwz9kGKgkH|c%#MlF8=8S?Rh=48d8Z0fo$Z7S?^*xV@a zKHuN6!Exc|oV&59ZYc;VE zltsWz&n`ho(E9Dgmm29Fu|B0aU~hzIaE^>G!q*(F#_n_^8vZ7(p&V(EgV`j5B^J=4 zeT294Az4QRtDWDBR%;y(v%zXYA+Ocf2Zu?48f4Ysw%ChF+M5sL^HA(GEjLKjh8MSp zQ=zgb-<;>8U;O;mL>Z0ymsONtrcAV2m!*vDKzMOuG)5_7IWEs8j}RQB;r5nRcIdYg~fR7jW?H0}l0tct;z-|r?^Rz%=)ne%@<=7xRd zZ&+R(kg$3SAd@`({A^QZCM{SZ|E9KjoSP4(g{pP05iF|befj?IWm!n`I2NxWs&xsI zlF*_@>`jocvUKUNk0qq<3k?k>_cJc0Pd8eCfE&&qe!~%eQ@Zs8m<4x3<(@~3t9$*> zR7}!8j4qHf#d~Lh00C}Jf~keXI!=xYee>oni1x^I-X1n1P@bGV15?-o{-m zCVA6qJL^+S`DdGGt5n-}UdI8-!E#i(f_-lcQxBD$wh2 z%$<(7_5}#=%S$+U)42-%y1Tdi&T)?PQJT+LkK6y4=awnhWB`6V7FQ)Nn#`Cz&9iw< zQQ#ygL!OqaKm!s6qe7{>aconEj@=H3tr&sbpE2SQpDPm%I!ryrD4xDLgJZvsy6?6r z4^#~Q*}LR&RI_1#ChKJT7v5C4qFag}d50v%K&4+DZ9H6%M#KIITk#o6&xEl8u?GDhhg=%5i4r^#VDt$iP0v0W^VV_0OF}y z@~Xhf1575#9iM^uYuWGgd!b&{G4(rK=oZU*=@W0S9y^!pK8U>=fISKUsiTr|1<v+b}*LVw1LZWTAQ z>ePg&lFCR&Io-74LID_3ZxTC~#Dk86c!>@CcVWh-XoB3NsL$KbP`13|-;`ONb$-(NU~Vg>~aq3gow^K$Xb z1v!8EobKZy*0GRMA3xWC$LU93{k1I5-zlldQve#pcn<(tp&}U+DwM%akqiN3v8jh1%zv4L8KNt zcRPJ9*t-^}_FlN@j?)Xzydno`KQ8IFRiXf#p&bVpSav81uOTQ%O|!YNV42P$^t&?wGnM3Uq zGC(QvoLL<<$j`t0w0Ty%H@FUB72YykrI)HQ_fFUF{o;Fu>80mS%A%4j>X^=^eL}rg z1S3CSx>hv}T*f!DV<1y{waJw4|M$<_YcrERPoK$Lr@3-YA9~m4WnlZsI1b})#jIM1 z>V^03ra*>lufA7aJK=(zLKP}T(R_&S2=gVp8~TsOVCHPj<>_BNCo}Wbt2K?5E;bvQ zur>z1t`@i`0+%);qTCpSJe9tnL%Wp8kH7P4b84J8*VE*4b)T(W7hTTN^<)z z!*$c=%n!KU91GXmMTt=LPioN4hu!DqXmqaKc-*);5Ra9P`zk(Z~AihfRvw1oGvQnEKkSVVWHWwaqivn*QeYX zGE*qiCd(%jtfm3gE6>YfURJbTD!V9*+>_oQK;m|&%X0pvoRtyRX~$}|L!#gU-{Q>YvqA^BeE*I@m}Kn zzIYLp3)hmb`8AdaWCm-wUgW3Wdt6G=YH{w9P?=;wOY4?_7#n%sh#=Km;Ih3`X?2>Z z)~%aR9&W6;S5CZa{28OS#ruf4>=oZ<&M}>R<)Tzh*&%(x>{-cUyaQa9lRsEBrMD?? z-5MAtw>jgbJ)2Ch&pv@svaD5_e0#t`IX`xV$f)J=ml3Pwi{0vFO}IkJ07E6tI+>{c zS{w(_jAT#iRsmp2=d^6Ou$2S2;+#HQ3SSOmavAFtVN072-ApfAdn2+r(S(7pO^IsJ z@`$xj(+kn~ZAF0#nJIfErea-hB%td2{qmRJ{#{>wg$pDE7J}!`(szrLgB5NF-z;vUVPuyvt_d8Y@nhkmoGQTZ0Uh&gAT#od8=9V|Nj-64hMbve3n539lLh zmw_%5(YhG(61gFeDrFNY<=Nl4&51a1US}e3X@;noA_|Pxk;%KD!|89&{awm37t5`| z(OT>897LfA*kY4Q+rTiXp0!n8{EOQ>&6=!24}Q<*MmSOc!e{LB;#p&vB4kk)0TbFZ zi0>5a`8)0cV6Cuy7T@DLLdQA03+$!E_d+WN0Iu_Axvz`(?lj&LHbvt1+z0o^Ii}ZM zI4Or}?v`=wILyo>fL57|4o#QQsI619XpP2uF&deFD&7muhhV$+Z2ea`^{U%sf+ubY zQu7j;JvTi?L5sq*^IR3Wcpv!r`~_UYc{xu@GPXH~>tNI3d8{XFvEZd~;{xu%xl;sI z{to-)z2b!BFFf!Knc8y|($hk<5)XsM1{t8Z971{nV6j&*!?Uo0lZG_MCPG@Y6ts{x z`ji%6UIa~wtk()5eNDB8b!e4L#yWNensW1MdGw1<8VGg) z!CGSUc13R#7bvd8wc&gF&rTa^4r(vjj({xNTQJ@s-XENrBhy4_6a%`;0au>12@I7j zIH#9ij5U=uHQB4fvcE<4r+*l%ye#iKbM)%|1O9Nbd zPxzVX6L*d4kXK$L;Ck-k55D=B6bxU6+k4v9qR#172MBuVb;a67E z4)*@rUmp<&4S-%*+};PIf>_^7`GZwcdJ6%UHxz_de)}MBak!paom3=@ky6txOTImD zo}3w5DX*v2%kv{Q$iH@4CCfuqQi_a6dmcJ#0ZXd^Rg5hYYc4cmhzB~zGYkZMwpfd7 z07L<v(1s<{4?;@d^_aJ(I z`G+AmPRgu;YU$vNQ{ZCIM>Z?6U`h@Ql6@N=l2=}~&58Ui#OFpx;4_TQ@s;{u;n_z0 zuy8W2FO~uqd7H~D!1*3xJN-T8gf)dI>|1@ouxw%cA^^;OXO8Xehx^C$+H)sm$AUX0 zwe>7Xjm(m9A&wonKqiFeN}4lAGLsfaMtGiNgytGY`lMO%)%Sl(&J+6ZPj8v-3CD;& z{iY{dFzP!+vEbo-j^1zc*{;)j&fj761zPU3urk-jZ8Z(@KAqz=VeVe%r;mSKiaOQ; z8kfpQhr{MnAWx`3e!$_n*!!0wL6l26(mvx`Wnn%6-_hwkm&51)vN&!bhYTx@0JZ>C z1gd;zrNY%jKjmN+jT`0PBmB8l(i<(sI5w{jj|F#LGAtUaJ9unDmk^JLx9w zc0c&vpUC+Bvyu0v3&;J`=(^3knT>2^aCVuC?Ji?<&+u$x*Efl0WNQ|qmi+Q^|uO7k=6jNyAFI( zPQDrgE)15dJSE|0Zj)7#>kqsnewAS3*_|pN;yBiMt(nPz5L7V4YCOE zFa_{539v=rDsa{TtmvZ^4_s_2q%RhS>M@}nEO61PMbM%}Yo)Pfxl#xVn!%}UbD@gM z$RIOOGo=G7#~#ZBz)*gmWmJROZMCEV4!Z{?OLf6s`RkK^HwgrZfz3VV&Yssy-Z&;B zQLwp3LCa+POg!h#m<0CH^RLR%qHQuHH0ScbW#>`gV(hOf8IGFwgqxPh{X0G;=U-z9 zi*(8Y632-aLTaI4;^lf*dcL0R>}SnxY#mSJT}M7FLvCb*at;~O7`SL2XRM*_0F!Z@ zXUJ2(G{AK=(jA?-$_S ze2?D%Cip!qS{9(9O=^0sn7g3%Iv`8GBb4d){LYmO_c=U|x;@v~Ylkgt8@dumbRgd><&t(j9ic<}rn{wGMeir#yQ z_l1YTs?#UW=yBP+&vp7e?ilKyp6vgr$d|t$Cy5F-xp;_2j+1MS;O9o43Jt911_v#}@O26cp>PMRh2mf5aMQC~lxZ>pZdpgMX z2g$E*mnV-7S|Vp@*&4rGemQEL+;@AOECM`~s&o80&6o=4p9SF3Fc9?Ha@ZTu`e`9k z3z<3nvS_X+U=g$wwp>e>iLu4crYX@_yAr}bxbPM8(E?BbVpNSli?vxQ23#CywyJQi zyuc7keCeVe72`T+AFx(ktcJ zXWZCZiTBUVAfw`c&Ft}=ZXj~@#95gG;JVEjhr%ICI))i0BHIP7L9%=O0{|{JJ{1cB zcRvbPYL!6-tnhB;1R%}{N(x^VxcIF38-Rv&jOTB4j(tWgT=;nL^abN%$oGW5x6sA? zQ0`|QUyo}pNPhC~kITZ|NTZ>pQV>}t6I)eDVRD5OBrQ`FwOS_mktLGbZn6C5hrgqi z->aF-J&cLxZ$Q=*M*10rkESV}H_w&tKIb?jrD>7pj!F=Fr0IRo`-Y8pPfziOBCr1W ztgN4YOhzZom2_Ma!6-L`e1?EThxa7pDS#_37bF3sl2;oC_%N+iYh+?*trUmWX|#7* zw@Sim%?JXtaz#)vjI5B%POLc5hI0vftSy{3C$5K*O|jWXlI-z|CyNEL7O)i~NaE>FH|0z^Kgw zE)%id02kmZJWbl6Y<%F(f0t7y6M&18eb)(Dc+c5%Zko@}%7qKY+Qo^$)i>FMFiC`i zHww5kU^1`heylzwzz%>dQ zsXiq3^CF>>eO{*(@`ZPQ8~fE=;dt1;mNHDJm}w!z=1tDI0mL-wr-X_AFo!liEPY!S z;`x;-Y&8X3jKxLZO6@#Tp1Ky`I&Fa~?=1*iWpX3l@3PFA<^vaGGevuo&%An0=1yFp zz(xO>j$t~?=iqq8!gXNlyX954cNM{$me8o*9eD-wC_t%o2KyxtDLg^k4pR7_2poid z1upD|+jAZF>F(Ebo^aP$;KC{cTUd|%>buO(x^K*}8THXE|1PC%tED8lR*J%vfDSCD z)XJok8ky9#Mv9UvC6B=M(eGXZaN*c0_kMEj-dnBZNAEZO<6PM!%Jbzdzkp+!&MW47 zU5D#Eclr#j7Z*aYX%W}SzAT)+|Ha3oxa)GHwS|(cV_KpD7_NuvqzI73Wm>a}l95-1 zR;r4V*J2&=t?(KtimbzTYa|zNmY=dx(vzxCL0clDodrlgvxP%g(T}hz-Y-UFr|;`~ zj(kB*yM->U)O}l8IPphTyjDzyw|qdlwJAp4OvuWI%-Dw4qJIQ%ojq}0mQCCuJ)Maz zaK&IN5xB;7pC>>6QOv>>yD80`_--N1;GN-X!|Cj67iI72hh#uo4t$L~5y#>XKvc_t zYYKo1%i-zL24(4ecYNWpz-3PVlAJkt3Tfyp*5Unr9r-$&)-i3XyTHwGK5$WKuc=53OA6kx1xb^CD`IYT+`VW#Vh0 z#;Hw)1TBh|E+b>%idnblAWvucti%AP5FO-=V?3J@t#dqt<(O3~5x9_nI+ZA>8w1xR z`oFk7F!Whrty(P!DClV6qT{+cD7#IHCtf%uON+M4;Lxl%;38~U;9?Wvr~tJ@!Hdp= zlX|a_|NPja%2%2oSunByW&y;{oG~`krL&lyH|N0hiHe)d3KmlDI{HBwax-dkff9fg zqh}k~Y8tpEN@|zu0bFcS%)@)b9*9i=SM#9DIMX%{x){CsO2Bmk-tUr(>c+suXQ09d zn?btEjezSF16-_(u$iYrh;g{Gq=!==Nr3@!bm#k`af+Cs(ihCY6ISr~0t#L~!*>kD zvIQs$S1t$#bEbfyI=L$D=J&%j& zsqg+-mJZzv$XYICtyajSNUfA5uaHteS7B0xOlngr`8O_>uYUO3R|#A=rpnw)16juU z!1K9)8oyd1c&|CbeIRrxAaWVk!#O(!XeEgE0jI9;sP_S%u|0pwTd0rgq{!x(cS~B* zBDH8Sc3)1QRwfd<*nAjTuHZE>Wwqqf;)Tz-NvP~4*GVR>Jsr?FCcH$3hUQ8C&HW`1+JF+aM|hHi3_r<7{C?s2QD4h*#)kVooC6#OHTI2G=DPh z8lMN|?z&Sa&dJJo`=xJk5%Qx+$QwD>bqOGfR<7m%7n>C0fvYWn>*(j>fGe73xOs?q zp7aeq=T;>{Ytf1WBRyX8j~Vyd%j)_77k%*j)a14(-xAd{ zaN%Jl_98UG`bOLOft8V3ts05@P86Xl1F)3=*h<3*kCqKL=gKd}Rm#Qe6>=uCPJTFY zgY0OxT&4qr*aI;iz*PX)%ExkE&^W;xpDjX`1ua^)*b9-c<&i=afJ*1|+p_TGX+l() zrbEiYmL0~&^h$KCSO71|TD9mL-&oZ$E>Hm|szBjCMJfSYe<5%&kAyVHA~SG^z9Sb< zIG#U+LIDNT>nPwZvXHazgY94W%W2fycF2$ro#q#*kCrwcx|Xcb0Ie|r`fJtT^D+R= zJefXpgM9BxzcTxPl&esHuz6sL1t5S6 zX@x;3yF2*+uD)_)$GZ)1@i+QlId{ePh5(OuNWn;(#qb5e0h{u;))K_YSXpW9;q%8v zG~w_)eI`$9eVGd=5 z>33Bj6G9x*6zMd$Kx1<;EwF2Te^kWSV~&8uL83b<>~IW2&S_<$Wy?f>zcnyM9^C&i z^)=(-@9>T@9K27o9e2-bF z(DxKCsk`3f<>n`wYaWo^DKl~XeD~s^!3$hofbnh;9^(^0@qZjEC6uPhl`mvqz=00kU&@<;qyfR*O}MOqL4J7 zZ2>^Xc@|i&yl`47T;QUG%K{gh4=F~VAC2RUf`$a<%aZin^7wb3Gbs&|E$6kcLBYXe zYb}VMHF0v8bCYm2qB6GU#JaRMV`sq9<2&9f16vb#iqvvtMziNYyVDy17Ymp;;OaK} zIsz9nv}OVqO6*Qf`N!uXbg|&TvI|@j$5+cApNauj+{Ek9QXAs3SMGGW3E-lI zD>=|l4sLr`UOnOVQd9~s&oV0Ri`EOy`I#W35YP3H@5Bw=iQ8Cc;f5Ok3iMYmn?)#uL0 z!qjatI=n!}hUQ6H%6u6WL3(he$zb~5;GLuY4m)?~yMy$?pqx}wO?Nu@GuH9;?7R`NzHL%y8p<2-MG%f#vO2dqRH zz=~P2q86=0*n()u;~>%sTy+QK<-cD&a8*s(CcOb%y{-scGp{RfS?Rli=~+~;XJxHZ z%XeRt0R(J@u(={|;ob2Au6vGtR!+LWr4UyV&-x= zpSxOqGHQeDZns=!0=7zm9HPeqT9C138H*Mn%R0$xY%My-Ll&@NU}Zon*D<{kY0YX5 zaIv>yIxSlo{n-pcZLL~XY(i`VTR{U{saWP<)2vZc$+EK&Q=0JQw_DVPX@kO{6?wld+rWh2Ni$9m^Td#SExC)R_&i;sC1#xP~fl zaqa~!8_18qRV?GW&6TIG1-MSzUWx{|2v~0(a22C~@WPgr1ui8Qs7!C9h?jlc6k6Uj%}ACJwk;5t^u-t^MmqAB5)CWwCT${Pc9pa6TdLa zTDaol%P+hN=>3!Y<`;jE-~Q^4s^8(6{O(tO()G_g{%85qQ!i*FdqR}Hn-pIKf)o!4 znDV~2T*nCU+KbU{r)`I#TmlnR0qr% zmcUxHC<9xBFNz>$ELv;_w>H zJ2=oa#U{q4fQtj2v#|C8SO3s7X&p$FyN~=EfXloCY>A*_JfELdkTGZFoGlkxuCPLl zWn;PK3of#$>OSd}JVVQ)HygOFSqb+^<+t5+&_5M$-O4$(?GqRy8*a#zUk|O6i)kz5 zVtRx8X!r(M->O0;19CKae6T^-U0SVI9_TV+4@D?w2BTK^!uIsvQn+%V%Yc?$jsaM+ zfD5wgtcA-qC)y@O`fDY^7JawqFmHgX3fDSamgVn~=YRX6$=sPB)V~HO;}(h+*mQx< zY_6dn%$bu&JS@;yfFkj}_P4WAIcc{7*NDJEg)Oh>96vlfSJsvtk-z*3B^xLH6e47q z+PqoT^(aH4VnKp+TBumq;%D!KRlk1pX{lh0n?M#`$`b8$$l)i9W+_|^#ervvD6iW|uk920R)2Dl2x5xBe-M%-IS z<3#a3v!LUB<~4c587Bph@`qH*%#8K2zu~>| zzhC*0y!sN3#X^}sCud+;-(MEiSf|a7JSIMKIcnje#g^Y0Hj&*c?v_3&EQtB+^6|WK zk!j`QndM2ZNS1u&y<*0}s0#zWkx@%COrf1CBBjN(`XTN(G2gOHurw&z%4=RMWix4QzD@6lsW&^ubHz@t@eS zPR+IQFO#VGbmd7QOVhP^53Qo_g?k&G`sK5dHE164^K_g;47T2A;L^atP7%OjfNZNL zaJ^zqsF{HSNbxQg$QXJ6m^(oZFC&{9CxMCl92V#tUX zaK&P75w;9)P0{W8qEf;@&V;X&z*xEaD1pm7C~XGk^VAP`mTrE+%9U0c09+SNGk7+@ zOwUJTW92>4GkH4FT+_gn*evMX#w+hOSCZfFTPzD%Uiocz9rRBHTkF6%5mJTPCK={L+hF3&%OV_;&>Dm@1FL(pQ{ zXQI5o^-QSlI$h7qmr!OCEfX`rjNfCTzsmQ%_EVXhT8#`dR~Tz+7_NyjgZL7xm|$lr zU@^d{KX5Td%_J?mf9DJ4&C#XdWsAm|Krz;SLzK|~*(TLD1rQNXrA#c0UwW%A&m56g=$ykyRm z`=wm)vd6N}#U@8}u;)9(!?B6+lsWFl9{7R`X+H^tcP5@)4xULio>va?gdFJ+$&gRI z=gS7Tbi(hiFyXF7xBBT1pOhh82`Qs+4dZYv6g%#ut2*GhFs9ipSbsxcgpBJwOFr@5 zFUxBu=&XjlAff2+K0H-Quger{gjNQWWI?BXj@XF*IQ{fHzm|-C^Kpz!TonA%_9+DGR30xd-yt;I!^a618 zyaI3y>yT*S;@z}+YI?HwPVZmBgthqVJ{k9(bNc*;zNT@%G)5P#R#Y5t5w-wXZeA7} zIfKhn09<1LT=7kc_+w7jeXd$zUO{6TsyoKiH!D0E+|d-U{8qW&E~hV6>FqI8J^vc8;7& zUn=J^*T_#sY?6&BH8LeoFGax(Qs|grE!0ZoFjy%-D%zCDWgGsXL7|HlE;DS88M4PX z##_(=WO+b~pV_3CN!W6MD-+VDLl0cB_aVW{ILjL~7r3m2%K%p;3YBS6p0h)qf8uW@ zBS)d6kcG^g35EV!=aG=q37Jiar%^*uix&Xtj7eZGYaA~2Qsg*p#%C)vxD?PcPliWk z%hrYW%isRM=+m5#?4!ViWr_udE;A#*e;2$cnxdnC#dX|<1u7=??)tBP`;O!eT#QUK zPlxCk9(0=z@lp+e2IJ*7ep-Ys16f|+8m!HU9O%~o*My#n=er=t++BK+sz=h0}&sy_*1uor!A9OoA9ozB|>C?7U9sPR% z61(BNyW%Wts7$(G`DPTdHv~q?@xA{due^j~a-YoLX+fhki-k20r4=To_o_1QcHA; z$A0{jjP5rbu$V4gL%dfpb;G;j6)jDzaZNpM%#lyN_p5T&JwL5%xc5z)^Z|d`EaO_5 zY3;h8V=rEa9+?i(rQ>U*BLLD2W8(ssg)UvT&4gCmCLXp7kXfr&A?|yIr1qR8zx?s< z^fHSNXuoi#a{qXx(l9P`<{1qA7bsny_RQdp-`T?>CS_Cick?7`QYO%*TQUoqq z#99%&*`(+;E3;R!`f2ez@C?~Akxk<27mPXI+Y9QG$aq}lBsNsu6$P$D3m4TAP)gjk zDf#{Os-(b`AfN4cU4H84&YQJ8$}9s?jg<&nX1gYV%R-YMTs4+oI0sW>^oK4#*t$KK zD(yq5ax>=L@X}P=kS9MFQ!Zz6s^wzlN_lM9CfV6$g_Hnv)N191d5BuGf>_o#TXdfH ztY^$EfLJW179q=RPIS!N3teUiA3ztD30oPi2wSvnSqql|FV{idD*#kHY*nfn0T%_} zQcD-UH^4PjmgEAs9tUtSV?&0{=0b%bEEBXY0 z^l44BT&KXr^_(=nFw1ma{>*#7BB`C`;@M4{DH5%!-dakwb!s$y=F=M-Q2pfMauN6xj;1#;^6BG|z2DS{S@Ojh1)eiaX zu`M4q{$_fS?#*@oT6w4V^?V?FKv>l0WtV-#UGo{?+BhBF{Gjw`lZW??=fnF&(84=_ z<>spyz=iA7F-!3tMuDs0um`weS97_^ZlS=1e6n{4U=;#f0J!>a*_jfBu0B{M&#=WUNr~a;^|0=_7pM`r_0-&OEyz%Mki~Px0vj|&> zz%>=Xl`406#!}RZ0mb}YD+G{Dhj`W+_>{5b*yGoIrUb4Y$+!>5j|mou@Zm2X(4n}# zx$^sc3*`qo923${exOA8?L*-zK^D0DWZ)`ZwkbGKE^zt7m7n~9i)tot1sEkeRc-}r zbqoxb*=;7s*GB-hGHc~xR-OE2>^3=kW4%lZESDSyFa%H{Oxa+j94E0L#0b^vq>yvF zUO|k&MJw1UfE1vLmMsOZm?g_DQx>?qN_QcP&}Etr30kq1#st?_`Krh6$G;2P~z zATyaFi*mNfbJoJee2_I}CXTbO%c&P%)hOO-9e^&@S|EjTY zaX26LXzR#AI+z~?u06iMWrcT(&y;Y0xdONryrg||6OV2FsPt`H3P_9xE{fy9bq8d{ zfXhHvYozD7xm)CqPnsc%G)5IqS2K9NOI$Y6kO}}Utzk2igbQ3xKKhJg_MM9YCj<8l z&kxT~feY#!&XkWl{6$m-EO2p$=66j`JfN9=0pJ?hdn$ly0`8afk)pi7<+ajaIhcdO zY^dy5aX$)q*LnwOn&2`H&-32*!3@WJ`iEOXGM>@5lBRrp145TP);kq1f zQ3kqb{hA19&z3RW=F6{s_>At~oLKB$aH;7#!*96#dH1B znG0OBa&a6_swL3XG;lEzyHOFu^h4mv2LShx-K&qtiI*&J*%Q3{Wbehr*DgwJ*vBXU1)mJ8oVf(*av-Cd_pVJQ1k!Tq{61ea?TDEA_ zvIA3VFT@0&txSj(ErJ%UT%2d%*o3W^Wy>@ndI8HHxXgOa{Xk0Lfs4=A+{9y> zKXQ5Cf}+6XLRSY|U#HMS`N}81qkv_=!|c*ngs{xRxEa14itF6zv zK3qNV40`~!x;X%&P=?m19QGjPwtK}5x7S5qJ_%>7eOW-x(sl|>z2S+ z8Q*KB{O++o#LkrkDz637LFRF-dTqQey>1k81TJoXY5&HDq-z_3)zt%+Q9kao>6v(J z`-kNueK>V8$Fb98?~J}n-evbQchQt^-Eme*Ovm?pNP4s_#Q9k37J-XRg?@15r{)5e zO*?tgHqZ;eb@_bZ!$`3lt-+Aa$@|v}9(W=D?HQz(c$2n)3$8l&; zX8OeQWQE59*M^E?050Z_00QLCwwdj+@bv}(S9DaB529T`N~puth&E`f!a7RU=VN1#oQzaQ#)& zv|1jJ7zkMBUONMza))JMIddB8>12%WG_H~BK+NdH6(zgzAOSzg^W@G||0=IMcgCb- zR%9uH6bl9d784}qcAXXs3S9VJKf81Hv(0Co|NV=yWBGm3J3J8yZmJH>%LwvO%NCAL zT|ID3lI%W90bH?|Ld~8$8^6_nD=I)rdlZ(rBbUfCPhLH6odI;uo7e#0;rNM+-9(`P za|$H{;M%$AJ~`nTOVK<)SKJq#>De=9OfA^%JI=z@eBd(BRSHO$EXjd!@_`4wC}&Ue zh2wF|uDz$AwQKhsGtua=om+@M^UG%?qwieoYXXj&4Y4^91v!>G2Giw(4}2cLWeSz% zO+2WXe(~rtGNQ+11upBT9xu~NFlOQ6JRA8`s`P7{FaPt|N97`WRqB77JLi-x-~hZf zw@g-xv87E+d)7QCU0SnA@oIsKJr~*hNGs0-nb2>E{Okw6)8k)h;wI6}+=V|r^(XoJ zUtiJ!nI~<48(;W{mqFNiUGoqlPQT%^8n#H|fbo9vUR{6SGSJm4$Z#6@(uTmb=2|RV zuPbn|8L>}z8lWp4v|_+DQ3l>j;QFQeOHRD-D<8{mvcP3rI?S@BJNG+00VC$On9ja( zQC2NDB)yW^tXc@riUF55uVG+kTEUV7W8{v5pNs*Q=Iu!1XV03-G?rNjqVzKO99hO_ z1wnrz8!PUVo&YYoxI`fY`84&W1D6XW%@e_@G5ov(To$w-hJUynFUk1e72e~i zQY5=p{+_!-9_+|CTZ^S6YmTuFzXy|!ajI`O9kMfHLH<>JeCt>qR3+z z-_y#K4$$IfuJ;43#3sc!*m6I!IngvJUIDnADg#`ZTjbAA0=QTMp%XC*EIPGo*L@@m z9k7}`6wl!E85UGXGZwgzU{1btP8Jqzl_BkB$?**zm(zdcj*yD*wY7{9sA$Eycpm%G zF6>BbOy8VSE^sk%YP&xYtwzk|Hkf|@_;a#++DB#*Bb#{CJMbT zY*8+7<&3x*;Nk@u;G%`=a=^9Q+ob3NTnalVY~z4Sw=>fnTiB#nc3I%+76q;n=^QM> z@ux^Tz{!Um25@Ob0Q==GdD@g`St}LZOy69VJoD>6$%Ni>P=M3Im918;9=t}(I|e7n z2k!suH38S~o@ILf<6$Ny+l$b^0Otg*and6tOFs9(ugiI)O-?v_b2oV{{H$q+D`K+E ziJZ39-7Q^P5w47%nD>}X0~f_%bl8k&fU5)6-H3b4o{6WlXQDaW@yy8O78Z`|e!q0RAs_dM*1%l6FJ7R!l3D^>6Ond| zg=^26qw-1=xa`$kelll^(?3bz+OL+aKB1<7i=8$ATsHx@zI}awixclz)Q6U7(7lJ8 zTi{Zc4?+>9=bnB^%F8xO_XzSa+=D(yi@lNldLlhin$IA=WQU(5l%>ZG#w=XMdd+l> z{UNRKw9g{loH>a~)_Ht~W1K&A&NS!qdrX_I09?M%^$u{w=?w+0rsM})w;;2;*mUo43k40isZRez}EO0c_nMJe5UVanHR1COs$Z@@LDP4xQGC#99pUvDV|m> z$XKrcTWZN#sl63#k3@>FWqKMKiitP5A+N_uE_b&SK}bR@0Q2 z{xE08V5i5v|D-G{-hqT(fS09AhB&jJ*)l|7%R0$h5vXDg@=b}*6@x9#O)o_+aA^kQ z$($}bc{U+%^>Fe4T*yFtfXk{;PsIc=aH>C8wL~5O1Eky%$dsJnEd(xiGQ~W@LIAjm z8l*F=KQ3@}MPWrBt}uXW-}Zz^^VT#$X(o(!>fCt+F0&18p6CAEx#eThzwKl^j}kyI zEnNUD3fE(S%R(0&=)2%vb;foCg@5}Hz=Y1YoVZWQzFUwvHr`dMIv@{uKY;7>)dJU#EpSc1xf%y_(__%WmibH=;P`z82y&69rAqf! z8SlHtHdng*Qr<@7@fH|(8 z>)4byzTaZ`%}-5}JFgCR67$%xbh785GZgapchNn^=YRWmDH~TQi42wU{u zQm{~``Q8AoV*svK_4v)5%$2*qHN^tgbknqm{GoSnsz=idaM8l`?Upww`b`$JINAKn zE5a_NfTS;$ZYodw><=; zv)}Lix4WM5JEp%b4_vNwDo%deK}`WydjMAleAf}58AZOKeXcy2S}u~dOwMMkl`r&J zE7gFl5|Egl$%I7S6>uP znEm8`ey z1D}QiLuJ>d`!4S^&(*FEpH94Yp8I#_mXAxnC~(ozMd+dkT9`+HYZ7F}h-{BSG^0hkY90Vv{0(>%M=xYT)`g zfNNNfGHn7gj^0!rmc77bn#2eL3IpfHarZXyUqr_3Nq* zO2=d~{E~5eznqM9%UHe$T?8)EBk(5VpZD$iw4AaL#c?3y5Sa7+#je$R4t!@&%;K;4 z{+`_*#Ir5Jb&Zi-wGYY(RMt2lm6@OLj{+AytJ+64N@-nDmLHE>-xby1d21#pF}h06?3j8 zruBvb7q>T2zQ%k(^qu2)-6JpTCaj$&@vFF;T}AnGuecg09$^*mCnyW#@lM_zjZCZ z)eSd)js-4eW&|ybmx4sdjE>In1TNIh4)&e7(v{I6A~4h9cjfd6u{iiOn6N56eosm`tDaAlcIqf@3BbXh}J9%TW=I_W%sFYfyv7ChfxfbC`GIJ3b8|^<0qHk!wdX7PPgcy>CLO~Z6@Y$XevsvrIUkKUk7WZ~ z1puV+QZS-Ip8T2ZnP{$#xb-?pQlxUTl9N3Li0{nnnt_P??iYWSqS1@-o-hb&x(vOg zM1Jy(C(O3ykC|E6@&FgtYjc#Yr^B_mw|{!#Z<0NDA@cbNYUT2SD?c?KxQvC%goOZb zt-I@*EL5K}wlvOLgO#nhcy}ny7`))3mnNGbF2G@%^$+P*;l?h;Knh#AcLxy<(T&Zk~tyr_6 z_19wTECnZbu8IPe0Wk|-(eFJ<1g;4I!j`|oe2an00c>F%o#wmX=FiI7EYH%13kie3 zWh_ug3Dx93tO~GXlDsGlht6S zyr=xk_rjg--uABmt|zrd>6i}} z0LC_Bb;WWQ09IEO*KwYQyllL*3k;HiadYL#pFeGOrRQzt=8u(U(pC85uKvSs{vwmo zs&W2VE=>7BmRH<{K3mz4@$tGH0LJ)X_aFGEoI2?is+f2P;*^1{*tL2mzBBf{IllXY z(z{JI-V+n&?54m-*}I0mT<*KVNq34rR@}AwOzBgq{y}W2;x64o9@+kG>Cw*g_>B3# zU0y8#E)|{)fotEoJLQ#^uO7JSrXB=vv4`T7f$N9Y3Amb?;_@}`J$Gd+iV&tReEff9 zRFAo8>10g5=zX~?aIx}^=f$#uEg|kQ%L-QHO}G|wO%}L%qCDyYkcyKpT)YEZjg`1< z)4B@a^55PUxPqz3l!r@NXr#Qq*K~Phe1%+0TOxnS*eLhkRxL9EOJyQJN}c3GkOKj* zOe`(eKg;u(u$8CHhz$TIGuX7(F`iZ{I|L8?vgnUR5w2`gVulM`&23VQfmb|iT@7$C z;OS_r8x^WTCN)K7Ti`<4A}}!=1P85V^Wue5=jH4xXEfUU`B%wT&}NHvw`c%K3r5|3s57o*M7QJ$8qD0K0jQOtDtUbxfY^&gU6DJ9r1pbEgvS~UwH zsG%FGg*_4Vw$e|fCfI`3rPndhH=Sqg?P!84qIv;pA4HFgM$l`&nX$WOlcc7H^@0}O88aFAbWefQ~q3hgf(}c*T#EUE+=!$|zsG%aJkl zAZ5hu2xr;@k=uEc0bnzMPCe2lML*y&PV#BN#!7V+g)JAj#$es3P$d%gWCbqk!*%gB zCWs4i=9N>(AkOJJt&sqP&b?}Y>*7fingB5-oYztQTw)o-8qBE+SVpbpGy|f7z>t{O z3~&njvOOMkTr>}G(Gk|>Nat~k58eGG8PR?w67obD#;^|nE(IwEAmxFrs0dhz0zA>m zm8j+bS3&>k%L5nBl{024ni=u4yWX8vXp^D^E`OM6j?`(M{v*B+)e^-6SH_S9|G&NS z0F0wJ+wkdR)0+#p%T4aRce(f83+@dY(*mZ3B=lYbA)y755RwoGErswWKmvr`yD`RK z8;pCAt!DH6@B7Wp-QM1ubSIr`12@*|ZF9S`vpX}-e$!-48i1=#m~D=R;TdGD$WG77#e3BE z!WQp9oxRBp;LuxCj>! z;5xg4z%?GgRdpz0A7&QKS8rS*}T_zKR!3vqh&;qqy(rLsS7krWI%U7qcDnk+s1WElpK83ITe z1aKM%U>X1o#JbLb2%w6HPz8V1l4T~GHv3FlEU$V{{jt}f0WQDQ%0O3C3RbwjRuy79 zRs^irAs}4UiBaHM0Kke@HvlEoHETX#3*r*nU2v>Zl?6yRqh)g5xyHi91i}2Ph=7F+ ztvdWxyQA}KvT#>{*1gmE^)1KbDu5KWkjMyJ+EAVlwogh3U-+%UnrAK3JVUR+#Em7k z)ohKwJv$5Jo@<_z)<;hSXpB*7R@=}NpT%mj5%&4z1g;Q(%cX?C#ompR@t%y3LCu!{ zxXe6*LExg(b!0?prC}z;-8Q50T(k{Ws=zfWMjYqH4Nx5aCSHmCjX=gV9N{r-xO%mo zA)i&CN|D1tOx0eBtX|-hJ3~>h4bjP~&A_LQM)S;BBhWzWC*Bh;Q`dO(;*!-2AHVaN z{O|wXkQbkRLtgmj8}j^9uS2iNvwwXVdP!b=?j70i=@u#8;fr+p2>73Gx7#5Mco7kb z$a8(_(U+uk?a|0Xytxj;2DS`v4Uk${JpeBc>4fgaF)qryP{hl&ExY8ych|_OcfXWR z-(4@O-&-$h-v3J0eDIZg_Q3}E{G*NXCDP#Lbtud&)6p?nG~N(iUD|7M$uLj>=a~)m zAid5Qb+**XW_2QgDtX{)0N`Nn(-V-N4(+&5R=*#7U+nec9gkSit^a(pjO%x*)XVNI z4FOw?tL8!dr0Egth1p5EHJ%{vz4WR6fbW=nFCrk$e8Y+#fGo_}Oo3?-@I|-kgSFDP z?MysBwuKvt_tI3&8u5ODidO4d5x6*=j{z;pRGksHasc5+hnmQx=R~U%@#gBkvYhp? zZ_l@~Z2Xnd6u{M(z@?4nDO$XYav=q-698QQi2|2_9(R1Z9HBIS=Uzl3VQZiFkMDh~ z_KUE)Hq~t@NyjY{S))!1c+OUTBkdEDY&fz*Qf>)xaBRK6Yv!X4-i0P}E8j zjZ+J*Rw+A;f3u7{f#{=fI$Rn5_@n6cezf>1seMFmqs$v2M`{WZ?wcN#rpMvj;Xcy%FaQ_S2+)<2-B%i9_W{VXkeh#YUu0}A zy+z)GeMDM7W6AtO^AM9S*@AtaH;MkGD}Nz5N1LH62v3A9Hl#OgmRf2zbiz4Bni@r~0oijg}*&ldO?DRhe#y#BnHJfDC=(BaYD_Ro?TsL0( zumYDl{=_RUG@s}1Se9U)sp-JUymr7AxLBoFI&itc;kzZ?hYPkSm;cIBT7au2GR11y zU8OpfY$VE_HmyTl<;DhMWJ~XPvVY(lSwHAUa?OeJWOQggz-pNc0WewMinVb0ty!kp za6lOQA%a$a091d#n!=SrR{DX9Fx4j<3tmCkqRJ0kv~aOX(X(*Tx&??*klKq>!gb_j zY%oud+PkwrEnRB8Vvj}UbL^E!DQv+XGQc8!>A;_6k`RAuGfd4OX))8p2tRNHx{H_J zA}x;}FHOUMp|EM6#U+P=P~eJ#tpf*KwwI!=dp&R109>mSnO_hpG(&{L_Ofvo>y$8@ zO6QOPE@a|OvPWuL9%JFE0C4S$1+IE1%qarbVQe(-2QK_d<7%I^(D>p~_eZ61>2vBw z|G_`6&fl2>rU0P0!>=-&@#cB$0 zaNfxy(e78giyqmvWv`6r$q&1}NE3af$zg!5s5Nj+Vo`cC+yu^VF(UAE0b3TyD5>$ym5554e_3yd1DKMjFw= z1>iF6xsnAgd#1A8n)lbsz*ckQ^ck1SnvcyeH-s*emSP>>DSsXp5%V=(7NUX8itgjL z*T}fO%TUG+l57CiP1ijF;PRlH;l;DlDYbYpt|QMkZMU$G<%C)&>CeO;fvZ6VxDJ@o z23$45-LT$E*r>K{sIx4q)?eQ5u|W0>SSWjktdNIVER!i!=E{)J3K^VrnhXxJ-4?A} zwp!811zc*`g8I?2Md$)pnMU%ly$>VpvXWG3z-1xJ1zmPMHQ-{EBHM5o3s*h7;8Ouy z8$OO&xD0S%179U-?SeQS7e}0@C5vNm?c0SM9sW4pme$216D*=7j9)S~6I9UpR)NZX zk#dA#9ls05*ba;nVAB=goL8Q6kF=?7suXP-tq4dRAmAEYiiOK&LJ{C%X2H^d8I#S% zuvk9+Vx91~5!+5V!77nr0V>_V#i=<6Ts>Qr6SzD;aRQfGxQ2Pab-NF^%(@Je_~BIPZ&Z7f?wT-*+~vtINH-i8iFIr+y@rwRuo?T33AAPusi2yhJs zd<+6`bt@Ne8ApFsWjp(>mCJcQd-BiEO0!zS@x1%sp4bzz?CL}-w%;On)dX-oaQl-| zwZ z*muspcUl#x`5QNI9PzKPWd--@Gw(@W>$wsNwUV2z|BLMLJv)VAsKobi%`$=Qf3k$Hhpv!Ux}GDaA30k_ z0*(e}an8dPG6=vmP_0}BxCmOTKJ>#DMXMFtaj{CVAAm@!6CsYZWqTi{7r3Hu<%g}_ zp2drhWx=c5z@?4m$H|nu^CDCGXktLRAwcO@BtT1n3t+Wp$6j3;D5H>|b|cfvM}p!y zs|xjZOlW{9W`tPRf$o^-@MWVtRoJZ?=Vp%;j`>Bfp)1-`B3GS#m$a=mS)r??*LJHl zLF#}3*U}i^QYe7@rgpV#K{3GP-2-#8p60bG}!?;93^(ZZZs8_grmJm8{p1D76(tWqr2>_7ZE z@-Nu}kItTl;+ifHq$hs!th7Io4gY(gfHu~x^aB?i{ifo-Y?tVaJGbqY1(VN~8dbX@ z+#H47JRf%(E<579-R5AdgLIPf(cKoy`cTk}p$`?=r8hkMlLe zyVnSLbHl9Oh|}JHonF}A6Yo$TsUGSsll!iS4p(AN&ew)w-oy_$=1(ZI**luRMN0|` z@^9Hr6prI^4e7L4YJ0%NM)MT~E{-`B1ulOZuH@c7`;2JeS~2M=wQL#Sn&=G?;Rmj9 zh!X(U@#E!{IN(a&t^Ig|jP1GtVdpdNEkBxhm3*<<!tqTqwzd4 zz;z&$rZ!w027V_5r|3 z*ifGSnE|r#ye2B{*;zI1004bvNklBS%K6c43H4QhG34rU= z3IUhD(Y$Fm&zbq-A&QFi@Au>PtBvM8;5t!(YnrUC5O5XBR3C7${T7wu0oP?Q<8U!< zSQzrR%+Qh9a-SYT9BQWSiBV`3aonJPBb*^lWjT8W6w469VlMFZ^PfonHq!wZ-BIB7 zQ{bu(*@Bv|#qpO+m10GKEB%gFxAME2F1t_a9>x5y7oO1|g)O$Vq21$F0ebWg|Bw#3!=&MHeWdvb{iVeTgQO+Y;)DU% z9w^PLQP@{)2)0M)`rjUW#tb8abJ+A|8eijt+|3Uf*fKq&`D{h5z(-rd zqlV(12I4ugiqs8SR%HPfmkj}2tWx~h%4jdeRNgaY;@I6J@aS!qoMpPy&d(((Xhg?6N3*}^u#aI|pMKYSFP z#~252AznOC_->29W#xyhL_q2H@0ZJOYD!O)qV{y`fkL3GEI)3reBOPbNdLLACGS+Z zv+e?!khMrbsXsI<>ns_TeWn2}Xpq8}v1HLomB+SP*fs-`vdYl3!=n7~!+nLOx{$wR)gs}FiL5BUNQ&^KL*P=27lDiL zMcBf&`ePzyf`r?%y+AHK^)6|D!c?8xs$DjqNI@z&;BqT|Y%UjY4Q&|(F6MCtuCT&< zLB*ZkG9n!CAcDtMO!%oZ%pOpVHe4^t$E>(LL>god#k1rTHl1Wl-{mN@ztMBz zX?gJ%jZ42`oQ)D3cmtS7{N4fLbhvcqn|15W1$;8M%E0WP(;7w{aVeF zI((MAFYo>nsWjkfjQ6`S*R$D6v8h~gu76kvXAH!-NR%L)r%kz18dV*GYXKwxTe(#L zUSYOf#kMyzL_Gr6@jl>6#?ha~nQqD2k2lJwu4e+Gkq3o2peV<+8z5Jl`AgZfVVm&; z&-!ff8}(e|l04aL0J-kzrjXjyR^ZpZeW^3{foQpEh-^QY7HKteklqqWA;#fumE*5IZ0hfiX)PRf5xwCZV{e%ni z=**5SU+tDN7hEBAtM)*FoF^PjzM(?acNn-3ls8}eR0elhBGt3lCW<}u3|v{Th{Bdt z6t-yf;yNd+t_djr{at@W0gCj^TZFuY-gQter_Z&#j(LJVU%*AQhcpUn&6f}?ZPq|P zSl_pYgKDyA1M?db*qeU(8_7LxsN~>dfH36;te_4Ua3N1Ted^WHxD4Q`k2Fr;dg;0M z5s%)F%X0KbdBIux(MB0b;0lk#wMI&_Y{CnBDi4&~E`C6EY+@Treu9`L9hxSY22C7Q zP1T_RE!$qpw96uBabF(b%(T;r4rFS9DG_k>bpRJ3%vM7t1g@}eJ)mBY9aY|1x9oa1 zz*K6$wNM+)*GA+|C2*|*aCsRRmuAFyBo1$zRxRzN$gdL3@UUdt30k?BX0WhQK;v=# z(L&}WFgB1UXtBybs}~ai7taG%u&Y=uKmBg$c)|>6ro9z|(3O7R8s3J$W!kNjAOni~ zs#7@Njd5wkZ61Wf=8B0wlZI6QTq##6x|Am1LT1aVNd>OvQ)TsssRI|DqAquDEs)8B zSNJSkD6l->Is(9T#RYc+fD6AvM6ybf?cgkEr3PH7IW4Ft2HAJMufNzV7oB>8 zkijwf1}Rh-;Nr;n34kl>&<3s-|NWi}>AFm+;hs2HDdCA#g#PwRQPA?swC~cvYq2~g z)LlmQSRr41Zmb}Yc=T?S3w!6j-DNwTNKeLJ$BH1VmQS9|dSPMAyn(`YA>y6wfwYQ> z7I>C?{~SS;iUDt`QCk z(I^WACt%ABT*ksxG2r@IMs_(J&vrQOZ3OORgyd$8()YQ=5hLaP8=lm*nEa78kjL-T zn(xIo&!y0WZ3|GkkN&J5%I1&WF|OO+@R=0l7YYZ#E@pc>50(ke{IKUUR)~hn0GCUC z$nxtT02e2twi8mb8nFh}>x4SW%%l6tn_cJ2x4mb}u09Lp7bne-DOnug)KnX?-PVvS z_BJF~K^|aH7Pf3vqE;(H7Pg`muF`?a0F||BMMVhfM;L>j=sBXmWgEcT#_*Kguj_2n zg>6Ds&n$u$L5pp-OdGDGfQy5ldUGjqYM)woai{eEv26I%Shy6XAY%eX;y|LHWsA_n zYDI-7_FUwb3ldi`8^9wSZTW1weD%pD^;@uGuR@ot0$?Vo?JSVEn5YZ)7Mh_Wn5pXZ zaGce4UIJ&L-CxWDfUcb-a@pDUNyi$qq&eWIRg9%8{lGP%%?kO_YbdM?U^5g7+icsw zDQe={a8YzvteAL-2VBgo8xmwrimrHEY`Kc3R$^wf}kwZpMZ$rm4Qk~3#tD)p;&18nt10ZY*0 z=;8yg%tPVJxgp)a#n~$EWgD)81Y9=WB5~%q0;Hwq{`tD(bzC6F;+{CcFdN4crh;vk z;$e$GX4-Dm2UHN$s^LB#_~k#P$SVlVb74eM(Ot>FpX}3n z#BN&2c^J{myg@Bo%##$j09Jr4J3I}0QmgjhH^?^fx0rYD*Vq49TAV=Z9jl9dfaP1) z?IeNgC;-<_&jWDnC_iwWIUT@t7(fE~QEoOhF#&K*l$W3Tz{Ex545c`Fp}gRH4&WLA z;NtXH91UJ)tiZB)Hs>cDEUf@^kKOmY6zyRo`_8ZN4e{|~$sXt|10uH?lzD`aZT@Z_ z%L+U%p2zki)d5eL&wCxQv=&A4e{=0~7F`eE8kGUA7`b4JI_SXFQ)(ikXdh}X4>z45 zdwVXHZ~HHoms>8CWmTujpwL|HQOG$G`*T=_@F_B&>N2czSO*Sf%7*U7;>BSebOd<< z7ndGz(XwTM%K#IhD!%#9EZ5^-<38c`2BxW4N#U)a_zXWLv2?qXeI{RK(IOsxo z@$om2`QaQ$Puj?y2}%p#%#Ay;EyBpth(I2Es z%~|@gv;rV0Y(XuZaOF~B;9{eCf?NY+N+a8xChI=ksMpoZ&dW$t*fwpt5N=v$5&+j} z0Io)9wQvQYt9%x&NR?t5fNSF5<=)gjBNVu3-D(^jp}=+3g}+J-xaho9?}+}NtfOxu z{)_+hjx9UoZ-4raOv+oXRfF}lryOB%APQB2Re!Aa!@anGi-j^LaPBI1-}1+U3S9o{ zF-kxEaIM^a?E})J`cOFr;j5dCuxfic_ekn);Ns8;Y*;>Aj>CuRguGMbi%-2aj4J-m zOo0iOd;OtE)|qE+I$fBv`o(`lE+CXHZRZS*Gow8ZZR zIB={dRx9q`&5TTB-3Q;u*lvrZE_-S+4sgF5Wu8_|f4sy4R}{JoaB*6!K?+TGC>}z7&UU-s0=i0= z{}Z$bToh|a;LcfeL#e>!g03J$eE&qSsx090z$qTC?EY9;;HsI$b#^&!D`!+2AYXPl zMFhaLzQ<{DeU14tE^D?71mJMG9j!J5Wc3SUJDbBgER_La02W|Ofr7RgQ zdmYj;wZtfENd$)acvXjfpt1lJC-0c~O%SxAfMpfwiRi6sZ$w=Ns}vU~OtD(guXxyk z;;Iw@TzMDBdR8eiQ8902W`@j5yYeEj@oSRfaB=z_Q$+|NQEA&IxT0PAWbW{@k%)WC z)b=aowI@E3lHDdVR7=@D#Yq&9$y z1vRZ(4WTG-MJ-&Wpk*P7cYxBkLL}*aBjYh<5p~>Q#RdIaPj(;w+4Fdgjdr(h-6`+C zzDj+YNWSZTvT zn7Am*m*Dz^vSIB;`NzXA0eVlzJ$088knZYgZ$y9upurCle#L^8v4C;TNJ2&(KnN%8 z{@v}-o{7=0c%^TtA*+bfC+Ph{I`f|8K0HG<-`)I}G_NrNppECMK+5OL@#6?yd=GH{9&E+Vqe$VM_JFHl zc%U44fPl+1nx6>Zdf)r8JwqvuUMMd(Yd-u+hId&Zb?_m?nILG1ZWso1Wg}m}vRT$B zg|7a&^W}xVzhxS^({aH^P2pT@`k~c}?084|kEfydu9F?(F0l2c+V4m%@40I8! z>=;{SoGtFBCCX>1@*s)JnEl*m( z&Nm~?Gm&|~Rm?$5k$7l%vQ>)ws-!rHwSHZCmaO8P`(^Ri^QCnaTA!xMh=wcVUk|>H z1ZNVTj zXfH-H{ZBH$=! z`~3b&lQ~D=_X%VyVivf}I9y$uPp%Mf?b@_QCJbB_0Ip%U=MgBB+R4=fuAKlb#07F> z6re_kFfXpmb5+PtPjFap&D$#5(IZZ!P>%P9RT!LpX4_XgW%auoYk;e(+;!uFoD9P&r4STu04>>x1nLpr}mN?1$6<|h1b zr)7;bAaE-e->7Z4QUWf-l?x^^DqE=omv^idGQ#Hga{YPE6xrQ*fe13APr9EYXCFOF zh5|5#WOE!XLKdNl)+zuMEm@ujRFQQqxvds1z!u=kf|(gtD+*Trv9Z3Jz-264b@Ad( z?suN7|JVaABn0*@)LtZ-D6mA{#r6_KJK4*G86FY|6O<3Q76G_gRvja4Lo<<}$H<5# zOXazTUc;9T!3utu@c5O)YcP#*U11AQrwNoN;reiY{4Fg~yGPO@k__&1hM?T@F4RBs@ zZ)M~9P4d}CYvr>Kzm!kk`9eN?W37DnI`qaD^3Kbj%9}5KEH6Lvj{NUmZ^^TNeMSEL z_)GG{AO0=Bx$QAIZ_y1hq4ycm{5V?km_M+PHI|%cRiRs~VvGeYQy3GtPDDQQs~aAW zJ^6bzoc=H;<2dsE+RxU@=bx^V&sTG4*4KRcrL0*6ePWg$y|YH%e)SW1^QDjF*}uOc zzxm}Oa`i=b%JktEO4r6S0Y+VP%AMMwei17b2PzH1l}j$*V%x2H5J#l{?QMUTLVRHH zzU-4p{tnac)Y64O*bg$bq_B`jUSWoVz+qM&=Hnx98$RN;1HN{kU^K226BUUL48`YesJ?{4YN#vvi(tQprz)58D@;YrAIpaj6x zvf3nh^}in`{{ZNZ@`Cf(M;l~#S9WZng$o};P-EN&t=&!WA()H2DHj0N6gnOsBhv?6 zARoQ?rN);|3QjSNdgo-)wa$| zxY%fZF%tJUnF`?2flrZ6^oztcLfuTtT zGLO;HIy6JtXU#%_7^#-1$A101?A>a9r!^CH3F(+!v}iG*azC$+giOoV{t_l)X0Rsl zE1%ii2fzKz)qj_~Itu{XV)3bDp&e$G#iD z#cD-k;bI%EuFWR_xYnBRCgHq0gEMQ}zuqn52P};Mms&}@FX*EITsQpW?kI2}UQF99 zFOEFWib!*Ez7Xcz#ds%vdir(JGiRLitUpb<)|)IHYmJjmwW;ya;iS>hw#F!Fb^K6i zdF)`xJ-WX%IkKNLtlC%VAU~)97-1(G4r1D<${@fK!l(n8(t2eqST5M2g1}`9V+&lr zyuSRv_3(rLltJC+NS{{IrGJ}wlGkdk^lLdo`m~%Ty_-*!p3SC6k7kplQ^Rr6y3TNE zapF*EbWDHYbY(0MkApbzINKuSgb9$eE}AOPAXp_*5V#Di4VPn(_m1s%hOGP4jJt); z3M9oOfQtu{kAl=4&y7IX_C$7@(%CQaOH38w4&)5G5$gQ?Qn;l+VXI_ov6O7X5A#L7 zTD4h*by_HOvht)po~>GYw2hVvviu@&u^ksaCJ@)`rFiN2H&x8SHIt3z#{d>4BF`ao z#RFGeKvBzTtWqrhI9#96!qu4_TR2L-Nt=zaY=V1l>M0ih#yp`R0F2erODA2ay&IVq z>$ef}Vw_LcnMdP~olk5vqc)638rD3U;s-MTiqp4gTP>CythE5d>o7tnTUeb~l81_)eg<-*s8HbT`lS4cQa zANk14kl-Tw2wX^nMfjqeH|iW|R%N8L2~CxDp;=hYLdG##@)|9dr+)j2w)0|UU`)*r z&PRx2gGyUvpyDcEtE3o-)Yltu9}+f!tHiUi&^>U?KcsivdD0?l0>G(a7A`+{niaTWK7-?ZKTZxxt#i>F*0yw=tqaz$c;a}Tk>}q;L;2k z@n@_R4rysh+BWBAm;ZBTUm-bF@&HhFvSm9WdVgKk^TY=3gbpLK-H-(;Agg{>KWuaK zcv`qPdb}CfG-cq*0&pP=HA7wGj_ZCWdv=!(xbD35VX1X&U&K!*1*aNNb>w-~0f!XZ zVo}wR-_^h~Vp}^}=X5+RT%SWW)I%IoT6L%pY40f>u3U--t|8j1@uaLi^1IvrCWUO| z49DlqyNka=Zh3p`YOII!I-VPWP$u`u<{{dKi{ozLRTDgxeLJzu_FKELk4&`dTPfOX z+M``}!LOy!QA728%3&2@QouC?1-ofPpM$t2a9yUrRXz(BU-PqOU2A|VR2p#6!bRXJ zhlR`YzxspqGPL7zshh>YZ2iDB6rkb>aiDEHvqs?_N8HAwQeC#v~9e!>JWfM@Y0WRRvmJishGu9Txy648B_Oi12aQUL$5|K_z<(p1t$mKN_%7`rXO5_j>i;Wd4yj-gb ztrVi{k}!p(1u&HdTWmDX#_imvjol%wTJ)@3s#1W)f*ew7JaSuPQ{ z7D#6Wu0=@PV`WNT0@r4(O4P|k6{bwW(e_)Bwp*r$38iLXRxRSM5MPq>My`}**&_g2 zleJp0Rn{zN8J>lVevzAcq8_sPr&In|ED}{UZqTDqwQ&Pkc>5(|Gu9l@@ zruuIIVMyFu;wNhAro+Z>Z+u$%)SoZSLld;OVQYmi$_-a8`GIS6I|7$!!&Op@41%!0 z>uNhR+_MLOQR|kG4j$;`b}J@b3gGIG_Y+@|$Ut&qL`zmw?5a%}Fp51!|3T0)=i@QL zocUctj;|9Q4I$%8nuuVqyU8EK+ZH&vpihhlOY(H~;Kj16*{7 zn`D5?#vR+~UA*8XX?6sASFw;l*ws>KppF0(6@iHDkO)~UNC``TCblh87_k~ToABxu&b zb{)hu$ILQ=mU2oSZ_F+H)&*HnnX$HXnxC*~*F$(a4v;s#@2RqmA6#&}BTbf2^bYwy zxBPZxNKUX0l4LEDP5# zX;poayz<|VQj24s-_`H0mmwWb!82#r*~^k2L_=}@A-FbWfXjT0jY2pGI|K24_LiG3 z{*7$kWUP24$ahVHc$NpW?BfEwW$y)1`0{Eg2wb|KRxNgXB5Y|*3APoEk%yyvDcWg9 zp5M>1h9CHF=PtcT>K(zk6e|a~*ub9tV-)aHmfwW_1Ah4oll5!m@>`h#a1p31bVWtD zs)bCUM!370*Xv-NstFCs>L&kgI!pGpStLarPm{mbUo6v5$P=~*Qmp<{sPYS7#kmiA zW8DtTpl!E&z(vSnRU^;Abq-|8xefi`r0@jji32L%wpsVAR#=*O58d#Tto)GWmkYSM z0I=dUA6g)t5SET%HkuzJllq=3>pwzGo%2P{XCT=6Gl{u0Iwa z6>sq}jq8p4`wehSMq(cY;5tLruVU2-GHd`AL670oo>E*Yba~*V)nx`IOt2U*TDUGX zb15RTGvE{}15|{kF^C&1v&JCP#d;PkS7x7?N0BmBh*24c$_0!V;38ykAjQ#;1unuC zGcJnjo~28Ht4}$q6nS5~K@;g4zuY1tde4_S*|f5-;2J6o@$7S|jL?zhZ@v6}*|W<7 z6B8xId8dhy=Foicya$T+>!O7>N$wG>#vx#_z++n*0uW^($pDcVC(8pR3oisOg&5;6 zDC^%Zr`W7KNiID8V1$3QJ?1 zA~bQyZNgUUAg2br`1^RV@TJ(MhhopYn#f}xy7&L2nDZCH@s4tslWr8pPgWq>1K%K(?(!o@smQn!~KitH~;g{uA@LGw6rf~VS{#|~XqHJ<07>3k^ z^C0fx#r?5jI1-P;1=RppRnP8*^=`FZIA+t0+rd;1j;27FdJba zV=?Uo=m*zlIyGrk-J^FtCqo-A0`Rfn{zPZHu4I5~i~^T84i~Po57%RcW4_?b^&?^M z3qe$e<>JvlMq$=RtrD!Zi7ogzPSP+eheyO}Im&LEhRmjLWP@hE>SG_z(-2}c04H`e zU4;p7v;@&&<_9ha0A_$|6u^NNu8FexqjCV3J`j=ht2fHf9= zoYt*lk&jNuTP|OHzFEU)9q-IM>CznUE1COGv%{;x0hnoF-v`M0b~g*~60KUy|7y3X zR^0Wi6mLeMz6%*1*tFISz}F1JR}5VfQ#=T+szTUuDI|P*;QWP zLf&Z`&F2!hpv1s6DRtoDsu!Hq?|mtQ+b_ns@ILeY;(&|REdyM($$_>D4Ug83g67AM zkU!q}4=LCUO2m1Y=j|`SIy(^2l0~4Rm@gs>nm2OY6Nh`yYD8MN2wVg!)|9Bl%X?=0 zu=jxLJP)|)X`U4iFfK9P-0%@E8^?ZG=nDF60swMdFI~XZgdf*Fr4P8GwIET&hQWrT zRNy)>4A=^HM`6)j8^zWPb(G;%y2-O`7E6A+#j>^SDe}OHOJz!Up$q^VS>Un_-w8~F zDg`b=Rd~7C#(rA1)EdU$@tC(i@*8hG72u*JOGk_cVEO&I04i0vV2dgbaIspkJ|cfg z9{|_K-x#<7^zbWY@0MNKzRC^>QM9vAigzKw6?p3$HUbHYZtvzInLT`^_JZRO3kq5x ztLf4{bh32LUW^AlO1jCN5Jk%;|3q?Y4w2^7M@j4IV?2$OR@KHx%M(UPi{nR0vlB)mQyVSKu-+WX zg_<6ZFHKKPk>TY+O^?HVsL64FD<~K1xyNArFjf&DgG8dD%vf7&qmc->a2^2HNhoZ( z(ZZE7aKSOthg&he;4}H? zz18ymyPwGW?|dxpzx|24`__l@4)pdLAIO`pzALZ2{Fc1@;v4eP^RHp~y1e|t8>-h{ zdPm-T1%6)sK(=n$se#kZHnf~*RpNfh|7N$80KPaBM9G$7DcrbMinkQ$R6j+V_R9WU z$Vk|(Ymdm;b1s#f!}^$K3;;L8ca93$VfUoOS%m&vP5Pm^;FUm(L2vX*&6JFur= z6rvQKyrr&tAQfpm@A>7Dy&CDq4__|e^21ajSwG3N$x22p*rLj1;R0|qK;%#BeV(lU z#6SjtM=e`OEZUm{Um<2NK_r|#$Y79Z=-{MmG>ODSlXCvXLOFTp+0vL*iuh`4n>8Jv zHAB^oy%s~Wpn1|RYY7UqsnYU@De|k!AD3;L@*|*9R8SyA9F3S?Jb)J4u--ry@)3k9 zV&P)O;>%}@N3-KEcl<~C=PZzBcnN83^H(h<1THSM4c7=6-Tw3laM7I32D>U;n=opY z9`rG@V>O40KY;KR`^;l6%kOUcoBZzQPs#6Z{ipol7V2sF-3@<}Utjf@+;iola?e$d zWBIt;eZ^x&mp>|ZUG^8%otHf#zr5^W)g71qS#|p*56Nwp{7G*A=|ghk$_M0}nK#IS zAs0(t)49^@m{BN5`Nhr=rI}$yt0FCQG4bUhBRxq6KAj|=mJ7Jd;`5Kz$>1(0OT8*A zv__&pVw)I%UKNhR)mHAj?hiUZXPo2jgVGYhMjjj<<;6>Gk|swIjtp>V;YR?1f&fMN z!O5?R0vG)gxVXP2hn~6eJ^+_#n`R1HFU+Mn<0l@tEF2}LAXp`m8@Rl4U_S@dG^5IQ zktqYtlyw~NIN})A$kUE>+!;B*w8;Ax+5Ghmx#9A=Wd5|3GGXW<89Qjcj2pZ_mm~Vl zk|8~($$+ktC9m@Y>D6(JbZopvXiK5!7+mZTy&Yi# z6LIjHIjPM>y_1PT;)|K<6$CMke=mh(;`sqdYyIWd7j z|NrMig$`PFH~Xr4|9cY=@2z3x>;uqf4~2q+gxe%Me#;aCvn|;o)|*UaGZA%S$J71u ze;k5j{Rmf%Z!2cJy~G~90vP4QhxYqfudCz!UNk)hS(a&>Q^*fk6F57Q1!nyU? z7e^16gC7wag^S$yEV*d22IV({Eg`SwZ(9%dl9Z3E+deL6k%-VuJ)`GVpmbG6t;*4Q z8gb7P1g&lvij@-|L<=9q2Xw~89yZlhZ3|Lw-p0;pG-gHH%Ab zN}9XdDTEIV!`IdQehqs zs<&Lzq>Z6d{SpMWo=C1)arV@@P_QIuY^Z}@|5;YL|>vhj@5FK|GZESIzNCy zMzz$Z-_`4%fGnj9UXTM~>mR_Af~#Bafc_ok$$oDOh!_l9dT>Fd*l4;1{f8|3JY}(- z{U>eU1u#JSuOm*AhMT@AoA;;56vW_176**rCzi5t8K9`JkE9u(QT3@YgHsk6S-qd> zkQe(Lzrd;gSdC?v9Ky54nX(kE2RfEx)+v6I7W_HKaK*arAn{^&6w63^d23!0z|)gv z?y}5(fcHY%hnu_~pFY|N0MesCzgwj6y17)p1}pYXO58UU*qO5k*|={U_dXwCEJvlu z!~2dUe#Y5M@-=T-rEjGHKlTjwMHg>wT{*GB84hwe1c8GgI3NTjSo%2Ahox%w-+R}vx{ zzHi@#BV9`(%R;rIPc(X6QSk@O@?CcUagp49oIpm<+qMr~zCJfs667njU*qtmO#Tz> zAA$5g6~D_XvLyFMv3lk3B@I6UWelfQT#@r_FQuE)l3Ui{HDyKP9NJUE{rAE?LUd9* z1*q8A?J;azjR;$ov9h|+80SP&Qnu5nn=~*iX@L7y`F9B6e_U}WCXGQy>$R%abr1oU z!}QYibh88&H0R}zknJi)nrM2H2CkNK{Vif1EW}^8Ast~@o?d86*gI2l`IgwZjyIW0 zw>G|rm-VHhu{=_Wd?0+7P0R!U6-Gyw>NDceTHVfm0GK$(_FZ@TH}9Y&-|T;V_gKpf zIkl!b4n?#mhmnTB2-S&2EC*;V`ZM%?pRnhM`BZ<}x!Jp+Cltl30lG(K#^RcENL|Hw zd?zqC!;z)9i4a!Td`u?FDrzg$XRbG3BKf-aPXmdqEw8Ub;N8_P@V8d(vhz!dW96X> z<4_wi=^EA6Bf(0<1)iqW`aE}$0jHzj1=Ogm5YK}|zaa^(N<1X>SjbREV;pe24!+7`#mpXA867u=o zS+0e|D_|kxT>0KFV3{oTVf@AMpS^ONWsF;hZve=pA{Nt=Ms}OpFMotn+A#@ybV`34 zqSUX)Kj4_i!$Vor^6Vkm7|jaL0@v``0w?l2VN<3wwssH!{h7U#a|- zup3n#0W*B~*HbF~(q%OeVFy~adqaljmi2||Zxn=u&o6>3EPsusJjth(ChF&D+#v0s z@TdKxiC-ec6OBQfP1TWiZImZ(gRGC3KnuF?A6ksKOG>Um98aq#(8g&SOc9l}R7AK0 zyloK+cu$RA^e0-_Ws}`H=C*N|C>s+Baqv{+F>Eo3J91oZEV zlRR2?Zd@Pn6)Xo(y#eP1iS8F~y+@DTQI{m7UQ&1TnL(MvTO?=(TwIiH=Ji3_h}`5% zYjL;VzuJEV%U>U#NibKU-wa9wdiIh;4vh3mFXquDX@*(1|2UJ~)#p0^k%s}H%fQ<|Z zsdkn~qYwW%f;ng2_xbXyH}Gf*B5qJTOK9!lqaalZDJT@s8OrLvi6y{qp>>sT4O-; zXEC6UbV#e~-03}O7aJ|KzU@%Dv`OyB7Rk^?WDCXFm|V1;8#l}$ z#;wU=7CmZGU|qVN5oGBZs13B&lo7+EsKhEfy^_PIX+?5y`j9TN#X*mMm9GhHJmGWM z5%+qsoDh9(t5NNoS0BL$eaJB39zWoc=!Zr;Y?n{6#539v3?fp#5r50x&b)1B=%0e2!4tcTW^R zb8fPcyJv9LrUNaof|@Q8pz84Rn#wQwP%f(_2Q8HTki!$XfXwv_XpVOv8EwDC%>&Z- zkZcZw)5!dt^}ooDbJO}1O+#>;Ub+EU$JbQc9phbirR=#a7*Y-ZI^(TX`yTWZ8=Uva z!^fOHs2|M4_I{<0Zc(HI>ESn}n**P)dg{2x@0bTP<+be-PyfY)s8-wK;F3eJsfJ!7 zcn3HMq1aq>pr?2pa)cA#*?*TW_1R}0yx>YBL4qw6IKKogAyQ4)LmLzNUK7*Xkgan4 zBB#3(gGcY!f6MHG?z{c%;6cJ{HNv6Cg!M~+dD0C=W-)z-Fdt{-N&LU}s)~(BJ}mzh zpz#kPD|2ad@t3!Qa4d=;#?KU`BUvcm6V0VAYYiqi9ndIz@c2xNeaF*b3$Ar-*)r`H zyS~|wMo8!LVuBuyoS9We(>f+4`o> z1|2>Q(r8=CLHir~rQLRc%F@L;r1B}V-lYkprcZY2Gv-Qho%5!sb4%WuVapP?jxamv z=zp6`nJnHjgb>M`^Hg?loPcD20KcIf9f`mUC7db_l~c2=0pB22 z=Rs>R@OFq}e~G*&-L`_%adYe2QELTX!Vm!RBpA_iN7J$e#!bph*xlv^V$xWJ^jD$| z_#sf2q<7@95gEDeV+Fb)Fz6e&?6N0d77YL_u@oL0I`0Q4cOn)!>Cz<3cs~U~JO@j| zdHhbt;#?qp! z4~}DLvsw~*N5gvWt(G-Bo1;6sB+@Uu^NdU?&6{Y6e9g2UYV~X;r{{`gpdTh-2lA+| za++=)!#;zPa8Z|GKm1|es6{obaEJ{g zh%PQr&~d9=#1L=D@G3Me!5k9Y&9oO0RNJG6TM?yJ;8ONeO)3EVNZ++?u&0)~^dpyX zkG4x%5hVxH;Y7Z<#Tfm&aYYYVoqL3Op|=>6{l-m0q0fNsQ6V385QPE6M`28DBY~>5 zN54MW!p%dS<_lYHx907^$z0IT=Phs;XxsPgled2TaD8>h9|+I11t7D1oHnga6z+dw zoNoP&+b$B~7nfav<8YJ8W|w9meoy zw`$$6%^Quil}ZfWjn5_L$EPrU(MaW$z%}SK)3@}quvJ+8R0(-yA|E7$f`s0@o^=c* zk{q-9-k7)Ir0}@v#cO@Vx%)^oHTw2XaE_0<=t6d)Y?5A#ny1+>1)Ebrxu;_PhF4^$ zHH7Q8^7qY|kphn3xIMe65jK#-U!>6C`3L`IL!t@PiL0<@up%0l!i-lvF>e8%i(nF+h?B_2QO?9<;RwQ6bu1r1$n3-HOctojMn+L4XWU zR*&i1f>Z;!@Mekle61$bU}4QeX!Vi%NHo+;}fDLSh+n_`1lV%-08i79uwS3 z2?uq_i(=#0A1i*$eNj_8D1V&BPYCQJjPsGS0$eTMv(RP-GQ{2`Q+&7~>0oQ9p2Qql z3wUYLEH=0hc?FK+poX$F-&j%cWxOLXSdcZ{sc$$*RyR)pZYEQ#u~cx8bp1iAdyfXg z$sksq6HTCA^Fe{Cxhnj|8l&jNlK7)J303C?W)URz*yh6s31u*lYpIV!KSEAs`p4Qw zt(6Eh9C-1cAQZDl4))c0EZEbC0KiO5_cnCqxC^xQ;U6X_o3T|-5yeIYjb{vvCzOIg z=?T!aYB3sF^shN+vFfMI5y$(G#ty?56qP~qYeXX>gA#FQn z?KvrQf~DIMu^L~$guupMgvm0G4JoIcTdSUy+l7F?TU%@Nd6avT*4Et~75d>Z4`uM? zy+%t3h3HR~rDPhgr*R9i**D}8SUcHMp_$Dewk4rS8$f2cRUVmLhoK$*?SF>wu~fPV z))9MlJ$5Rin_g;qRkNSv$`H0ParhPmAMOYT;+F ztYif@B+XAAzy0uXiLw&o9x`eG!{Le}t0w|?V&jyWZbjYG?JTf;xOVQpkZ#QfU@mj4 z=#&vD-soWP5V-blvLi7yX(8WyS|9JpJY32OdIkgDk$(k9K{YsH30eCJw_4-zKyT?2 z`N6n^6fjG@htb?04C9t~J=nGQf68}D>^c$3gU0o* z6Cnt6whMlQL3x{(hC0yfZE|brU*>zris$Yza{nO>r1-d7Tt7a z$-^4^@phuo&#f^_V*Bg=FkaY1A?P8DYNxod$vVJz5Yq)$-)tB?nk067X&^vBQ1MLo zcl(R!+kPtEMH%fiJM|e6`s!5uE1$ z^bqlbKUt2VX8&CGZ}wKIi$7{G6jswT-I>70)~9o(T;Uk75VUe`Z}(Z*w&lb+(Uma$z0@~5}8vHLbp4j5!g{Dw*kyOe!fN8|1k@BEgGiZ~vO#F@4#hAJ3T;U2s zuHN#ow<04w2uOQ!%?4q2A`EZ#&)h;K18cY*qk!`r&tTyS~F{qMM1j+^Os^5-FcGDdH0h zV;6_6c8U`+unP6GM`kzSnZ|UV4EPO}823sH+0N8>3vP4f!AdR)l!`_Hmuf9;FidWc zjCxqRcneYyy`hT`wI{lLR9SbGg>Q}DUCDLYBHoeg1Se38va0Wnz98#?_H^%*?i=0( zkPk1!CRQsf&kmh^?u;Eng@lrasBOj{K7W?8&X2`n8^JKCxCB6OYk>SI-w%7O%B;{w1aWg*kmFZ-<7ky9|FUgO<6o%WY-h7HQ!{pI|WOj6)Iu4|SY&ff4 zW={t_VCLv|t&$zSak;sZEgFTwbiJIC&q8dDv1L2P_0kZo_t3n_j;cllEI!=QlIgAT zk%Ee%72*??1-C3TIa7f}Ga`2RZ;n2n&`!AjVQZ4Da$$sV@f%#A-5Xqj>DB)P%={Lz zS)JC+eo;cM!IvQkHJkvyhc`SYZ@9mZ$5)w~-aN9R^W<7xAD+}sN^LYB(i~vPgiv@L zN^`PY-ac;D4kPd#-$YEjq zd3AK2DbX~3Pu$;j1%0MphTZZer7C!2bXTn0EH` z_ayflxuD@7)ludfG@x6at!=e?ILngTaZ8X21xgwDScH(^@K{4qSILpc3Ugv7+`-6F zj7N5{`D(2Zyr+D*+8mdWkv;g?k$v6qyk?Ki*Qjmr{oIqlP^-wX@uPqLEnU&kZIJK6 zNdU?B(%o|uKWl%kg;OWJV05SzE^@D)T7p#L2Ra8umn9(q*NySFS>nS=I}-EW=6CXb z0@=k2F$tCN^9RxtYJ(?n>5kokc>8OOdscGy6J;!-(iGYfHg-G%R;|rJjO*^*qM@9IXMk{qvaiyVC2;_t| zA4Bl!r4y)=X>TcB7^>6N2vdHQ9B46keZ3E5ea`@Y=$FubN9CMrZNXjuJDOT&3Doeks+SnPkU<_`l)H^c`=95``Cw zx^_#rNXMM_zJ5BG{kQjZCm<(2n9EnajHYV?oE8QD&4Axqf9 z4}v7Q5Gmc&B}z{E&a2EbywW}1K}OPO0^_py?*FkV+dkw}=~?~Tv|;JC-M&k4moE$Z z{n&tILkKYJypXKr!iU0{-K&T&Hp_K*KcYg}&`f!vKUu_*e%Ee&G`@Q}JTU?=clrDq z&@yPf+d4Oa9=Gii&R#O0P~iF)7Y2Fv7k+|Mm_4d=U7x73DTc zH$W)q8Q1*t+N;rd|AH|9rOhzGVQ6#p*WADia!T*b_E3`-oO1!|&K}XQYJ8R}UM&nm z5RKM~BO6rQ-!!SX)Ap#j)8~@DvxdoCG;wI}sa{%eS|RGSY*ADzDJ2dwTBd{&Tl9Hw zfzH3k2(^+)n#<&ns4-fh#XE9%7mcyUrwJ;VlEi;6>-9RWP zL@nL-6-?yin=f7^IkEnaCdY`m$g4(BJKzZmC!L}`Zxa1 zr2~$#k}xhy`~KZyIX2oB@>{bBdrKvKGY#Km4u+sQJC3U*ST<`y@eFPXMRA8WbbTQh<8 zUSA%c4pya9kI!i80*Lr+3BEa00mFYCut9g@AL{~|zBb%3_6=_wg%O<_4sWBt$CNsz z=mWcUbQwXJp-rA}tA{j0Q2nW{HnMQ^3Ru;5z+{l)_4D8Au~GCV^qRw9_fi4LuMAu9 z{meATn2L^tK9AO?VZdfK9T&r2s;3+)pbhKuw(6ia-tp$c3(JJlE{eDxvK+dqC5ibx zwAS|K!E&s7>X%^|hk8lp0;s80K;m=q<5S4X$5%bE5<897gwzvgwGKxd%N@|WHK`fL@!Bl^`8*_Zq%;dWlOj;v<1m}#$Aa?((oQgKVJ9U zf4`seo_5n-@X@De!i{K+V~{*DtLIsM;7p3nlIp6I%73P3&?|jE{w{juW!d$ayV~iz zOV~4xzCidfEEqd_HlGt|H^x%@GR6)D(M`_y0LvQij`+;ipEs0{OY^{MxSd(Vqr%Tp zaJlevhIFHQ9lHv#f7`b2{xwgEtxipHo8C(5SG-v>_fAqB9ZcxsISK{0sRZJ`4v=82 z^F(A$Q|ai1It9#sB4bpp2{O|7?{1c`XP{U0l|iE&aWi!1D`|x|Mg>IzQgzdq-)`K} zW#2RS)tCo<0H}2&gy)OeOvvpD>eonMB-gFj3_X6bBvd%U$A)qY8N7=ETj&*B3*;~0 z##CTWE8HAb<|Zc&Yo?Rue*~~lApI<)P&I0v!bPphQvpX)+Y;k!VXtwoy(cpvSLrdE zAlc-Cj*c>m4@v`A46jwbFK?Dw@bVk&_yb;*A1>& zG?fGT&AVSV)&*;Ft#b$SE{hz&a<2KxM8ofb}HBm7nui# z!p$qU;Nky#*^=|%w_r!Pgmet|?l2(v%+bpivC#TKz0t3FDQ%J^CHPvUn#Yclgx@(z)05Wm_Xt+$VE>vcxNH zA-d7Q2)@-W?Qq_ofl*^QN+qxARtIbS!$HocnY|<02_UH9pwvzX$|C>AO-!dZM7K zYm2zBtk=*sSaL-mg78WsW66DY>_R;QwlK_-roE}~xsD$+$RYoJ#j^mZb!_%?Br7O) z*%2Myvs$p!#VxichvW97yQde#2338-;_1^@2!UakkghpmEHKLd{edwt|5f#R-nnt&$0y{NAB^G2b@q<=Pl)Fl$1nLdZ+pE&9PC0R2!3x zjZ{B{&v8oDOM-cBR&<7Wp_%Nq0XzTgDjOa(Jr>*jQ}?CFoFiF8PBiOqQ)63SYD>~_ zi?=w-L=#xHcNov`JyKlU?IQv>a1g=V{|elg+nKv@?v;njV#e8C0u>u&&-JU@@B7w@ z_h+7xV+ea%3u}?eMeW4C_k!?qFd>G2rxyLFNJqQ)ZRM~hKvfjh!i930#a8-MQ&>%bC;zW7W7xS930y&>@Kzx$iI zXJSE8Inton$#Fy-FTV4p$5A*$V zzx^h`6+Z{LSV+-RnF8rFDKPf{&c(VsxWCn&fB80Bn}l%6N3ZWA-&M6mDl62-Xp!?+?%T?1?AwQ`;@>yD+cvZ-x zN>Koe_@$v6Au)2!W$0XrXtD7cz8h~dy7n||{aY$#!K#13+(XJshdYKyVi=4mP1RZq zU_}bv>Ogl2f6q-??PP&cM#kYRBaUG;>4L7#)AFz)SjfS$uvwH8oAgjTuhLOqUt_}M zx9&QvNr^ilM-#7DPXLV<4%&`q&43{#CsL)iWt*=W@#TFQx<9W5I$lDGiGd`;MnJ22 ze_5h0)j(teY5$;a?LIcc&H8Ckqof}b7<>d1pFSV(r8n^-uZac#C;C%Qd9ES0B)`7t zxuUgwFTA5kaKe#>W|6n)qu3`sJSjb{TK5K41U_|f`LQd3Ys}!%c8lT| z^iP} ztLoG)Nz=5$NIXS^mJX0}iFz;2{J^dx(?`J}EJ+-*9T|bfrjqmt?`(TK(32`_B7g zVWE%azkFfY4SWnP@u)Jq+8;L-Y4h@}^9KVm=eH-h*F9vDaXdV?89#&Z!ef^3&7Hrs zZu2Cs>fJq}e0UT-lhmSOp7^VVA7m*--A*5~C+ITbcs}_vSH2$IU%z`CG4XQJ*5t{inFwk!~SdDgzaSBgvp!cgE>pM zJzBH_ZNb~I#?gAP0>IjzTc7cM&8d8W18;c@(?JHE!$k*2w^7B7vKdTfuI|9~$p!9i zRM58N(*b;DLrsSTOTQXgR4MX-^YiQTpc(5|nK{2=GZH!5JMWEiDoWPjspYdTnDO%| zA}}5P98?!@y(roWdOkv`cVkvDE39vAumQs&ueZUK0-OdN*rs(4AhRBtHFH72q*PUn zyYzs|F{+jJxLoD4#EiTz)ZQaU2I5>t73xE{L+hz?Zoxxs3$Nj}^6>gtSp!aK10FzH zMolW#i{bOd(vt0*!J6l#=lek--mTO>yY-~(K8yq;j#6uR=^V|PVOrSrJzPkG=&y#G z=ZDs;_YaDr5?1K^o_3J{1_BHjTnNPXM+mJ^S?wNEGm7;>%24E2QzlJ`^KZ^;@kk^o z-z1L_Jc#p73}@%AbUkD9&#vlG)jAXtW$@B)3+Ob|hCrdHb{r8f;+vBVT%V=h>0B}x ztvT|?Hz$+WE;~h7fr9YY42);01nJ{{1XgX-$-#AzfU7iO-1dJXB)_YiYJ)YNZ zsH{;n3S1BSewV}++m+x0xNIjLVs;1%zTTs*icE^p5Gh3D`{(F?=eQpFh9i1CA9!?k zW4jyOP(){egsAycvrRMn$vgExF(8oqexPglYh#k%av<~kSE-qtXx$Okw&~_NlkZV$ zk_|Aoc$VQOxmdUa<`3vVGq1?5sjV))n$I)kN;J+0aS%>eNm9 z>z4-WHo*bXxK=hB6py4JSatV#gGY_HT<49LrWPbjdCEi$B2mTLqKqQ!xqyms_&&b1 z#d(9pEgDX5@>MKhXx!~|<(Rr7u~^(lhPP2=I&}d}&(5V1tpnU@!HNsCZ!-%fS{zPt zZje3hetu>2bS}Dbju2XTz9Jy~*KRY%x`wC@uKKoNc99l;0wU*^N*v`^SdG{NL@yuC z03h_uvuMC&EW^*K60{hP|MlE5P_BM1N6OGi&i4-wZRXm()FTd$riF}dMp^Dowp~Y% zVp0xWkl)YUe0D%Jr4|wN5l)6tL%#WOmR}qL^nuL05v};@6*J-g!ys(#wgp?^Q1S7^h~S#U)`O zq`bSE_vPWx|9mU;WGqgzgPB+SIZ^!OcCCWK^De{eVMWP2Jy_~7R{RP6vh!g{oKeaI z6y+)9$bpk32{o|uvu4U8L$8U3CWMBadWp{hFAn;5SW7oJUZQ?YXs!b}%>(OYmwGdOjNo-ud^|K((_FbL17*d_MrI!yvpmj1UN$vqic)iWO*y84MY^!jOoc6^A~TTkPh>Q-M}qK&yd z;>g+&Q}S*haSY_7(5^ zj#yTpE^$@nO&{rk;gm-F2-Z*SI8nR%<=xgDL_XN2GT16+c6fEjZdBW#y>-vXZ<3J8 zcNu~xx3m>WNDa_sUPoNO=l(Tw*rMQ?&2U?G{c&f)Iiuu%FMcn199J-E_>TQKU{6LBe{LBgkU9CCWs@5 zR7$S-lZm5g)X{hwlSKTi8;)fgCEuqd=Lc$^jE0jKJ$#NfYKMg5nR0Yu9al zmD2r6vm=(|x341~sD)r+FAvJcUC&d>_Nhczos9->*RnE)&atqeJ`w|x>7=|y-#>1IUBnk2Q8Pr?< ztsR)N?zL%>`<*we0kqOe;twA@{%?;Ssj&OiZD{tZQ#Z)`P|ZloHXpCZmXo??U_Anz zGuN>AjZXGo6pH+Dd}H(vv08fMAZ|}-BAHPPE!}Be#JLi!A-rBM?j6ol2EhvWXFs+n zGvJf8jeFdC8^m``M7?jzSbE$^vQ89`J?wxR>E_B$NMGFCpXPF$SWm<;)+a;bfi!-h zpq`bht}kUuNzB;2WujU+z!M>}6!*TzKQH{aG!}2Rr}ALU`cdM)on3H={>mI_nK8TP zO2xo_4zNdIxqczuPKukhu}esrWwvR^lXBi61<%zz7SFLmK2pG#D=c3IpQ0Rd?+yN# z5gS_Gv&cnpaM;~9gW#^q$`9uEi`mS9hgu%Ru1Br2rHkSYiI z^U-?04utgsBRwU8Vm&3l7I+H3HV+$FHq7qh=(qDRYaJ=7wuSN9D~`qIQcCJ_&TCSm zw*U+YhA8&3@+n53beuNI?ZvZO%kS8bDwQdQ>Vp5AiEABJ>KD0bJKrD+U|d|zitE^_ z#u%R??zbN$l6y7M&LlEmMP@Kt_Y<<&UkFb}kglr;%RHT9PAvvs-W7iL%xA5?S|~L% zzgdT?tP9Ot-ggLUTX>fVepK`};kX#8N=sGBdb|C=lS1IN;!*kbxLxe=hvK^P$u6Oi z@xZNg$8E7R9QxtC$a}F*0H#ymGG-Ef12yfU`MJCOX!vpISXBt8ZSM#@%uu{AQt4{g zV;_7|**#?BsAaRwCDNKV+XJjWM>DWSr5LDC=*m^Q31G!q$Yh-p%jK}wY?BWXeNoJu zd*Py-{%7MDAY2*Qp7}5f-E6nDI@d%5b4% z{-1|Z7ANj7kgL;ObCHm=>!E6W3d7kgwtCs~J2q5NMWb2!>GTcY!BE!cJ8JTro;!$KmVpnw`N6~HT z^Fx=G3C(?Plzp2Aa$�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 BG0gw~ diff --git a/scripts/shell_commands.cfg b/scripts/shell_commands.cfg index c6723f0a1..5bc2bc88b 100644 --- a/scripts/shell_commands.cfg +++ b/scripts/shell_commands.cfg @@ -6,5 +6,3 @@ command: ~/printer_data/config/scripts/system_info.py timeout: 5.0 verbose: True - -[include is_workflow/is_workflow_cmd.cfg] From b22121ebc63f504fdefd19865c0e38f1dd530c2c Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:07:24 +0100 Subject: [PATCH 21/79] add mellow SB2040 v2 and SB2040 Pro toolhead boards (#417) --- .../toolhead/Mellow_SB2040_Pro.cfg | 20 +++++ .../toolhead/Mellow_SB2040_v2.cfg | 20 +++++ .../toolhead/Mellow_SB2040_Pro.cfg | 76 +++++++++++++++++++ .../toolhead/Mellow_SB2040_v2.cfg | 76 +++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 config/mcu_definitions/toolhead/Mellow_SB2040_Pro.cfg create mode 100644 config/mcu_definitions/toolhead/Mellow_SB2040_v2.cfg create mode 100644 user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg create mode 100644 user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg diff --git a/config/mcu_definitions/toolhead/Mellow_SB2040_Pro.cfg b/config/mcu_definitions/toolhead/Mellow_SB2040_Pro.cfg new file mode 100644 index 000000000..4b27bf71d --- /dev/null +++ b/config/mcu_definitions/toolhead/Mellow_SB2040_Pro.cfg @@ -0,0 +1,20 @@ +[board_pins toolhead_manufacturer] +mcu: toolhead +aliases: + MCU_EMOT_EN=gpio7 , MCU_EMOT_STEP=gpio9 , MCU_EMOT_DIR=gpio10 , MCU_EMOT_CS=gpio8 , + + MCU_5V_ENDSTOP=gpio28 , + MCU_ENDSTOP=gpio29 , + MCU_HV_ENDSTOP=gpio25 , + + MCU_FAN0=gpio13 , MCU_FAN1=gpio14 , MCU_FAN2=gpio15 , + + MCU_TEMP=gpio27 , MCU_ONBOARD_NTCK100K=gpio26 , + + MCU_HEAT=gpio6 , + + MCU_RGB=gpio12 , + MCU_PWM0=gpio16 , MCU_PWM1=gpio17 , + + MCU_ADXL_CS=gpio1 , MCU_ADXL_SCK=gpio0 , MCU_ADXL_MOSI=gpio3 , MCU_ADXL_MISO=gpio2 , # gpio0-2-3 share with EMOT SPI!!! + MCU_MAX31865_CS=gpio22 , MCU_MAX31865_SCK=gpio18 , MCU_MAX31865_MOSI=gpio19 , MCU_MAX31865_MISO=gpio23 , diff --git a/config/mcu_definitions/toolhead/Mellow_SB2040_v2.cfg b/config/mcu_definitions/toolhead/Mellow_SB2040_v2.cfg new file mode 100644 index 000000000..8d1999a42 --- /dev/null +++ b/config/mcu_definitions/toolhead/Mellow_SB2040_v2.cfg @@ -0,0 +1,20 @@ +[board_pins toolhead_manufacturer] +mcu: toolhead +aliases: + MCU_EMOT_EN=gpio7 , MCU_EMOT_STEP=gpio9 , MCU_EMOT_DIR=gpio10 , MCU_EMOT_UART=gpio8 , + + MCU_5V_ENDSTOP=gpio28 , + MCU_ENDSTOP=gpio29 , + MCU_HV_ENDSTOP=gpio25 , + + MCU_FAN0=gpio13 , MCU_FAN1=gpio14 , MCU_FAN2=gpio15 , + + MCU_TEMP=gpio27 , MCU_ONBOARD_NTCK100K=gpio26 , + + MCU_HEAT=gpio6 , + + MCU_RGB=gpio12 , + MCU_PWM0=gpio16 , MCU_PWM1=gpio17 , + + MCU_ADXL_CS=gpio1 , MCU_ADXL_SCK=gpio0 , MCU_ADXL_MOSI=gpio3 , MCU_ADXL_MISO=gpio2 , + MCU_MAX31865_CS=gpio22 , MCU_MAX31865_SCK=gpio18 , MCU_MAX31865_MOSI=gpio19 , MCU_MAX31865_MISO=gpio23 , diff --git a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg new file mode 100644 index 000000000..9dd48ab1f --- /dev/null +++ b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg @@ -0,0 +1,76 @@ + +#-------------------------------------------# +#### Mellow SB2040 Pro MCU definition ######## +#-------------------------------------------# + +[mcu toolhead] +##-------------------------------------------------------------------- +canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +# If you want to override the wiring of the Mellow SB2040, keep in mind that this +# board is defined using the "toolhead" name. So you should use "pin: toolhead:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/toolhead/Mellow_SB2040_Pro.cfg] # Do not remove this line +[board_pins sb2040_mcu] +mcu: toolhead +aliases: + E_STEP=MCU_EMOT_STEP , E_DIR=MCU_EMOT_DIR , E_ENABLE=MCU_EMOT_EN , E_TMCUART=MCU_EMOT_CS , + + X_STOP=MCU_ENDSTOP , + PROBE_INPUT=MCU_HV_ENDSTOP , + TOOLHEAD_SENSOR=MCU_5V_ENDSTOP , + + E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_TEMP , CHAMBER_TEMPERATURE=MCU_ONBOARD_NTCK100K , + + PART_FAN=MCU_FAN0 , E_FAN=MCU_FAN1 , + + STATUS_NEOPIXEL=MCU_RGB , + + ADXL_CS=MCU_ADXL_CS , ADXL_SCLK=MCU_ADXL_SCK , ADXL_MOSI=MCU_ADXL_MOSI , ADXL_MISO=MCU_ADXL_MISO , + + +#----------------------------------------# +# Mellow SB2040 Pro pins remapping # +#----------------------------------------# + +# These pins overrides are automatically added when you select a CANbus +# toolhead MCU during the installation process. They should provide a +# good base to work with. Feel free to adapt to your board if needed! + +[extruder] +step_pin: toolhead:E_STEP +dir_pin: toolhead:E_DIR +enable_pin: !toolhead:E_ENABLE +heater_pin: toolhead:E_HEATER +sensor_pin: toolhead:E_TEMPERATURE +#pullup_resistor: 1000 # (1000 for PT1000 with jumper conn,4700-default without jumper) +## for PT100: +#sensor_type: MAX31865 +#sensor_pin: toolhead:MCU_MAX31865_CS +# spi_software_sclk_pin: toolhead:MCU_MAX31865_SCK +# spi_software_mosi_pin: toolhead:MCU_MAX31865_MOSI +# spi_software_miso_pin: toolhead:MCU_MAX31865_MISO +#rtd_reference_r: 430 + +[probe] +pin: ^toolhead:PROBE_INPUT + +[fan] +pin: toolhead:PART_FAN + +[heater_fan hotend_fan] +pin: toolhead:E_FAN + +## Uncomment the following line if not using sensorless homing +## and having the X endstop plugged to the toolhead MCU +# [stepper_x] +# endstop_pin: ^toolhead:X_STOP + +[neopixel status_leds] +pin: toolhead:STATUS_NEOPIXEL + +[tmc2240 extruder] +uart_pin: toolhead:E_TMCUART + diff --git a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg new file mode 100644 index 000000000..4717038a0 --- /dev/null +++ b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg @@ -0,0 +1,76 @@ + +#-------------------------------------------# +#### Mellow SB2040 v2 MCU definition ######## +#-------------------------------------------# + +[mcu toolhead] +##-------------------------------------------------------------------- +canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +# If you want to override the wiring of the Mellow SB2040, keep in mind that this +# board is defined using the "toolhead" name. So you should use "pin: toolhead:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/toolhead/Mellow_SB2040_v2.cfg] # Do not remove this line +[board_pins sb2040_mcu] +mcu: toolhead +aliases: + E_STEP=MCU_EMOT_STEP , E_DIR=MCU_EMOT_DIR , E_ENABLE=MCU_EMOT_EN , E_TMCUART=MCU_EMOT_UART , + + X_STOP=MCU_ENDSTOP , + PROBE_INPUT=MCU_HV_ENDSTOP , + TOOLHEAD_SENSOR=MCU_5V_ENDSTOP , + + E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_TEMP , CHAMBER_TEMPERATURE=MCU_ONBOARD_NTCK100K , + + PART_FAN=MCU_FAN0 , E_FAN=MCU_FAN1 , + + STATUS_NEOPIXEL=MCU_RGB , + + ADXL_CS=MCU_ADXL_CS , ADXL_SCLK=MCU_ADXL_SCK , ADXL_MOSI=MCU_ADXL_MOSI , ADXL_MISO=MCU_ADXL_MISO , + + +#----------------------------------------# +# Mellow SB2040 v2 pins remapping # +#----------------------------------------# + +# These pins overrides are automatically added when you select a CANbus +# toolhead MCU during the installation process. They should provide a +# good base to work with. Feel free to adapt to your board if needed! + +[extruder] +step_pin: toolhead:E_STEP +dir_pin: toolhead:E_DIR +enable_pin: !toolhead:E_ENABLE +heater_pin: toolhead:E_HEATER +sensor_pin: toolhead:E_TEMPERATURE +#pullup_resistor: 1000 # (1000 for PT1000 with jumper conn,4700-default without jumper) +## for PT100: +#sensor_type: MAX31865 +#sensor_pin: toolhead:MCU_MAX31865_CS +# spi_software_sclk_pin: toolhead:MCU_MAX31865_SCK +# spi_software_mosi_pin: toolhead:MCU_MAX31865_MOSI +# spi_software_miso_pin: toolhead:MCU_MAX31865_MISO +#rtd_reference_r: 430 + +[probe] +pin: ^toolhead:PROBE_INPUT + +[fan] +pin: toolhead:PART_FAN + +[heater_fan hotend_fan] +pin: toolhead:E_FAN + +## Uncomment the following line if not using sensorless homing +## and having the X endstop plugged to the toolhead MCU +# [stepper_x] +# endstop_pin: ^toolhead:X_STOP + +[neopixel status_leds] +pin: toolhead:STATUS_NEOPIXEL + +[tmc2209 extruder] +uart_pin: toolhead:E_TMCUART + From d0a0c01befab04ae2847a38fa7bd80a71991b44b Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:08:34 +0100 Subject: [PATCH 22/79] correct overriders misspelling (#425) --- config/hardware/probes/dockable.cfg | 4 +- config/hardware/probes/dockable_virtual.cfg | 4 +- config/software/bed_mesh/bed_mesh_120mm.cfg | 2 +- config/software/bed_mesh/bed_mesh_180mm.cfg | 2 +- config/software/bed_mesh/bed_mesh_250mm.cfg | 2 +- config/software/bed_mesh/bed_mesh_300mm.cfg | 2 +- config/software/bed_mesh/bed_mesh_350mm.cfg | 2 +- config/software/bed_mesh/bed_mesh_mk52.cfg | 2 +- config/software/tilting/qgl_180mm.cfg | 2 +- config/software/tilting/qgl_250mm.cfg | 2 +- config/software/tilting/qgl_300mm.cfg | 2 +- config/software/tilting/qgl_350mm.cfg | 2 +- config/software/tilting/z_tilt_120mm.cfg | 2 +- config/software/tilting/z_tilt_250mm.cfg | 2 +- config/software/tilting/z_tilt_300mm.cfg | 2 +- config/software/tilting/z_tilt_350mm.cfg | 2 +- .../bed_mesh_calibrate.cfg | 60 +++++++++---------- .../dockable_probe_overrides.cfg} | 0 .../probing/{overides => overrides}/qgl.cfg | 0 .../{overides => overrides}/z_tilt.cfg | 0 20 files changed, 48 insertions(+), 48 deletions(-) rename macros/base/probing/{overides => overrides}/bed_mesh_calibrate.cfg (97%) rename macros/base/probing/{overides/dockable_probe_overides.cfg => overrides/dockable_probe_overrides.cfg} (100%) rename macros/base/probing/{overides => overrides}/qgl.cfg (100%) rename macros/base/probing/{overides => overrides}/z_tilt.cfg (100%) diff --git a/config/hardware/probes/dockable.cfg b/config/hardware/probes/dockable.cfg index 4bd8e7361..aff5bf45e 100644 --- a/config/hardware/probes/dockable.cfg +++ b/config/hardware/probes/dockable.cfg @@ -3,10 +3,10 @@ variable_probe_type_enabled: "dockable" variable_startprint_actions: "bed_soak", "extruder_preheating", "chamber_soak", "tilt_calib", "extruder_heating", "purge", "clean", "z_offset", "bedmesh", "primeline" gcode: -# Dockable probe definition also include the probe management and overides directly from here +# Dockable probe definition also include the probe management and overrides directly from here [include ../../../macros/base/probing/generic_probe.cfg] [include ../../../macros/base/probing/dockable_probe.cfg] -[include ../../../macros/base/probing/overides/dockable_probe_overides.cfg] +[include ../../../macros/base/probing/overrides/dockable_probe_overrides.cfg] [probe] pin: ^PROBE_INPUT diff --git a/config/hardware/probes/dockable_virtual.cfg b/config/hardware/probes/dockable_virtual.cfg index 9ac19f628..3e3835429 100644 --- a/config/hardware/probes/dockable_virtual.cfg +++ b/config/hardware/probes/dockable_virtual.cfg @@ -8,10 +8,10 @@ variable_probe_type_enabled: "dockable_virtual" variable_startprint_actions: "bed_soak", "extruder_preheating", "chamber_soak", "tilt_calib", "extruder_heating", "purge", "clean", "z_offset", "bedmesh", "primeline" gcode: -# Dockable probe definition also include the probe management and overides directly from here +# Dockable probe definition also include the probe management and overrides directly from here [include ../../../macros/base/probing/generic_probe.cfg] [include ../../../macros/base/probing/dockable_probe.cfg] -[include ../../../macros/base/probing/overides/dockable_probe_overides.cfg] +[include ../../../macros/base/probing/overrides/dockable_probe_overrides.cfg] [probe] pin: ^PROBE_INPUT diff --git a/config/software/bed_mesh/bed_mesh_120mm.cfg b/config/software/bed_mesh/bed_mesh_120mm.cfg index a49908760..0e0372d31 100644 --- a/config/software/bed_mesh/bed_mesh_120mm.cfg +++ b/config/software/bed_mesh/bed_mesh_120mm.cfg @@ -5,7 +5,7 @@ variable_bed_mesh_enabled: True gcode: # Also include directly the dockable probe overide of BED_MESH_CALIBRATE from here -[include ../../../macros/base/probing/overides/bed_mesh_calibrate.cfg] +[include ../../../macros/base/probing/overrides/bed_mesh_calibrate.cfg] # And also include the adaptive mesh macro at the same time [include ../../../macros/calibration/adaptive_bed_mesh.cfg] diff --git a/config/software/bed_mesh/bed_mesh_180mm.cfg b/config/software/bed_mesh/bed_mesh_180mm.cfg index fae7f41c2..ade7bd60f 100644 --- a/config/software/bed_mesh/bed_mesh_180mm.cfg +++ b/config/software/bed_mesh/bed_mesh_180mm.cfg @@ -5,7 +5,7 @@ variable_bed_mesh_enabled: True gcode: # Also include directly the dockable probe overide of BED_MESH_CALIBRATE from here -[include ../../../macros/base/probing/overides/bed_mesh_calibrate.cfg] +[include ../../../macros/base/probing/overrides/bed_mesh_calibrate.cfg] # And also include the adaptive mesh macro at the same time [include ../../../macros/calibration/adaptive_bed_mesh.cfg] diff --git a/config/software/bed_mesh/bed_mesh_250mm.cfg b/config/software/bed_mesh/bed_mesh_250mm.cfg index 15a68ad24..c7ba5b1f5 100644 --- a/config/software/bed_mesh/bed_mesh_250mm.cfg +++ b/config/software/bed_mesh/bed_mesh_250mm.cfg @@ -5,7 +5,7 @@ variable_bed_mesh_enabled: True gcode: # Also include directly the dockable probe overide of BED_MESH_CALIBRATE from here -[include ../../../macros/base/probing/overides/bed_mesh_calibrate.cfg] +[include ../../../macros/base/probing/overrides/bed_mesh_calibrate.cfg] # And also include the adaptive mesh macro at the same time [include ../../../macros/calibration/adaptive_bed_mesh.cfg] diff --git a/config/software/bed_mesh/bed_mesh_300mm.cfg b/config/software/bed_mesh/bed_mesh_300mm.cfg index d2b8e062e..edfaad310 100644 --- a/config/software/bed_mesh/bed_mesh_300mm.cfg +++ b/config/software/bed_mesh/bed_mesh_300mm.cfg @@ -5,7 +5,7 @@ variable_bed_mesh_enabled: True gcode: # Also include directly the dockable probe overide of BED_MESH_CALIBRATE from here -[include ../../../macros/base/probing/overides/bed_mesh_calibrate.cfg] +[include ../../../macros/base/probing/overrides/bed_mesh_calibrate.cfg] # And also include the adaptive mesh macro at the same time [include ../../../macros/calibration/adaptive_bed_mesh.cfg] diff --git a/config/software/bed_mesh/bed_mesh_350mm.cfg b/config/software/bed_mesh/bed_mesh_350mm.cfg index ae6728ec6..63c23527e 100644 --- a/config/software/bed_mesh/bed_mesh_350mm.cfg +++ b/config/software/bed_mesh/bed_mesh_350mm.cfg @@ -5,7 +5,7 @@ variable_bed_mesh_enabled: True gcode: # Also include directly the dockable probe overide of BED_MESH_CALIBRATE from here -[include ../../../macros/base/probing/overides/bed_mesh_calibrate.cfg] +[include ../../../macros/base/probing/overrides/bed_mesh_calibrate.cfg] # And also include the adaptive mesh macro at the same time [include ../../../macros/calibration/adaptive_bed_mesh.cfg] diff --git a/config/software/bed_mesh/bed_mesh_mk52.cfg b/config/software/bed_mesh/bed_mesh_mk52.cfg index 3c7d4ce2f..91deb0556 100644 --- a/config/software/bed_mesh/bed_mesh_mk52.cfg +++ b/config/software/bed_mesh/bed_mesh_mk52.cfg @@ -5,7 +5,7 @@ variable_bed_mesh_enabled: True gcode: # Also include directly the dockable probe overide of BED_MESH_CALIBRATE from here -[include ../../../macros/base/probing/overides/bed_mesh_calibrate.cfg] +[include ../../../macros/base/probing/overrides/bed_mesh_calibrate.cfg] # And also include the adaptive mesh macro at the same time [include ../../../macros/calibration/adaptive_bed_mesh.cfg] diff --git a/config/software/tilting/qgl_180mm.cfg b/config/software/tilting/qgl_180mm.cfg index 1ed235190..314a25f01 100644 --- a/config/software/tilting/qgl_180mm.cfg +++ b/config/software/tilting/qgl_180mm.cfg @@ -6,7 +6,7 @@ variable_qgl_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/qgl.cfg] +[include ../../../macros/base/probing/overrides/qgl.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/qgl_250mm.cfg b/config/software/tilting/qgl_250mm.cfg index 6b59e611a..0be712261 100644 --- a/config/software/tilting/qgl_250mm.cfg +++ b/config/software/tilting/qgl_250mm.cfg @@ -6,7 +6,7 @@ variable_qgl_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/qgl.cfg] +[include ../../../macros/base/probing/overrides/qgl.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/qgl_300mm.cfg b/config/software/tilting/qgl_300mm.cfg index 8fedbfe1b..8b6403a77 100644 --- a/config/software/tilting/qgl_300mm.cfg +++ b/config/software/tilting/qgl_300mm.cfg @@ -6,7 +6,7 @@ variable_qgl_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/qgl.cfg] +[include ../../../macros/base/probing/overrides/qgl.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/qgl_350mm.cfg b/config/software/tilting/qgl_350mm.cfg index 5461ae6f4..6b1f03c64 100644 --- a/config/software/tilting/qgl_350mm.cfg +++ b/config/software/tilting/qgl_350mm.cfg @@ -6,7 +6,7 @@ variable_qgl_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/qgl.cfg] +[include ../../../macros/base/probing/overrides/qgl.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/z_tilt_120mm.cfg b/config/software/tilting/z_tilt_120mm.cfg index 9db6069d5..76fbafcb6 100644 --- a/config/software/tilting/z_tilt_120mm.cfg +++ b/config/software/tilting/z_tilt_120mm.cfg @@ -6,7 +6,7 @@ variable_ztilt_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/z_tilt.cfg] +[include ../../../macros/base/probing/overrides/z_tilt.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/z_tilt_250mm.cfg b/config/software/tilting/z_tilt_250mm.cfg index 2082bce69..77f84bc26 100644 --- a/config/software/tilting/z_tilt_250mm.cfg +++ b/config/software/tilting/z_tilt_250mm.cfg @@ -6,7 +6,7 @@ variable_ztilt_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/z_tilt.cfg] +[include ../../../macros/base/probing/overrides/z_tilt.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/z_tilt_300mm.cfg b/config/software/tilting/z_tilt_300mm.cfg index f800ec2c6..d510a5db3 100644 --- a/config/software/tilting/z_tilt_300mm.cfg +++ b/config/software/tilting/z_tilt_300mm.cfg @@ -6,7 +6,7 @@ variable_ztilt_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/z_tilt.cfg] +[include ../../../macros/base/probing/overrides/z_tilt.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/config/software/tilting/z_tilt_350mm.cfg b/config/software/tilting/z_tilt_350mm.cfg index dfd5aa5c3..586f00fad 100644 --- a/config/software/tilting/z_tilt_350mm.cfg +++ b/config/software/tilting/z_tilt_350mm.cfg @@ -6,7 +6,7 @@ variable_ztilt_enabled: True gcode: # Also include directly the dockable probe overide of qgl from here -[include ../../../macros/base/probing/overides/z_tilt.cfg] +[include ../../../macros/base/probing/overrides/z_tilt.cfg] [include ../../../macros/base/homing/tilting.cfg] diff --git a/macros/base/probing/overides/bed_mesh_calibrate.cfg b/macros/base/probing/overrides/bed_mesh_calibrate.cfg similarity index 97% rename from macros/base/probing/overides/bed_mesh_calibrate.cfg rename to macros/base/probing/overrides/bed_mesh_calibrate.cfg index 968923ec2..8a5effe79 100644 --- a/macros/base/probing/overides/bed_mesh_calibrate.cfg +++ b/macros/base/probing/overrides/bed_mesh_calibrate.cfg @@ -1,30 +1,30 @@ -############################################################################# -# Dockable probe macros highly inspired from https://github.com/jlas1/Klicky-Probe -# Reworked by Elpopo and myself to simplify it while trying to stay generic -############################################################################# - -[gcode_macro BED_MESH_CALIBRATE] -rename_existing: _BASE_BED_MESH_CALIBRATE -description: Perform Mesh Bed Leveling with klicky automount -gcode: - {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} - {% set probe_type_enabled = printer["gcode_macro _USER_VARIABLES"].probe_type_enabled %} - - {% if verbose %} - { action_respond_info("Bed Mesh Calibrate") } - {% endif %} - _CG28 - - ACTIVATE_PROBE - - {% if probe_type_enabled == "dockable" %} - SET_GCODE_VARIABLE MACRO=_PROBE_ON_ERROR_ACTION VARIABLE=probing VALUE=True - {% endif %} - - _BASE_BED_MESH_CALIBRATE {% for p in params %}{'%s=%s ' % (p, params[p])}{% endfor %} - - {% if probe_type_enabled == "dockable" %} - SET_GCODE_VARIABLE MACRO=_PROBE_ON_ERROR_ACTION VARIABLE=probing VALUE=False - {% endif %} - - DEACTIVATE_PROBE +############################################################################# +# Dockable probe macros highly inspired from https://github.com/jlas1/Klicky-Probe +# Reworked by Elpopo and myself to simplify it while trying to stay generic +############################################################################# + +[gcode_macro BED_MESH_CALIBRATE] +rename_existing: _BASE_BED_MESH_CALIBRATE +description: Perform Mesh Bed Leveling with klicky automount +gcode: + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + {% set probe_type_enabled = printer["gcode_macro _USER_VARIABLES"].probe_type_enabled %} + + {% if verbose %} + { action_respond_info("Bed Mesh Calibrate") } + {% endif %} + _CG28 + + ACTIVATE_PROBE + + {% if probe_type_enabled == "dockable" %} + SET_GCODE_VARIABLE MACRO=_PROBE_ON_ERROR_ACTION VARIABLE=probing VALUE=True + {% endif %} + + _BASE_BED_MESH_CALIBRATE {% for p in params %}{'%s=%s ' % (p, params[p])}{% endfor %} + + {% if probe_type_enabled == "dockable" %} + SET_GCODE_VARIABLE MACRO=_PROBE_ON_ERROR_ACTION VARIABLE=probing VALUE=False + {% endif %} + + DEACTIVATE_PROBE diff --git a/macros/base/probing/overides/dockable_probe_overides.cfg b/macros/base/probing/overrides/dockable_probe_overrides.cfg similarity index 100% rename from macros/base/probing/overides/dockable_probe_overides.cfg rename to macros/base/probing/overrides/dockable_probe_overrides.cfg diff --git a/macros/base/probing/overides/qgl.cfg b/macros/base/probing/overrides/qgl.cfg similarity index 100% rename from macros/base/probing/overides/qgl.cfg rename to macros/base/probing/overrides/qgl.cfg diff --git a/macros/base/probing/overides/z_tilt.cfg b/macros/base/probing/overrides/z_tilt.cfg similarity index 100% rename from macros/base/probing/overides/z_tilt.cfg rename to macros/base/probing/overrides/z_tilt.cfg From 15172ce3814f591d57ab861bfa5a602b2776c932 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:39:21 +0100 Subject: [PATCH 23/79] check if heatsoak is configured to verbose message (#424) --- macros/helpers/heatsoak.cfg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/macros/helpers/heatsoak.cfg b/macros/helpers/heatsoak.cfg index 53bc640ca..d794c75f0 100644 --- a/macros/helpers/heatsoak.cfg +++ b/macros/helpers/heatsoak.cfg @@ -44,6 +44,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set heaterbed_enabled = printer["gcode_macro _USER_VARIABLES"].heaterbed_enabled %} + {% set heatsoak_bed_enabled = printer["gcode_macro _USER_VARIABLES"].print_default_soak) > 0 %} # configured heatsoak default value {% if heaterbed_enabled %} {% if verbose %} @@ -58,7 +59,9 @@ gcode: G4 P{60000 * 1} {% endfor %} {% else %} - RESPOND MSG="No heatsoak needed, continue" + {% if heatsoak_bed_enabled %} + RESPOND MSG="No heatsoak needed, continue" + {% endif %} {% endif %} {% if verbose %} From fd29fedb3eb61433a6ff4a0324e12a5079a1e68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Tue, 9 Jan 2024 21:04:24 +0100 Subject: [PATCH 24/79] typo --- macros/helpers/heatsoak.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros/helpers/heatsoak.cfg b/macros/helpers/heatsoak.cfg index d794c75f0..7be25f746 100644 --- a/macros/helpers/heatsoak.cfg +++ b/macros/helpers/heatsoak.cfg @@ -44,7 +44,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set heaterbed_enabled = printer["gcode_macro _USER_VARIABLES"].heaterbed_enabled %} - {% set heatsoak_bed_enabled = printer["gcode_macro _USER_VARIABLES"].print_default_soak) > 0 %} # configured heatsoak default value + {% set heatsoak_bed_enabled = printer["gcode_macro _USER_VARIABLES"].print_default_soak > 0 %} # configured heatsoak default value {% if heaterbed_enabled %} {% if verbose %} From 784bdf56f9b36c0735d8619fbcfd96928b33ff14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ars=C3=A8ne=20Thieffry?= Date: Thu, 11 Jan 2024 00:46:32 +0100 Subject: [PATCH 25/79] Add pin definitions for Fysetc S6 V2.X --- .../mcu_definitions/main/Fysetc_S6_v2.x.cfg | 47 ++++++++++++++++++ docs/pinout.md | 3 +- .../mcu_defaults/main/Fysetc_S6_v2.x.cfg | 49 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 config/mcu_definitions/main/Fysetc_S6_v2.x.cfg create mode 100644 user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg diff --git a/config/mcu_definitions/main/Fysetc_S6_v2.x.cfg b/config/mcu_definitions/main/Fysetc_S6_v2.x.cfg new file mode 100644 index 000000000..aaf671020 --- /dev/null +++ b/config/mcu_definitions/main/Fysetc_S6_v2.x.cfg @@ -0,0 +1,47 @@ +[board_pins mcu_manufacturer] +aliases: + MCU_X_MOT_STEP=PE11 , MCU_X_MOT_DIR=PE10 , MCU_X_MOT_ENABLE=PE9 , MCU_X_MOT_CS_PDN=PE7 , MCU_X_MOT_UART=PE8 , + MCU_Y_MOT_STEP=PD8 , MCU_Y_MOT_DIR=PB12 , MCU_Y_MOT_ENABLE=PD9 , MCU_Y_MOT_CS_PDN=PE15 , MCU_Y_MOT_UART=PC4 , + MCU_Z_MOT_STEP=PD14 , MCU_Z_MOT_DIR=PD13 , MCU_Z_MOT_ENABLE=PD15 , MCU_Z_MOT_CS_PDN=PD10 , MCU_Z_MOT_UART=PD12 , + MCU_E0_MOT_STEP=PD5 , MCU_E0_MOT_DIR=PD6 , MCU_E0_MOT_ENABLE=PD4 , MCU_E0_MOT_CS_PDN=PD7 , MCU_E0_MOT_UART=PA15 , + MCU_E1_MOT_STEP=PE6 , MCU_E1_MOT_DIR=PC13 , MCU_E1_MOT_ENABLE=PE5 , MCU_E1_MOT_CS_PDN=PC14 , MCU_E1_MOT_UART=PC5 , + MCU_E2_MOT_STEP=PE2 , MCU_E2_MOT_DIR=PE4 , MCU_E2_MOT_ENABLE=PE3 , MCU_E2_MOT_CS_PDN=PC15 , MCU_E2_MOT_UART=PE0 , + MCU_TMC_MOSI=PE14 , MCU_TMC_MISO=PE13 , MCU_TMC_SCK=PE12 , + + MCU_X_MIN=PB14 , MCU_Y_MIN=PB13 , MCU_Z_MIN=PA0 , + MCU_X_MAX=PA1 , MCU_Y_MAX=PA2 , MCU_Z_MAX=PA3 , + + MCU_FAN0=PB0 , MCU_FAN1=PB1 , MCU_FAN2=PB2 , + + MCU_RGB_R=PB6 , MCU_RGB_G=PB5 , MCU_RGB_B=PB7 , MCU_LED_DEBUG=PD3 , + + MCU_E0_OUT=PB3 , MCU_E1_OUT=PB4 , MCU_E2_OUT=PB15 , + + MCU_BED_OUT=PC8 , + + MCU_TE0=PC0 , MCU_TE1=PC1 , MCU_TE2=PC2 , MCU_TB=PC3 , + + MCU_I2C_SLC=PB8 , MCU_I2C_SDA=PB9 , + MCU_SWD_DIO=PA13 , MCU_SWD_CLK=PA14 , + MCU_Pi_PWR_UART_TX1=PA9 , MCU_Pi_PWR_UART_RX1=PA10 , + MCU_P2_DP=PA12 , MCU_P2_DM=PA11 , + + # AUX3 header + MCU_AUX3_5V=<5V> , MCU_AUX3_CD=PB10 , + MCU_AUX3_MISO=PA6 , MCU_AUX3_MOSI=PA7 , + MCU_AUX3_SCK=PA5 , MCU_AUX3_CS=PA4 , + MCU_AUX3_GND= , MCU_AUX3_RST= , + + # EXP1 header + EXP1_1=PC9 , EXP1_2=PA8 , + EXP1_3=PC11 , EXP1_4=PD2 , + EXP1_5=PC10 , EXP1_6=PC12 , # Slot in the socket on this side + EXP1_7=PD0 , EXP1_8=PD1 , + EXP1_9= , EXP1_10=<5V> , + + # EXP2 header + EXP2_1=PA6 , EXP2_2=PA5 , + EXP2_3=PC6 , EXP2_4=PA4 , + EXP2_5=PC7 , EXP2_6=PA7 , # Slot in the socket on this side + EXP2_7=PB10 , EXP2_8= , + EXP2_9= , EXP2_10=<5V> , \ No newline at end of file diff --git a/docs/pinout.md b/docs/pinout.md index 8e0101db8..21b79a5b1 100644 --- a/docs/pinout.md +++ b/docs/pinout.md @@ -77,4 +77,5 @@ For more information on the boards and pinouts, please see directly the manufact - [BTT Manta 8P](https://github.com/bigtreetech/Manta-M8P) - [Fly SHT](https://mellow.klipper.cn/#/board/fly_sht36_42/) - [BTT EBB](https://github.com/bigtreetech/EBB) - - [BTT SKR Mini E3](https://github.com/bigtreetech/BIGTREETECH-SKR-mini-E3) \ No newline at end of file + - [BTT SKR Mini E3](https://github.com/bigtreetech/BIGTREETECH-SKR-mini-E3) + - [Fysetc S6](https://github.com/FYSETC/FYSETC-S6) \ No newline at end of file diff --git a/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg b/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg new file mode 100644 index 000000000..896290525 --- /dev/null +++ b/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg @@ -0,0 +1,49 @@ + +#---------------------------------------------# +#### Fysetc S6 v2.x MCU definition ######## +#---------------------------------------------# + +[mcu] +##-------------------------------------------------------------------- +# This board work by using a serial connection by default. If you +# want to use CAN, invert the commented lines and use canbus_uuid. + +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/Fysetc_S6_v2.x.cfg] # Do not remove this line +[board_pins s6_mcu] +mcu: mcu +aliases: + X_STEP=MCU_X_MOT_STEP , X_DIR=MCU_X_MOT_DIR , X_ENABLE=MCU_X_MOT_ENABLE , X_TMCUART=MCU_X_MOT_UART , # Replace with X_TMCUART=MCU_X_MOT_CS_PDN if you're using SPI drivers such as TMC2240 or TMC5160 + Y_STEP=MCU_Y_MOT_STEP , Y_DIR=MCU_Y_MOT_DIR , Y_ENABLE=MCU_Y_MOT_ENABLE , Y_TMCUART=MCU_Y_MOT_UART , # Replace with Y_TMCUART=MCU_Y_MOT_CS_PDN if you're using SPI drivers such as TMC2240 or TMC5160 + + Z_STEP=MCU_Z_MOT_STEP , Z_DIR=MCU_Z_MOT_DIR , Z_ENABLE=MCU_Z_MOT_ENABLE , Z_TMCUART=MCU_Z_MOT_UART , # Replace with Z_TMCUART=MCU_Z_MOT_CS_PDN if you're using SPI drivers such as TMC2240 or TMC5160 + Z1_STEP=MCU_E1_MOT_STEP , Z1_DIR=MCU_E1_MOT_DIR , Z1_ENABLE=MCU_E1_MOT_ENABLE , Z1_TMCUART=MCU_E1_MOT_UART , # Replace with Z1_TMCUART=MCU_E1_MOT_CS_PDN if you're using SPI drivers such as TMC2240 or TMC5160 + Z2_STEP=MCU_E2_MOT_STEP , Z2_DIR=MCU_E2_MOT_DIR , Z2_ENABLE=MCU_E2_MOT_ENABLE , Z2_TMCUART=MCU_E2_MOT_UART , # Replace with Z2_TMCUART=MCU_E2_MOT_CS_PDN if you're using SPI drivers such as TMC2240 or TMC5160 + + E_STEP=MCU_E0_MOT_STEP , E_DIR=MCU_E0_MOT_DIR , E_ENABLE=MCU_E0_MOT_ENABLE , E_TMCUART=MCU_E0_MOT_UART , # Replace with E_TMCUART=MCU_E0_MOT_CS_PDN if you're using SPI drivers such as TMC2240 or TMC5160 + + DRIVER_SPI_MOSI=MCU_TMC_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MISO=MCU_TMC_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_SCK=MCU_TMC_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 + + X_STOP=MCU_X_MIN , Y_STOP=MCU_Y_MIN , Z_STOP=MCU_Z_MIN , + PROBE_INPUT=MCU_Z_MAX , + RUNOUT_SENSOR=MCU_Y_MAX , + + E_HEATER=MCU_E0_OUT , E_TEMPERATURE=MCU_TE0 , + BED_HEATER=MCU_BED_OUT , BED_TEMPERATURE=MCU_TB , + + PART_FAN=MCU_FAN1 , E_FAN=MCU_FAN0 , + CONTROLLER_FAN=MCU_FAN2 , + EXHAUST_FAN=MCU_E2_OUT , + FILTER_FAN=MCU_RGB_R , + HOST_CONTROLLER_FAN=MCU_RGB_G , + + CHAMBER_TEMPERATURE=MCU_TE1 , ELECTRICAL_CABINET_TEMPERATURE=MCU_TE2 , + + LIGHT_OUTPUT=MCU_E1_OUT , + #LIGHT_NEOPIXEL= , # You can use MCU_X_MAX if you bridge the pads to have 5V on this pin + STATUS_NEOPIXEL=MCU_RGB_B , From 14da7e4de2901d27e0d112a007d8cb62ee5aff2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ars=C3=A8ne=20Thieffry?= Date: Mon, 15 Jan 2024 22:00:45 +0100 Subject: [PATCH 26/79] add TR8x2 leadscrew config for trident --- .../hardware/axis/Z/Trident_TR8x2_1.8deg.cfg | 18 ++++++++++++++++++ user_templates/printer.cfg | 1 + 2 files changed, 19 insertions(+) create mode 100644 config/hardware/axis/Z/Trident_TR8x2_1.8deg.cfg diff --git a/config/hardware/axis/Z/Trident_TR8x2_1.8deg.cfg b/config/hardware/axis/Z/Trident_TR8x2_1.8deg.cfg new file mode 100644 index 000000000..8649a265e --- /dev/null +++ b/config/hardware/axis/Z/Trident_TR8x2_1.8deg.cfg @@ -0,0 +1,18 @@ +[stepper_z] +rotation_distance: 2 +microsteps: 32 +full_steps_per_rotation: 200 + +[stepper_z1] +rotation_distance: 2 +microsteps: 32 +full_steps_per_rotation: 200 + +[stepper_z2] +rotation_distance: 2 +microsteps: 32 +full_steps_per_rotation: 200 + +# We also include the default wiring and speeds from here to avoid duplicating +[include default_wiring_3M.cfg] +[include default_speed.cfg] diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index e7f50e614..674cc2954 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -37,6 +37,7 @@ # [include config/hardware/axis/Z/Trident_TR8x8_1.8deg.cfg] # [include config/hardware/axis/Z/Trident_TR8x4_1.8deg.cfg] +# [include config/hardware/axis/Z/Trident_TR8x2_1.8deg.cfg] # [include config/hardware/axis/Z/V0_TR8x8_1.8deg.cfg] # [include config/hardware/axis/Z/V0_TR8x4_1.8deg.cfg] From 8524631acd33fe7a647cddcda0797e28d1d91a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ars=C3=A8ne=20Thieffry?= Date: Mon, 15 Jan 2024 22:55:04 +0100 Subject: [PATCH 27/79] Add older version of Fysetc mini12864 display --- .../displays/Fysetc_mini12864_v1.2_v2.0.cfg | 35 +++++++++++++++++++ .../Fysetc_mini12864_v1.2_v2.0_inversed.cfg | 35 +++++++++++++++++++ user_templates/printer.cfg | 2 ++ 3 files changed, 72 insertions(+) create mode 100644 config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg create mode 100644 config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg diff --git a/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg new file mode 100644 index 000000000..037a75c46 --- /dev/null +++ b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg @@ -0,0 +1,35 @@ +# Neopixel leds integrated in the Fysetc mini12864 display +[gcode_macro _USER_VARIABLES] +variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_led_name: "fysetc_mini12864" +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] + + +[display] +lcd_type: uc1701 +cs_pin: EXP1_8 +a0_pin: EXP1_7 +rst_pin: EXP1_6 +encoder_pins: ^EXP2_8, ^EXP2_6 +click_pin: ^!EXP1_9 +## Some micro-controller boards may require an spi bus to be specified: +#spi_bus: spi +## Alternatively, some micro-controller boards may work with software spi: +contrast: 63 +spi_software_miso_pin: EXP2_10 +spi_software_mosi_pin: EXP2_5 +spi_software_sclk_pin: EXP2_9 + +[output_pin beeper] +pin: EXP1_10 + +[led fysetc_mini12864] +red_pin: EXP1_5 +green_pin: EXP1_4 +blue_pin: EXP1_3 +initial_RED: 0.1 +initial_GREEN: 0.5 +initial_BLUE: 0.0 \ No newline at end of file diff --git a/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg new file mode 100644 index 000000000..b84a888ab --- /dev/null +++ b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg @@ -0,0 +1,35 @@ +# Neopixel leds integrated in the Fysetc mini12864 display +[gcode_macro _USER_VARIABLES] +variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_led_name: "fysetc_mini12864" +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] + + +[display] +lcd_type: uc1701 +cs_pin: EXP1_3 +a0_pin: EXP1_4 +rst_pin: EXP1_5 +encoder_pins: ^EXP2_3, ^EXP2_5 +click_pin: ^!EXP1_2 +## Some micro-controller boards may require an spi bus to be specified: +#spi_bus: spi +## Alternatively, some micro-controller boards may work with software spi: +contrast: 63 +spi_software_miso_pin: EXP2_1 +spi_software_mosi_pin: EXP2_6 +spi_software_sclk_pin: EXP2_2 + +[output_pin beeper] +pin: EXP1_1 + +[led fysetc_mini12864] +red_pin: EXP1_6 +green_pin: EXP1_7 +blue_pin: EXP1_8 +initial_RED: 0.1 +initial_GREEN: 0.5 +initial_BLUE: 0.0 \ No newline at end of file diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 674cc2954..9e3208a04 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -130,6 +130,7 @@ ### that correspond to your display brand in the following lines: # [include config/hardware/displays/BTT_mini12864.cfg] # [include config/hardware/displays/Fysetc_mini12864.cfg] +# [include config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg] ### As BTT and Fysetc have done the wiring exactly the opposite on their boards, if you are mixing ### the brands (ie. a BTT display on a Fysetc board, or the opposite), please use the file @@ -137,6 +138,7 @@ ### rotate connectors 180 degree according to this documentation: https://docs.vorondesign.com/build/electrical/mini12864_klipper_guide.html # [include config/hardware/displays/BTT_mini12864_inversed.cfg] # [include config/hardware/displays/Fysetc_mini12864_inversed.cfg] +# [include config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg] # ---------------------------------------------------------------------------------------- From 562ba0a94afc33dc36c1d8af286ab9bdf422eec4 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:52:45 +0100 Subject: [PATCH 28/79] HappyHare & other related dev (#371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * HappyHare MMU integration in Klippain * Spoolman support * Multiple MCU templates added or modified, especially MMU templates * LED system rework to support the LED_effects plugin and rainbow barf, etc... ( #416 ) * TMC Autotune moonraker updater predefined config (add your motor defs to your overrides.cfg or mcu.cfg) --------- Co-authored-by: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Co-authored-by: claudioguareschi <33001685+claudioguareschi@users.noreply.github.com> Co-authored-by: Félix Boisselier Co-authored-by: ksummers92 <66363414+ksummers92@users.noreply.github.com> --- README.md | 114 ++++---- config/hardware/ercf.cfg | 24 +- config/hardware/lights/config_colors.cfg | 56 ++++ config/hardware/lights/fcob_white.cfg | 1 + config/hardware/lights/neopixel_caselight.cfg | 2 + .../lights/neopixel_caselight_effects.cfg | 185 +++++++++++++ config/hardware/lights/status_leds.cfg | 2 + .../hardware/lights/status_leds_effects.cfg | 230 ++++++++++++++++ .../lights/status_leds_rainbow_barf.cfg | 33 +++ .../status_leds_rainbow_barf_effects.cfg | 230 ++++++++++++++++ config/hardware/mmu.cfg | 15 ++ config/machine.cfg | 17 +- .../mcu_definitions/ercf/BTT_MMB_CAN_v1.0.cfg | 29 -- .../ercf/Tircown_ERCF_easy_brd.cfg | 12 - .../mcu_definitions/main/BTT_SKR_Pro_V1.2.cfg | 52 ++++ .../mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg | 23 ++ .../mcu_definitions/mmu/BTT_SKR_Pico_v1.0.cfg | 25 ++ .../{ercf => mmu}/Fysetc_ERCF_ERB.cfg | 9 +- .../{ercf => mmu}/Mellow_fly_ERCF.cfg | 18 +- .../mmu/Tircown_ERCF_easy_brd.cfg | 12 + config/software/spoolman.cfg | 6 + docs/configuration.md | 50 ++-- docs/features/adaptive_bed_mesh.md | 2 +- docs/images/mmu/HHv2_error_tmc.png | Bin 0 -> 17086 bytes docs/images/mmu/HHv2_mcu_tmc.png | Bin 0 -> 13727 bytes docs/images/mmu/HHv2emptygate.png | Bin 0 -> 13209 bytes docs/mmu.md | 104 ++++++++ docs/pinout.md | 48 ++-- install.sh | 37 +-- macros/base/cancel_print.cfg | 20 +- macros/base/end_print.cfg | 20 +- macros/base/homing/homing_conditional.cfg | 8 +- macros/base/homing/tilting.cfg | 9 - macros/base/park.cfg | 41 ++- macros/base/pause_resume.cfg | 13 +- macros/base/probing/overrides/qgl.cfg | 10 + macros/base/probing/overrides/z_tilt.cfg | 11 + macros/base/start_print.cfg | 49 ++-- macros/calibration/calibrate.cfg | 12 +- macros/hardware_functions/mmu.cfg | 249 ++++++++++++++++++ macros/hardware_functions/status_leds.cfg | 45 +++- macros/helpers/filament_swap.cfg | 77 ++---- macros/helpers/prime_line.cfg | 24 +- macros/helpers/spoolman.cfg | 20 ++ macros/miscs/startup.cfg | 42 ++- moonraker/base.conf | 9 - moonraker/led_effect.conf | 5 + moonraker/spoolman.conf | 6 + moonraker/tmc_autotune.conf | 8 + user_templates/mcu.cfg | 1 - .../mcu_defaults/ercf/BTT_MMB_CAN_v1.0.cfg | 31 --- .../mcu_defaults/ercf/Fysetc_ERCF_ERB.cfg | 37 --- .../mcu_defaults/ercf/Mellow_fly_ERCF.cfg | 38 --- .../ercf/Tircown_ERCF_easy_brd.cfg | 28 -- .../mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg | 1 + .../mcu_defaults/main/BTT_SKR_Mini_E3_v2.cfg | 2 +- .../mcu_defaults/main/BTT_SKR_Mini_E3_v3.cfg | 2 +- .../mcu_defaults/main/BTT_SKR_Pico_v1.0.cfg | 2 +- .../mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg | 31 +++ .../mcu_defaults/main/Double_BTT_SKR_v1.4.cfg | 14 +- .../main/Fysetc_Catalyst_v1.x.cfg | 2 +- .../mcu_defaults/main/Fysetc_S6_v2.x.cfg | 1 + .../mcu_defaults/main/Fysetc_Spider_v1.x.cfg | 1 + .../mcu_defaults/main/Fysetc_Spider_v2.x.cfg | 1 + .../mcu_defaults/main/LDO_Leviathan_v1.2.cfg | 1 + .../main/MY-OWN-CUSTOM-TEMPLATE.cfg | 1 + .../mcu_defaults/mmu/BTT_MMB_CAN_v1.0.cfg | 53 ++++ .../mcu_defaults/mmu/BTT_SKR_Pico_v1.0.cfg | 27 ++ .../mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg | 37 +++ .../mcu_defaults/mmu/Mellow_fly_ERCF.cfg | 37 +++ .../mmu/Tircown_ERCF_easy_brd.cfg | 29 ++ .../mcu_defaults/toolhead/BTT_SB2240_v1.0.cfg | 2 +- .../toolhead/Mellow_SB2040_Pro.cfg | 5 +- .../toolhead/Mellow_SB2040_v1.cfg | 5 +- .../toolhead/Mellow_SB2040_v2.cfg | 5 +- user_templates/moonraker.conf | 15 ++ user_templates/overrides.cfg | 2 +- user_templates/printer.cfg | 29 +- user_templates/save_variables.cfg | 15 +- user_templates/variables.cfg | 67 +---- 80 files changed, 1935 insertions(+), 601 deletions(-) create mode 100644 config/hardware/lights/config_colors.cfg create mode 100644 config/hardware/lights/neopixel_caselight_effects.cfg create mode 100644 config/hardware/lights/status_leds_effects.cfg create mode 100644 config/hardware/lights/status_leds_rainbow_barf.cfg create mode 100644 config/hardware/lights/status_leds_rainbow_barf_effects.cfg create mode 100644 config/hardware/mmu.cfg delete mode 100644 config/mcu_definitions/ercf/BTT_MMB_CAN_v1.0.cfg delete mode 100644 config/mcu_definitions/ercf/Tircown_ERCF_easy_brd.cfg create mode 100644 config/mcu_definitions/main/BTT_SKR_Pro_V1.2.cfg create mode 100644 config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg create mode 100644 config/mcu_definitions/mmu/BTT_SKR_Pico_v1.0.cfg rename config/mcu_definitions/{ercf => mmu}/Fysetc_ERCF_ERB.cfg (90%) rename config/mcu_definitions/{ercf => mmu}/Mellow_fly_ERCF.cfg (58%) create mode 100644 config/mcu_definitions/mmu/Tircown_ERCF_easy_brd.cfg create mode 100644 config/software/spoolman.cfg create mode 100644 docs/images/mmu/HHv2_error_tmc.png create mode 100644 docs/images/mmu/HHv2_mcu_tmc.png create mode 100644 docs/images/mmu/HHv2emptygate.png create mode 100644 docs/mmu.md create mode 100644 macros/hardware_functions/mmu.cfg create mode 100644 macros/helpers/spoolman.cfg create mode 100644 moonraker/led_effect.conf create mode 100644 moonraker/spoolman.conf create mode 100644 moonraker/tmc_autotune.conf delete mode 100644 user_templates/mcu_defaults/ercf/BTT_MMB_CAN_v1.0.cfg delete mode 100644 user_templates/mcu_defaults/ercf/Fysetc_ERCF_ERB.cfg delete mode 100644 user_templates/mcu_defaults/ercf/Mellow_fly_ERCF.cfg delete mode 100644 user_templates/mcu_defaults/ercf/Tircown_ERCF_easy_brd.cfg create mode 100644 user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg create mode 100644 user_templates/mcu_defaults/mmu/BTT_MMB_CAN_v1.0.cfg create mode 100644 user_templates/mcu_defaults/mmu/BTT_SKR_Pico_v1.0.cfg create mode 100644 user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg create mode 100644 user_templates/mcu_defaults/mmu/Mellow_fly_ERCF.cfg create mode 100644 user_templates/mcu_defaults/mmu/Tircown_ERCF_easy_brd.cfg diff --git a/README.md b/README.md index 078af819e..7f3da803b 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,57 @@ -# Klippain - -> Klippain - The pain-free recipe for (french)bread and butter Klipper configuration! - -Klippain is a generic, modular, and highly customizable Klipper configuration for 3D printers. Designed for use on various machines such as Cartesian, CoreXY and CoreXZ, it has been reported working correctly on Voron V2.4, Voron Trident, Voron V0, Voron SwitchWire, TriZero, VZbot, Ender5, Ender3, Prusas, etc... - -![Klippain](./docs/klippain.png) - -Klippain is regularly updated with new features and merged PRs from users. You can reach me on the Voron Discord as **Frix_x#0161**. - -Fun fact: "pain" \pɛ̃\ is the French word for bread, so there's no pain in this pain—only joy! Thanks to the French channel "honhonhonbaguette-FR" on the Voron Discord for the joke and name suggestion! - - -## Features - -Klippain is designed for versatility. By selecting and enabling the desired hardware and software options, it can be used on a wide range of machines. - -Custom features available out of the box include **adaptive bed mesh**, **custom printer calibration macros**, **automated input shaper workflows**, and **vibration measurement** macros and scripts, ... Refer to the [features documentation](./docs/features.md) for a detailed list and usage instructions. - - -## Installation - -To install Klippain, first ensure you have already Klipper, Moonraker, and a WebUI installed on your printer. If not, use [KIAUH](https://github.com/th33xitus/kiauh). - -Then, run the installation script using the following command over SSH. This script will backup your old configuration, download this GitHub repository to your RaspberryPi home directory, and set up Klippain in `~/printer_data/config`. You will also be prompted to select and install MCU board_pins templates. This is recommended for faster `mcu.cfg` setup, but you can do it manually later if you prefer. - -```bash -wget -O - https://raw.githubusercontent.com/Frix-x/klippain/main/install.sh | bash -``` - -Finally, Klippain requires a few simple steps to configure and customize it for your printer: please follow the [configuration guide](./docs/configuration.md). - - > **Warning** - > - > General rule to keep the auto-update feature working: **never modify Klippain files directly**, but instead add overrides as per the documentation! To proceed, you can modify all the pre-installed templates in your config root folder (`printer.cfg`, `mcu.cfg`, `variables.cfg` and `overrides.cfg`) as they will be preserved on update. - - -## Removing Klippain - -In case Klippain doesn't suit your needs or if you installed it by mistake, you can easily remove Klippain and revert to your previous configuration by using the automated uninstall script. During the uninstallation process, the script will remove all specific Klippain files and configurations. Additionally, you will be given an option to restore your previously backed-up configuration, allowing your printer to return to its last working state (from before Klippain was installed). - -To run the uninstall script, execute the following command over SSH: - -```bash -wget -O - https://raw.githubusercontent.com/Frix-x/klippain/main/uninstall.sh | bash -``` - - > **Note** - > - > All backups are preserved during the uninstallation process. So, you can easily revert back at any time if you wish to :stuck_out_tongue_winking_eye: - - -## Support the Project - -I strive to accommodate user requests that align with this configuration's design. Feel free to open an issue or a PR for specific hardware device support or new features. - -Alternatively, consider buying me a coffee or contributing to new hardware purchases to support my work! +# Klippain + +> Klippain - The pain-free recipe for (french)bread and butter Klipper configuration! + +Klippain is a generic, modular, and highly customizable Klipper configuration for 3D printers. Designed for use on various machines such as Cartesian, CoreXY and CoreXZ, it has been reported working correctly on Voron V2.4, Voron Trident, Voron V0, Voron SwitchWire, TriZero, VZbot, Ender5, Ender3, Prusas, etc... + +![Klippain](./docs/klippain.png) + +Klippain is regularly updated with new features and merged PRs from users. You can reach me on the Voron Discord as **Frix_x#0161**. + +Fun fact: "pain" \pɛ̃\ is the French word for bread, so there's no pain in this pain—only joy! Thanks to the French channel "honhonhonbaguette-FR" on the Voron Discord for the joke and name suggestion! + + +## Features + +Klippain is designed for versatility. By selecting and enabling the desired hardware and software options, it can be used on a wide range of machines. + +Custom features available out of the box include a full featured set of standard macros, **adaptive bed mesh**, **custom printer calibrations**, **automated input shaper workflows**, and **vibration measurement** macros and scripts, ... Refer to the [features documentation](./docs/features.md) for a detailed list and usage instructions. + + +## Installation + +To install Klippain, first ensure you have already Klipper, Moonraker, and a WebUI installed on your printer. If not, you can use [KIAUH](https://github.com/th33xitus/kiauh). + +Then, run the installation script using the following command over SSH. This script will backup your old configuration, download this GitHub repository to your RaspberryPi home directory, and set up Klippain in `~/printer_data/config`. You will also be prompted to select and install MCU board_pins templates. This is recommended for faster `mcu.cfg` setup, but you can do it manually later if you prefer. + +```bash +wget -O - https://raw.githubusercontent.com/Frix-x/klippain/main/install.sh | bash +``` + +Finally, Klippain requires a few simple steps to configure and customize it for your printer: please follow the [configuration guide](./docs/configuration.md). + + > **Warning**: + > + > General rule to keep the auto-update feature working: **never modify Klippain files directly**, but instead add overrides as per [the documentation](./docs/overrides.md)! To proceed, you can modify all the pre-installed templates in your config root folder (`printer.cfg`, `mcu.cfg`, `variables.cfg` and `overrides.cfg`) as they will be preserved on update. + + +## Removing Klippain + +In case Klippain doesn't suit your needs or if you installed it by mistake, you can easily remove Klippain and revert to your previous configuration by using the automated uninstall script. During the uninstallation process, the script will remove all specific Klippain files and configurations. Additionally, you will be given an option to restore your previously backed-up configuration, allowing your printer to return to its last working state (from before Klippain was installed). + +To run the uninstall script, execute the following command over SSH: + +```bash +wget -O - https://raw.githubusercontent.com/Frix-x/klippain/main/uninstall.sh | bash +``` + + > **Note**: + > + > All backups are preserved during the uninstallation process. So, you can easily revert back at any time if you wish to :stuck_out_tongue_winking_eye: + + +## Support the Project + +I strive to accommodate user requests that align with this configuration's design. Feel free to open an issue or a PR for specific hardware device support or new features. + +Alternatively, consider buying me a coffee or contributing to new hardware purchases to support my work! diff --git a/config/hardware/ercf.cfg b/config/hardware/ercf.cfg index 7cf97e801..3a478857a 100644 --- a/config/hardware/ercf.cfg +++ b/config/hardware/ercf.cfg @@ -1,26 +1,10 @@ +## DEPRECATED! +## Please use the mmu.cfg file instead + + ## Enraged Rabbit Carrot Feeder config file ## Designed to be used with Ercf Software V3 "Happy Hare" (HH) by moggieuk: https://github.com/moggieuk/ERCF-Software-V3 [gcode_macro _USER_VARIABLES] variable_klippain_ercf_enabled: True gcode: - -[extruder] -max_extrude_only_distance: 200 -max_extrude_cross_section: 50.0 - -# Custom macro to raise an error during the START_PRINT and stop it in case of an ERCF error -[gcode_macro _ERCF_ERROR_CHECK] -gcode: - {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} - {% set INITIAL_TOOL = printer["gcode_macro START_PRINT"].initial_tool %} - - {% if printer.ercf.enabled %} - {% if printer.ercf.tool|int != INITIAL_TOOL or printer.ercf.filament != "Loaded" %} - {action_raise_error("ERCF error while loading filament! Please check and restart the print")} - {% else %} - {% if verbose %} - RESPOND MSG="T{INITIAL_TOOL} ready" - {% endif %} - {% endif %} - {% endif %} diff --git a/config/hardware/lights/config_colors.cfg b/config/hardware/lights/config_colors.cfg new file mode 100644 index 000000000..681fcb60c --- /dev/null +++ b/config/hardware/lights/config_colors.cfg @@ -0,0 +1,56 @@ +## This file contain the color definitions used for the different LED states +# You can override it if needed to define your own colors. These defaults +# should be a good starting point + +[gcode_macro _LEDS_COLORS_DEFINITION] +variable_colors: { + 'logo': { + '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}, + 'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.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}, + 'done_printing': {'r': 0.0, 'g': 1.0, 'b': 0.0, 'w': 0.0}, + 'standby': {'r': 0.01, 'g': 0.01, 'b': 0.01, 'w': 0.1}, + 'error': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, + }, + 'nozzle': { + '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}, + 'done_printing': {'r': 1.0, 'g': 1.0, 'b': 0.0, 'w': 1.0}, + 'error': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, + }, + 'caselight': { + '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}, + 'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.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}, + 'done_printing': {'r': 0.0, 'g': 1.0, 'b': 0.0, 'w': 0.0}, + 'standby': {'r': 0.01, 'g': 0.01, 'b': 0.01, 'w': 0.1}, + 'error': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, + }, + 'minidisplay': { + 'on': {'r': 0.0, 'g': 0.2, 'b': 0.4, 'w':1.0}, + 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'error': {'r': 0.4, '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} + } + } + +gcode: diff --git a/config/hardware/lights/fcob_white.cfg b/config/hardware/lights/fcob_white.cfg index 4ff581fc1..8c18f06dc 100644 --- a/config/hardware/lights/fcob_white.cfg +++ b/config/hardware/lights/fcob_white.cfg @@ -1,4 +1,5 @@ # White lights using 24V (example: white fcob) + [gcode_macro _USER_VARIABLES] variable_light_enabled: True variable_light_pin_name: "caselight" diff --git a/config/hardware/lights/neopixel_caselight.cfg b/config/hardware/lights/neopixel_caselight.cfg index 1f9884e5b..5894e325d 100644 --- a/config/hardware/lights/neopixel_caselight.cfg +++ b/config/hardware/lights/neopixel_caselight.cfg @@ -1,4 +1,5 @@ # Neopixel leds used as general printer lights + [gcode_macro _USER_VARIABLES] variable_status_leds_caselight_enabled = True variable_status_leds_caselight_led_name: "caselight" @@ -6,6 +7,7 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] +[include config_colors.cfg] [neopixel caselight] diff --git a/config/hardware/lights/neopixel_caselight_effects.cfg b/config/hardware/lights/neopixel_caselight_effects.cfg new file mode 100644 index 000000000..6d593d236 --- /dev/null +++ b/config/hardware/lights/neopixel_caselight_effects.cfg @@ -0,0 +1,185 @@ +# Neopixel leds used as general printer lights +# using LED_effects + +[gcode_macro _USER_VARIABLES] +variable_status_leds_caselight_enabled = True +variable_status_leds_caselight_led_name: "caselight_effects" +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] +[include config_colors.cfg] + + +[neopixel caselight] +pin: LIGHT_NEOPIXEL +# The pin connected to the neopixel. This parameter must be +# provided. +chain_count: 31 +# 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: GRB +# Set the pixel order required by the LED hardware (using a string +# containing the letters R, G, B, W with W optional). The default is +# GRB. +initial_RED: 0.0 +initial_GREEN: 0.0 +initial_BLUE: 0.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.# + + +######################################################### +# Define led effects for the different printer states +######################################################### +## Ready State +[led_effect cl_standby] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 20.00 1 add (1.00,1.00,1.00) + static 0 0 top (0.07,0.37,0.57) + +## Busy State +[led_effect cl_busy] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 add (1.00,1.00,1.00) + static 0 0 top (1.00,0,0) + +## Heating State +[led_effect cl_heating] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 top (1.00,0.00,0.00) + +## Leveling State +[led_effect cl_leveling] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 add (1.00,1.00,1.00) + static 0 0 top (0.5,0.1,0.4) + +## Homing State +[led_effect cl_homing] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 add (1.00,1.00,1.00) + static 0 0 top (0.0, 0.6, 0.2) + +## Cleaning State +[led_effect cl_cleaning] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 add (1.00,1.00,1.00) + static 0 0 top (0.0, 0.02, 0.5) + +## Meshing State +[led_effect cl_meshing] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 add (1.00,1.00,1.00) + static 0 0 top (0.2, 1.0, 0.0) + +## Calibrating Z State +[led_effect cl_calibrating_z] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 10 1 add (1.00,1.00,1.00) + static 0 0 top (0.0, 0.0, 0.35) + +## Printing State +[led_effect cl_printing] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + breathing 120 1 add (1.00,1.00,1.00) + static 0 0 top (0.0, 0.0, 0.3), (0.0, 0.3, 0.0), (0.3, 0.0, 0.0) + +## Printing Done State +[led_effect cl_done_printing] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + strobe 0.20 0.60 subtract (1.00,0.00,1.00) + static 1.00 1.00 top (1.00,1.00,1.00) + +## Error State +[led_effect cl_error] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) + +## On State +[led_effect cl_on] +leds: + neopixel:caselight +autostart: false +frame_rate: 24 +layers: + static 0 0 top (1.0, 1.0, 1.0) + +## Off State +[led_effect cl_off] +leds: + neopixel:caselight (1) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (0.0, 0.0, 0.0) + +## Printer startup effect +[led_effect cl_startup] +leds: + neopixel:caselight +autostart: true +frame_rate: 24 +layers: + gradient 0.3 1 add (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0) + +## Critical error effect +[led_effect critical_error] +leds: + neopixel:caselight +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) +autostart: false +frame_rate: 24 +run_on_error: true diff --git a/config/hardware/lights/status_leds.cfg b/config/hardware/lights/status_leds.cfg index 09cf248f1..7494e7864 100644 --- a/config/hardware/lights/status_leds.cfg +++ b/config/hardware/lights/status_leds.cfg @@ -1,4 +1,5 @@ # Neopixel leds used on the toolhead (stealthburner style) + [gcode_macro _USER_VARIABLES] variable_status_leds_enabled: True variable_status_leds_logo_led_name: "status_leds" @@ -9,6 +10,7 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] +[include config_colors.cfg] [neopixel status_leds] diff --git a/config/hardware/lights/status_leds_effects.cfg b/config/hardware/lights/status_leds_effects.cfg new file mode 100644 index 000000000..8cf00f0e1 --- /dev/null +++ b/config/hardware/lights/status_leds_effects.cfg @@ -0,0 +1,230 @@ +# Neopixel leds used on the toolhead (stealthburner style) +# using LED_effects + +[gcode_macro _USER_VARIABLES] +variable_status_leds_enabled: True +variable_status_leds_logo_led_name: "status_leds_effects" +variable_status_leds_logo_idx: '1' +variable_status_leds_nozzle_led_name: "status_leds_effects" +variable_status_leds_nozzle_idx: '2,3' +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] +[include config_colors.cfg] + + +[neopixel status_leds] +pin: STATUS_NEOPIXEL +# 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: 0.0 +initial_GREEN: 0.0 +initial_BLUE: 0.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.# + +######################################################### +# Define led effects for the different printer states +######################################################### +## Ready State +[led_effect sb_logo_standby] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 20 1 top (0.0, 0.0, 1.0) + +[led_effect sb_nozzle_standby] +leds: + neopixel:status_leds (2,3) +autostart: false +frame_rate: 24 +layers: + breathing 20 1 top (0.0, 0.0, 1.0) + +## Busy State +[led_effect sb_logo_busy] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (1,0,0) + +## Heating State +[led_effect sb_logo_heating] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (1,0,0) + +[led_effect sb_nozzle_heating] +leds: + neopixel:status_leds (2,3) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (1.0, 0.18, 0.0, 0.0) + +## Leveling State +[led_effect sb_logo_leveling] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.5, 0.1, 0.4) + +## Homing State +[led_effect sb_logo_homing] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.0, 0.6, 0.2) + +## Cleaning State +[led_effect sb_logo_cleaning] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.0, 0.02, 0.5) + +## Meshing State +[led_effect sb_logo_meshing] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.2, 1.0, 0.0) + +## Calibrating Z State +[led_effect sb_logo_calibrating_z] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.0, 0.0, 0.35) + +## Printing State +[led_effect sb_logo_printing] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + gradient 0.3 1 add (0.3, 0.0, 0.0),(0.3, 0.3, 0.0),(0.3, 0.1, 0.0) + +## Printing Done State +[led_effect sb_logo_done_printing] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + strobe 0.2 0.6 add (1.00,1.00,1.00) + breathing 10.00 0.00 subtract (0.0,0.40,0.0) + static 0.00 1.00 top (0.0,1.0,0.0) + +[led_effect sb_nozzle_done_printing] +leds: + neopixel:status_leds (2,3) +autostart: false +frame_rate: 24 +layers: + strobe 0.2 0.6 add (1.00,1.00,1.00) + breathing 10.00 0.00 subtract (0.0,0.40,0.0) + static 0.00 1.00 top (0.0,1.0,0.0) + +## Error State +[led_effect sb_logo_error] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) + +[led_effect sb_nozzle_error] +leds: + neopixel:status_leds (2,3) +autostart: false +frame_rate: 24 +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) + +## On State +[led_effect sb_logo_on] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (1.0, 1.0, 1.0) + +[led_effect sb_nozzle_on] +leds: + neopixel:status_leds (2,3) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (1.0, 1.0, 1.0) + +## Off State +[led_effect sb_logo_off] +leds: + neopixel:status_leds (1) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (0.0, 0.0, 0.0) + +[led_effect sb_nozzle_off] +leds: + neopixel:status_leds (2,3) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (0.0, 0.0, 0.0) + +## Printer startup effect +[led_effect startup] +leds: + neopixel:status_leds +autostart: true +frame_rate: 24 +layers: + gradient 0.3 1 add (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0) + + ## Critical error effect +[led_effect critical_error] +leds: + neopixel:status_leds +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) +autostart: false +frame_rate: 24 +run_on_error: true diff --git a/config/hardware/lights/status_leds_rainbow_barf.cfg b/config/hardware/lights/status_leds_rainbow_barf.cfg new file mode 100644 index 000000000..2463794ce --- /dev/null +++ b/config/hardware/lights/status_leds_rainbow_barf.cfg @@ -0,0 +1,33 @@ +# Neopixel leds used on the toolhead (stealthburner style) +# in a rainbow barf pattern PCB + +[gcode_macro _USER_VARIABLES] +variable_status_leds_enabled: True +variable_status_leds_logo_led_name: "status_leds" +variable_status_leds_logo_idx: '1,2,3,4,5,6,7,8' +variable_status_leds_nozzle_led_name: "status_leds" +variable_status_leds_nozzle_idx: '9,10' +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] +[include config_colors.cfg] + + +[neopixel status_leds] +pin: STATUS_NEOPIXEL +# The pin connected to the neopixel. This parameter must be provided. +chain_count: 10 +# 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: GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRBW, GRBW +# Set the pixel order required by the LED hardware. Options are GRB, +# RGB, GRBW, or RGBW. The default is GRB. +initial_RED: 0.0 +initial_GREEN: 0.0 +initial_BLUE: 0.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.# diff --git a/config/hardware/lights/status_leds_rainbow_barf_effects.cfg b/config/hardware/lights/status_leds_rainbow_barf_effects.cfg new file mode 100644 index 000000000..9221b5080 --- /dev/null +++ b/config/hardware/lights/status_leds_rainbow_barf_effects.cfg @@ -0,0 +1,230 @@ +# Neopixel leds used on the toolhead (stealthburner style) +# in a rainbow barf pattern PCB using LED_effects + +[gcode_macro _USER_VARIABLES] +variable_status_leds_enabled: True +variable_status_leds_logo_led_name: "status_leds_effects" +variable_status_leds_logo_idx: '1,2,3,4,5,6,7,8' +variable_status_leds_nozzle_led_name: "status_leds_effects" +variable_status_leds_nozzle_idx: '9,10' +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] +[include config_colors.cfg] + + +[neopixel status_leds] +pin: STATUS_NEOPIXEL +# The pin connected to the neopixel. This parameter must be provided. +chain_count: 10 +# 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: GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRBW, GRBW +# Set the pixel order required by the LED hardware. Options are GRB, +# RGB, GRBW, or RGBW. The default is GRB. +initial_RED: 0.0 +initial_GREEN: 0.0 +initial_BLUE: 0.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.# + +######################################################### +# Define led effects for the different printer states +######################################################### +## Ready State +[led_effect sb_logo_standby] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 20 1 top (0.0, 0.0, 1.0) + +[led_effect sb_nozzle_standby] +leds: + neopixel:status_leds (9-10) +autostart: false +frame_rate: 24 +layers: + breathing 20 1 top (0.0, 0.0, 1.0) + +## Busy State +[led_effect sb_logo_busy] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (1,0,0) + +## Heating State +[led_effect sb_logo_heating] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (1,0,0) + +[led_effect sb_nozzle_heating] +leds: + neopixel:status_leds (9-10) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (1.0, 0.18, 0.0, 0.0) + +## Leveling State +[led_effect sb_logo_leveling] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.5, 0.1, 0.4) + +## Homing State +[led_effect sb_logo_homing] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.0, 0.6, 0.2) + +## Cleaning State +[led_effect sb_logo_cleaning] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.0, 0.02, 0.5) + +## Meshing State +[led_effect sb_logo_meshing] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.2, 1.0, 0.0) + +## Calibrating Z State +[led_effect sb_logo_calibrating_z] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + breathing 3 1 top (0.0, 0.0, 0.35) + +## Printing State +[led_effect sb_logo_printing] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + gradient 0.3 1 add (0.3, 0.0, 0.0),(0.3, 0.3, 0.0),(0.3, 0.1, 0.0) + +## Printing Done State +[led_effect sb_logo_done_printing] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + strobe 0.2 0.6 add (1.00,1.00,1.00) + breathing 10.00 0.00 subtract (0.0,0.40,0.0) + static 0.00 1.00 top (0.0,1.0,0.0) + +[led_effect sb_nozzle_done_printing] +leds: + neopixel:status_leds (9-10) +autostart: false +frame_rate: 24 +layers: + strobe 0.2 0.6 add (1.00,1.00,1.00) + breathing 10.00 0.00 subtract (0.0,0.40,0.0) + static 0.00 1.00 top (0.0,1.0,0.0) + +## Error State +[led_effect sb_logo_error] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) + +[led_effect sb_nozzle_error] +leds: + neopixel:status_leds (9-10) +autostart: false +frame_rate: 24 +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) + +## On State +[led_effect sb_logo_on] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (1.0, 1.0, 1.0) + +[led_effect sb_nozzle_on] +leds: + neopixel:status_leds (9-10) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (1.0, 1.0, 1.0) + +## Off State +[led_effect sb_logo_off] +leds: + neopixel:status_leds (1-8) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (0.0, 0.0, 0.0) + +[led_effect sb_nozzle_off] +leds: + neopixel:status_leds (9-10) +autostart: false +frame_rate: 24 +layers: + static 0 0 top (0.0, 0.0, 0.0) + +## Printer startup effect +[led_effect startup] +leds: + neopixel:status_leds +autostart: true +frame_rate: 24 +layers: + gradient 0.3 1 add (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0) + +## Critical error effect +[led_effect critical_error] +leds: + neopixel:status_leds +layers: + strobe 1 1.5 add (1.0, 1.0, 1.0) + breathing 2 0 difference (0.95, 0.0, 0.0) + static 1 0 top (1.0, 0.0, 0.0) +autostart: false +frame_rate: 24 +run_on_error: true diff --git a/config/hardware/mmu.cfg b/config/hardware/mmu.cfg new file mode 100644 index 000000000..1df0ad5f7 --- /dev/null +++ b/config/hardware/mmu.cfg @@ -0,0 +1,15 @@ +## MMU config file +## Designed to be used with the "HappyHare" (HH) software backend by moggieuk: https://github.com/moggieuk/Happy-Hare + +[gcode_macro _USER_VARIABLES] +variable_klippain_mmu_enabled: True +gcode: + +[extruder] +max_extrude_only_distance: 200 +max_extrude_cross_section: 50.0 + + +# Also include directly the MMU macros and config from here +[include ../../mmu/base/mmu_*.cfg] +[include ../../macros/hardware_functions/mmu.cfg] diff --git a/config/machine.cfg b/config/machine.cfg index dbe821047..06e87e844 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -1,17 +1,13 @@ [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: - {% set probe_type_enabled = printer["gcode_macro _USER_VARIABLES"].probe_type_enabled %} - {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} STATUS_LEDS COLOR="ERROR" {% endif %} - - {% if probe_type_enabled == "dockable" %} + {% if printer["gcode_macro _USER_VARIABLES"].probe_type_enabled == "dockable" %} _PROBE_ON_ERROR_ACTION {% endif %} - -[exclude_object] + CANCEL_PRINT [idle_timeout] timeout: 1800 @@ -19,11 +15,16 @@ gcode: RESPOND MSG="Idle timeout reached" TURN_OFF_HEATERS M84 + {% if printer["gcode_macro _USER_VARIABLES"].light_enabled %} + LIGHT_OFF + {% endif %} + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} + STATUS_LEDS COLOR="OFF" + {% endif %} [pause_resume] - [display_status] - +[exclude_object] [respond] [force_move] diff --git a/config/mcu_definitions/ercf/BTT_MMB_CAN_v1.0.cfg b/config/mcu_definitions/ercf/BTT_MMB_CAN_v1.0.cfg deleted file mode 100644 index 0051ce533..000000000 --- a/config/mcu_definitions/ercf/BTT_MMB_CAN_v1.0.cfg +++ /dev/null @@ -1,29 +0,0 @@ -[board_pins ercf_manufacturer] -mcu: ercf -aliases: - MCU_MOTOR1_STEP=PB15 , MCU_MOTOR1_DIR=PB14 , MCU_MOTOR1_EN=PA8 , MCU_GEAR_MOTOR1_CS=PA10 , - MCU_MOTOR2_STEP=PD2 , MCU_MOTOR2_DIR=PB13 , MCU_MOTOR2_EN=PD1 , MCU_GEAR_MOTOR2_CS=PC7 , - MCU_MOTOR3_STEP=PD0 , MCU_MOTOR3_DIR=PD3 , MCU_MOTOR3_EN=PA15 , MCU_GEAR_MOTOR3_CS=PC6 , - MCU_MOTOR4_STEP=PB6 , MCU_MOTOR4_DIR=PB7 , MCU_MOTOR4_EN=PB5 , MCU_GEAR_MOTOR4_CS=PA9 , - MCU_SCK=PA5 , MCU_MISO=PA6 , MCU_SPI0_MOSI=PA7 , - MCU_MOTOR3_DIAG=PB9 - - # MMB STP definition - MCU_STP1=PA3 , # a.u.a. MOTOR1_DIAG - MCU_STP2=PA4 , # a.u.a. MOTOR2_DIAG - MCU_STP3=PB8 , # a.u.a. MOTOR4_DIAG - MCU_STP4=PB7 , - MCU_STP5=PC15 , - MCU_STP6=PC13 , - MCU_STP7=PC14 , - MCU_STP8=PB12 , - MCU_STP9=PB11 , - MCU_STP10=PB10 , - MCU_STP11=PB2 , - - MCU_MOT=PA0 , - MCU_SENSOR=PA1 , - MCU_RGB=PA2 , - - MCU_I2C_SDA=PB4 , - MCU_I2C_SCL=PB3 , diff --git a/config/mcu_definitions/ercf/Tircown_ERCF_easy_brd.cfg b/config/mcu_definitions/ercf/Tircown_ERCF_easy_brd.cfg deleted file mode 100644 index 0b7d46229..000000000 --- a/config/mcu_definitions/ercf/Tircown_ERCF_easy_brd.cfg +++ /dev/null @@ -1,12 +0,0 @@ -[board_pins ercf_manufacturer] -mcu: ercf -aliases: - MCU_GEAR_STEP=PA4 , MCU_GEAR_DIR=PA10 , MCU_GEAR_ENABLE=PA2 , - MCU_SELECTOR_STEP=PA9 , MCU_SELECTOR_DIR=PB8 , MCU_SELECTOR_ENABLE=PA11 , MCU_SELECTOR_DIAG=PA7, - MCU_TMCUART=PA8 , - - MCU_GEAR_STOP=PB9 , MCU_SELECTOR_STOP=PB9 , - - MCU_SERVO=PA5, - - MCU_ENCODER=PA6, diff --git a/config/mcu_definitions/main/BTT_SKR_Pro_V1.2.cfg b/config/mcu_definitions/main/BTT_SKR_Pro_V1.2.cfg new file mode 100644 index 000000000..b1576cec2 --- /dev/null +++ b/config/mcu_definitions/main/BTT_SKR_Pro_V1.2.cfg @@ -0,0 +1,52 @@ +[board_pins mcu_manufacturer] +aliases: + MCU_XM_STEP=PE9 , MCU_XM_DIR=PF1 , MCU_XM_ENABLE=PF2 , MCU_XM_TMCUART=PC13 , MCU_XM_TMCTX=PE4 , + MCU_YM_STEP=PE11 , MCU_YM_DIR=PE8 , MCU_YM_ENABLE=PD7 , MCU_YM_TMCUART=PE3 , MCU_YM_TMCTX=PE2 , + MCU_ZM_STEP=PE13 , MCU_ZM_DIR=PC2 , MCU_ZM_ENABLE=PC0 , MCU_ZM_TMCUART=PE1 , MCU_ZM_TMCTX=PE0 , + MCU_E0M_STEP=PE14 , MCU_E0M_DIR=PA0 , MCU_E0M_ENABLE=PC3 , MCU_E0M_TMCUART=PD4 , MCU_E0M_TMCTX=PD2 , + MCU_EM1_STEP=PD15 , MCU_EM1_DIR=PE7, MCU_EM1_ENABLE=PA3 , MCU_EM1_TMCUART=PD1 , MCU_EM1_TMCTX=PD0 , + MCU_EM2_STEP=PD13 , MCU_EM2_DIR=PG9, MCU_EM2_ENABLE=PF0 , MCU_EM2_TMCUART=PD6 , MCU_EM2_TMCTX=PD5 , + + + MCU_XSTOP=PB10 , MCU_YSTOP=PE12 , MCU_ZSTOP=PG8 , + MCU_E0STOP=PE15 , MCU_E1STOP=PE10 , MCU_E2STOP=PG5 , + + MCU_HEAT0=PB1 , MCU_HEAT1=PD14 , MCU_HEAT2=PB0 , + MCU_BED=PD12 , + + MCU_T0=PF3 , MCU_T1=PF4 , MCU_T2=PF5 , MCU_T3=PF6 , + + MCU_FAN0=PC8 , MCU_FAN1=PE5 , MCU_FAN2=PE6 , + + # Z-Probe Header + MCU_SERVOS=PA1 , MCU_PROBE=PA2 , + + # EXP1 header + EXP1_1=PG4 , EXP1_2=PA8 , + EXP1_3=PD11 , EXP1_4=PD10 , + EXP1_5=PG2 , EXP1_6=PG3 , # Key in the socket on other side + EXP1_7=PG6 , EXP1_8=PG7 , + EXP1_9= , EXP1_10=<5V> , + + # EXP2 header + EXP2_1=PB14 , EXP2_2=PB13 , + EXP2_3=PG10 , EXP2_4=PB12 , + EXP2_5=PF11 , EXP2_6=PB15 , # Key in the socket on other side + EXP2_7=PF12 , EXP2_8= , + EXP2_9= , EXP2_10=PF13 , + + # SPI header + MCU_SPI_MOSI=PC12 , MCU_SPI_MISO=PC11 , MCU_SPI_SCK=PC10 , MCU_SPI_CS=PA15 , + + # UART header + MCU_UART_RX3=PD9 , MCU_UART_TX3=PD8 , + + # I2C header + MCU_I2C_SDA=PB7 , MCU_I2C_SCL=PB6 , + + # I/O header + MCU_IO0=PD0 , MCU_IO1=PD2 , MCU_IO2=PD3 , MCU_IO3=PD4 , MCU_IO4=PD5 , + + # WIFI header (#_# = ROW_COL) + MCU_WIFI_1_2=PG0 , MCU_WIFI_1_3=PG1 , MCU_WIFI_1_4=PC7, + MCU_WIFI_2_1=PC6 , MCU_WIFI_2_2=PF14 , MCU_WIFI_2_3=PF15 \ No newline at end of file diff --git a/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg b/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg new file mode 100644 index 000000000..8cab0186d --- /dev/null +++ b/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg @@ -0,0 +1,23 @@ +[board_pins mmu_manufacturer] +mcu: mmu +aliases: + MCU_M1_STEP=PB15 , MCU_M1_DIR=PB14 , MCU_M1_EN=PA8 , MCU_M1_UART=PA10 , # MCU_M1_DIAG=PA3 , + MCU_M2_STEP=PD2 , MCU_M2_DIR=PB13 , MCU_M2_EN=PD1 , MCU_M2_UART=PC7 , # MCU_M2_DIAG=PA4 , + MCU_M3_STEP=PD0 , MCU_M3_DIR=PD3 , MCU_M3_EN=PA15 , MCU_M3_UART=PC6 , MCU_M3_DIAG=PB9 , + MCU_M4_STEP=PB6 , MCU_M4_DIR=PB7 , MCU_M4_EN=PB5 , MCU_M4_UART=PA9 , # MCU_M4_DIAG=PB8 , + + MCU_MISO=PA6 , MCU_SCK=PA5 , MCU_MOSI=PA7 , + + MCU_STP1=PA3 , MCU_STP2=PA4 , MCU_STP3=PB8 , # Shared with Steppers Diag pins 1-2-4 so it's better to use STP 4-11 for others servos/sensors + MCU_STP4=PB7 , MCU_STP5=PC15 , MCU_STP6=PC13 , MCU_STP7=PC14 , MCU_STP8=PB12 , MCU_STP9=PB11 , MCU_STP10=PB10 , MCU_STP11=PB2 , + + + MCU_MOT=PA0 , + MCU_SENSOR=PA1 , + MCU_RGB=PA2 , + + ## I2C header + MCU_I2C_SDA=PB4 , MCU_I2C_SCL=PB3 , + + ## SWD header + MCU_SWD_PA14=PA14 , MCU_SWD_PA13=PA13 , diff --git a/config/mcu_definitions/mmu/BTT_SKR_Pico_v1.0.cfg b/config/mcu_definitions/mmu/BTT_SKR_Pico_v1.0.cfg new file mode 100644 index 000000000..113022ac9 --- /dev/null +++ b/config/mcu_definitions/mmu/BTT_SKR_Pico_v1.0.cfg @@ -0,0 +1,25 @@ +[board_pins mmu_manufacturer] +mcu: mmu +aliases: + MCU_X_STEP=gpio11 , MCU_X_DIR=gpio10 , MCU_X_EN=gpio12 , + MCU_Y_STEP=gpio6 , MCU_Y_DIR=gpio5 , MCU_Y_EN=gpio7 , + MCU_Z_STEP=gpio19 , MCU_Z_DIR=gpio28 , MCU_Z_EN=gpio2 , + MCU_E0_STEP=gpio14 , MCU_E0_DIR=gpio13 , MCU_E0_EN=gpio15 , + MCU_TMCUART=gpio9 , MCU_TMCTX=gpio8 , + + MCU_X-STOP=gpio4 , MCU_Y-STOP=gpio3 , MCU_Z-STOP=gpio25 , + MCU_E0-STOP=gpio16 , + + MCU_HE=gpio23 , + MCU_HB=gpio21 , + + MCU_TH0=gpio27 , + MCU_THB=gpio26 , + + MCU_FAN1=gpio17 , MCU_FAN2=gpio18 , MCU_FAN3=gpio20 , + + MCU_SERVOS=gpio29 , + + MCU_PROBE=gpio22 , + + MCU_RGB=gpio24 , diff --git a/config/mcu_definitions/ercf/Fysetc_ERCF_ERB.cfg b/config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg similarity index 90% rename from config/mcu_definitions/ercf/Fysetc_ERCF_ERB.cfg rename to config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg index 410032d1d..c19425156 100644 --- a/config/mcu_definitions/ercf/Fysetc_ERCF_ERB.cfg +++ b/config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg @@ -1,10 +1,9 @@ -[board_pins ercf_manufacturer] -mcu: ercf +[board_pins mmu_manufacturer] +mcu: mmu aliases: MCU_GEAR_MOTOR_STEP=gpio10 , MCU_GEAR_MOTOR_DIR=gpio9 , MCU_GEAR_MOTOR_EN=gpio8 , MCU_GEAR_MOTOR_UART=gpio20 , - MCU_SELECTOR_MOTOR_STEP=gpio16 , MCU_SELECTOR_MOTOR_DIR=gpio15 , MCU_SELECTOR_MOTOR_EN=gpio14 , MCU_SELECTOR_MOTOR_UART=gpio17 , - MCU_GEAR_MOTOR_DIAG=gpio13 , + MCU_SELECTOR_MOTOR_STEP=gpio16 , MCU_SELECTOR_MOTOR_DIR=gpio15 , MCU_SELECTOR_MOTOR_EN=gpio14 , MCU_SELECTOR_MOTOR_UART=gpio17 , MCU_SELECTOR_MOTOR_DIAG=gpio19 , MCU_HALL_SENSOR=gpio25 , @@ -19,4 +18,4 @@ aliases: MCU_I2C1_SDA=gpio6 , MCU_I2C1_SCL=gpio7 , MCU_ADC0=gpio26 , MCU_ADC1=gpio27 , MCU_ADC2=gpio28 , MCU_ADC3=gpio29 , - GND= , 5V=<5V> , + GND= , 5V=<5V> , diff --git a/config/mcu_definitions/ercf/Mellow_fly_ERCF.cfg b/config/mcu_definitions/mmu/Mellow_fly_ERCF.cfg similarity index 58% rename from config/mcu_definitions/ercf/Mellow_fly_ERCF.cfg rename to config/mcu_definitions/mmu/Mellow_fly_ERCF.cfg index d5494105d..858160cb0 100644 --- a/config/mcu_definitions/ercf/Mellow_fly_ERCF.cfg +++ b/config/mcu_definitions/mmu/Mellow_fly_ERCF.cfg @@ -1,5 +1,5 @@ -[board_pins ercf_manufacturer] -mcu: ercf +[board_pins mmu_manufacturer] +mcu: mmu aliases: MCU_GEAR_STEP=gpio7 , MCU_GEAR_DIR=gpio8 , MCU_GEAR_EN=gpio6 , MCU_GEAR_UART=gpio9 , MCU_GEAR_DIAG=gpio23 , @@ -13,10 +13,10 @@ aliases: MCU_MISO=gpio16 , MCU_MOSI=gpio18 , MCU_SCK=gpio19 , - GND= , GND= , - 3.3V=<3.3V> , 3.3V=<3.3V> , - MCU_P26=gpio26 , MCU_P10=gpio10 , - MCU_P27=gpio27 , MCU_P11=gpio11 , - MCU_P28=gpio28 , MCU_P12=gpio12 , - MCU_P29=gpio29 , MCU_P24=gpio24 , - MCU_P25=gpio25 , MCU_P13=gpio13 , + GND= , GND= , + 3.3V=<3.3V> , 3.3V=<3.3V> , + MCU_IO26=gpio26 , MCU_IO10=gpio10 , + MCU_IO27=gpio27 , MCU_IO11=gpio11 , + MCU_IO28=gpio28 , MCU_IO12=gpio12 , + MCU_IO29=gpio29 , MCU_IO24=gpio24 , + MCU_IO25=gpio25 , MCU_IO13=gpio13 , diff --git a/config/mcu_definitions/mmu/Tircown_ERCF_easy_brd.cfg b/config/mcu_definitions/mmu/Tircown_ERCF_easy_brd.cfg new file mode 100644 index 000000000..08cbb16cd --- /dev/null +++ b/config/mcu_definitions/mmu/Tircown_ERCF_easy_brd.cfg @@ -0,0 +1,12 @@ +[board_pins mmu_manufacturer] +mcu: mmu +aliases: + MCU_GEAR_STEP=PA4 , MCU_GEAR_DIR=PA10 , MCU_GEAR_ENABLE=PA2 , + MCU_SELECTOR_STEP=PA9 , MCU_SELECTOR_DIR=PB8 , MCU_SELECTOR_ENABLE=PA11 , MCU_SELECTOR_DIAG=PA7, + MCU_TMCUART=PA8 , + + MCU_SELECTOR_STOP=PB9 , + + MCU_SERVO=PA5, + + MCU_ENCODER=PA6, diff --git a/config/software/spoolman.cfg b/config/software/spoolman.cfg new file mode 100644 index 000000000..387550718 --- /dev/null +++ b/config/software/spoolman.cfg @@ -0,0 +1,6 @@ +[gcode_macro _USER_VARIABLES] +variable_spoolman_enabled: True +gcode: + +# Automatically include the spoolman macros +[include ../../macros/helpers/spoolman.cfg] diff --git a/docs/configuration.md b/docs/configuration.md index 181fce681..82886ba82 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2,10 +2,9 @@ Klippain requires a few simple steps to configure and customize it for your printer: please follow the following documentation step by step in order to get your printer running. - > **Warning** + > **Warning**: > - > General rule to keep the auto-update feature working: **never modify Klippain files directly**, but instead add overrides as per the following documentation. To proceed, you can modify all the pre-installed templates in your config root folder (`printer.cfg`, `mcu.cfg`, `variables.cfg` and `overrides.cfg`) as they will be preserved on update. - + > General rule to keep the auto-update feature working: **never modify Klippain files directly**, but instead add overrides as per the following documentation. To proceed, you can modify all the pre-installed templates in your config root folder (`printer.cfg`, `mcu.cfg`, `variables.cfg` and `overrides.cfg` and, if applicable, the MMU configs files in the `mmu` directory created when you install Happy-Hare) as they will be preserved on update. ## 1. MCU Settings @@ -13,42 +12,51 @@ Before configuring Klippain, you will need to configure your MCUs and wiring. If Don't forget to fill in the serial_port or can_uuid of your MCUs. Refer to the [official Klipper documentation](https://www.klipper3d.org/FAQ.html#wheres-my-serial-port) for help. - ## 2. Printer Settings, Overrides, and Variables Don't overlook, this section is the most important. Now that your MCU is configured, you will need to follow some additionnal steps to configure Klippain: + 1. In `printer.cfg`, uncomment lines corresponding to your printer hardware or software components to enable them (e.g., extruder type, XY motors, Z motors, QGL vs Z_TILT, etc.). 1. Then, edit `overrides.cfg` according to the [overrides documentation and examples](./overrides.md). Use overrides to tweak machine dimensions, invert motor directions, change axis limits, currents, sensors type, or anything you feel the need to change. 1. Once Klipper boots successfully, adjust the `variables.cfg` file to match your machine's configuration. This file provides additional customization for macro behavior (coordinates, enabling/disabling software features, etc.). > **Note**: > - > If you plan to use an ERCF, Klippain is only compatible with the [Happy Hare](https://github.com/moggieuk/ERCF-Software-V3) software backend. - > Enable the ERCF lines in Klippain's `printer.cfg` and then install Happy Hare directly by following its official documention. **When the Happy Hare installer ask if you want to include all the ERCF files into your printer.cfg: answer no** as everything is already included in Klippain! - + > If you want to use an MMU/ERCF with Klippain, you need to install the [HappyHare](https://github.com/moggieuk/Happy-Hare) backend. Also, have a look at the Klippain [MMU documentation](./docs/mmu.md) for more specific details about its configuration. ## 3. Initial startup of the machine Before your first print, **carefully check all features to prevent issues on your machine!** Begin with the [config checks section from the official Klipper documentation](https://www.klipper3d.org/Config_checks.html). -Next, ensure the mechanical probe (if used) can be attached/detached, verify that QGL/Z_TILT works, and confirm correct coordinates for all components (purge bucket, physical Z endstop, etc.). Check your first layer calibration (and the `switch_offset` parameter of the automatic Z calibration plugin, if used), etc. +Next, ensure the mechanical probe (if used) can be attached/detached, verify that QGL/Z_TILT works, and confirm correct coordinates for all components (purge bucket, physical Z endstop, etc.). Check your first layer calibration (and the `switch_offset` parameter of the automatic Z calibration plugin, if used), etc... -Then, add this custom print start G-code to your slicer (example for SuperSlicer): -``` -START_PRINT EXTRUDER_TEMP={first_layer_temperature[initial_extruder] + extruder_temperature_offset[initial_extruder]} BED_TEMP=[first_layer_bed_temperature] MATERIAL=[filament_type] SIZE={first_layer_print_min[0]}_{first_layer_print_min[1]}_{first_layer_print_max[0]}_{first_layer_print_max[1]} INITIAL_TOOL={initial_extruder} -``` +## 4. Slicer configuration + +Klippain will work out of the box with most slicers on the market and your profiles should be almost ready to go. You will just need to set some custom start print and end print gcodes to give Klippain the correct info. -There is also a couple of other optionnal parameters that are supported in Klippain (they need to be added on the same one line following the other parameters): - - `CHAMBER=[chamber_temperature]` to be able to specify a target heatsoak temperature for the START_PRINT sequence - - `TOTAL_LAYER=[total_layer_count]` to be able to set the PRINT_STATS_INFOS in Klipper. If using this, you will need to add on your slicer custom layer change gcode the appropriate `SET_PRINT_STATS_INFO CURRENT_LAYER={layer_num}` +### Custom print start Gcode -Finally, add custom print end G-code to your slicer: +| Slicer | Custom start print gcode | +|:-------|:-------------------------| +|[SuperSlicer](https://github.com/supermerill/SuperSlicer)|`START_PRINT EXTRUDER_TEMP={first_layer_temperature[initial_extruder] + extruder_temperature_offset[initial_extruder]} BED_TEMP=[first_layer_bed_temperature] MATERIAL=[filament_type] SIZE={first_layer_print_min[0]}_{first_layer_print_min[1]}_{first_layer_print_max[0]}_{first_layer_print_max[1]} INITIAL_TOOL={initial_extruder}`| +|[OrcaSlicer](https://github.com/SoftFever/OrcaSlicer)|`START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] MATERIAL=[filament_type] SIZE={first_layer_print_min[0]}_{first_layer_print_min[1]}_{first_layer_print_max[0]}_{first_layer_print_max[1]} INITIAL_TOOL=[initial_tool]`| +|[PrusaSlicer](https://github.com/prusa3d/PrusaSlicer)|`START_PRINT EXTRUDER_TEMP={first_layer_temperature[initial_extruder]} BED_TEMP=[first_layer_bed_temperature] MATERIAL=[filament_type] SIZE={first_layer_print_min[0]}_{first_layer_print_min[1]}_{first_layer_print_max[0]}_{first_layer_print_max[1]} INITIAL_TOOL={initial_extruder}`| + +In addition, there are a few other optional parameters that are supported in Klippain (they must be added on the same line after the first parameters): + - `CHAMBER=[chamber_temperature]` *(for SuperSlicer and OrcaSlicer)* or `CHAMBER=[idle_temperature]` *(for PrusaSlicer)* to set a target heatsoak temperature during the START_PRINT sequence. + - `TOTAL_LAYER=[total_layer_count]` to be able to set the PRINT_STATS_INFOS in Klipper. If you use this, you will also need to add the corresponding `SET_PRINT_STATS_INFO CURRENT_LAYER={layer_num}` to your slicer custom layer change gcode. + - `TOOLS_USED=!referenced_tools!` *(only for MMU users)* is highly recommended to check only the used tools with the HappyHare [Moonraker gcode preprocessor](https://github.com/moggieuk/Happy-Hare/blob/main/doc/gcode_preprocessing.md). + - `CHECK_GATES=0` or `1` *(only for MMU users)* that will override the corresponding variable defined in Klippain `variables.cfg` for this specific print. + - `SYNC_MMU_EXTRUDER=1` *(only for MMU users)* if you want to stay with the default `sync_to_extruder: 0` value of HappyHare (defined in `mmu/mmu_parameters.cfg`), but still want to use the sync for a specific print. + + +### Custom print start Gcode + +All slicers will be happy with a simple: ``` END_PRINT ``` - > **Note** for ERCF users: - > - > By default, Klippain unloads the filament at the end of the print, but you can change the default behavior by modifying the variable `variable_ercf_unload_on_end_print` in your `variables.cfg` file. - > You can also specify the wanted behavior directly in your slicer end print custom gcode by using `END_PRINT ERCF_UNLOAD_AT_END=0`. - +In addition, there are a few other optional parameters that are supported in Klippain (they must be added on the same line after the first parameters): + - `FILTER_TIME=600` that will override the corresponding variable defined in Klippain `variables.cfg` for this specific print. Time is expressed in seconds. + - `MMU_UNLOAD_AT_END=0` or `1` *(only for MMU users)* that will override the corresponding variable defined in Klippain `variables.cfg`. diff --git a/docs/features/adaptive_bed_mesh.md b/docs/features/adaptive_bed_mesh.md index 699defa7e..5ceae934c 100644 --- a/docs/features/adaptive_bed_mesh.md +++ b/docs/features/adaptive_bed_mesh.md @@ -50,7 +50,7 @@ If you want to install it to your own custom config, here is the way to go: PRINT_START [all your own things...] SIZE=%MINX%_%MINY%_%MAXX%_%MAXY% ``` -> Please note that using the `[exclude_object]` tags (method 1) is a little bit less precise than using the original "SIZE" parameter (method 2) as the `[exclude_object]` tags are using the full parts sizes (not only the first layer). So if you do a part with large overhangs, it will do a large mesh using the tags but will only mesh the base of the part with the SIZE parameter. Also, if you add a skirt around the parts or use a purge tower (like ERCF users), there is no tags associated to this and the mesh can be a little bit smaller and lead to bad adhesion of these objects. So my advice is: use the [exclude_object] tags method for a new installation as it's much more easier to install. But if you are updating from an older version of the macro or use an ERCF, use the SIZE parameter! +> Please note that using the `[exclude_object]` tags (method 1) is a little bit less precise than using the original "SIZE" parameter (method 2) as the `[exclude_object]` tags are using the full parts sizes (not only the first layer). So if you do a part with large overhangs, it will do a large mesh using the tags but will only mesh the base of the part with the SIZE parameter. Also, if you add a skirt around the parts or use a purge tower (like MMU/ERCF users), there is no tags associated to this and the mesh can be a little bit smaller and lead to bad adhesion of these objects. So my advice is: use the [exclude_object] tags method for a new installation as it's much more easier to install. But if you are updating from an older version of the macro or use an MMU, use the SIZE parameter! 3. In klipper, if it's not already the case, add and configure a `[bed_mesh]` for your machine. This will be the base on which my macro compute the new adaptive bed mesh. Keep in mind that you can (and should) push the precision a little bit further: do not hesistate to go with a mesh of 9x9 (or even more) as with my adaptive bed mesh, not all the points will be probed for smaller parts. diff --git a/docs/images/mmu/HHv2_error_tmc.png b/docs/images/mmu/HHv2_error_tmc.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ec224cf0f9287e6d5990409edca6965477e7b7 GIT binary patch literal 17086 zcmeIaXH-*L)Gi!UY^dN-2}lz?iUkNoIs^r=A)ull9SlWE0wK}~@u(D~+2~DCK=T+e*wT>Hgs z(`yI!AKwoGfezlde&sF*v=a#e2}tbS4P1Hr{Gb(Z5J26%W&kSgl$-`W>~gzoav20F zix=WK2?C$@`CPX`fk1~Ew*Lf3-k+U8AOrIoS1#WRv}aK_<0S{t%#BTnry%7kac7}1 z*I)D;I0tqAA!~FMTQp-z@r*~P{ zixtEQP)bFAKb^hw{dj-^TvDi1vSF+?O>E%l1+ClihPO`$F*75z`)S&oqWoSxJ-vR_ z1sVGjc{7juznJ%Pip&E1R`t1+4jXDaf&PM$4?WlXb3FM!dmNTUtZ0Na6iVqn;y1lM z#n_T>r=f(m+i*O>DBRFrI?R6Uu;r%~o%7WoUC2j;aG3t*Cc!qjZJ)1|Y-jDxq}`eZ zlG_(!l0vSTwmILmh>BkLj=sC=zbsqv1F+ zY3Q6gd%GdWyk3=*KD@{(qtcV%R!}gbyM1+Ny5iOu&iO{Yfb|Mx4e#KtOwA8f0>F(Y z8MlBAdK-+;+he#*oLQGB)K)-mMb-9~O3mF{qR8Ey~Io|4%}SA;XwtmS(AFr-U_=R3mD@;!|#>jV0{^I`L_{ z<0l(886ONMb$nzfL|QZkA4G;l+o=Pn$*gyF}@%eXgFB#`2T7 z54oDo!}@Oab&p$kza}&r_=VNA$K!-dhP*rAVSbw*88(ry->q=woLX1<`e*LsRkA;o z$NFMb{^lofU1eJ~fJ#2uKgX?grfuA^O<(!`{b|<9Ou~hPs#9OWHAC*ym3o9tDi&LU z+f_pfSgj&%6ultl&d_NQFwHQ{PRZM{IaKoD^%_?`<>w|tRejDlYiS|I9X_vt2_DPm z)^kXLzCR+nPu&koqxhT6<|ElP(J40 znqtM4TUlTV)7%=UH`p&j@}|E(<(i8x`I3(g26sz=w=o1=dk%8s0ckQ}puMd{3;zSVqE|K#enbv7AO;6PXo6tO+YSkbq76 z4jZ+h?Pd1|RJ`O5mu}dX6>2c3%OM>_(Sw^hvCk&GlO62k5fZWSlu~rzvQxtd`XT~< z@Eo$Rl{?Vv$6n{vx=0jdIi=ovp1L#s=z={}X`#qYV{0l2-9QM+eUNt$SyIi7U3dUL z)7X&=PNFUsizHQ~1vQQ!Dep(`hBSr-bX3|Y(?%Bfopu_)FuQ>n+fx;RTYI}h-`?t6 zUX#$)8a9o|PsCauQi#AMoMvA=d@_vp<3!XambT%@`kSC{#8Z`nxk`rJ8&Rf}Q=>zLy@3PCEd+jPY5cw5-zEoc%rfSWt>fHD(=Mn-~+Zm6WL}{4;caI2A@; z{?I5QcMmF*R55!1nGn!K4-Z*H+`5`ZlCfHu<#LC=;q9ku3^aiWnY|QenjhF+Sc3PKj$5!LOhFL6S%;&* zwZ7Io?mw?FzV8np)i23QmV?QPg}ALYZ&Aq#3B|_K;3aW*ru|;*t9*4p5WOxhC-1pC z6`sESfLNnB_#1bb$WutEEZh4K6x%DY@g=sQRyZ}OWb}7@0QA9DGWX|q+sX1LEP7RC ztg)ABAa;IhBM{fm#$>*eJzs9;8Kv{6&TiUlz6Nk_Ph73fysbLj*c3200#2GB;2Gpb zh}P=`vP-lqV$yl-*3duZj66R3K>-6Y!K7c^k8Dx!6Nf*1u+D9I+vNS?hH!EhndAj+ zv{S|Ssn}IbVlJ2oBNy$|#p(GAqKDSQR)0R@FMKda#}4w?&xDhiW?8BM7T(Xj_u6T> zWad}6tK5n@0zZ^>(Bab8sz;d$J7EaC7Q05@BC#WSvCS&GRybt=PeExUwkyz}0V)5l z1^h+7%1yW7@kSh?ySjkBn(lfjCvA1efhSA6a!RAI#pXb-5I0@@nhZM&v(dkFstFvs z>%ywk-Ylo`Eg8K=Dy(iTS%@IPFr7qULOR~=p<~TN;|oS2#EF;79x%fs9(%Uc4MyBq z?d-w87#pG|lOT#01j- zz<5UpYbJ@q??jk8T7>v*P(6W0%E5sGeSV{ zNx;Bhi<)>ok@)r3;8szzjM?b1H07?1-zrnET41)e$=oD9=a6t%h!_A2&$LWPj^iV2c ztWI5Dqp?Ung;*o4Pnk66{PHd7(?kVwMOvL^U8fip@hgHGIVs5YzM!wH^f0P?KsZYo zV_rfAP=mur2jn=eTjHG-5UD`*OlYTq-4Dv(kx=yuVD9 zKx~iX$yLAuUojjJ5)$GYtW>ro^>ejGU{n=#&fA?IUkViMeKxx~uaR|==%Sn#TM^J4 zn!n}_^5dT=Y9DcfmT%cF8q!SFcwF@vGqI!UKd)goD_y{Co>ED5Wcubd%zl(|EA>GX z%E9!n(Qjf|fUj`8cjJ=zWW}(5$HK2|WHMwA%-u7hbh^%?@nry#%+ypJkUa$4s22s$ z-^E3UdWuI=(PJ&FbXC=`e@KU%t;|B&VOrH*;F0&j0HXRAw7$Rge@_94fd0sVH6*gS z{5>B)$Eg5*?dQHdy0O$ufXZz8cuwb1%?cPRg;4#rxu-#tdC&41$IJo7!fjnzDU}yS z`_803=oB_TsT&D6E0E;Bdwyg&b7?iJK@jHXX6P zNPhtjJ2zW~uK9cb&B*qp9Pn!wp`Z7svlUQj>KEc}+>=Qwj;=ppXNt!6OnPlrRi<{Y z@m%(A!pkWJx5y4>fMYS%QY z;k|<2bJw5?ah5(I=h(@^EU;pJ##(4vqk7Kl+0K7do^VmWdP2Eae_puzLmQs&r0+}6 zU|ISLaxSdddo?i<2bUa__41d`b+^G@+xzG(+9^?F&z$balE$`13PTv&vN#-%8V2N0Fn zm;sY%mqB`%Ed59H>#tL5LLeQggl$xK_Fs9H_Y>`cLVIsi;okqnnrSN)lpj5AIrQ?# z%KM>a8;E3(Kz^*l-Am16hvE3gTIBFYwWaSq)b_{(T~?aHxDa!}xR#ZBkej<_IkVlmB1Xi<|*sjDvHGrm2WpB-NHCz>yZ$U$koRV~;u*zGvurLBR<%6Vf}_1m*m z#1X_+z+YF}78O_AB=MTWU+cQd%A+fx(d_dSu~p9pn0e)KQg5uG3;Ll1Pu-o8;pIkl zkQ?6Pp4Fqg$lioauyZB_pS;GoP+U4m{4-mtvpsR~-?R)BOQ4<4kYDt&!kseBCUNgb zY34FX#fu&HXR#ykNSfRRzDf^H@;;{rIn(yV%Ns4lDFe5nlhPOZ!XAik_77;xi0w>< z{_6uOcH9+xxrV{Kxw-#t@WbAh)%otVH_PNrb0=HMbYBY(99d5)A00bT6>|GT0Y$3n zV=&#c3U0d@Ym~ESpt@iHyZvf>y_fXD;CSA#Sw-x*O-g=T+xy#x28v=664322kqd6{ z1CdkSd$@$349~VA8R0U0sqwE3ncnto>P^g#3pR5}vmr~#J~4w34~cUmRDM;*j5doF z7Ho_4J)-iOqev} z-r0lb7hO8oy5C#fGLu1fZxt+17-g|NWnu%4w!3F7E;I1>{dQq+&Agb+ z?YK&RY8Td-Y|yjkMqENRoA(OgpauUeRz&O{x7U~MWnLYkv1ZAH?xfPK2~-__tCRg~ z!Dh8A3BfG=j{6&STT6PWStGJW_-|I=^?@uDZ(V&D-HU}_!n!X?Q#bn)^{s0`O0|Gr zfp4+iHN7aTe)PB8*SQ@OpEvNpP?t^XpFivueEL|$-OZ5UDrJtPg8Z={@NsI>S8j3? zPsJ;(2A7cn*6S2y;m@pV9{Nc;FowH9x{_vjU(Z#g`R|aq+;J|WQXW4FncQk=a>6Sq z7Ip0*dQEDc?Zi~p`Nx@P7JF=D8?Cb8C!`%>+ZLuAnA~srb*#YdER8ycN#AJXV3eQb z%4*_krq1x{`WCy(?HTLmilLu;L|&Y6jx;mYyEyQcAi2&g-cTzyh*T10kN7K*#*>^$ zmAS}@?BwS&lOwiOngf6*3F6SF;J*-x$I1Kj@}|_&oh76lw1z#5PKDGq+`;0rwM~7k ztKqO2?||2B+gf#3m>{d)k1c?VZVxY*7CE)>>bvsAp)C{ep<~ssH+ufPi=k|5z{@~e z{g<|eWffy?%+~#GgKO_zX5L_;V9(2D!|IOFzfzjt!!|RRd$!hA#xKu$b8z08(nk_D zYh5P7-gR-;w<4kXYsfF&ZUb8H!?hI?(3u)_ANS6RZaC;jzu_NVVk5eBxQf@YbaJqGrWqmXx^U5vC3 z8Es*+iF{?2QFaaOW!>rc8>?`;p@=(*rn@V~KYsY(BBMI~0X!wUu2b0Bbf1U!tZqW~ z`F+6tJ5TRt#(xz~;5Uxf6=B53Z6wFx8|N0DTAWSPS}x0EU!2g$FQUS0ESWdz ztwH&mwOH+$v;lBQRb6RGpYr{#+Bp9>WAeRq8$IcfnjSzVo!g;+uWWIH^UHGpO?ezT z*XM8+VB-K@@ULwow|qqQP`x5x@-IZNLKjC*-p#(W0~8!3vd1y02jKV8MD}b0mlKWK zXt4g?PnDD_QQL&)6Y2kZ`hQ9e5?)g1(PdO1n{kk6(pyWr5Uf^*rvl7la4(@&si2)=#7I)djQ%(lzm*fT5g>-i z6f#v7ZK_sG@0F`C1A#IDnr~kOE>J*{vuS|aeEL!(>6^oe!}Q=-5smDky|#F{#>&i) zGvahQsz$l7Ny(hkO!yjeuLiwXedgT;*&F3IdI>F$PzVp=z;X(R>%2EIk=^Qr&j53w z7y;hK*}(P=!TH;3!R($Y4Kn2OUZi;QVfqt$4}JX@*9(cmX1${H3FwzSsiiRkn-C}vOb=LXuKA&$n5jdZ*SH)P#)ukQhhlLd& zJDyv{2vtrtTfQ@Iu>D&U9T$IpVC>vD#m~zE67!Pt*zSt;w0b|JyXJAMclRhwwy*h& z_*Nm;DRsnOOR<{dI;cFawjw8ved+Ag<8qc{f)15fFBj+YUd24~zhh5fAhT@JGNUhZ zLR~j>99U*dZsBxL^*IjHVQ9CO|5)-PiD*rPRhK!OwimI9w5x+iF{6VqX_OtH_3h=L z(IDM|up4Ygr(Zhy&>_^>Db5H#_Oy3jn|N{k3|Yt)hB2Zw_kvltq<@%pD@%1D&clWbN;o_sE(psMghz zIxb}Oc4fyPm4@UPNf4EaK|9SCE-sDhu@B~^rP+KFmEpDw#;}}7?C7Ej`G{kaU7g> zPbkY@AW<|Jt##Mt+i{DKe`eH2CjeE{PTgomyyJUNsGrr+4-PPshQB&+HZ$!B z2Xb4=_HS0QZl>XX6vSDjm7991K2~ zKypVk-+}LmgZ11o4YYn%+jL14HCB7aHL;TZ&fD~j`}n;#NG?inpU{}q@4YuxkrK7E zyS12pSn<$RifgG!Q$;&;Vrt&)A~~=bRXA>^66c5Q4;>Ok>y z0)Jvz<1QIk+P5davq8G~(KkMew;}dq!Q`w&(dx%q7S`!>!T5{TACB+Jb?hdN@Z)kI zE$T#NnU~(xR4uTcMGj=1-d-vGl}PrtJO-9)QR$i7)wJdz@O_n77xS$qnsZOO!1mom zdAHB#_mZf8#85@C!7-MUi*YZK7glamWb11rN`x92y|AO zhP>T*&SENL&Ma8+XlvcY^dpt*%#ZMb$-ytstC>QmbsO}^=M7;{Y2`K*qSz>)Hb!^* z{98FDR|vy8d3dVwXAF01EI@-jMe5Z2u?QP+`cSaxt2n_Zvq&)`cBS1{fn2^6SNtb_rEX zoRu2ZEg=ZsSaf+lZL@YM+&NRdtAe!Lz-r>JhkI5GMg$DRWwGF8o zjEJU=pqzDKKL==1lJsDIK4;@=k-oVV1O#dTP~(*-iBkq611B2~x<@+99j5Qzi%jb- zVBQd84zPb7!r1Qw?EqZbbDZ+YM!15($SeP~CTUs36A|pb+TctPAkF;`usFYn(8PRj zg8X%J+9(oY`mj#^9wHNtxuAH8OLQjFAdg_YRAGW|Q#xZDF1XT=%)h zVTj`U<4m{T=!4*^zLeg{PiPN&vt~huS>NyDd*JV)t6s!-A3(DEp@WJRz5KY~!wHIc z(1__WE0(e3s&h=6I;SiNpa9l?`XKFRqcwPf{xX@~ohRmguu8nm$h38&JuQAx-F-9W z4Syi+r?dWJjwMb1AO6TaXAV}g*lX+j?7e3FEywxuMu8ZWWLAQFDPxQ}xzgSJ|b@2{%*aIg)DZ99c*u<{s zAqH=d!!D2?$0u|@*8RaUk2BI&tQ^0;l5-h>zY6r!6jM9mGQG(e|CHgtD?2urh2a;? zEjUXwe=QLJ#cogMGmYoKj`y1c4T{#HqIX$ca=!d#tIOToD(szY%vnJVh4i|q)0e_?f=)kS9ea+@S|`8N|D&$PdGdNe z#>Za%OuS5ucLvGuYVBE>x61t1z(aYnfj{O-9@(J7QWd;=}$%?2s&JK{0 z{C1k+0Fop0@t@r9$M%P3%}3uVJ5a65-AY$SRP()U?j7l;L&!e@x*?TpUf$f&3q|XLfC;1*SfG|^_=7DGv@?y(>2;rf2TNDMV`i%mlMP9H2+c4 z%6XX5R7suQs1jOYF)(VjtnPpyp9)G7J2Tx5O~BNwRq9PT0h zHW%HUk9$(W$#EhEHo?wQ?&%BruV9rjVUNo<;UPQ`?fA%bO+l&I)wbIVITD$140eA$ z9-!FzEFR64=!a2t@m|=l!GU>IOlTvTDMRCjN?>Y1paaIh`uH4r#PVomqJg-gMSggb z1Fp&7tWZ3m`;Unom9hGJGuZiZ>sjCFru%C)qVuv9qV3(Z)+Te$josq$`^LKo@%gDQ z1FvE{$8B_7B}mxdpYObE7S{%Z3M9kul*G68JT3Pvm34{JB(EcSjcW3!M;tza$yTs4 z&8QNt;Z6=no68rdSFICpCccF=8#dj|K93qW8m0hA8N;t?flBAYc{MhxHVw*pt=tO3 zVBLvTEHqawgQ<$o3||W}#u83%tj;*5R4yJIzdP(L4tql^iH4CBOZ@O4(6Mbccctl! zDIxH}X+e4W#?Ne*u|>hFTtGiAdW&iMBC9_?K2I4}MA)VcL`S)Dpe+x<(R20PU`cVK z;V-OH#w$i?3-=Z0Yu0tn&io_gxn=U0qFnc(gdAwOZX1(j+k72d(CSMjU0two!$?gg z7j+gC%Zacg$oB@RMP^;t?xf;P3)-Ge$Iw|)z_?29rkzgSiy;5B5%t!^j#=+lPz_I# zVO%p`6m~Z#Gtzx}@qNar2yIuD_{e44&G>L~Xu%g54(xFLg{K#b(lMlakf-0)BP1+AL)2{}yx1s^{FezBNfuNG*7N3@f7bg;c7{%%<()_frN*LEO8GN)Y@+R}0@JilRMEYAfyz8k{bL|Z zs({NXMm%BFoPHyMwfa-W=6C^+3VB7uGGZG?`2RdZFb3Z56rrCtZTB9?OtqaQ=Z@uX+GVW6T1Adh4)oI`O(+*L1Kzj# zB<{8r@A2BYFn-SqrtNq1me}$&o3~{#rL!FrPazW zs@8Cog2)v6jo%@lt&aGE0&aaiVtod8(+7^fTrLwLWBtm3Po@FIyGwZI z-8#EKxahfG1a<)F&rS8sFa+X@t7p$|D2KimieK1|{2=TblA*8<*`l3YN*G)HBW3eH zX7s{ci+%IRA>`e?mm37DefA9fhd+w>Q%`4dKgyHGXiy0}u!^`_Lujpu=KtU(h+NDS8LTx4 zPIDThNYUkqS&hM7G9xvULzBzcFRa_+Y0yyx8Yh0+f}cnMbRU5F{}cK-L;Qyua@PsQzrTRmt`Y{JXI_7AfJs!r$oUfA@0r<9?WgI5~X__1X&KAVF0!+Yc1!z5dS!R>+fW9s&ur$-UA-jv1HYX1Hny}S5 zaU*;!_EL^9V^6px*fbf^(V2YgCqvluAS0=>BgHHUzLG2#pMJ6ADBE5us8P3Cu9M=O zsh^~)o-f~!if$wXPp4P=UAlGQ-bU#o`_z#7P=DZ88?~S8JJIMwZmN0PLynvHaV{hd z>Xu29$zv&ZrQ;m)6jCu5rCV&~W;1H-FxxLA4ikj<{qw0u2F?+Y75IZU+Ah7ATw(F4 zvhk+J!)4B?rcm0#w`EJyt`vymkWL^W8?94V8`++vfP-UMqGqZ31hW+_kAm|0slCX0 zFyq=rU2^_p9oIyP}md%&_I zKAJxE;^}f_7WX@Z%BAW%@ziX`O&_Q!1(q4o z9?@KB#P<4`Tl-2{h30RBC&!e;24kvo5Dc>nj-qUVu$x<;oc&ic~ ziCOf84HLu+C-gSjqubPf*y+JCU$R`|(z1pYgJ$PW{3_nA4}Ih(Dh5ypV$arG&L~#o zuq)g<&9B9;lW-&tw$3@h*${E;-Gzqd z&ausHlIym7IR0;}Wn4{@b*gCkdI^M`H=+!MMd(Vg5&L}8_WPLXTIxS)NG68BzUjUl zk;VZl_oDbz{b-lt}70Ash%E zVbvc-dhRYO)FPr|6dE-K+G!d3h_Gv6%_lq#JWyp6SgN;2R&_(|k2e0^ zx-3D9tZZZG%am{G)`}stUSsR8Jl9+X0iNZ&+z+^Ry%yiL7BOlQfIT&;qz|nt8F2k1 z0-k-&VKSjJ-amQMUv?U$oouwzTVU!y?ACEbcJoq2^zer4GZs}=E8kW_I(SntAv||> z>yjG#A2d&xIlCF3iaoW=WV-F4{L1kwTw0CcZbljceY^`bJahoaO#lNG0|u(xSR2Gj z)h3$XDTU(dT*J!zsRSajmrx$~X(|6bBS-%IBNN;fwERwWV?pt?pZ`AN#qBR zoolWaRJQC(MP&5Ftopa=F{1ec*KKa~g8Cm^pQVYYW1N2yJflZuQC~CqMM^WZQT^VA zGaagn{k@-r_n4++)pYHNqT6{q*rNn2ySH={e#9zltIBTVBn~oim&>1ojc?wvjrG@Y z$-aB!Si*5sedzeiRgyMk{n)(0mr#Dkl8pNh&bdx9j|+tlL0jU*pR?o|oyxbpWFtgf zJok1@)x7d_(g$Z_p@F(14AUhFa|i<`oj_-9bv3?{eAiqV#Ctl&<0FtdK`P zF)hZNxa5=a#SY32D18Cv**Rk9ltIYQE|qOh7KOd4t+mjMUi$4s8$hEbT`>^cGzjmu&`~ei|knCnH@RGRtKg=`ti`*;!lEw4NRVfSB``8*N2qW6AvzQ-W*!4 z0Q}X}s0P!qrz1l<)6I1(yOJRe)>ux1i4f;fk)8{PLKaCX#@d<{(VDO~YP=sK)~Ho0 ztRYy~#*opL@-BV!cm$UQj!&VPCRHw6Muh}*&fAd#QhRrQu1}Dn02_uO@(K66XZ|vJ4-kBB9qnK(JeU&LiNi)cG%`pSf_&M zEil72P=c%K1FDh)=K0m#L)oMM*%;_O&?4y8&TTX*2>f$AK9?*K;Ew1_ zuiXmslLmq8Y!4zUucT?1ZsR7`m;(EMGk`kP-dSd!j$Q?b1zVPnT4VoTaK7f95)kO) zakpB4bp(idCN38Fr4KF!0#)0xlCM08{%i?)awn$zPYVzJB(6b^fx^ZAtvT$AWg?{b zyd9vc-{R3bLAl@JHp;xQ%7})}Q4CRA2K3}iu|Mv(%8L`%0Q?r?khZ(g5&vmF)o^2E)V;3YyqX(B}%s9x^xE-V^ks<3!^J$U_rjceubD6qv@97we4> zWT1?c0ozzDh~Ei1D0>L~dZ6;Ur;y{SY@<{D_NE)_iNC>&3et{CFGV8jx@S^8RtlDG z083AQ7`t1RJ-;4YR9`(!)5O%JZ|_d2{Er7;`I+>PcMPEcg9vti<(Y~d4w&Ho>O0MT zX8Zz$V)Xiktp^PI|0G;oeZrlyuWsLDa8Za+E!6CjbObA?KD1YV{vCJc@Jin=t;OkT zR05|%M$3f)N!A~>j4xH}Hpz;8ohi)K zXmtaoy4-9`UD%b1;gBD^;qT!}3&6&ca>I~4>^}ak1Q#z?eEHx%8BxH%qSO=sm~=xI zoSCL!cA9M=eYW#iHY0F}M+ofUjiE#G*|oKd00y|dfKRA?ROdfYH=%3WS6(ihCfE4b zp|>^F?KG4AFDw+{Tngk(edL#IxteL0*y}J?^}P56cB2lNVf8%K)c{Mo?B4^{ra!z1}} zrafW&?exDVCa8(m5V5iGhP!mjma)CVXq^L~!KR8|i{qB*xLGu;JoZy}+KK;;Qx11b@zxZ;Jg#ruI-j3L&4(=g%07|uJ#le z9Gkrj9W!)FhSepuOI{D0P-V1%OVWfj5XoD$UR`NzgYA3fc{NHGp4t|o=_3fe+ES0a zgC6#kd|P!4ma%>heM@8m?-b^%n_*da0YQ>p#lrE3!6Od8=kkq*H^r`(>^c9n85tkc z92Z$&;*CcVDzD*8+%cFnm+a0Yi%c}9%s`Ik{UDDW*GH7?bEPSH! z8Ve$xL(N}9VIj?hwR9KXX^%CPwfBCy!G<-IajU-F6M_|Q}XvXkRGZcY@3B(t$@ z32B!8po+;UVB{>ty`_)LRDG-c{eXb~6sc*2Ih34KOeX#9r`VUG#vaJmi^mSUL|0uM zR(E%t$v3Xv6d@Obzc!Zz$}Sa^Kl_dMb^aL#FXRGv&irgx$_pX*v@SfA-S_h&UwOWa z%#%zzgjAJlm!d>o{=Bzok{S&T{l?=r7~MIyzsD1tSRe>rDdYwn&|Gom7b}F7D8Q2g zz*P1`6nCC%f?B;(z4@UV$8~rtYb3gtNC+Ma_Wvmg<|0O24Q*>W?3%vrMK8!pX%IC& zQtkh$6f9Ks!d{D_#O_57nKtaIHWAb$WeE+oJJ{nMLMxa==1Zkx_Pg+o_Nai6cTA!o zgEAi)$bB$5@Ph=uq^kZN{Sl`#j*722A?n~If3Xi*9@;`cJfnxiOL5xf4k4SQ&fd5! zv}t#-OB&ryaM%}Zsv9qJVRYCU%j93KUyeA04A%d|m<=Z&4?rH-tI}EuYlkubcc@+V z#GRdrqnxF}!m4WWJG;irS|v2vA%g?$ko_gl^ma4D5wZ(AD_%;~K?{J$DX*|TQFPz7 zh_Y3gkfE$T^yRN@)d`{%A#tgLF9Q-o%WR-d&{z?HqknK_ zZdRU;^^O6}D$1!w*45{lUfA>#*l7^6@wcznD6ceBR++GOW#D_LFJFk+kd<`|OVPPe zzgRgT=miU#6&v9z(kE-*wXflEB-Eqrs$cf!* z9V(|xNVeJxG$+!2P7J>v#Gk=}XOJ>wgeCwdR@rO?|_7yJ(Tf zFGtM2{ug4`zjpflSvhmH#-{E7YD7vJ5MEe7v((Ny{|Td3vuOJTr#n>l%m@|*auynl zNt;CeeG{2cV51L-THxPrso#J%26wRiDf;D@PM%9}+pRk|C~khov>!f92eWux?Z=vd zZwC*%hpMuFBUQhfTHVp4jR`f7U#OdCyO*w~%5Z@C^n@mpF6=Y%M55P zYb6y}UV#2W9|`%w_W76s3C6L+CE*fDjra}lw-LP6G#A3#9LuSmQF-%wY<8geG}~o3 z_jF?d_OIehHAs5D!AL|9QPUFRn1p1$o5Viwvs8^%I3tyo(PEP}kyQ{iT3lBTndH@hdf|_Lt!m$~obo(#d&m zNObZkp_C9oWCL%4C&)HkbdltUfE^}n)x5bO>(q;@I6pSyzRsDYfjB+kv;};Z>JYqG z1lxXKKW-z$49DrN^*m!}Y5hPOuq2lZze;bpXl&6thpE3>%8vAsDyjAj+NB>4)4Rde zuOw`qpeCxj!)0wk_#5GsA`A~Ek=|zbhSIwk?Rv5z95Q(m;l6y?vw;8w=bdg_seIT# zND4hfum=2(x2>O(*}yM4yS+uMy6a_?sLGa;8-;ZH5=TU1VS$T{ zKkV>*%rGiL6e?4u z5mZ@=AgyyD=~)2t(-hgxoD14O2`i-H0i0uoV{J9`8?hG-k=YyHBHII~*vmDk_eam& zbyzXaD<=C)4$zL$>EMtkh{-woih?@L<5j1^bU#!TF9Few!{?s+N!lA9epmh`XLDg? zgg~(IfM#VQ5fS>qroD{N>YE}^{Duo9F%i0Bg-;;6sFEPDfH`jKzcxjIQUTLOxOF=ToU-D1f zvW<=DI==JK#v?S9A){iGbxlyW2))#MpQvZ_Pt=p9 zTpYYzseV#+exeQyeSKF<0My_M(8=3uG4~H!{69n+hcd@NYuYj*Z$Mvpc=?e+PWz!xjg0XWgDHq(!WNx z#|Z){g{@*HPI;Vp`_*7%&YO3YivU8$?HkQqwL+_ZUV-rT2JpHA#d+AthuGK?Q;DRhxbG`Sv;IJLi1g@8kEY@b!J4 zcRg#ZXRZJGuT|b(LjpGZ!R`+>HZ~hz$B&+}v3Umxd>{Y)JHX$RFOG46f8M~J3iyi+ zeZXM`_~GruBf&>(Y+6b0ublfG@bh~YkDtZb*lc{f`sWQk=FSBh8?Za<=#j9jSoOrj zjb>?#t8vAdz4?Q`y|wMzKfY<7;`e+H<>IGAHZ1y^h0p%>k?VNt?@B*neHQF{g!O$E z_LI~jn_a)Xo*@61?~k6p=|I}4{jvQ0_Akftj(%YKr@wr9U)78e=qafF1AN^nOw1?> z{|89eVIigqI(oR1hdDD!;aE*v!drl3Ha3qQ7uCM8_RZ@pnBCf!uib9`PcL~z7AdC7 z5tF%Q6+*Um0&lcObyhra0Z%p*^XkB_H7jDw_9O+ecEEn4r$ zqWaXD2qb1RxDWs9yM&86PlC>q(egY&C&1vb5vd5!(xZ1hK$c&xT|2P;Oxr+NZBOv+ zgvoNwLY?}Mc|vBMP&}ZSUn$&Z%l-GpIe5(?9-|AjE`&a|U3=tWWMc5p3zw5_``#-V zpD!SvT={E}`}%JniJ@!1F-&Oii!Wg%(4{NT=ehd3h>4X2V1;2PLC&PET7X&MVN#%x z=&*O!9`oYdI6m~kV>j2ShYGdopfb*|6YMGjr$$i-%jJYIm(Nl$nD%)5)DHZ4T{&<` zs>`#^yISY5>Z6Ws@Y>$0E$qHjdA$HUo^G|LPvm9yBbK}#)*1nXkUL$eML z=-$Tl-Q{i~*KTc;?qt1iwM@CP(yeNl1x?91{^RE`;y6b~)uceI%R&rjM|Fg=Q_;sr z>GG2u5UqP!;ibZ;Uh9ync?fGZzX-LwaMNR}qNdc#g^1-+L^jz02HhH!x)sAKJcwBO zaZB}9KjI9Zu)=TGB9{IIk#(q?9F;0tQFyj5&eW)}PUsQ!s&Jmb=kcXA$sQr2j}|G~ z38waItWORJ&Q9*Ws}vW7dxQK3o9h^a}v7G zCHoW_M6O*f1T7b$p~wfg@&TcFT!>a#%`&UmZ5peB&h3qZna58t1`@l{@xetdAaq%F zgK)fEwQjzu$+2R0lS|U=A{YI}k|O!Iu{L036k#6qIFnb_1$Sw8#mxi?OU+YTxE;jl zm>u2_cbLwHtMidw;u=s~Lv%B56kmHb6<1V0`Gzi$U`P~Jk-GeLw%0iYmj*^bjWy7R z!4CU~+t!_hUhIr4OGQuM)Wz;IstQ!uV} zOrjz51Q)HwHyfMDiUD$M&*Gp{n${1x;3qvQpvywB`A)&cezlHfUBSld;#Yw4mgosG zJ?FFd*IbbEh3DDkS3=7xY%6WKk~U`0uljbVa9Xqjd2nES-t3`XejQ`J=F5*j=bHB+ zdJ4yPpB(0iz5I*nIbP77o0e_+^#kQ4Jz9`?5QHX~oQ`wk&Z|1b%@C{ww-zWCu4zI8 zal1NhbP6u=+Nx>in$FNL%t2AaW25$Dj*=Ku(MD4$1?~J^Sk%O#S zkSAifH=IRsUQIeSHb2iFPAXDVyhnyF|9TDDwfr&wdMLltDe{y{e1LYoda)}pi_?sZ z3z3A{0|!hhcg1UONYhK#Bl_2UnLrTcT2$QBkKQ)7Op!i2qKj~PPnQ>(J5`C*cYCmL zFSdiSUDhohU0vghjKwccuZ3-N(f8e_ySiaNIk?EE#iT=h0oBu{q}v>E!or8>*E$E{ zcLHp}DQROl$=fs=&NcRD4h7+^y^cSXj(cH`kuQAEkYB&q^g-O~XZ~O2pZ_dzUGc=p z7I8AeH#v)Q6P=lw$?kvtV!GBz7^VQRYQvgvHk(jNCxKpVR#+_QnV#VcJ|op5Gx$|w zCq;02n0KJtG@Y3`sU4ECNYI6uMF{SLwZ|^@Y|Pyu&?^iUJT~X>^~0^fv*WRw;`qOE zNL*E=lORfFDO2{Yzag4@1&B|uip0raUA|M=oQG$4&GU0b70b`}Xh6N4DF5{J`}RLQ z2P3Qbl!;V&Kx=r+#5i>!#{HzGI?pM|KmPSCf>;>Ykb@l1?kAsdPAIB{{a8<0&+^f? zYjVfOUQQg8W)6-|q|hJg_(huANa$2EcsI0e@*B6))?*~buI&&I0`8v+;ne3Z<>m%& z)h;iQ4^HW{;P@v>IjZ+NAzxgQJtzlW=Ua89*d4>+Y;%g6-%mCP)af~MOY?6&m^@sp zxdof5cU^z)#k`F{L(%BexoW}=L8I&#d{tT1u%V-fbr1V_v$~=-d*3ddWO48VZn0uE z0lR3Uxt-^PoSkrEm%oM~jyE1d=hjvGH5ImgzHO?$aauRhqpipPA6|M@RmGHb*!Nh|+%3VsQz&s&P%p%t#yv;^S z$Ahj13Vm%5tu1?WRG^r%WME_X>sE58sNL%HB}-G4ZTv7Xw8%q9a9W35k8YqDK*Z{H zfBbg8UOl|zrfFISW?!myf-*A*Ip$Z|;Y_h__Kslt^%U^)?*W(SOqfgc2+!^^FFi2c zc_7XoSbwPN=hvE-WcGf*xsqTSOcdfVuQhffmG2}#!79ZZj7zmCgsk>SlpLHqwr;bZ zd{*QG>#{zt{Qsh3CYz1w9godiM}ao~aCl<)p_|jF*vO!DdTK~=k)qXP$V zv7Mq~0lHFH<`S@@)$8JC{jja9cBc3s?AZd0d~)iwpZ%^qyr|wBOHPFLrmScah0dw# z3&vgySnhaWlB&c)w9Fe0tLhX8n3=ErX<=i?&|bVUXbQb~UEyE*6}vNVRbyeB6Bf3C z*H?H&u5Hv*WKTSh!E~<{NBcRCe|u%d5}&$mjC*eX_t5%33T=*cn{dYNsG8@y)}j%_ z&}(X+T-0W6=yTYuyUY*7*z+8(T#Kl|M)~luheL&*3C9A-s<*+pyM1M=-`SUKyhu+w0PZ+xAd zkq?!d99#wG=vHTxQC4Se1fR%J*T>2*vsK9j<)7+QcSjkRYvo(i<+sIS~ zb}G=7ji^?PwNCVXTkHLWXs@HhR%(C`@47gxR3HbVI{c-X3$1nF{6V`>VOSLYt5l*N z|9Px3k{c6zcvD$*LxZD?Y=~Z=1< z!?@f5mGIGok_Vzx|yUW}6%=3S| z^MTEyxG&m|3@3ZW`P-)!W+WHamvX5R9kQmN!BX9Xub)Cw{=p2%#7i8iUvK}m#f_D6 z=bj2TL!C(%{W;ItKYA=>&6oXswxd%qA2S#jB4tlJN zCq1A@gYv*AFK09}UDtu;@;sSW<7Zdym}A8AKOInL$F-4xakT5S%ejGS{wYwWBdPjY z;3;UF{nMc{_I>gg2?JbV^o}G8?P}7|E$X-?YMl|>@Ni)JE+~^1s9xloqT_77oE(6W zbF0QC1f#|BlSMB4&|){3qRTLtwBy9k2qRvW0_eJ!1xVG&qZr{JLI+aCh8)IR6y<^FdH)0g`7JPf<_+V33Pz>$N zlv(%##H>sk7)`_MhRj+c%0x*52T}7c&kl$$CKHYGxSYU(13Xqr5R-jjCi{y&LG?>z z5>g!`gGe$)9Mt=&O}lY4tP%Vj3ojFe(Xa;%>_aG1#pUX~qqIn_D7v!FU|NERZEY&r zqlyxC?;3W51`l*)&^cViGZ=ZLun_u*zyEZ@22Jh-~OhILzw4YnR= z_XpE#N2%DCwgKXf5jzHR!M9@7;Mi4zqvWHLcSzv+>IOJkuOqwdmXZigt*n8feC{ku ze7PLrFDwS@#m)Q?J69$`%Nkf$2E52cb341}Z`qR`@988yN!74tRWE&zpA)_q0lf<+ zEWK&t`w7ZY-MFDRrRXR(`&7Nhh52?k6(db1N#_f(dBmyo{fmG_A4gjQMGM?O6C4%R zdVNvn4TKz+;wQQ~60Ef35~vdJ*3rsNNc>m(3^Py?mR=x5d0j6*Y2^=*4rEmNHJ^Q4 z7}tERGOET7v9+}FQvLx}{H6n*{I&h9IW$&V720*UoNd7Et-M@aAR)zw>JV3wRGJ}C zY0!p0{0{>nZ#$@fS-1)A+E*;^^OIpc{n8praH^6Y5sU_x+#RJ&JjuF>kf7QvoK z?zgN^D_QV%+0Q<}K9BLn8T$QYqVEynCnj*Pxh|dZ@RLr1j6?sfzndt=-YVz|vpVYy zF?@W!*^bHAKNuvX3G6~(-F~8b{Vjtd9pXb@<*V%+&;O%mmrWrV^dl0P@^ZZ;jLI@U zi^xDix_-<3poj?#BvFS@dIbo!7~?t60&P-ICHFO=aG+= z-@0X~c!o3oVq^2G?Wlj?U9-uBpm`A;wc`?9_GP6}dS@afPvV63Y;Dpcd7f`dx!bZO z5F0UUEdiSuNUo@Llz|9qh7y2d`)&S%?m1JkxB=tJN9VR#aBNl(f=ddpx7W*JN%#Tp zRMnyuYz`Q3E>r#)6g9Ls*ew5riDoHvWx(O!LtqbWUBWenW+ow#eBmC$toZ}fn4Wz6Mw_p}8&(;w4Roa{O$14`}0dZBT8j@aH zXB@P4j#%u&Bpw+^YsBitGa^`K+P6S^01NN%e9UT{aJ4n?p1}@L)U5QTVU%;$&HE0M_G_~6mN`6(HNZ9*-H+PTv+I`E2F*Rf2+c^g89q9;=3<}{v*nVyup%BgS)r87Kk6)Y;x z^Ggx$=x<0|fr8bGoAG$Y!F9@HN%kF!h`26R_&q%l#Rcz1sF@PW=ZqN1(#zjnij}s- z`^QyZ7mlSD^!GjF0@1J^r^YfCBVr%B#>oA)-M`w6#dJ_Rt+;JEyP&g|9jV4_)(v#*vrdP|gC0v-JT=VK$H0@ejVvz#2Sz$03mVqksu5wP} z;pxeS0wm6sdc5}w*z_@gJ$|LJbrlV;2TR0nZ6)|zI~0-}I zzFIx?u~>T(jNi-Mv%hB-{g)BhCI_+K3S>7)n`!W)3;iT}VAyo*qLX*=-}>EPWG75) zV1G(6xFK-p1*`<|!FJ4(_W=nvIlJQLGxa-JJTkGq>(dnLRZLtXVmHTtSxNb{R=q&u z7e4e3=Lc%>zCc85@unF>{ah-Xc&lJ|Zv5&9fHaz^alB$|9Vpbui10ByTRKtNBWLxW zGNBgG3$2#)I6{j;aZfbDOj1Iw(=O#AJ=0M*3Eqerr{_2>n#1htdfRmx#ixD4|#!2=J9ZIGNH|}28(J_2T&2xfKGq2 zF@D>sv@uiZ_+)hk`zkJlNY?Eh{rC zjU6J2g~lQa(w^xq0FiTRpd^ISST0YF6M$1pDNGf-Uh=&gg8)O{YUU?OYG@MDj%hikXo#Rir zx~>d`v?)bT0vLPz%?)!&)o^9hjO+BQms+eHv5iC-EAA&01gdw4cqaKsXijBf!CfI! z%@|~ya||c^iKco0!VfLuXIX{f|TA{ic|EG(f#0v0gIEq421T&AUvB{8NG0pOXbh8jJL@-{I& z)Uh4c+z9o&_AE^rutzTi&nhb}V^I)R}$ zk$wAG1|{AhTbZ%}AZz)i()eb(ZHG8@;8ZCE<&!SSZY$$;xbyKrosiItXKNNp@3TWG zry1L@j_p{XJR`U8AzbxQAo@j?%)4p`fP^ZkNw9_q-#37QsSQ3JsDaOvt;yhm_{O4?hQ<<;ByFA2zkvlRA$eWM7n zUw_OMus#Z|Wh+kxJvAAO+E+CgtXS2N5QL+k@SoK0WpWdIu|{PO(&V*}{aj398%$XM z%2?6B$e=h0l0(kp)M5MzeB4}{CPR={xev4iVB%pT|UjthH-Y(Jt<;-I{` zEa){q(H-?3^@z?(d1-v{w9%jxB?jAH>;I)BBXDQ|R_W$~ymaLL*V}96;j>f0qlCfV zn5TcmnEx(C6}ymix7Xl$p{&id>$3UA4@Fr0?Mrk^QQOIM>6Wxn%c(9!6}F`+u(<%9 zksKq+ho;}vl%V?>)NIw}Yt4W^)RU@iuoz9yQ^2voG?~HmA}&47>LodZ0)o#_bi=Cm zOV3CN1JfP70^+T`F%4BH>G&}jVZ?!yPORqv=uU0N615#5$6=B;luH;{QHft|Q05zx zREu(q6nfg~+`7A5&RW^8S1SIhsOAR(+1j?{hY{VK{--F&f#jT?aoatjGFf^-_Bj1y zZO|-$eC=G%4&%24_^`mns1XLIu6xxQ3bmM^i%_TtLmr;OC z?jJO?*INx~3+WrT%J!qGAOUgvw)*i7Uf)MdOD(8Td0r=tH~?PFVz8)HeQAWlCkB{U zauf}Wb~tzqF4+Yu1~@_)X(Bdr8uT;OJ^R~{9}%-}z6F#uC0vGdOMGXANt(Ox=7ECc zH!p^HDmO=6XKY2(=JLkMcAQrU8V!x1H3ThdSZdPZi9h9|r$u6LQWHsw{lBD26U*)0^@Fvp1-EgeK(=wiy zCx6hct~;iB$F=5@K4q)Q)sj)RSk;4i;#wdl>Qz0>*0+GAB>*Ch#M`uwp zPeZ$H@5)Qih)*5or;tsl1J10Eh4TJx#{kE6Ipy*j5%tETeJw`{q+3b~=lPevVY~BV zWe7*1o~v3iR0@ae6xtF0V*mngscQ{=8tTolFfTESv1an==4!Fp_HqsT#dtK;yHQL( z;!{1Sy=Bxg&;)nQ{Sp7!0W;@2HaI$&+g*RQuMYJ*aM@tDpf{mLAnm*H$E~gI{NvKo zbaS_DpuSx3M-=0Sm&yys4S~iAdu4R4K&Y&$Tdl3rqv2d)JL-%=l+{BvY>KHFxeNZT zP1as|AWYT?*|dpmX=%KqUJ4Lj1oSy#M>^lyb`=O0iF1cs^)mVocc^}RF$;Q1Tvwp$ zz{Qs5$GLN_3-p5p=iK=jL_>D9!+rl5hA~-+2XNWmpOT^?Y(Cm{D{;nJYPV0WUJ=S&aQ`OQSq?pGY$s`)p&=_W+bAW!F9nmt;SpN z=Sqq4WXkx)r7$)pNYq7a7k}S|UeGIn+T&a= zu{r>Iii7TCAkeI7>C!E8`3RDKfH?q13r9m!Qa9G2V9l8LIsor|Y4zM{9O+u|aDWgVnh0~({R_XVPaBgwe5 zpMRRJ?gT|4`CfLyXnTIgK*PngqT%P?6>rJSF7&zn#-m*qYSP*&bKct@pHklC??6)Z z+ZV30#L;(Fgc=Ls3Zf|RxjT0OJmnRgIC;lut!?%5j~DzNLhdJi%>7syG~`s^j}!RRAo0-Zt54wV~MN+Ko0X z`O)y2VSZ=H+2M7f_R#@#Wi4AWK0bi~+Vr%*p=cTBvc<@hqd!-sVzK(mE6-Q?)WgMJ zW~-#K``Ah_P&}-D9EM+$e?65dWwE>Pa#6qc(@tbj*n02ACrM=*dGeoIIn*L| zX(n%+!~`KTX5S9(dB6X%GLYlv0xORJ7F{>Y&(AZgA!N}@s=N21&3oi$TdeKxl?|4g zT}%J2$JTA$s}$(Au0Eh$mVuoR`4l-t%u-$1v=c-9|9D&3>-zCa*Z-QaF_(b>iHGak z|M}eC8$dtQ1P|p-??H^MV5~FH0lU$+etzm^^t=sjS`)d!1@_h>`^lHG??iXjS~pc> zz)vw*HH7VvHHTJpeleK@f$0dGc@@QKfLg>Ng1OgPHU3r3%=_G~(Q2Qo)?X18oq}Ms za_;HrR;AUkZ0xCzg|w;aLe-{U(5~I8naHD}dLl?=cY!Kp4JU|N_F+$uezDV|7M}Y) zv7_Y>9Zldv4Rtc`cD?2=7U~^>+q{PVQuhAp+p~589t&Aw3&b9bNsfUnc$cE1ty~J> z;7t-GWGSV4JF?i_DkfM7wA41HWS)QGk3l^yzuc&5j{Jlq_6pMrxDbj1e zhpt`=+Ff;-XadiAnxpdSf*jj*Lb-?I*378Pn*MCrrnT-{@&r*xRnqGn6%T< zzi5TLkZoA+O$?xgPJ(wmX(ma6ZrYWw%ytqyfUsc$iawgd(~S>MMT(L8mCK*+KpKOU z@Sa19_WZMq7|)bVX*1%aHh=!F{(zBN29v6@@rl0birJ1Lr^aI1Hy+3$tU4{n;$Uu2 z8_)JEb5_V%(5pawB5hsd^ZzQhd#YHlLe?927vD3S7|Q)(E7>V=o>e*KBq+`lRZUH} zql(>`XYNHel@&hOZ-kxIoHh>dl#-9T6+5SnsD8h~)Ns*(Qrvg## z?P(9c+Hf1>*QPpiiKFS{iCKf?GvW?nd~V&8*)BMy1}F-4Da#~DaifH=TsmG4Ey{vg zE1D2ux|-3eNb{*b(;K#ImjhI34Eo7!VtteRr8v=@&jv@>`R!>Pv^!>esj5pc2JR(o zkH18hz$i7!SI^ic*G4GQe~@oVQ>Ibx^8a*WFg>>D5V9d(bX(Id{a$~gK$&{KaaSYZz9cA#sj5|MldH*$%zK2#G4U5{3mekz^Kbb zK|2VMLo}*RpW>)>&*NT_0-=ld!?EP-8RZbv4sn;%z~$t2zGJ@JrpIy|8>o@0DtjW+;m}oI z$Ckw~E^1b6ds{I`&e^|@$OVN%t@vDAZdg6-@sRBaXxU^^wL0q(LMTk$BWdmT&a^tC z!zkNvUA(`lVo_0X$1AJu@(Z8um)i-t#fZf-K4r(Fm}kt~P3wUw`rC;jcigFj8LB%& z;*!Ey={fi6kDE$sXXJ1L&`uijx=wNui6{p>EiA?vL<7`ulp^)o2N(vcUT&MfjD!%u zWjxPFz6S(Mk9g>RQk&tJ*Dii(8)u6&RYcY>_1pCU=%YL_q8wP_I0Y`g!wYYPOqOkJ z^xjMStX^~nOir9VEk$=J{=VwgRs2l7$6@VfH)q6!6~`eHPI_FB$kgbo<}pmfYt>A93dNk z(Zu0{On>k4hw)AQBfe!kG2;k`W*7eI60wPTlIq9%<0{Zlh?0WMc78K*tlE_b#Zn*o zqeNb1ihJ%?D=2qveXmx z8pxzb#vfXeTDIeu=I}~3`1-osf%-B@tQ}&OrFCf6Hl~%9P&@sztBiS1lQwMH=64>e ztpi6kA#_c0d{^NCgDyD^#peozM*tX&`~X#5Q|OVrH@->DN^xv3FTk}=W|zjz0WIhp zI`iXDkUG6bn-o0=ZHV-SUXSmBr}vH@8W>euaqC^$pEo;r!*r3S>e*Bi;N`a>?7yv> z2n*_($RCj7u^k>81JT!cr%cRS5tqhUG9GF#&WZ!UDYxMY9thp6@kx$O_qCIc^N>(W zlJX}K=3^Q~H?#!YJHaoPARhWRQX+uBC!4$#_gx7_n$!n6#pRWmcKZM=S^LffLO$(E z1=(*e@tnZ!SZ{4gPHIys!hRYh}V11^CBV72+v$UuFVn$fy$rR*9EEi>bcrxzQ zKgeHJ>s=EggFTLK+8`cpS7Pa#->&fz-uLet==P@%BID5ks4DDo%#hWz4&5F(->m(m zd3Kw2&0+SIKjkFmvZk z!j4(l2d{IHdT<9)kw5#!uTxvi_CObNHTQoF&uROujn01+jKS+Do~wBjX!-8_?fSnz zxtcw?2LIw1T?ExC`nwl25c+iEpur5xDb z186DIO(iPxW(IOY%yx(U8)D^H#-RN#cGSKh4cR$6Rvoov_5G3m8}x)|xA(kr7JX0C zIacjaw%G}3DzWFFc=vd97>lsys&ZWK!vo(Dj2WUOYpYtQQJc%gEStclBd zxj_x51FQp4QK`)24HYyLs4~yYzDWGuysZpdBSUr?Kzv(237uA2rRv-NG|(6{ma%t` zcJ~sx(r>iGzcnU41ukAgYNF?_$>ZfqheLkc`;_#V{WoJt_G9V8d#4*b-b4)_^pC%v z_ncHGD|sca(FPN5Nf>fpM|28HEqrQv9vO%|-ihua0ZiREZ)OPm9l&adTVCV>wGRVb z<2uYpv+r9v@zkWxYgCoougRW{mJZyCOHzf)w&yMCNR7sHwSSyIo)Oei(l`$`uu`P4 zBk4`@hY9FPJW(-)OA*+fI9~(4zAz{b99t-la17{u5zQ?22oR1H#+XQPq|Z)eCKJzp z%zy-l8MJUmp&;E!T^}-IVt7cgE%}WtAUNtEQ?#o2d!o73(X5IIbSga-=X+vxvwQ86 z$G(b^WKoKPSt%^y`S_+F^vh9~^9Z`f2jw1Hfr`-c_a>s?bsk6U6?|r9+LvaJ7kox) z5bY#=WZ!6v2l~3+digH69+k@+z_A_L#hr)Vs>_ov~(HscHoAplDuQv2m-P zj6jGsvdim?XaY`#rnbqd_n<^yv}SBDrmOgEA8SbB{9C<$&*PTg^7yM^f&=yg=V^H6 z$2TCcxEBy5s%1MLZ9SdQNIJtTe2CktYcX6t?Sc~1(Lmyvk@Y;XIbjz*h518S zFgxQhX3N+GigY2r@gVbuvwSm8E(z|!NrfxY4Lx;P=v4DQCu)70!lPF4Y}wseI@NZ*LvbaV~`y=dP6m*>}MiK14b>tR9}9Uj(24V+4+Zru9# zPHLk8sO?1}(g=w8;Z_78rgzBBUqXEt0_I&0ej1Rx5ykt0>EANw3uj1D<=}>A5t2jO zO~6sJ^Q%qm%s@?QXCryMeFOY4tjd94_D88QqY4mjN`@o6IMh0fbLBg0Bwol@f#<;Q|LP zMwWw9``SeL=TbMuhq=UUV^Xo;hI|H9_KaiZxAJbXl%h+!tMQlcPB;;+9cs zRel(yCIZSEyv*E;nBBB`iWILbRQHy;%-*VBsqTe>F3H~n{$m_Ud}DjtR?pK3sdBGV zm}I|u;8Fa*=&~d_MT+rs9?k?|R2md=quTa!vp%jWs-|KMZ?%PC8r5~$x>S2%nmvG6 z_Dn13aK{GXliP^Le*BxyqjQnOvRQG}YzGK)Azxi#dLC^WEcoSP==*_j5jqEA+e!IO zIJ!Mv=LHPkU*ByzqKCC0qbG{<(dW84S3WURq5Xf2+&Zn4Fww*9?IBdu_cFb4pd8WZ5>W%tWy3V6(bK_t8 z!G^kaQ&PshyD`YuTpW|A!kv=7j%hK+4B?$9>jlBJ|7fNS5a+-Bzfqn;fnMbUb|)8@ z-2^6F$+~dQOp2)rGd>Z0IBM~`N%Opq=W3#t@}lvm0#4>D(}Xo!Qtwm-X#3suP$N%GO?plXLcYAfgEH58tB0nWT#Z)!8O@z%99o~wa9&(Vns3*o5^K!yB(iwTr4P` zGz1m7{QahvKz1_nHNxS)%j*2sxS!wd+B7GiSV5=W X>-}{lX7O*Ua>I^=9Hsx|%WwY|BLm9T literal 0 HcmV?d00001 diff --git a/docs/images/mmu/HHv2emptygate.png b/docs/images/mmu/HHv2emptygate.png new file mode 100644 index 0000000000000000000000000000000000000000..67f1374a11a0481cb7587a8bd66540a722aed2d9 GIT binary patch literal 13209 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 z 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 I!0OZg0wMf4IsgCw literal 0 HcmV?d00001 diff --git a/docs/mmu.md b/docs/mmu.md new file mode 100644 index 000000000..53f57c112 --- /dev/null +++ b/docs/mmu.md @@ -0,0 +1,104 @@ +# MMU Configuration in Klippain + +Klippain is fully compatible with Multi-Material Units (MMU) and leverages the [HappyHare](https://github.com/moggieuk/Happy-Hare) software backend for an easy and effective use of them. + +This documentation outlines the procedures for setting up and operate an MMU within Klippain. It includes instructions on proper usage and troubleshooting common issues. + + +## Installing HappyHare + + > **Note**: + > + > If you were using the previous ERCF-Software-V3, move your old `ercf_***.cfg` files in a safe place for future reference and then uninstall it completely by running `~/ERCF-Software-V3/install.sh -u && rm -rf ~/ERCF-Software-V3`. + +Follow these steps to install the latest HappyHare: + +```bash +cd ~ +git clone https://github.com/moggieuk/Happy-Hare.git +cd Happy-Hare +./install.sh -i +``` + +Klippain requires a few simple steps to configure and customize it for your printer, if you haven't already followed the [configuration guide](./configuration.md), please do so first. + +Finally, enable Klippain's MMU feature by uncommenting the corresponding line in your `printer.cfg`. Don't forget to have a look at the HappyHare config files in the `mmu` folder at the root of your config. + + +## Configuration Tips + +HappyHare is a software with a lot of features and you should first have a look at how it works and its concepts [here](https://github.com/moggieuk/Happy-Hare?tab=readme-ov-file#---readme-table-of-contents) and its documentation section [here](https://github.com/moggieuk/Happy-Hare/tree/main/doc). On top of this, Klippain define a couple of things a bit differently to allow more flexibility and a better integration with it. + +### Check gates on START_PRINT + +If you want to check the gates at the start of a print to avoid an error when using a gate that was previously marked as empty, it is recommended to set `variable_mmu_check_gates_on_start_print: True` in your Klippain `variables.cfg`. + + > **Note**: + > + > Be sure to also include `TOOLS_USED=!referenced_tools!` in your slicer custom start print gcode in order to allow the [HappyHare Moonraker gcode preprocessor](https://github.com/moggieuk/Happy-Hare/blob/main/doc/gcode_preprocessing.md) to work correctly and and to ensure that all tools are checked. + +### Early check errors during START_PRINT + +In Klippain, you have two options to control how and when MMU errors are detected during the start of a print: + + 1. **Managed by Klippain**: This allows the system to check for errors during the sequence and, if errors are detected, to stop the sequence immediately so that you can troubleshoot the MMU. However, you'll need to restart the print after the MMU problems are fixed. + To enable this mode, set `variable_mmu_check_gates_on_start_print: True` in your Klippain `variables.cfg`. Note that when this is set, the original `print_start_detection` parameter of HH will have no effect, as Klippain will take over the management of MMU state changes. + + 1. **Managed by HappyHare**: This allows HappyHare to automatically detect the start and end of a print. However, if an MMU error occurs, the system will only pause at the very end of the START_PRINT sequence, meaning you'll have to wait until then to fix any MMU problems. However, once the problem is resolved, you can resume printing, provided you have been able to manually purge, clean, and prepare the nozzle for printing. + To enable this mode, set `variable_mmu_check_gates_on_start_print: False` in your Klippain `variables.cfg` to allow HappyHare to take care of this and set its `print_start_detection` parameter to your liking. + +Using these parameters, you can choose to detect errors early and stop printing immediately for faster troubleshooting, or you can stick with the default mode, which stops printing at the end of the START_PRINT sequence for error handling. The choice depends entirely on your preferences and how you want to handle MMU errors during printing. + +### Difference between GATE and TOOL + + - **GATE** refers to the physical MMU slot + - **TOOL** refers to the virtual tool (or filament) used in software. The one you can call using the `Tx` command. + +By default, as you can see with the `MMU_REMAP_TTG` command in HappyHare, GATE and TOOL are mapped equivalently one by one. But you can use the same command to change this mapping like this: `MMU_REMAP_TTG TOOL=x GATE=y`. + +This feature is particularly useful if you have already sliced a project with certain tools defined in the slicer and want to reprint it after moving the filament spools to different gates, or with different filament colors without having to reorganize the spool positions or reslice your project. For more information, please look at the official HappyHare [Tool-to-Gate (TTG) mapping documentation](https://github.com/moggieuk/Happy-Hare?tab=readme-ov-file#3-tool-to-gate-ttg-mapping). + +### Using Bypass + +If you want to print without using the MMU features, you can use the MMU bypass mode. Here is how to use it: + 1. Home the MMU by running `MMU_HOME FORCE_UNLOAD=1`. + 1. Select the bypass mode with `MMU_SELECT_BYPASS`. + 1. Finally, manually insert the filament into the bowden tube up to the extruder gears and load the filament with the `MMU_LOAD` command or start the print (the `START_PRINT` sequence will automatically try to load the filament into the toolhead). + +At the end of the print, you can use the `MMU_EJECT` command (if `variable_mmu_unload_on_end_print` is set to False in Klippain `variables.cfg`, otherwise it is ejected automatically) to unload the filament from the extruder and then manually pull it out of the bowden tube. + +### Spoolman support with MMU + +HappyHare can natively handle spool changes in Spoolman. This requires some configuration in the `mmu/mmu_parameters.cfg` file: + 1. Set `enable_spoolman:1` to enable spoolman support in HH. + 1. Then configure the spool IDs using the `gate_spool_id:` variable. + +You can also use the `MMU_GATE_MAP GATE=n SPOOLID=id` macro at runtime to change the spool ID associated with a gate. + + > **Note**: + > + > If you set the `INITIAL_TOOL` parameter in your slicer custom start gcode, Klippain will use it to select and activate the correct spool from Spoolman for the print. + + +## MMU error messages in Klippain + +### Variable check error + +``` +MMU support is enabled in Klippain, but some variables are missing from your variables.cfg. Please update your template or refer to the corresponding documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md +``` + +If you have the previous message in the console when Klippain is starting, you will want to update your Klippain `variables.cfg` template file or check that the MMU variables are set correctly in it: + - `variable_mmu_force_homing_in_start_print`: True or False + - `variable_mmu_unload_on_cancel_print`: True or False + - `variable_mmu_unload_on_end_print`: True or False + - `variable_mmu_check_gates_on_start_print`: True or False + - `variable_mmu_check_errors_on_start_print`: True or False + +### Empty gate error + +![](./images/mmu/HHv2emptygate.png) + +If you encounter an error despite the gate being loaded correctly, it's often because the gate was previously marked as empty and hasn't had its status updated. To resolve this during a print, for instance, you can use the command `MMU_GATE_MAP GATE=n AVAILABLE=1`. + +It's a best practice to verify the state of each gate after changing filaments. Use the `MMU_GATE_MAP` command to ensure your setup is accurate. Additionally, the `MMU_CHECK_GATE` command allows you to update the status for all MMU gates. If you need to update specific gates or tools, you can use commands like `MMU_CHECK_GATE TOOLS=0,2,5` to check and update tools 0, 2, and 5, or `MMU_CHECK_GATE GATES=0,2,5` for gates 0, 2, and 5, respectively. diff --git a/docs/pinout.md b/docs/pinout.md index 21b79a5b1..2501a75b6 100644 --- a/docs/pinout.md +++ b/docs/pinout.md @@ -2,24 +2,25 @@ In Klipper, once a `[board_pins]` is defined, the aliases are used in all sections to make them more readable ([official board_pins Klipper documentation](https://www.klipper3d.org/Config_Reference.html#board_pins)). I use this mechanism extensively on a two-level model to add genericity and simplify the MCU configuration for everyone. - ## Configuring your mcu.cfg file Klippain is designed using a two-level [board_pins] model: + 1. First level: Some rules and pin naming conventions (let's call them "Frix-x names") were defined and used in all config files. Then a set of [user board_pins templates](./../user_templates/mcu_defaults/) were created for the most common MCUs of the market. This is basically what you need to put in your `mcu.cfg` file. 2. Second level: Since it's always a pain to retrieve the pin names from the boards manufacturer's documentation like `PA12` or `gpio23` (let's call them "controller names"), I added a second layer of [board_pins] to link some "easy to retrieve names" (ie. what's printed on the MCU boards around the ports and easy to read with "MCU_" as a prefix) to these "controller names". This second layer of board_pins is located [in this folder](./../config/mcu_definitions/) and is not intended to be modified. To summarize, we have two board_pins used for each MCU. One user board_pins and one manufacturer board_pins. They link the following: + ``` Frix-x names -> Manufacturer (PCB print) names > controller names ``` So in order to populate your own `mcu.cfg` file, just copy one of the [user template](./../user_templates/mcu_defaults/) into it. Then feel free to change the wiring to your liking. For example, if you have wired your part fan to port `FAN3` instead of `FAN0`, just change the definition to `PART_FAN=MCU_FAN3` and that's it! - > **Info** + > **Info**: + > > Klipper does not allow `[board_pins]` sections to contain pin modifiers such as `!`, `^` and `~`. Moreover, when configuring multiple MCUs at the same time, all the aliases used in the hardware sections must be prefixed with the MCU name. This is a current limitation of Klipper and is why you need to use the overrides.cfg file to add them. - ## Using a new MCU If you want to use a new MCU that is not yet supported in my config, you just have to define a new [board_pins] in your `mcu.cfg` file and use the same convention. Also feel free to also add a manufacturer board_pins to my config and submit a PR: I'll be happy to merge it and extend MCU support for new boards :) @@ -27,46 +28,57 @@ If you want to use a new MCU that is not yet supported in my config, you just ha Here is a list of all the "Frix-x names" available to use in your own board_pins: #### Steppers + - `[EXYZ1-3]_STEP`: drivers step pins - `[EXYZ1-3]_DIR`: drivers dir pins - `[EXYZ1-3]_ENABLE`: drivers enable pins - `[EXYZ1-3]_TMCUART`: drivers UART pins - - Beside standard axis there is also the support for the `GEAR_...` and `SELECTOR_...` drivers used in the ERCF + - `DRIVER_SPI_MOSI`, `DRIVER_SPI_MISO`, `DRIVER_SPI_SCK`: used in case of SPI drivers + - Beside standard axis there is also the support for the `MMU_GEAR_...` and `MMU_SEL_...` drivers used in the MMU/ERCF/TRADRACK #### Endstops & Probe + - `[XYZ]_STOP`: classic axis endstops pins - - `PROBE_INPUT`: classical probe like Klicky, Omron, Pinda, TAP, etc... + - `PROBE_INPUT`: classical probe input like Klicky, Omron, Pinda, TAP, etc... + - `MMU_SEL_ENDSTOP`: for the MMU/ERCF physical selector endstop + +#### Heaters -#### Heaters - `E_HEATER`: hotend heater cartridge - `BED_HEATER`: bed heating pad (or bed SSR) #### Temperature sensors + - `E_TEMPERATURE`: hotend temperature sensor - `BED_TEMPERATURE`: bed temperature sensor - - `CHAMBER_TEMPERATURE`: chamber temperature sensor + - `CHAMBER_TEMPERATURE`: chamber temperature sensor (used to heatsoak the chamber during the START_PRINT sequence) - `ELECTRICAL_CABINET_TEMPERATURE`: electrical cabinet temperature sensor (not really used in the config, but if present, this sensor is added to the Mainsail / Fluidd web interface as an additional info) #### Fans + - `E_FAN`: hotend fan. This fan should stay at 100% whenever the hotend is hot, so a PWM capable pin is not mandatory - - `PART_FAN`: part fan used during the print. This pin should be a PWM capable pin to allow power modulation - - `EXHAUST_FAN`: for an exhaust filter (such as the Voron basic exhaust). This pin should be a PWM capable pin to allow power modulation - - `FILTER_FAN`: for a filter (such as a Nevermore filter). This pin should be a PWM capable pin to allow power modulation + - `PART_FAN`: part fan used during the print. This pin should be a PWM capable pin to allow modulation of the fan speed + - `EXHAUST_FAN`: for an exhaust filter (such as the Voron basic exhaust). This pin should be a PWM capable pin to allow modulation of the fan speed + - `FILTER_FAN`: for a filter (such as a Nevermore filter). This pin should be a PWM capable pin to allow modulation of the fan speed - `CONTROLLER_FAN`: to cool down your MCUs or electronic bay - `HOST_CONTROLLER_FAN`: to cool down your Pi (or equivalent Klipper host controller) #### Lights + - `LIGHT_OUTPUT`: simple chamber lights (such as 24v leds or 24v fcob light bars) - - `LIGHT_NEOPIXEL` : neopixel chamber lights - - `STATUS_NEOPIXEL` : toolhead neopixel lights (such as the one used on the Voron StealthBurner toolhead) + - `LIGHT_NEOPIXEL` : neopixels chamber lights + - `STATUS_NEOPIXEL` : toolhead/machine status led neopixels (such as the one used on the Voron StealthBurner toolhead) + - `MMU_NEOPIXEL`: for the specific MMU/ERCF neopixel leds #### Other I/Os - - `RUNOUT_SENSOR`: filament motion sensor - - `ERCF_ENCODER`: filament motion sensor used in the ERCF carriage - - `TOOLHEAD_SENSOR`: toolhead filament sensor used for the ERCF - - `SERVO_PIN`: for a mechanical and movable probe dock or brush (such as the ones that are commonly found on the Voron V0 mods) - - `ERCF_SERVO`: for a the ERCF servo + - `RUNOUT_SENSOR`: filament runout sensor (currently only one motion or switch sensor is supported in Klippain) + - `MMU_ENCODER`: filament motion sensor used in the MMU/ERCF carriage + - `TOOLHEAD_SENSOR`: optional toolhead filament sensor used for the MMU/ERCF/TRADRACK + - `SERVO_PIN`: for a mechanical and movable probe dock or brush (such as the ones that are commonly found on the Voron V0 mods) + - `MMU_SERVO`: for the MMU servo + - `MMU_GATE_SENSOR`: for the MMU/TRADRACK gate sensor + - `MMU_PRE_GATE_[0-11]`: for the MMU/ERCT sensors ## External references @@ -78,4 +90,4 @@ For more information on the boards and pinouts, please see directly the manufact - [Fly SHT](https://mellow.klipper.cn/#/board/fly_sht36_42/) - [BTT EBB](https://github.com/bigtreetech/EBB) - [BTT SKR Mini E3](https://github.com/bigtreetech/BIGTREETECH-SKR-mini-E3) - - [Fysetc S6](https://github.com/FYSETC/FYSETC-S6) \ No newline at end of file + - [Fysetc S6](https://github.com/FYSETC/FYSETC-S6) diff --git a/install.sh b/install.sh index 46a3ceb0c..a551732ad 100755 --- a/install.sh +++ b/install.sh @@ -26,6 +26,8 @@ FRIX_CONFIG_PATH="${HOME}/klippain_config" BACKUP_PATH="${HOME}/klippain_config_backups" # Where the Klipper folder is located (ie. the internal Klipper firmware machinery) KLIPPER_PATH="${HOME}/klipper" +# Branch from Frix-x/klippain repo to use during install (default: main) +FRIX_BRANCH="main" set -eu @@ -73,10 +75,11 @@ function check_download { local frixtemppath frixreponame frixtemppath="$(dirname ${FRIX_CONFIG_PATH})" frixreponame="$(basename ${FRIX_CONFIG_PATH})" + frixbranchname="${FRIX_BRANCH}" if [ ! -d "${FRIX_CONFIG_PATH}" ]; then echo "[DOWNLOAD] Downloading Klippain repository..." - if git -C $frixtemppath clone https://github.com/Frix-x/klippain.git $frixreponame; then + if git -C $frixtemppath clone -b $frixbranchname https://github.com/Frix-x/klippain.git $frixreponame; then chmod +x ${FRIX_CONFIG_PATH}/install.sh printf "[DOWNLOAD] Download complete!\n\n" else @@ -141,7 +144,7 @@ function install_config { # Helper function to ask and install the MCU templates if needed function install_mcu_templates { - local install_template file_list main_template install_toolhead_template toolhead_template install_ercf_template + local install_template file_list main_template install_toolhead_template toolhead_template install_mmu_template read < /dev/tty -rp "[CONFIG] Would you like to select and install MCU wiring templates files? (Y/n) " install_template if [[ -z "$install_template" ]]; then @@ -204,33 +207,33 @@ function install_mcu_templates { fi fi - # Finally see if the user use an ERCF board - read < /dev/tty -rp "[CONFIG] Do you have an ERCF MCU and want to install a template? (y/N) " install_ercf_template - if [[ -z "$install_ercf_template" ]]; then - install_ercf_template="n" + # Finally see if the user use an MMU/ERCF board + read < /dev/tty -rp "[CONFIG] Do you have an MMU/ERCF MCU and want to install a template? (y/N) " install_mmu_template + if [[ -z "$install_mmu_template" ]]; then + install_mmu_template="n" fi - install_ercf_template="${install_ercf_template,,}" + install_mmu_template="${install_mmu_template,,}" - # Check if the user wants to install an ERCF MCU template - if [[ "$install_ercf_template" =~ ^(yes|y)$ ]]; then + # Check if the user wants to install an MMU/ERCF MCU template + if [[ "$install_mmu_template" =~ ^(yes|y)$ ]]; then file_list=() while IFS= read -r -d '' file; do file_list+=("$file") - done < <(find "${FRIX_CONFIG_PATH}/user_templates/mcu_defaults/ercf" -maxdepth 1 -type f -print0) - echo "[CONFIG] Please select your ERCF MCU in the following list:" + done < <(find "${FRIX_CONFIG_PATH}/user_templates/mcu_defaults/mmu" -maxdepth 1 -type f -print0) + echo "[CONFIG] Please select your MMU/ERCF MCU in the following list:" for i in "${!file_list[@]}"; do echo " $((i+1))) $(basename "${file_list[i]}")" done - read < /dev/tty -p "[CONFIG] Template to install (or 0 to skip): " ercf_template - if [[ "$ercf_template" -gt 0 ]]; then + read < /dev/tty -p "[CONFIG] Template to install (or 0 to skip): " mmu_template + if [[ "$mmu_template" -gt 0 ]]; then # If the user selected a file, copy its content into the mcu.cfg file - filename=$(basename "${file_list[$((ercf_template-1))]}") - cat "${FRIX_CONFIG_PATH}/user_templates/mcu_defaults/ercf/$filename" >> ${USER_CONFIG_PATH}/mcu.cfg + filename=$(basename "${file_list[$((mmu_template-1))]}") + cat "${FRIX_CONFIG_PATH}/user_templates/mcu_defaults/mmu/$filename" >> ${USER_CONFIG_PATH}/mcu.cfg echo "[CONFIG] Template '$filename' inserted into your mcu.cfg user file" - printf "[CONFIG] You must install ERCF Happy Hare from https://github.com/moggieuk/ERCF-Software-V3 to use ERCF with Klippain\n\n" + printf "[CONFIG] Note: keep in mind that you have to install the HappyHare backend manually to use an MMU/ERCF with Klippain. See the Klippain documentation for more information!\n\n" else - printf "[CONFIG] No ERCF template selected. Skip and continuing...\n\n" + printf "[CONFIG] No MMU/ERCF template selected. Skip and continuing...\n\n" fi fi } diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index 6f62b8717..9bc7d521a 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -5,8 +5,8 @@ gcode: {% set turn_off_heaters_in_end_print = printer["gcode_macro _USER_VARIABLES"].turn_off_heaters_in_end_print %} {% set safe_extruder_temp = printer["gcode_macro _USER_VARIABLES"].safe_extruder_temp|float %} {% set light_intensity_end_print = printer["gcode_macro _USER_VARIABLES"].light_intensity_end_print %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} - {% set ercf_unload_on_cancel_print = printer["gcode_macro _USER_VARIABLES"].ercf_unload_on_cancel_print %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} + {% set mmu_unload_on_cancel_print = printer["gcode_macro _USER_VARIABLES"].mmu_unload_on_cancel_print %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} @@ -16,13 +16,13 @@ gcode: PARK - {% if klippain_ercf_enabled and ercf_unload_on_cancel_print %} - {% if printer.ercf.enabled %} - # unload filament and park into ercf - ERCF_EJECT + {% if klippain_mmu_enabled and mmu_unload_on_cancel_print %} + {% if printer.mmu.enabled and printer.mmu.tool|int != -2 %} + # Unload filament and park the MMU + MMU_EJECT {% endif %} {% else %} - # pull back the filament a little bit + # Pull back the filament a little bit G92 E0 G1 E-10 F2100 {% endif %} @@ -61,6 +61,12 @@ gcode: STATUS_LEDS COLOR="OFF" {% endif %} + {% if klippain_mmu_enabled %} + {% if printer.mmu.enabled and printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_END STATE=cancelled + {% endif %} + {% endif %} + # If a filament sensor is connected, re-enable it in case it was disabled during printing {% if filament_sensor_enabled %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index 45241d99b..dd7d5cce2 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -5,8 +5,8 @@ gcode: {% set turn_off_heaters_in_end_print = printer["gcode_macro _USER_VARIABLES"].turn_off_heaters_in_end_print %} {% set safe_extruder_temp = printer["gcode_macro _USER_VARIABLES"].safe_extruder_temp|float %} {% set light_intensity_end_print = printer["gcode_macro _USER_VARIABLES"].light_intensity_end_print %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} - {% set ercf_unload = params.ERCF_UNLOAD_AT_END|default(printer["gcode_macro _USER_VARIABLES"].ercf_unload_on_end_print)|int %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} + {% set mmu_unload = params.MMU_UNLOAD_AT_END|default(printer["gcode_macro _USER_VARIABLES"].mmu_unload_on_end_print)|int %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} @@ -16,10 +16,10 @@ gcode: PARK - {% if klippain_ercf_enabled and ercf_unload %} - {% if printer.ercf.enabled %} - # unload filament and park into ercf - ERCF_EJECT + {% if klippain_mmu_enabled %} + {% if printer.mmu.enabled and mmu_unload %} + # unload filament and park into MMU. Or just unload filament out of extruder if using bypass. + MMU_EJECT {% endif %} {% else %} # pull back the filament a little bit @@ -59,7 +59,13 @@ gcode: LIGHT_ON S={light_intensity_end_print} {% endif %} {% if status_leds_enabled %} - STATUS_LEDS COLOR="OFF" + STATUS_LEDS COLOR="DONE_PRINTING" + {% endif %} + + {% if klippain_mmu_enabled %} + {% if printer.mmu.enabled and printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_END + {% endif %} {% endif %} # If a filament sensor is connected, re-enable it in case it was disabled during printing diff --git a/macros/base/homing/homing_conditional.cfg b/macros/base/homing/homing_conditional.cfg index b3498a7a7..37ff1eeaa 100644 --- a/macros/base/homing/homing_conditional.cfg +++ b/macros/base/homing/homing_conditional.cfg @@ -8,9 +8,7 @@ gcode: STATUS_LEDS COLOR="HOMING" {% endif %} G28 + {% if status_leds_enabled %} + STATUS_LEDS COLOR="READY" + {% endif %} {% endif %} - - {% if status_leds_enabled %} - STATUS_LEDS COLOR="READY" - {% endif %} - \ No newline at end of file diff --git a/macros/base/homing/tilting.cfg b/macros/base/homing/tilting.cfg index 50fe6457a..9a5e2b108 100644 --- a/macros/base/homing/tilting.cfg +++ b/macros/base/homing/tilting.cfg @@ -4,7 +4,6 @@ gcode: {% set FORCE_OPERATION = params.FORCE|default('true') %} {% set conf_QGL = printer["gcode_macro _USER_VARIABLES"].qgl_enabled %} {% set conf_ztilt = printer["gcode_macro _USER_VARIABLES"].ztilt_enabled %} - {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set probe_type_enabled = printer["gcode_macro _USER_VARIABLES"].probe_type_enabled %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} @@ -12,10 +11,6 @@ gcode: SET_GCODE_VARIABLE MACRO=_PROBE_ON_ERROR_ACTION VARIABLE=probing VALUE=True {% endif %} - {% if status_leds_enabled %} - STATUS_LEDS COLOR="LEVELING" - {% endif %} - {% if conf_QGL %} {% if printer.quad_gantry_level.applied|lower == 'false' or FORCE_OPERATION|lower == 'true' %} {% if verbose %} @@ -39,7 +34,3 @@ gcode: {% if probe_type_enabled == "dockable" %} SET_GCODE_VARIABLE MACRO=_PROBE_ON_ERROR_ACTION VARIABLE=probing VALUE=False {% endif %} - - {% if status_leds_enabled %} - STATUS_LEDS COLOR="READY" - {% endif %} diff --git a/macros/base/park.cfg b/macros/base/park.cfg index 6e70e1d34..0c1196925 100644 --- a/macros/base/park.cfg +++ b/macros/base/park.cfg @@ -1,14 +1,16 @@ [gcode_macro PARK] description: Park the toolhead at the back and retract some filament if the nozzle is hot gcode: - {% set E = params.E|default(1.7)|float %} + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + {% set E = params.E|default(1.7)|float|abs %} + {% set MATERIAL = printer['gcode_macro START_PRINT'].material %} {% set Px, Py = printer["gcode_macro _USER_VARIABLES"].park_position_xy|map('float') %} - {% set Px = params.X|default(Px)|float %} {% set Py = params.Y|default(Py)|float %} {% set park_lift_z = printer["gcode_macro _USER_VARIABLES"].park_lift_z %} + {% set Z_HOP = params.Z_HOP|default(park_lift_z)|float %} {% set firmware_retraction_enabled = printer["gcode_macro _USER_VARIABLES"].firmware_retraction_enabled %} {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed * 60 %} @@ -17,16 +19,35 @@ gcode: {% set max_z = printer.toolhead.axis_maximum.z|float %} {% set act_z = printer.toolhead.position.z|float %} - {% set z_safe = act_z + park_lift_z %} + {% set z_safe = act_z + Z_HOP %} {% if z_safe > max_z %} {% set z_safe = max_z %} {% endif %} - # retract filament before move up toolhead - {% if printer.extruder.temperature > 185 and firmware_retraction_enabled %} - G10 + {% if printer.toolhead.homed_axes != "xyz" %} + RESPOND MSG="Cannot park because XYZ not homed" + {% else %} # retract filament before move up toolhead + {% if printer.extruder.can_extrude %} + {% if firmware_retraction_enabled %} # use firmware_retraction parameter for retract (in case firmware retraction is selected in printer.cfg) + {% if verbose %} + RESPOND MSG="Firmware retraction enabled, Extruder retraction = {printer.firmware_retraction.retract_length}" + {% endif %} + G10 + {% else %} # otherwise: + {% if MATERIAL != "XXX" %} # use material parameter if available for retract, otherwise use default value + {% set material = printer["gcode_macro _USER_VARIABLES"].material_parameters[MATERIAL] %} + {% set E = material.retract_length %} + {% endif %} + {% if verbose %} + RESPOND MSG="Firmware retraction disabled, Extruder retraction = {E}" + {% endif %} + G92 E0 + G1 E-{E} F2100 + {% endif %} + {% else %} + RESPOND MSG="no extruder retraction because extruder temperature ({printer.extruder.temperature}) is lower than min_extrude_temp ({printer.configfile.config.extruder.min_extrude_temp})" + {% endif %} + G90 + G1 Z{z_safe} F{Sz} + G0 X{Px} Y{Py} F{St} {% endif %} - G90 - G1 Z{z_safe} F{Sz} - - G0 X{Px} Y{Py} F{St} diff --git a/macros/base/pause_resume.cfg b/macros/base/pause_resume.cfg index 5a1eecfb3..54b2af0bf 100644 --- a/macros/base/pause_resume.cfg +++ b/macros/base/pause_resume.cfg @@ -24,11 +24,20 @@ gcode: {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed %} {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} {% set light_intensity_printing = printer["gcode_macro _USER_VARIABLES"].light_intensity_printing %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% if not printer.pause_resume.is_paused %} - RESPOND MSG="Print is not paused. Resume ignored" + RESPOND MSG="Print is not paused. Resume ignored" {% else %} - RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1 MOVE_SPEED={St} + {% if klippain_mmu_enabled %} + {% if printer.mmu.enabled and printer.mmu.is_locked %} + RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=0 + {% else %} + RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1 MOVE_SPEED={St} + {% endif %} + {% else %} + RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1 MOVE_SPEED={St} + {% endif %} {% if light_enabled %} LIGHT_ON S={light_intensity_printing} {% endif %} diff --git a/macros/base/probing/overrides/qgl.cfg b/macros/base/probing/overrides/qgl.cfg index a788d0584..6b5d6b953 100644 --- a/macros/base/probing/overrides/qgl.cfg +++ b/macros/base/probing/overrides/qgl.cfg @@ -8,12 +8,18 @@ rename_existing: _BASE_QUAD_GANTRY_LEVEL description: Conform a moving, twistable gantry to the shape of a stationary bed with klicky automount gcode: {% set tilting_travel_accel = printer["gcode_macro _USER_VARIABLES"].tilting_travel_accel %} + {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% if verbose %} { action_respond_info("Quad gantry leveling") } {% endif %} + _CG28 + + {% if status_leds_enabled %} + STATUS_LEDS COLOR="LEVELING" + {% endif %} ACTIVATE_PROBE @@ -28,3 +34,7 @@ gcode: SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} DEACTIVATE_PROBE + + {% if status_leds_enabled %} + STATUS_LEDS COLOR="READY" + {% endif %} diff --git a/macros/base/probing/overrides/z_tilt.cfg b/macros/base/probing/overrides/z_tilt.cfg index 54ae64e6d..548b40ce3 100644 --- a/macros/base/probing/overrides/z_tilt.cfg +++ b/macros/base/probing/overrides/z_tilt.cfg @@ -8,13 +8,20 @@ rename_existing: _BASE_Z_TILT_ADJUST description: Conform a moving bed to the shape of a stationary gantry with dockable probe automount gcode: {% set tilting_travel_accel = printer["gcode_macro _USER_VARIABLES"].tilting_travel_accel %} + {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + {% if verbose %} { action_respond_info("Z tilt adjust") } {% endif %} + _CG28 + {% if status_leds_enabled %} + STATUS_LEDS COLOR="LEVELING" + {% endif %} + ACTIVATE_PROBE # Set the tilting acceleration prior to any movement @@ -28,3 +35,7 @@ gcode: SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} DEACTIVATE_PROBE + + {% if status_leds_enabled %} + STATUS_LEDS COLOR="READY" + {% endif %} diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 401eb1eb0..5ba892879 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -7,6 +7,9 @@ variable_soak: 0 variable_chamber_temp: 0 variable_chamber_maxtime: 0 variable_initial_tool: 0 +variable_check_gates: 0 +variable_tools_used: "" +variable_sync_mmu_extruder: 0 variable_material: "XXX" variable_fl_size: "0_0_0_0" variable_bed_mesh_profile: "" @@ -19,9 +22,12 @@ gcode: {% set SOAK = params.SOAK|default(printer["gcode_macro _USER_VARIABLES"].print_default_soak)|int %} # Heatsoak time of the bed in minutes {% set CHAMBER_TEMP = params.CHAMBER|default(printer["gcode_macro _USER_VARIABLES"].print_default_chamber_temp)|int %} # Chamber temperature setpoint {% set CHAMBER_MAXTIME = params.CHAMBER_MAXTIME|default(printer["gcode_macro _USER_VARIABLES"].print_default_chamber_max_heating_time)|int %} # Chamber heatsoak timeout in minutes - {% set INITIAL_TOOL = params.INITIAL_TOOL|default(0)|int %} # Initial tool (for the ERCF initialization) + {% set INITIAL_TOOL = params.INITIAL_TOOL|default(0)|int %} # Initial tool (for the MMU/ERCF initialization) {% set MATERIAL = params.MATERIAL|default(printer["gcode_macro _USER_VARIABLES"].print_default_material)|string %} # Material type set in the slicer {% set FL_SIZE = params.SIZE|default("0_0_0_0")|string %} # Get bounding box of the first layer for the adaptive bed mesh + {% set CHECK_GATES = params.CHECK_GATES|default(printer['gcode_macro _USER_VARIABLES'].mmu_check_gates_on_start_print)|int %} # Check if MMU gates are availables + {% set TOOLS_USED = params.TOOLS_USED|default("")|string %} # Check if MMU gates (used in gcode file) are availables + {% set SYNC_MMU_EXTRUDER = params.SYNC_MMU_EXTRUDER|default(0)|int %} # set MMU gear motor and extruder synchronization during print TODO {% set BED_MESH_PROFILE = params.MESH|default("")|string %} # Bed mesh profile to load # Set the variables to be used in all the modules based on the slicer parameters @@ -31,6 +37,9 @@ gcode: SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=chamber_temp VALUE={CHAMBER_TEMP} SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=chamber_maxtime VALUE={CHAMBER_MAXTIME} SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=initial_tool VALUE={INITIAL_TOOL} + SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=check_gates VALUE={CHECK_GATES} + SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=tools_used VALUE='"{TOOLS_USED}"' + SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=sync_mmu_extruder VALUE={SYNC_MMU_EXTRUDER} SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=material VALUE='"{MATERIAL}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=fl_size VALUE='"{FL_SIZE}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_mesh_profile VALUE='"{BED_MESH_PROFILE}"' @@ -47,8 +56,8 @@ gcode: {% set light_intensity_printing = printer["gcode_macro _USER_VARIABLES"].light_intensity_printing %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set force_homing_in_start_print = printer["gcode_macro _USER_VARIABLES"].force_homing_in_start_print %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} - {% set ercf_reset_stats_on_start_print = printer["gcode_macro _USER_VARIABLES"].ercf_reset_stats_on_start_print %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} + {% set mmu_force_homing_in_start_print = printer["gcode_macro _USER_VARIABLES"].mmu_force_homing_in_start_print %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set firmware_retraction_enabled = printer["gcode_macro _USER_VARIABLES"].firmware_retraction_enabled %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} @@ -88,14 +97,6 @@ gcode: STOP_FILTER {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if ercf_reset_stats_on_start_print %} - ERCF_RESET_STATS - {% endif %} - {% endif %} - {% endif %} - SET_GCODE_OFFSET Z=0 M221 S100 M220 S100 @@ -115,6 +116,11 @@ gcode: _CG28 {% endif %} + # If an MMU is enabled, initialize it for the print + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_INIT + {% endif %} + # Here is the core of the START_PRINT were we get the startprint_actions variable # to do the procedure in the correct order for the configured probe (or user custom override) {% set sp_actions = printer["gcode_macro _USER_VARIABLES"].startprint_actions %} @@ -173,6 +179,12 @@ gcode: LIGHT_ON S={light_intensity_printing} {% endif %} + {% if klippain_mmu_enabled %} + {% if printer.mmu.enabled and printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_START + {% endif %} + {% endif %} + {% if verbose %} RESPOND MSG="Start printing !" {% endif %} @@ -287,7 +299,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% set purge_and_brush_enabled = printer["gcode_macro _USER_VARIABLES"].purge_and_brush_enabled %} {% set purgeclean_servo_enabled = printer["gcode_macro _USER_VARIABLES"].purgeclean_servo_enabled %} @@ -312,12 +324,9 @@ gcode: M109 S{EXTRUDER_TEMP} - # Load intial tool in the ERCF if needed - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - ERCF_CHANGE_TOOL STANDALONE=1 TOOL={INITIAL_TOOL} - _ERCF_ERROR_CHECK - {% endif %} + # Load intial tool into MMU (if needed) + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_LOAD_INITIAL_TOOL {% endif %} {% if purgeclean_servo_enabled %} @@ -387,9 +396,6 @@ gcode: {% if bed_mesh_enabled %} {% if BED_MESH_PROFILE == "" %} - {% if status_leds_enabled %} - STATUS_LEDS COLOR="MESHING" - {% endif %} {% if verbose %} RESPOND MSG="Bed mesh measurement..." {% endif %} @@ -453,3 +459,4 @@ gcode: # [gcode_macro _MODULE_CUSTOM3] # gcode: # ## Your custom code here + diff --git a/macros/calibration/calibrate.cfg b/macros/calibration/calibrate.cfg index 715d33562..8efac3d8d 100644 --- a/macros/calibration/calibrate.cfg +++ b/macros/calibration/calibrate.cfg @@ -8,16 +8,24 @@ gcode: {% set BED_TEMP = params.BED_TEMP|default(printer["gcode_macro _USER_VARIABLES"].print_default_bed_temp)|float %} {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(printer["gcode_macro _USER_VARIABLES"].print_default_extruder_temp)|float %} {% set MATERIAL = params.MATERIAL|default("ABS")|string %} + {% set TOOL = params.TOOL|default(0)| int %} # optional: used only in case of an MMU {% set center_x = printer.toolhead.axis_maximum.x|float / 2 %} {% set center_y = printer.toolhead.axis_maximum.y|float / 2 %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} + {% if klippain_mmu_enabled %} + {% if printer.mmu.enabled and printer.mmu.filament == "Loaded" %} + {% set TOOL = printer.mmu.tool|int %} # use the current loaded tool + {% endif %} + {% endif %} + {% if TYPE=="flow" %} # No bed mesh needed for this one as it's a small center print so we compute the size manually (default flow size is 40mm) {% set computed_size = (center_x - 20)|string + '_' + (center_y - 20)|string + '_' + (center_x + 20)|string + '_' + (center_y + 20)|string %} # Call the standard START_PRINT with almost no soaking time and no chamber temp requirement (we want to go fast!) - START_PRINT EXTRUDER_TEMP={EXTRUDER_TEMP} BED_TEMP={BED_TEMP} MATERIAL={MATERIAL} SOAK=1 SIZE={computed_size} + START_PRINT EXTRUDER_TEMP={EXTRUDER_TEMP} BED_TEMP={BED_TEMP} MATERIAL={MATERIAL} SOAK=1 SIZE={computed_size} INITIAL_TOOL={TOOL} TOOLS_USED={TOOL} FLOW_MULTIPLIER_CALIBRATION EXTRUSION_WIDTH=0.471 END_PRINT FILTER_TIME=0 @@ -26,7 +34,7 @@ gcode: {% set computed_size = (center_x - 60)|string + '_' + (center_y - 60)|string + '_' + (center_x + 60)|string + '_' + (center_y + 60)|string %} # Call the standard START_PRINT with almost no soaking time and no chamber temp requirement (we want to go fast!) - START_PRINT EXTRUDER_TEMP={EXTRUDER_TEMP} BED_TEMP={BED_TEMP} MATERIAL={MATERIAL} SOAK=1 SIZE={computed_size} + START_PRINT EXTRUDER_TEMP={EXTRUDER_TEMP} BED_TEMP={BED_TEMP} MATERIAL={MATERIAL} SOAK=1 SIZE={computed_size} INITIAL_TOOL={TOOL} TOOLS_USED={TOOL} PRESSURE_ADVANCE_CALIBRATION END_PRINT FILTER_TIME=0 diff --git a/macros/hardware_functions/mmu.cfg b/macros/hardware_functions/mmu.cfg new file mode 100644 index 000000000..161db484f --- /dev/null +++ b/macros/hardware_functions/mmu.cfg @@ -0,0 +1,249 @@ +## Custom MMU Macros used in Klippain +## Automatically included when an MMU is defined in printer.cfg + +[gcode_macro _KLIPPAIN_MMU_INIT] +description: Internal macro to initialize the MMU during the START_PRINT sequence +gcode: + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + {% set mmu_force_homing_in_start_print = printer["gcode_macro _USER_VARIABLES"].mmu_force_homing_in_start_print %} + + {% set INITIAL_TOOL = printer["gcode_macro START_PRINT"].initial_tool %} + {% set CHECK_GATES = printer["gcode_macro START_PRINT"].check_gates %} + {% set TOOLS_USED = printer["gcode_macro START_PRINT"].tools_used %} + {% set SYNC_MMU_EXTRUDER = printer["gcode_macro START_PRINT"].sync_mmu_extruder %} + + {% if printer.mmu.enabled %} + # Manually changing the MMU state to start print (see https://github.com/Frix-x/klippain/blob/main/docs/mmu.md#early-check-errors-during-start_print) + {% if printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_START + {% endif %} + + # Park the toolhead to get on a safe place (without retracting the filament) + PARK E=0 + + # If the MMU is not in bypass mode + {% if printer.mmu.tool|int != -2 %} + # Home the MMU if necessary and pre select the initial tool + {% if mmu_force_homing_in_start_print or printer.mmu.is_homed == 0 %} + MMU_HOME TOOL={INITIAL_TOOL} FORCE_UNLOAD=1 + {% endif %} + + # If we need to check the gates (specified by the slicer or the Klippain variable) + {% if CHECK_GATES %} + {% if TOOLS_USED != "!referenced_tools!" %} + + # If we are in the case of a multi-filament print + {% if TOOLS_USED and printer.mmu.tool|string != TOOLS_USED %} + {% if verbose %} + RESPOND PREFIX='MMU info:' MSG=" You are planning a multi-filament print. The tool(s): {TOOLS_USED} will be checked to limit the risk of errors." + {% endif %} + + # First eject in case a bad tool is already loaded, then check the gates and select the initial tool + MMU_EJECT + MMU_CHECK_GATE TOOLS={TOOLS_USED} + MMU_SELECT TOOL={INITIAL_TOOL} + + # Else if the TOOL_USED parameter is not valid... We can still start the print but only check the initial tool + {% elif printer.mmu.tool|int != INITIAL_TOOL or (printer.mmu.tool|int == INITIAL_TOOL and printer.mmu.filament != "Loaded") %} + {% if verbose %} + {% if printer.mmu.tool|int != INITIAL_TOOL %} + RESPOND PREFIX='Config info:' MSG=" Only T{INITIAL_TOOL} will be checked! You should consider using TOOLS_USED=!referenced_tools! in the custom start gcode of your slicer" + {% elif printer.mmu.tool|int == INITIAL_TOOL and printer.mmu.filament != "Loaded" %} + RESPOND PREFIX='Config info:' MSG=" T{INITIAL_TOOL} is selected but the filament is not loaded. In order to avoid a possible error if the initial tool is marked as empty in HappyHare, it will be checked!" + {% endif %} + {% endif %} + + # First eject in case a bad tool is already loaded, then check the initial tool gate + MMU_EJECT + MMU_CHECK_GATE TOOLS={INITIAL_TOOL} + {% endif %} + + # Else if there was an error in the Moonraker gcode preprocessor (TOOL_USED is still equal to "!referenced_tools!") + {% else %} + {% if verbose %} + RESPOND PREFIX='MMU info:' MSG=" TOOLS_USED={TOOLS_USED} is likely not valid. Please check your slicer custom start gcode and verify that the HappyHare Moonraker gcode preprocessor is working! There will be no check on the gates and they will all be marked as available to avoid an error" + {% endif %} + + # Reset the state status (Available or Empty) for all the MMU gates to avoid an error + {% set gate_str = printer.mmu.ttg_map|join(',') %} + MMU_GATE_MAP GATES={gate_str} AVAILABLE=-1 + {% endif %} + + # Else if no check of the gates is wanted (specified by the slicer or the Klippain variable) + {% else %} + {% if verbose %} + RESPOND PREFIX='Config info:' MSG=" No gate check requested by the user. You should consider variable_mmu_check_gates_on_start_print: True in your Klippain variables.cfg or use the MMU_CHECK_GATES=1 parameter in your slicer custom start gcode" + {% endif %} + {% if printer.mmu.tool|int != INITIAL_TOOL %} + MMU_HOME FORCE_UNLOAD=1 TOOL={INITIAL_TOOL} + {% endif %} + {% endif %} + + # First instance of the MMU error check (if enabled...) to stop the START_PRINT sequence earlier + {% if printer['gcode_macro _USER_VARIABLES'].mmu_check_errors_on_start_print and printer.mmu.print_start_detection|int == 0 %} + _MMU_ERROR_CHECK1 + {% endif %} + + # Else if the MMU is in bypass mode, we just check for an error + {% else %} + # First instance of the MMU error check (if enabled...) while in bypass mode to stop the START_PRINT sequence earlier + {% if printer['gcode_macro _USER_VARIABLES'].mmu_check_errors_on_start_print and printer.mmu.print_start_detection|int == 0 %} + _MMU_ERROR_CHECK1 + {% endif %} + {% endif %} + + # Set the sync_to_extruder mode of HH if wanted by the user for the print (set from the slicer custom start gcode) + {% if printer.configfile.config.mmu.sync_to_extruder == 0 and printer.mmu.tool|int != -2 %} + {% if SYNC_MMU_EXTRUDER == 1 %} + {% if verbose %} + RESPOND MSG="MMU gear motor will be synchronized with the extruder during the print" + {% endif %} + MMU_TEST_CONFIG sync_to_extruder=1 + {% endif %} + + # Force disable the sync_to_extruder mode of HH if the MMU is set in bypass mode + {% elif (printer.configfile.config.mmu.sync_to_extruder == 1 or SYNC_MMU_EXTRUDER == 1) and printer.mmu.tool|int == -2 %} + {% if verbose %} + RESPOND MSG="MMU bypass mode is used so its gear motor cannot be synchronized with the extruder during the print" + {% endif %} + MMU_TEST_CONFIG sync_to_extruder=0 + {% endif %} + + # Preload the MMU gates if the filament is not already loaded and the MMU is set in normal mode + {% if printer.mmu.tool|int != -2 %} + {% if printer.mmu.filament != "Loaded" %} + {% if printer.mmu.tool|int != INITIAL_TOOL %} + MMU_SELECT TOOL={INITIAL_TOOL} + MMU_PRELOAD + {% endif %} + {% else %} + {% if printer.mmu.tool|int != INITIAL_TOOL %} + MMU_EJECT + MMU_SELECT TOOL={INITIAL_TOOL} + MMU_PRELOAD + {% endif %} + {% endif %} + {% endif %} + + # Manually reset the MMU state to the initial state (see https://github.com/Frix-x/klippain/blob/main/docs/mmu.md#early-check-errors-during-start_print) + {% if printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_END STATE=standby + {% endif %} + {% endif %} + + +[gcode_macro _KLIPPAIN_MMU_LOAD_INITIAL_TOOL] +description: Internal macro to load the initial filament during the START_PRINT sequence +gcode: + {% set INITIAL_TOOL = printer["gcode_macro START_PRINT"].initial_tool %} + + {% if printer.mmu.enabled %} + # Manually changing the MMU state to start print (see https://github.com/Frix-x/klippain/blob/main/docs/mmu.md#early-check-errors-during-start_print) + {% if printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_START + {% endif %} + + # If the MMU is not in bypass mode, we load the initial tool if not already loaded + {% if printer.mmu.tool|int != -2 %} + MMU_CHANGE_TOOL TOOL={INITIAL_TOOL} STANDALONE=1 + + # Else if in bypass mode, then manually load the filament (that was manually inserted) to the nozzle + {% else %} + MMU_LOAD + {% endif %} + + # Second instance of the MMU error check (if enabled...) to stop the START_PRINT sequence earlier + {% if printer['gcode_macro _USER_VARIABLES'].mmu_check_errors_on_start_print and printer.mmu.print_start_detection|int == 0 %} + _MMU_ERROR_CHECK2 + {% endif %} + # And manually reset the MMU state to the initial state (see https://github.com/Frix-x/klippain/blob/main/docs/mmu.md#early-check-errors-during-start_print) + {% if printer.mmu.print_start_detection|int == 0 %} + _MMU_PRINT_END STATE=standby + {% endif %} + {% endif %} + + +[gcode_macro _KLIPPAIN_MMU_SET_CLOGDETECTION] +description: Internal macro to automatically disable or re-enable MMU clog detection as needed +gcode: + {% set clog_detection = params.STATE|int %} + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + + {% if printer.mmu.enabled %} + {% if printer.mmu.clog_detection > 0 and printer.configfile.config.mmu.sync_to_extruder == 0 %} + {% if clog_detection == 0 %} + MMU_TEST_CONFIG enable_clog_detection={clog_detection} + {% if verbose %} + RESPOND MSG="MMU clog detection automatically disabled" + {% endif %} + {% elif clog_detection > 0 %} + MMU_TEST_CONFIG enable_clog_detection={clog_detection} + {% if verbose %} + RESPOND MSG="MMU clog detection automatically re-enabled" + {% endif %} + {% endif %} + {% endif %} + {% endif %} + + +# Custom macros to check for an error on the MMU and stop the START_PRINT sequence earlier +# (see https://github.com/Frix-x/klippain/blob/main/docs/mmu.md#early-check-errors-during-start_print) +[gcode_macro _MMU_ERROR_CHECK1] +description: Internal macro to check for an error on the MMU and stop the START_PRINT sequence earlier +gcode: + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + + {% if printer.mmu.print_state|string == "pause_locked" or printer.mmu.is_locked %} + {action_raise_error("MMU is locked! Please check your MMU and use the RESUME command to unlock it. Then restart the print")} + {% endif %} + + {% if verbose %} + {% if printer.mmu.tool|int == -1 %} + RESPOND PREFIX='MMU gate:' MSG=" no tool selected!" + {% elif printer.mmu.tool|int == -2 %} + RESPOND PREFIX='MMU gate:' MSG=" bypass mode selected" + {% elif printer.mmu.filament == "Loaded" %} + RESPOND PREFIX='MMU gate:' MSG=" T{printer.mmu.tool} already loaded" + {% else %} + RESPOND PREFIX='MMU tool:' MSG=" T{printer.mmu.tool} preloaded" + {% endif %} + {% endif %} + +[gcode_macro _MMU_ERROR_CHECK2] +description: Internal macro to check for an error on the MMU and stop the START_PRINT sequence earlier +gcode: + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + {% set INITIAL_TOOL = printer["gcode_macro START_PRINT"].initial_tool %} + + {% if printer.mmu.print_state|string == "pause_locked" or printer.mmu.is_locked %} + {action_raise_error("MMU is locked! Please check your MMU and use the RESUME command to unlock it. Then restart the print")} + {% elif printer.mmu.filament != "Loaded" %} + {action_raise_error("Filament is not loaded! Please check your MMU and then restart the print")} + {% elif printer.mmu.tool|int != -2 and printer.mmu.tool|int != INITIAL_TOOL %} + {action_raise_error("Initial tool ({INITIAL_TOOL}) and MMU tool ({printer.mmu.tool}) are different! Please check your MMU and then restart the print")} + {% endif %} + + {% if verbose %} + {% if printer.mmu.tool|int == -1 %} + RESPOND PREFIX='mmu gate:' MSG=" something get wrong, no active tool!" + {% elif printer.mmu.tool|int == -2 %} + RESPOND PREFIX='mmu gate:' MSG=" bypass mode selected and filament loaded" + {% else %} + RESPOND PREFIX='mmu tool:' MSG=" T{printer.mmu.tool} ready" + {% endif %} + {% endif %} + +# This is just a debug macro that just print a couple of variables related to the MMU and HappyHare +[gcode_macro _MMU_CHECK_STATE] +description: Display some MMU parameters to debug it +gcode: + RESPOND PREFIX= MSG=" Klippain with Happy_Hare_V2.x support in main branch" + RESPOND PREFIX= MSG=" mmu.print_state : {printer.mmu.print_state}" + RESPOND PREFIX= MSG=" mmu.is_locked : {printer.mmu.is_locked}" + RESPOND PREFIX= MSG=" mmu.tool : {printer.mmu.tool}" + RESPOND PREFIX= MSG=" mmu.print_start_detection : {printer.mmu.print_start_detection}" + RESPOND PREFIX= MSG=" mmu.clog_detection : {printer.mmu.clog_detection}" + RESPOND PREFIX= MSG=" mmu.filament : {printer.mmu.filament}" + RESPOND PREFIX= MSG=" mmu.filament_pos : {printer.mmu.filament_pos}" + RESPOND PREFIX= MSG=" mmu.selector_touch_enable : {printer.configfile.config.mmu.selector_touch_enable}" + RESPOND PREFIX= MSG=" mmu.sync_drive : {printer.mmu.sync_drive}" diff --git a/macros/hardware_functions/status_leds.cfg b/macros/hardware_functions/status_leds.cfg index 5642f91c0..0e170653c 100644 --- a/macros/hardware_functions/status_leds.cfg +++ b/macros/hardware_functions/status_leds.cfg @@ -2,7 +2,7 @@ # src : https://github.com/VoronDesign/Voron-Stealthburner/blob/main/Firmware/stealthburner_leds.cfg # Contributed by Voron discord users wile.e, Tetsunosuke, and etherwalker -# Heavily modified by Frix-x to be more adapted for the generic config goal +# Heavily modified by Frix-x to be more adapted for the generic config goal of Klippain # The following status macro is available: @@ -33,7 +33,7 @@ gcode: gcode: {% set leds_name = params.LEDS %} {% set color_name = params.COLOR %} - {% set color = printer["gcode_macro _USER_VARIABLES"].status_leds_colors[leds_name][color_name] %} + {% set color = printer["gcode_macro _LEDS_COLORS_DEFINITION"].colors[leds_name][color_name] %} {% set led = printer["gcode_macro _USER_VARIABLES"]["status_leds_" + leds_name + "_led_name"] %} {% set idx = printer["gcode_macro _USER_VARIABLES"]["status_leds_" + leds_name + "_idx"] %} {% set transmit = params.TRANSMIT|default(1) %} @@ -46,7 +46,7 @@ gcode: {% set leds_name = params.LEDS %} {% set color_name = params.COLOR %} {% set led = printer["gcode_macro _USER_VARIABLES"]["status_leds_" + leds_name + "_led_name"] %} - {% set color = printer["gcode_macro _USER_VARIABLES"].status_leds_colors[leds_name][color_name] %} + {% set color = printer["gcode_macro _LEDS_COLORS_DEFINITION"].colors[leds_name][color_name] %} {% set transmit = params.TRANSMIT|default(1) %} SET_LED LED={led} RED={color.r} GREEN={color.g} BLUE={color.b} WHITE={color.w} TRANSMIT={transmit} @@ -155,10 +155,16 @@ gcode: 'caselight': 'printing', 'minidisplay': 'on' }, - 'off': { - 'logo': 'off', - 'nozzle': 'off', - 'caselight': 'off', + 'printing': { + 'logo': 'printing', + 'nozzle': 'on', + 'caselight': 'printing', + 'minidisplay': 'on' + }, + 'done_printing': { + 'logo': 'done_printing', + 'nozzle': 'done_printing', + 'caselight': 'done_printing', 'minidisplay': 'off' }, 'on': { @@ -167,12 +173,18 @@ gcode: 'caselight': 'on', 'minidisplay': 'on' }, + 'off': { + 'logo': 'off', + 'nozzle': 'off', + 'caselight': 'off', + 'minidisplay': 'off' + }, 'error': { 'logo': 'error', 'nozzle': 'error', 'caselight': 'error', 'minidisplay': 'error' - } + } } %} {% if not (color in status_color) %} @@ -180,12 +192,21 @@ gcode: {% endif %} {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} - _SET_LEDS_BY_NAME LEDS="logo" COLOR={status_color[color].logo} TRANSMIT={logo_transmit} - _SET_LEDS_BY_NAME LEDS="nozzle" COLOR={status_color[color].nozzle} TRANSMIT=1 + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_logo_led_name == "status_leds"%} + _SET_LEDS_BY_NAME LEDS="logo" COLOR={status_color[color].logo} TRANSMIT={logo_transmit} + _SET_LEDS_BY_NAME LEDS="nozzle" COLOR={status_color[color].nozzle} TRANSMIT=1 + {% elif printer["gcode_macro _USER_VARIABLES"].status_leds_logo_led_name == "status_leds_effects"%} + SET_LED_EFFECT EFFECT={"sb_logo_" + status_color[color].logo} REPLACE=1 FADETIME=0.5 + SET_LED_EFFECT EFFECT={"sb_nozzle_" + status_color[color].nozzle} REPLACE=1 FADETIME=0.5 + {% endif %} {% endif %} - {% if printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_enabled %} - _SET_ALLLEDS_BY_NAME LEDS="caselight" COLOR={status_color[color].caselight} TRANSMIT=1 + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_enabled%} + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_led_name == "caselight"%} + _SET_ALLLEDS_BY_NAME LEDS="caselight" COLOR={status_color[color].caselight} TRANSMIT=1 + {% elif printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_led_name == "caselight_effects"%} + SET_LED_EFFECT EFFECT={"cl_" + status_color[color].caselight} REPLACE=1 FADETIME=0.5 + {% endif %} {% endif %} {% if printer["gcode_macro _USER_VARIABLES"].status_leds_minidisplay_enabled %} diff --git a/macros/helpers/filament_swap.cfg b/macros/helpers/filament_swap.cfg index 4c258ede2..2ee6ce78c 100644 --- a/macros/helpers/filament_swap.cfg +++ b/macros/helpers/filament_swap.cfg @@ -2,11 +2,12 @@ description: Do a PAUSE, park the toolhead over the purge bucket and unload the filament gcode: {% set TEMP = params.TEMP|default(printer["gcode_macro _USER_VARIABLES"].print_default_extruder_temp)|float %} + {% set DISTANCE = params.DISTANCE|default(105)|float %} SAVE_GCODE_STATE NAME=CHANGE_FILAMENT_state PAUSE _CONDITIONAL_MOVE_TO_PURGE_BUCKET Z_DROP=0 - UNLOAD_FILAMENT + UNLOAD_FILAMENT TEMP={TEMP} DISTANCE={DISTANCE} RESTORE_GCODE_STATE NAME=CHANGE_FILAMENT_state @@ -18,8 +19,8 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% set re_enable_filament_sensor = 0 %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} {% if filament_sensor_enabled %} {% if (printer['filament_motion_sensor runout_sensor'] is defined and printer['filament_motion_sensor runout_sensor'].enabled) or (printer['filament_switch_sensor runout_sensor'] is defined and printer['filament_switch_sensor runout_sensor'].enabled) %} @@ -31,15 +32,8 @@ gcode: {% endif %} {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - ERCF_TEST_CONFIG enable_clog_detection=0 - {% if verbose %} - RESPOND MSG="ERCF clog detection deactivated to unload filament" - {% endif %} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE=0 {% endif %} SAVE_GCODE_STATE NAME=UNLOAD_FILAMENT_state @@ -63,15 +57,8 @@ gcode: {% endif %} {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - ERCF_TEST_CONFIG enable_clog_detection={printer.ercf.clog_detection} - {% if verbose %} - RESPOND MSG="Filament unloaded, ERCF clog detection reactivated" - {% endif %} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE={printer.mmu.clog_detection} {% endif %} @@ -83,7 +70,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% set re_enable_filament_sensor = 0 %} {% if filament_sensor_enabled %} @@ -96,15 +83,8 @@ gcode: {% endif %} {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - ERCF_TEST_CONFIG enable_clog_detection=0 - {% if verbose %} - RESPOND MSG="ERCF clog detection deactivated to load filament" - {% endif %} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE=0 {% endif %} SAVE_GCODE_STATE NAME=LOAD_FILAMENT_state @@ -127,15 +107,8 @@ gcode: {% endif %} {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - ERCF_TEST_CONFIG enable_clog_detection={printer.ercf.clog_detection} - {% if verbose %} - RESPOND MSG="Filament loaded, ERCF clog detection reactivated" - {% endif %} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE={printer.mmu.clog_detection} {% endif %} @@ -146,7 +119,7 @@ gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% set re_enable_filament_sensor = 0 %} {% if filament_sensor_enabled %} @@ -159,15 +132,8 @@ gcode: {% endif %} {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - ERCF_TEST_CONFIG enable_clog_detection=0 - {% if verbose %} - RESPOND MSG="ERCF clog detection deactivated for filament tip shaping" - {% endif %} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE=0 {% endif %} SAVE_GCODE_STATE NAME=TIP_SHAPING_state @@ -191,7 +157,7 @@ gcode: # Flushing Klipper's buffer to ensure the tip shaping sequence is done before continuing M400 - + RESTORE_GCODE_STATE NAME=TIP_SHAPING_state {% if filament_sensor_enabled and re_enable_filament_sensor %} @@ -201,13 +167,6 @@ gcode: {% endif %} {% endif %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - ERCF_TEST_CONFIG enable_clog_detection={printer.ercf.clog_detection} - {% if verbose %} - RESPOND MSG="Filament tip shaping done, ERCF clog detection reactivated" - {% endif %} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE={printer.mmu.clog_detection} {% endif %} diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index dfb872384..f10bd3daf 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -13,7 +13,7 @@ gcode: {% set Sz = printer["gcode_macro _USER_VARIABLES"].z_drop_speed * 60 %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} - {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} {% set re_enable_filament_sensor = 0 %} @@ -55,15 +55,8 @@ gcode: # Finally we compute the speed to get the correct flowrate for the prime line {% set speed = (prime_line_flowrate / (line_height * line_width)) * 60 |float %} - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - {% if verbose %} - RESPOND MSG="ERCF clog detection deactivated for the prime line" - {% endif %} - ERCF_TEST_CONFIG enable_clog_detection=0 - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE=0 {% endif %} {% if filament_sensor_enabled %} @@ -107,15 +100,8 @@ gcode: # Flushing Klipper's buffer to ensure the primeline sequence is done before continuing M400 - {% if klippain_ercf_enabled %} - {% if printer.ercf.enabled %} - {% if printer.ercf.clog_detection > 0 %} - {% if verbose %} - RESPOND MSG="ERCF clog detection reactivated after the prime line" - {% endif %} - ERCF_TEST_CONFIG enable_clog_detection={printer.ercf.clog_detection} - {% endif %} - {% endif %} + {% if klippain_mmu_enabled %} + _KLIPPAIN_MMU_SET_CLOGDETECTION STATE={printer.mmu.clog_detection} {% endif %} {% if filament_sensor_enabled and re_enable_filament_sensor %} diff --git a/macros/helpers/spoolman.cfg b/macros/helpers/spoolman.cfg new file mode 100644 index 000000000..827d17bfb --- /dev/null +++ b/macros/helpers/spoolman.cfg @@ -0,0 +1,20 @@ +[gcode_macro SET_ACTIVE_SPOOL] +description: Set Spoolman active spool +gcode: + {% if params.SPOOL_ID %} + {% set spool_id = params.SPOOL_ID|int %} + {action_call_remote_method( + "spoolman_set_active_spool", + spool_id=spool_id + )} + {% else %} + {action_respond_info("Parameter 'SPOOL_ID' is required")} + {% endif %} + +[gcode_macro CLEAR_ACTIVE_SPOOL] +description: Clear Spoolman active spool +gcode: + {action_call_remote_method( + "spoolman_set_active_spool", + spool_id=None + )} diff --git a/macros/miscs/startup.cfg b/macros/miscs/startup.cfg index 2ffd2719d..ab55531a5 100644 --- a/macros/miscs/startup.cfg +++ b/macros/miscs/startup.cfg @@ -30,21 +30,37 @@ gcode: _INIT_TMC2240 {% endif %} - # If ERCF is included in Klippain, we also check that HH is installed + # If an MMU/ERCF is included in Klippain, we also check that the correct HH version is installed + {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} {% set klippain_ercf_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_ercf_enabled %} - {% if klippain_ercf_enabled %} - _INIT_CHECK_ERCF + {% if klippain_mmu_enabled or klippain_ercf_enabled %} + _INIT_CHECK_MMU {% endif %} # User custom startup process. Define them in your overrides.cfg if needed :) _INIT_USERCUSTOM - RESPOND MSG="Klippain started and ready !" + {% if klippain_mmu_enabled %} + RESPOND MSG="Klippain with MMU support started and ready!" + {% else %} + RESPOND MSG="Klippain started and ready!" + {% endif %} + + +[gcode_macro _INIT_LEDS] +gcode: + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} + {% if printer["gcode_macro _USER_VARIABLES"].caselight_on_at_startup|default(False) %} + STATUS_LEDS COLOR="READY" + {% else %} + STATUS_LEDS COLOR="OFF" + {% endif %} + {% endif %} [gcode_macro _INIT_TMC2240] gcode: - # This macro can be copied over to overrides.cfg and will allow the values to defined automatically on klipper startup + # This macro can be copied over to overrides.cfg and will allow the values to be defined automatically on klipper startup # TMC2240 extruder initialization macro to set the driver registers based on Esoterical's github page. These settings are not # universal and not necessary for all SB2240 owners. Adapt them to your needs! # https://github.com/Esoterical/voron_canbus/blob/main/toolhead_flashing/common_hardware/BigTreeTech%20SB2209%20and%20SB2240/SB2240%20Stepper%20Configuration%20and%20Undervoltage.md @@ -125,12 +141,22 @@ gcode: {action_respond_info(parameters.output)} -[gcode_macro _INIT_CHECK_ERCF] +[gcode_macro _INIT_CHECK_MMU] gcode: - {% if printer.ercf is not defined %} - { action_raise_error("ERCF is enabled in Klippain, but Happy Hare, the supported ERCF backend software is not detected. Please install it now from https://github.com/moggieuk/ERCF-Software-V3 !") } + {% if printer.mmu is not defined %} + {% if printer.ercf is not defined %} + { action_raise_error("MMU support is enabled in Klippain, but HappyHare, the supported MMU/ERCF backend software is not detected. See the corresponding documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md") } + {% else %} + { action_raise_error("ERCF support is enabled in Klippain, but the old version of version of HappyHare (ie. ERCF-Software-V3) is installed. Please uninstall it and install the latest HappyHare instead. See the corresponding documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md") } + {% endif %} + {% elif printer['gcode_macro _USER_VARIABLES'].mmu_force_homing_in_start_print is not defined or printer['gcode_macro _USER_VARIABLES'].mmu_unload_on_cancel_print is not defined or printer['gcode_macro _USER_VARIABLES'].mmu_unload_on_end_print is not defined or printer['gcode_macro _USER_VARIABLES'].mmu_check_gates_on_start_print is not defined or printer['gcode_macro _USER_VARIABLES'].mmu_check_errors_on_start_print is not defined %} + { action_raise_error("MMU support is enabled in Klippain, but some variables are missing from your variables.cfg. Please update your template or refer to the corresponding documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md") } + {% elif printer["gcode_macro _USER_VARIABLES"].mmu_check_errors_on_start_print and printer.mmu.print_start_detection|int == 1 %} + RESPOND MSG="The HappyHare function to automatically detect the start and end of a print has been automatically disabled to allow early detection of an error during the Klippain START_PRINT sequence. This allow a more efficient debugging of the MMU. Refer to the Klippain MMU documentation" + MMU_TEST_CONFIG print_start_detection=0 # Override this value to disable the HappyHare auto detection of start and end of print in order to call _MMU_PRINT_START and _MMU_PRINT_END manually {% endif %} + [gcode_macro _INIT_USERCUSTOM] gcode: # ---- CUSTOM Macro section diff --git a/moonraker/base.conf b/moonraker/base.conf index b6140e15d..e6ac5a6bb 100644 --- a/moonraker/base.conf +++ b/moonraker/base.conf @@ -43,12 +43,3 @@ origin: https://github.com/Frix-x/klippain.git primary_branch: main managed_services: moonraker klipper install_script: install.sh - -[update_manager Klippain-ShakeTune] -type: git_repo -path: ~/klippain_shaketune -channel: beta -origin: https://github.com/Frix-x/klippain-shaketune.git -primary_branch: main -managed_services: klipper -install_script: install.sh diff --git a/moonraker/led_effect.conf b/moonraker/led_effect.conf new file mode 100644 index 000000000..8868bb4a3 --- /dev/null +++ b/moonraker/led_effect.conf @@ -0,0 +1,5 @@ +[update_manager led_effect] +type: git_repo +path: ~/klipper-led_effect +origin: https://github.com/julianschill/klipper-led_effect.git +is_system_service: False diff --git a/moonraker/spoolman.conf b/moonraker/spoolman.conf new file mode 100644 index 000000000..f2e90e9a6 --- /dev/null +++ b/moonraker/spoolman.conf @@ -0,0 +1,6 @@ +[spoolman] +server: http://localhost:7912 +# URL to the Spoolman instance. This parameter must be provided. +sync_rate: 5 +# The interval, in seconds, between sync requests with the +# Spoolman server. The default is 5. diff --git a/moonraker/tmc_autotune.conf b/moonraker/tmc_autotune.conf new file mode 100644 index 000000000..c26fe334d --- /dev/null +++ b/moonraker/tmc_autotune.conf @@ -0,0 +1,8 @@ +[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 diff --git a/user_templates/mcu.cfg b/user_templates/mcu.cfg index 94aa22eb9..c69d4b8c4 100644 --- a/user_templates/mcu.cfg +++ b/user_templates/mcu.cfg @@ -44,4 +44,3 @@ # [include config/hardware/extruder/TMC/TMC2209.cfg] # [include config/hardware/extruder/TMC/TMC2240.cfg] # ---------------------------------------------------------------------------------------- - diff --git a/user_templates/mcu_defaults/ercf/BTT_MMB_CAN_v1.0.cfg b/user_templates/mcu_defaults/ercf/BTT_MMB_CAN_v1.0.cfg deleted file mode 100644 index 5e665890b..000000000 --- a/user_templates/mcu_defaults/ercf/BTT_MMB_CAN_v1.0.cfg +++ /dev/null @@ -1,31 +0,0 @@ - -#---------------------------------------------# -#### BTT MMB CAN 1.0 MCU definition ########### -#---------------------------------------------# - -[mcu ercf] -##-------------------------------------------------------------------- -serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path -# canbus_uuid: change-me-to-the-correct-canbus-id -##-------------------------------------------------------------------- - -# If you want to override the wiring of the BTT MMB CAN, keep in mind that this -# board is defined using the "ercf" name. So you should use "pin: ercf:PIN_NAME" -# in your own overrides.cfg files. - -[include config/mcu_definitions/ercf/BTT_MMB_CAN_v1.0.cfg] # Do not remove this line -[board_pins mcu_ercf] -mcu: ercf -aliases: - GEAR_STEP=MCU_MOTOR1_STEP , GEAR_DIR=MCU_MOTOR1_DIR , GEAR_ENABLE=MCU_MOTOR1_EN , GEAR_TMCUART=MCU_MOTOR1_CS , - SELECTOR_STEP=MCU_MOTOR2_STEP , SELECTOR_DIR=MCU_MOTOR2_DIR , SELECTOR_ENABLE=MCU_MOTOR2_EN , SELECTOR_TMCUART=MCU_MOTOR2_CS , - SELECTOR_DIAG=MCU_STP2 , - - GEAR_STOP=MCU_ENDSTOP , SELECTOR_STOP=MCU_ENDSTOP , - - TOOLHEAD_SENSOR=MCU_STP1 , # double used with MOTOR1_DIAG, so might collide - ERCF_SERVO=MCU_MOT , - ERCF_ENCODER=MCU_SENSOR , - ERCF_NEOPIXEL=MCU_RGB , - - diff --git a/user_templates/mcu_defaults/ercf/Fysetc_ERCF_ERB.cfg b/user_templates/mcu_defaults/ercf/Fysetc_ERCF_ERB.cfg deleted file mode 100644 index 2489a0207..000000000 --- a/user_templates/mcu_defaults/ercf/Fysetc_ERCF_ERB.cfg +++ /dev/null @@ -1,37 +0,0 @@ - -#---------------------------------------------# -#### Fysetc ERCF ERB MCU definition ########### -#---------------------------------------------# - -[mcu ercf] -##-------------------------------------------------------------------- -serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path -##-------------------------------------------------------------------- - -# If you want to override the wiring of the Fystec ERCF ERB, keep in mind that this -# board is defined using the "ercf" name. So you should use "pin: ercf:PIN_NAME" -# in your own overrides.cfg files. - -[include config/mcu_definitions/ercf/Fysetc_ERCF_ERB.cfg] # Do not remove this line -[board_pins mcu_ercf] -mcu: ercf -aliases: - GEAR_STEP=MCU_GEAR_MOTOR_STEP , GEAR_DIR=MCU_GEAR_MOTOR_DIR , GEAR_ENABLE=MCU_GEAR_MOTOR_EN , GEAR_TMCUART=MCU_GEAR_MOTOR_UART , - SELECTOR_STEP=MCU_SELECTOR_MOTOR_STEP , SELECTOR_DIR=MCU_SELECTOR_MOTOR_DIR , SELECTOR_ENABLE=MCU_SELECTOR_MOTOR_EN , SELECTOR_TMCUART=MCU_SELECTOR_MOTOR_UART , - SELECTOR_DIAG=MCU_SELECTOR_MOTOR_DIAG , - - GEAR_STOP=MCU_ENDSTOP , SELECTOR_STOP=MCU_ENDSTOP , - - TOOLHEAD_SENSOR=MCU_HALL_SENSOR , - ERCF_SERVO=MCU_SERVO , - ERCF_ENCODER=MCU_ENCODER , - ERCF_NEOPIXEL=MCU_RGB , - - EXTRA_PINS1=MCU_UART0_TX , EXTRA_PINS2=MCU_UART0_RX , - EXTRA_PINS3=MCU_SPI0_SCK , EXTRA_PINS4=MCU_SPI0_MISO , - EXTRA_PINS5=MCU_SPI0_MOSI , EXTRA_PINS6=MCU_SPI0_CS , - EXTRA_PINS7=MCU_I2C1_SDA , EXTRA_PINS8=MCU_I2C1_SCL , - EXTRA_PINS9=MCU_ADC0 , EXTRA_PINS10=MCU_ADC1 , - EXTRA_PINS11=MCU_ADC2 , EXTRA_PINS12=MCU_ADC3 , - EXTRA_PINS13= , EXTRA_PINS14=<5V> , - diff --git a/user_templates/mcu_defaults/ercf/Mellow_fly_ERCF.cfg b/user_templates/mcu_defaults/ercf/Mellow_fly_ERCF.cfg deleted file mode 100644 index 7a33e9ef2..000000000 --- a/user_templates/mcu_defaults/ercf/Mellow_fly_ERCF.cfg +++ /dev/null @@ -1,38 +0,0 @@ - -#---------------------------------------------# -#### Mellow Fly ERCF MCU definition ########### -#---------------------------------------------# - -[mcu ercf] -##-------------------------------------------------------------------- -serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path -##-------------------------------------------------------------------- - -# If you want to override the wiring of the Mellow Fly ERCF board, keep in mind that this -# board is defined using the "ercf" name. So you should use "pin: ercf:PIN_NAME" -# in your own overrides.cfg files. - -[include config/mcu_definitions/ercf/Mellow_fly_ERCF.cfg] # Do not remove this line -[board_pins mcu_ercf] -mcu: ercf -aliases: - GEAR_STEP=MCU_GEAR_STEP , GEAR_DIR=MCU_GEAR_DIR , GEAR_ENABLE=MCU_GEAR_EN , GEAR_TMCUART=MCU_GEAR_UART , - SELECTOR_STEP=MCU_SELECTOR_STEP , SELECTOR_DIR=MCU_SELECTOR_DIR , SELECTOR_ENABLE=MCU_SELECTOR_EN , SELECTOR_TMCUART=MCU_SELECTOR_UART , - SELECTOR_DIAG=MCU_SELECTOR_DIAG , - - GEAR_STOP=MCU_ENDSTOP , SELECTOR_STOP=MCU_ENDSTOP , - - SPI_SCLK=MCU_SCK , SPI_MOSI=MCU_MOSI , SPI_MISO=MCU_MISO , - - TOOLHEAD_SENSOR=MCU_EXTRA , - ERCF_SERVO=MCU_SERVO , - ERCF_ENCODER=MCU_ENCODER , - - EXTRA_PINS1= , EXTRA_PINS2= , - EXTRA_PINS3=<3.3V> , EXTRA_PINS4=<3.3V> , - EXTRA_PINS5=MCU_P26 , EXTRA_PINS6=MCU_P10 , - EXTRA_PINS7=MCU_P27 , EXTRA_PINS8=MCU_P11 , - EXTRA_PINS9=MCU_P28 , EXTRA_PINS10=MCU_P12 , - EXTRA_PINS11=MCU_P29 , EXTRA_PINS12=MCU_P24 , - EXTRA_PINS13=MCU_P25 , EXTRA_PINS14=MCU_P13 , - diff --git a/user_templates/mcu_defaults/ercf/Tircown_ERCF_easy_brd.cfg b/user_templates/mcu_defaults/ercf/Tircown_ERCF_easy_brd.cfg deleted file mode 100644 index 843d925ee..000000000 --- a/user_templates/mcu_defaults/ercf/Tircown_ERCF_easy_brd.cfg +++ /dev/null @@ -1,28 +0,0 @@ - -#--------------------------------------------------# -#### Tircown ERCF easybrd MCU definition ########### -#--------------------------------------------------# - -[mcu ercf] -##-------------------------------------------------------------------- -serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path -##-------------------------------------------------------------------- - -# If you want to override the wiring of the ERCF easy brd, keep in mind that this -# board is defined using the "ercf" name. So you should use "pin: ercf:PIN_NAME" -# in your own overrides.cfg files. - -[include config/mcu_definitions/ercf/Tircown_ERCF_easy_brd.cfg] # Do not remove this line -[board_pins mcu_ercf] -mcu: ercf -aliases: - GEAR_STEP=MCU_GEAR_STEP , GEAR_DIR=MCU_GEAR_DIR , GEAR_ENABLE=MCU_GEAR_ENABLE , GEAR_TMCUART=MCU_TMCUART , - SELECTOR_STEP=MCU_SELECTOR_STEP , SELECTOR_DIR=MCU_SELECTOR_DIR , SELECTOR_ENABLE=MCU_SELECTOR_ENABLE , SELECTOR_TMCUART=MCU_TMCUART , - SELECTOR_DIAG=MCU_SELECTOR_DIAG , - - GEAR_STOP=MCU_GEAR_STOP , SELECTOR_STOP=MCU_SELECTOR_STOP , - - ERCF_SERVO=MCU_SERVO , - - ERCF_ENCODER=MCU_ENCODER , - diff --git a/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg b/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg index 5386782fd..8f5851bfc 100644 --- a/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg +++ b/user_templates/mcu_defaults/main/BTT_Manta_M8P_v2.0.cfg @@ -51,3 +51,4 @@ aliases: LIGHT_NEOPIXEL=MCU_M5_STOP , SERVO_PIN=MCU_PROBE1 , + diff --git a/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v2.cfg b/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v2.cfg index 19c2844c1..2ca40ae42 100644 --- a/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v2.cfg +++ b/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v2.cfg @@ -48,7 +48,7 @@ uart_pin: TMCUART tx_pin: TMCTX uart_address: 1 -# comment this section if you are using a toolhead with own mcu +# Comment this section if you are using a toolhead with its own MCU [tmc2209 extruder] uart_pin: TMCUART tx_pin: TMCTX diff --git a/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v3.cfg b/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v3.cfg index f03eed60f..39ca708cf 100644 --- a/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v3.cfg +++ b/user_templates/mcu_defaults/main/BTT_SKR_Mini_E3_v3.cfg @@ -48,7 +48,7 @@ uart_pin: TMCUART tx_pin: TMCTX uart_address: 1 -# comment this section if you are using a toolhead with own mcu +# Comment this section if you are using a toolhead with its own MCU [tmc2209 extruder] uart_pin: TMCUART tx_pin: TMCTX diff --git a/user_templates/mcu_defaults/main/BTT_SKR_Pico_v1.0.cfg b/user_templates/mcu_defaults/main/BTT_SKR_Pico_v1.0.cfg index ceeaba930..684cf6e1f 100644 --- a/user_templates/mcu_defaults/main/BTT_SKR_Pico_v1.0.cfg +++ b/user_templates/mcu_defaults/main/BTT_SKR_Pico_v1.0.cfg @@ -46,7 +46,7 @@ uart_pin: TMCUART tx_pin: TMCTX uart_address: 1 -# comment this section if you are using a toolhead with own mcu OR if you use an MMU with Happy_Hare V2 +# Comment this section if you are using a toolhead with its own MCU [tmc2209 extruder] uart_pin: TMCUART tx_pin: TMCTX diff --git a/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg b/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg new file mode 100644 index 000000000..3fa28618d --- /dev/null +++ b/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg @@ -0,0 +1,31 @@ +#----------------------------------------# +#### BTT SKR Pro v1.2 definition ######## +#----------------------------------------# + +[mcu] +##------------------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +##------------------------------------------------------------------------------- + +[include config/mcu_definitions/main/BTT_SKR_Pro_V1.2.cfg] # Do not remove this line +[board_pins xyze_SKR_mcu] +mcu: mcu +aliases: + X_STEP=MCU_XM_STEP , X_DIR=MCU_XM_DIR , X_ENABLE=MCU_XM_ENABLE , X_TMCUART=MCU_XM_TMCUART , + Y_STEP=MCU_YM_STEP , Y_DIR=MCU_YM_DIR , Y_ENABLE=MCU_YM_ENABLE , Y_TMCUART=MCU_YM_TMCUART , + Z_STEP=MCU_ZM_STEP , Z_DIR=MCU_ZM_DIR , Z_ENABLE=MCU_ZM_ENABLE , Z_TMCUART=MCU_ZM_TMCUART , + + E_STEP=MCU_E0M_STEP , E_DIR=MCU_E0M_DIR , E_ENABLE=MCU_E0M_ENABLE , E_TMCUART=MCU_E0M_TMCUART , + + TOOLHEAD_SENSOR=MCU_E0STOP , SERVO_PIN=MCU_PROBE , + + X_STOP=MCU_XSTOP , Y_STOP=MCU_YSTOP , Z_STOP=MCU_E1STOP , PROBE_INPUT=MCU_ZSTOP , + + E_HEATER=MCU_HEAT0 , E_TEMPERATURE=MCU_T0 , + BED_HEATER=MCU_BED , BED_TEMPERATURE=MCU_T1 , + + PART_FAN=MCU_FAN1 , E_FAN=MCU_FAN0 , + + LIGHT_NEOPIXEL=MCU_SERVOS , + STATUS_NEOPIXEL=MCU_IO2 + diff --git a/user_templates/mcu_defaults/main/Double_BTT_SKR_v1.4.cfg b/user_templates/mcu_defaults/main/Double_BTT_SKR_v1.4.cfg index 2c2f4ed0c..0c7c97bd3 100644 --- a/user_templates/mcu_defaults/main/Double_BTT_SKR_v1.4.cfg +++ b/user_templates/mcu_defaults/main/Double_BTT_SKR_v1.4.cfg @@ -26,15 +26,15 @@ aliases: E_STEP=MCU_E0M_STEP , E_DIR=MCU_E0M_DIR , E_ENABLE=MCU_E0M_ENABLE , E_TMCUART=MCU_E0M_UART , - GEAR_STEP=MCU_ZM_STEP , GEAR_DIR=MCU_ZM_DIR , GEAR_ENABLE=MCU_ZM_ENABLE , GEAR_TMCUART=MCU_ZM_UART , - SELECTOR_STEP=MCU_E1M_STEP , SELECTOR_DIR=MCU_E1M_DIR , SELECTOR_ENABLE=MCU_E1M_ENABLE , SELECTOR_TMCUART=MCU_E1M_UART , - SELECTOR_DIAG=MCU_ZSTOP , + MMU_GEAR_STEP=MCU_ZM_STEP , MMU_GEAR_DIR=MCU_ZM_DIR , MMU_GEAR_ENABLE=MCU_ZM_ENABLE , MMU_GEAR_UART=MCU_ZM_UART , + SELECTOR_STEP=MCU_E1M_STEP , MMU_SEL_DIR=MCU_E1M_DIR , MMU_SEL_ENABLE=MCU_E1M_ENABLE , MMU_SEL_UART=MCU_E1M_UART , + MMU_SEL_DIAG=MCU_ZSTOP , - GEAR_STOP=MCU_E1DET , SELECTOR_STOP=MCU_E1DET , + MMU_GEAR_ENDSTOP=MCU_E1DET , MMU_SEL_ENDSTOP=MCU_E1DET , - ERCF_SERVO=MCU_E0DET , - ERCF_ENCODER=MCU_PWRDET , - TOOLHEAD_SENSOR=MCU_ZSTOP , + MMU_SERVO=MCU_E0DET , + MMU_ENCODER=MCU_PWRDET , + TOOLHEAD_SENSORR=MCU_ZSTOP , X_STOP=MCU_XSTOP , Y_STOP=MCU_YSTOP , diff --git a/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg b/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg index 3af3f85d4..8e5e621ad 100644 --- a/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg +++ b/user_templates/mcu_defaults/main/Fysetc_Catalyst_v1.x.cfg @@ -34,4 +34,4 @@ aliases: CONTROLLER_FAN=MCU_FAN2 , LIGHT_NEOPIXEL=MCU_NEOPIXEL , - \ No newline at end of file + diff --git a/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg b/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg index 896290525..3ed3e9fe5 100644 --- a/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg +++ b/user_templates/mcu_defaults/main/Fysetc_S6_v2.x.cfg @@ -47,3 +47,4 @@ aliases: LIGHT_OUTPUT=MCU_E1_OUT , #LIGHT_NEOPIXEL= , # You can use MCU_X_MAX if you bridge the pads to have 5V on this pin STATUS_NEOPIXEL=MCU_RGB_B , + diff --git a/user_templates/mcu_defaults/main/Fysetc_Spider_v1.x.cfg b/user_templates/mcu_defaults/main/Fysetc_Spider_v1.x.cfg index 84d632764..4b974fd28 100644 --- a/user_templates/mcu_defaults/main/Fysetc_Spider_v1.x.cfg +++ b/user_templates/mcu_defaults/main/Fysetc_Spider_v1.x.cfg @@ -33,6 +33,7 @@ aliases: X_STOP=MCU_X_MAX , Y_STOP=MCU_Y_MAX , Z_STOP=MCU_Z_MIN , PROBE_INPUT=MCU_Z_MAX , RUNOUT_SENSOR=MCU_Y_MIN , # If using sensorless homing: you will need to move the runout sensor on another pin + SERVO_PIN=MCU_X_MIN , # If using sensorless homing: you will need to move the servo on another pin E_HEATER=MCU_E0_OUT , E_TEMPERATURE=MCU_TE0 , BED_HEATER=MCU_BED_OUT , BED_TEMPERATURE=MCU_TB , diff --git a/user_templates/mcu_defaults/main/Fysetc_Spider_v2.x.cfg b/user_templates/mcu_defaults/main/Fysetc_Spider_v2.x.cfg index 2c5e4a7e6..bf61860f7 100644 --- a/user_templates/mcu_defaults/main/Fysetc_Spider_v2.x.cfg +++ b/user_templates/mcu_defaults/main/Fysetc_Spider_v2.x.cfg @@ -33,6 +33,7 @@ aliases: X_STOP=MCU_X_MAX , Y_STOP=MCU_Y_MAX , Z_STOP=MCU_Z_MIN , PROBE_INPUT=MCU_Z_MAX , RUNOUT_SENSOR=MCU_Y_MIN , # If using sensorless homing: you will need to move the runout sensor on another pin + SERVO_PIN=MCU_X_MIN , # If using sensorless homing: you will need to move the servo on another pin E_HEATER=MCU_E0_OUT , E_TEMPERATURE=MCU_TE0 , BED_HEATER=MCU_BED_OUT , BED_TEMPERATURE=MCU_TB , diff --git a/user_templates/mcu_defaults/main/LDO_Leviathan_v1.2.cfg b/user_templates/mcu_defaults/main/LDO_Leviathan_v1.2.cfg index f5d5f6c58..62ddb37b2 100644 --- a/user_templates/mcu_defaults/main/LDO_Leviathan_v1.2.cfg +++ b/user_templates/mcu_defaults/main/LDO_Leviathan_v1.2.cfg @@ -45,3 +45,4 @@ aliases: LIGHT_OUTPUT=MCU_LED , STATUS_NEOPIXEL=MCU_NEOPIXEL, + diff --git a/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg b/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg index f75465e9a..40b1f8f95 100644 --- a/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg +++ b/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg @@ -51,3 +51,4 @@ aliases: STATUS_NEOPIXEL= , SERVO_PIN= , + diff --git a/user_templates/mcu_defaults/mmu/BTT_MMB_CAN_v1.0.cfg b/user_templates/mcu_defaults/mmu/BTT_MMB_CAN_v1.0.cfg new file mode 100644 index 000000000..12a00f67b --- /dev/null +++ b/user_templates/mcu_defaults/mmu/BTT_MMB_CAN_v1.0.cfg @@ -0,0 +1,53 @@ + +#-----------------------------------------------# +#### BTT MMB CAN board MCU definition ########### +#-----------------------------------------------# + +[mcu mmu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +# If you want to override the wiring of the BTT MMB CAN board, keep in mind that this +# board is defined using the "mmu" name. So you should use "pin: mmu:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg] # Do not remove this line +[board_pins mmu_mcu] +mcu: mmu +aliases: + MMU_GEAR_STEP=MCU_M1_STEP , MMU_GEAR_DIR=MCU_M1_DIR , MMU_GEAR_ENABLE=MCU_M1_EN , MMU_GEAR_UART=MCU_M1_UART , + MMU_SEL_STEP=MCU_M2_STEP , MMU_SEL_DIR=MCU_M2_DIR , MMU_SEL_ENABLE=MCU_M2_EN , MMU_SEL_UART=MCU_M2_UART , + + MMU_GEAR_DIAG=MCU_STP1 , # Shared with MCU_STP1 + MMU_SEL_DIAG=MCU_STP2 , # Shared with MCU_STP2 + + MMU_SEL_ENDSTOP=MCU_STP11 , + + MMU_SERVO=MCU_MOT , + MMU_ENCODER=MCU_SENSOR , + MMU_NEOPIXEL=MCU_RGB , + # MMU_GATE_SENSOR=MCU_STP1 , # (if not GEAR DIAG!) + + MMU_PRE_GATE_0=MCU_STP3 , + MMU_PRE_GATE_1=MCU_STP4 , + MMU_PRE_GATE_2=MCU_STP5 , + MMU_PRE_GATE_3=MCU_STP6 , + MMU_PRE_GATE_4=MCU_STP7 , + MMU_PRE_GATE_5=MCU_STP8 , + MMU_PRE_GATE_6=MCU_STP9 , + MMU_PRE_GATE_7=MCU_STP10 , + # MMU_PRE_GATE_8="" , + # MMU_PRE_GATE_9="" , + # MMU_PRE_GATE_10="" , + # MMU_PRE_GATE_11="" , + + SPI_SCLK=MCU_SCK , SPI_MOSI=MCU_MOSI , SPI_MISO=MCU_MISO , + + ## I2C header + I2C_SDA=MCU_I2C_SDA , I2C_SCL=MCU_I2C_SCL , I2C_GND= , I2C_5V=<5V> , + + ## SWD header + SWD_Reset= , SWD_PA14=MCU_SWD_PA14 , SWD_GND= , SWD_PA13=MCU_SWD_PA13 , SWD_3.3V=<3.3V> , + diff --git a/user_templates/mcu_defaults/mmu/BTT_SKR_Pico_v1.0.cfg b/user_templates/mcu_defaults/mmu/BTT_SKR_Pico_v1.0.cfg new file mode 100644 index 000000000..a77860f0d --- /dev/null +++ b/user_templates/mcu_defaults/mmu/BTT_SKR_Pico_v1.0.cfg @@ -0,0 +1,27 @@ + +#----------------------------------------# +#### BTT SKR Pico v1.0 mmu definition ######## +#----------------------------------------# + +[include config/mcu_definitions/mmu/BTT_SKR_Pico_v1.0.cfg] # Do not remove this line +[board_pins mmu_mcu] +mcu: mmu +aliases: + MMU_GEAR_STEP=MCU_Y_STEP , MMU_GEAR_DIR=MCU_Y_DIR , MMU_GEAR_ENABLE=MCU_Y_EN , MMU_GEAR_UART=MCU_TMCUART , + MMU_SEL_STEP=MCU_X_STEP , MMU_SEL_DIR=MCU_X_DIR , MMU_SEL_ENABLE=MCU_X_EN , MMU_SEL_UART=MCU_TMCUART , + + MMU_GEAR_ENDSTOP=MCU_Z-STOP , MMU_SEL_ENDSTOP=MCU_Y-STOP , + + MMU_SERVO=MCU_SERVOS , + MMU_ENCODER=MCU_X-STOP , + MMU_NEOPIXEL=MCU_RGB , + MMU_GATE_SENSOR=MCU_E0-STOP , + + EXTRA_PINS1=MCU_UART0_TX , EXTRA_PINS2=MCU_UART0_RX , + EXTRA_PINS3=MCU_SPI0_SCK , EXTRA_PINS4=MCU_SPI0_MISO , + EXTRA_PINS5=MCU_SPI0_MOSI , EXTRA_PINS6=MCU_SPI0_CS , + EXTRA_PINS7=MCU_I2C1_SDA , EXTRA_PINS8=MCU_I2C1_SCL , + EXTRA_PINS9=MCU_ADC0 , EXTRA_PINS10=MCU_ADC1 , + EXTRA_PINS11=MCU_ADC2 , EXTRA_PINS12=MCU_ADC3 , + EXTRA_PINS13= , EXTRA_PINS14=<5V> , + diff --git a/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg b/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg new file mode 100644 index 000000000..e9465512c --- /dev/null +++ b/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg @@ -0,0 +1,37 @@ + +#---------------------------------------------# +#### Mellow Fly ERCF MCU definition ########### +#---------------------------------------------# + +[mcu mmu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +# If you want to override the wiring of the Mellow Fly ERCF board, keep in mind that this +# board is defined using the "mmu" name. So you should use "pin: mmu:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/mmu/Mellow_fly_ERCF.cfg] # Do not remove this line +[board_pins mmu_mcu] +mcu: mmu +aliases: + MMU_GEAR_STEP=MCU_GEAR_STEP , MMU_GEAR_DIR=MCU_GEAR_DIR , MMU_GEAR_ENABLE=MCU_GEAR_EN , MMU_GEAR_UART=MCU_GEAR_UART , + MMU_GEAR_DIAG=MCU_GEAR_DIAG , + MMU_SEL_STEP=MCU_SELECTOR_STEP , MMU_SEL_DIR=MCU_SELECTOR_DIR , MMU_SEL_ENABLE=MCU_SELECTOR_EN , MMU_SEL_UART=MCU_SELECTOR_UART , + MMU_SEL_DIAG=MCU_SELECTOR_DIAG , + + MMU_SEL_ENDSTOP=MCU_ENDSTOP , + MMU_SERVO=MCU_SERVO , + MMU_ENCODER=MCU_ENCODER , + MMU_GATE_SENSOR=MCU_EXTRA , + + SPI_SCLK=MCU_SCK , SPI_MOSI=MCU_MOSI , SPI_MISO=MCU_MISO , + + MMU_PRE_GATE_0=MCU_IO26 , MMU_PRE_GATE_1=MCU_IO10 , + MMU_PRE_GATE_2=MCU_IO27 , MMU_PRE_GATE_3=MCU_IO11 , + MMU_PRE_GATE_4=MCU_IO28 , MMU_PRE_GATE_5=MCU_IO12 , + MMU_PRE_GATE_6=MCU_IO29 , MMU_PRE_GATE_7=MCU_IO24 , + MMU_PRE_GATE_8=MCU_IO25 , MMU_PRE_GATE_9=MCU_IO13 , + diff --git a/user_templates/mcu_defaults/mmu/Mellow_fly_ERCF.cfg b/user_templates/mcu_defaults/mmu/Mellow_fly_ERCF.cfg new file mode 100644 index 000000000..172b7c06f --- /dev/null +++ b/user_templates/mcu_defaults/mmu/Mellow_fly_ERCF.cfg @@ -0,0 +1,37 @@ + +#---------------------------------------------# +#### Mellow Fly ERCF MCU definition ########### +#---------------------------------------------# + +[mcu mmu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +# If you want to override the wiring of the Mellow Fly ERCF board, keep in mind that this +# board is defined using the "mmu" name. So you should use "pin: mmu:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/mmu/Mellow_fly_ERCF.cfg] # Do not remove this line +[board_pins mmu_mcu] +mcu: mmu +aliases: + MMU_GEAR_STEP=MCU_GEAR_STEP , MMU_GEAR_DIR=MCU_GEAR_DIR , MMU_GEAR_ENABLE=MCU_GEAR_EN , MMU_GEAR_UART=MCU_GEAR_UART , + MMU_GEAR_DIAG=MCU_GEAR_DIAG , + MMU_SEL_STEP=MCU_SELECTOR_STEP , MMU_SEL_DIR=MCU_SELECTOR_DIR , MMU_SEL_ENABLE=MCU_SELECTOR_EN , MMU_SEL_UART=MCU_SELECTOR_UART , + MMU_SEL_DIAG=MCU_SELECTOR_DIAG , + + MMU_SEL_ENDSTOP=MCU_ENDSTOP , + MMU_SERVO=MCU_SERVO , + MMU_ENCODER=MCU_ENCODER , + MMU_GATE_SENSOR=MCU_EXTRA , + + SPI_SCLK=MCU_SCK , SPI_MOSI=MCU_MOSI , SPI_MISO=MCU_MISO , + + MMU_PRE_GATE_0=MCU_IO10 , MMU_PRE_GATE_1=MCU_IO26 , + MMU_PRE_GATE_2=MCU_IO11 , MMU_PRE_GATE_3=MCU_IO27 , + MMU_PRE_GATE_4=MCU_IO12 , MMU_PRE_GATE_5=MCU_IO28 , + MMU_PRE_GATE_6=MCU_IO24 , MMU_PRE_GATE_7=MCU_IO29 , + MMU_PRE_GATE_8=MCU_IO13 , MMU_PRE_GATE_9=MCU_IO25 , + diff --git a/user_templates/mcu_defaults/mmu/Tircown_ERCF_easy_brd.cfg b/user_templates/mcu_defaults/mmu/Tircown_ERCF_easy_brd.cfg new file mode 100644 index 000000000..861f0336a --- /dev/null +++ b/user_templates/mcu_defaults/mmu/Tircown_ERCF_easy_brd.cfg @@ -0,0 +1,29 @@ + +#--------------------------------------------------# +#### Tircown ERCF easybrd MCU definition ########### +#--------------------------------------------------# + +[mcu mmu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +##-------------------------------------------------------------------- + +# If you want to override the wiring of the ERCF easy brd, keep in mind that this +# board is defined using the "mmu" name. So you should use "pin: mmu:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/mmu/Tircown_ERCF_easy_brd.cfg] # Do not remove this line +[board_pins mmu_mcu] +mcu: mmu +aliases: + MMU_GEAR_STEP=MCU_GEAR_STEP , MMU_GEAR_DIR=MCU_GEAR_DIR , MMU_GEAR_ENABLE=MCU_GEAR_ENABLE , + MMU_SEL_STEP=MCU_SELECTOR_STEP , MMU_SEL_DIR=MCU_SELECTOR_DIR , MMU_SEL_ENABLE=MCU_SELECTOR_ENABLE , + + MMU_GEAR_UART=MCU_TMCUART , # used for [tmc2209 stepper_mmu_gear] AND [tmc2209 stepper_mmu_selector] uart_pin in Happy_Hare + MMU_SEL_DIAG=MCU_SELECTOR_DIAG , + + MMU_SEL_ENDSTOP=MCU_SELECTOR_STOP , + MMU_SERVO=MCU_SERVO , + MMU_ENCODER=MCU_ENCODER , # (if not GATE_SENSOR!) + # MMU_GATE_SENSOR=MCU_ENCODER , # (if not ENCODER!) + diff --git a/user_templates/mcu_defaults/toolhead/BTT_SB2240_v1.0.cfg b/user_templates/mcu_defaults/toolhead/BTT_SB2240_v1.0.cfg index 672961559..37985e486 100644 --- a/user_templates/mcu_defaults/toolhead/BTT_SB2240_v1.0.cfg +++ b/user_templates/mcu_defaults/toolhead/BTT_SB2240_v1.0.cfg @@ -65,7 +65,7 @@ pin: toolhead:E_FAN [neopixel status_leds] pin: toolhead:STATUS_NEOPIXEL -# Since ADXL shares pins with the SPI interface of the TMC, it must be set up here, since different pin aliases must not resolve to the same pin +# Don't be surprised with the name of the pin. This is because the SPI bus is shared between motors and ADXL on this CANBoard. [tmc2240 extruder] cs_pin: toolhead:MCU_MOTOR_SPI_NSS spi_software_sclk_pin: toolhead:ADXL_SCLK diff --git a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg index 9dd48ab1f..3f7e35c6d 100644 --- a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg +++ b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_Pro.cfg @@ -18,9 +18,10 @@ mcu: toolhead aliases: E_STEP=MCU_EMOT_STEP , E_DIR=MCU_EMOT_DIR , E_ENABLE=MCU_EMOT_EN , E_TMCUART=MCU_EMOT_CS , - X_STOP=MCU_ENDSTOP , - PROBE_INPUT=MCU_HV_ENDSTOP , + X_STOP=MCU_ENDSTOP , + PROBE_INPUT=MCU_HV_ENDSTOP , TOOLHEAD_SENSOR=MCU_5V_ENDSTOP , + EXTRUDER_SENSOR=MCU_FAN2 , E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_TEMP , CHAMBER_TEMPERATURE=MCU_ONBOARD_NTCK100K , diff --git a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v1.cfg b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v1.cfg index a5b92ea37..4021b4d75 100644 --- a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v1.cfg +++ b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v1.cfg @@ -18,9 +18,10 @@ mcu: toolhead aliases: E_STEP=MCU_EMOT_STEP , E_DIR=MCU_EMOT_DIR , E_ENABLE=MCU_EMOT_EN , E_TMCUART=MCU_EMOT_UART , - X_STOP=MCU_ENDSTOP , - PROBE_INPUT=MCU_HV_ENDSTOP , + X_STOP=MCU_ENDSTOP , + PROBE_INPUT=MCU_HV_ENDSTOP , TOOLHEAD_SENSOR=MCU_5V_ENDSTOP , + EXTRUDER_SENSOR=MCU_FAN2 , E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_TEMP , CHAMBER_TEMPERATURE=MCU_ONBOARD_NTCK100K , diff --git a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg index 4717038a0..265086e82 100644 --- a/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg +++ b/user_templates/mcu_defaults/toolhead/Mellow_SB2040_v2.cfg @@ -18,9 +18,10 @@ mcu: toolhead aliases: E_STEP=MCU_EMOT_STEP , E_DIR=MCU_EMOT_DIR , E_ENABLE=MCU_EMOT_EN , E_TMCUART=MCU_EMOT_UART , - X_STOP=MCU_ENDSTOP , - PROBE_INPUT=MCU_HV_ENDSTOP , + X_STOP=MCU_ENDSTOP , + PROBE_INPUT=MCU_HV_ENDSTOP , TOOLHEAD_SENSOR=MCU_5V_ENDSTOP , + EXTRUDER_SENSOR=MCU_FAN2 , E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_TEMP , CHAMBER_TEMPERATURE=MCU_ONBOARD_NTCK100K , diff --git a/user_templates/moonraker.conf b/user_templates/moonraker.conf index b86bd6202..bd96e978c 100644 --- a/user_templates/moonraker.conf +++ b/user_templates/moonraker.conf @@ -31,6 +31,21 @@ # [include moonraker/z_calibration.conf] # ----------------------------------------------------------------- +##### Spoolman plugin update management and server config --------- +# [include moonraker/spoolman.conf] +## If you want to change the default "localhost" IP, uncomment the two lines below to manually specify your Spoolman server IP +# [spoolman] +# server: http://YourSpoolmanIP:7912 +# ----------------------------------------------------------------- + +##### led_effect plugin update management ------------------------ +# [include moonraker/led_effect.conf] +# ----------------------------------------------------------------- + +##### TMC Autotune plugin update management ---------------------- +# [include moonraker/tmc_autotune.conf] +# ----------------------------------------------------------------- + ##### Add your custom moonraker config customizations and overrides below this line... # ------------------------------------------------------------------------------------ diff --git a/user_templates/overrides.cfg b/user_templates/overrides.cfg index 2b540fffe..cfb16a0a2 100644 --- a/user_templates/overrides.cfg +++ b/user_templates/overrides.cfg @@ -14,7 +14,7 @@ #> Main control MCUs are called "mcu" (and "secondary" when using a double MCU configuration) #> Toolhead CANboard MCUs are called "toolhead" -#> ERCF MCUs are called "ercf" +#> MMU/ERCF MCUs are called "mmu" # ------------------------------------------------------------------------------------------ diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 9e3208a04..2551bdbb7 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -158,7 +158,13 @@ ### -------------------------------------------------------------------------------------- # [include config/hardware/lights/fcob_white.cfg] # [include config/hardware/lights/neopixel_caselight.cfg] -# [include config/hardware/lights/status_leds.cfg] +# [include config/hardware/lights/status_leds.cfg] # Standard StealthBurner style LEDs +# [include config/hardware/lights/status_leds_rainbow_barf.cfg] # Rainbow Barf StealthBurner style LEDs + +# The following files are to be used with the LED effect plugin: https://github.com/julianschill/klipper-led_effect +# [include config/hardware/lights/neopixel_caselight_effects.cfg] +# [include config/hardware/lights/status_leds_effects.cfg] # Standard StealthBurner style LEDs +# [include config/hardware/lights/status_leds_rainbow_barf_effects.cfg] # Rainbow Barf StealthBurner style LEDs # ---------------------------------------------------------------------------------------- @@ -193,16 +199,12 @@ # ---------------------------------------------------------------------------------------- -# ------------------------------------------------------------------------------ ERCF ----> Select either all lines or none +# --------------------------------------------------------------------------- MMU/ERCF ----> You can select multiple lines ### -------------------------------------------------------------------------------------- -### Klippain is designed to be used with the ERCF Happy Hare software: https://github.com/moggieuk/ERCF-Software-V3 -### Please run its own install script to get Happy Hare ready to be used -### Then, include all of the following files that are created during the installation of Happy Hare to enable ERCF in Klippain -# [include ercf_hardware.cfg] -# [include ercf_parameters.cfg] -# [include ercf_software.cfg] -# [include ercf_menu.cfg] # Optional: use it if you also have a Mini12864 display to add the ERCF menu entries -# [include config/hardware/ercf.cfg] +### Klippain is designed to be used with the MMU/ERCF HappyHare software backend: https://github.com/moggieuk/Happy-Hare +### Please refer to the corresponding Klippain documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md +# [include config/hardware/mmu.cfg] +# [include mmu/optional/mmu_menu.cfg] # Optional: use it if you also have a Mini12864 display and want to add the MMU/ERCF menu entries # ---------------------------------------------------------------------------------------- @@ -276,6 +278,13 @@ # ---------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------- SPOOLMAN ---- +### -------------------------------------------------------------------------------------- +### You must have the Spoolman plugin installed... from here: https://github.com/Donkie/Spoolman +# [include config/software/spoolman.cfg] +# ---------------------------------------------------------------------------------------- + + ################################### ### DO NOT EDIT BELOW THIS LINE ### diff --git a/user_templates/save_variables.cfg b/user_templates/save_variables.cfg index 21009a950..133b160ad 100644 --- a/user_templates/save_variables.cfg +++ b/user_templates/save_variables.cfg @@ -1,15 +1,2 @@ [Variables] -ercf_calib_0 = 1.0 -ercf_calib_1 = 1.0 -ercf_calib_2 = 1.0 -ercf_calib_3 = 1.0 -ercf_calib_4 = 1.0 -ercf_calib_5 = 1.0 -ercf_calib_6 = 1.0 -ercf_calib_7 = 1.0 -ercf_calib_8 = 1.0 -ercf_calib_9 = 1.0 -ercf_calib_10 = 1.0 -ercf_calib_11 = 1.0 -ercf_calib_ref = 500.0 -ercf_calib_clog_length = 8.0 +mmu_calibration_0 = 1.0 diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index c9c67dc09..a2bced1e3 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -187,13 +187,15 @@ variable_material_parameters: { ################################################ -## ERCF specific variables +## MMU/ERCF specific variables ################################################ -## This section is only considered if an ERCF is installed and configured +## This section is only considered if an MMU/ERCF is installed and configured -variable_ercf_unload_on_cancel_print: False -variable_ercf_unload_on_end_print: True -variable_ercf_reset_stats_on_start_print: False +variable_mmu_force_homing_in_start_print: False +variable_mmu_unload_on_cancel_print: False +variable_mmu_unload_on_end_print: True +variable_mmu_check_gates_on_start_print: False # True is recommended but you must have TOOLS_USED=!referenced_tools! in your slicer START_PRINT parameters. Otherwise it will only check the INITIAL TOOL... +variable_mmu_check_errors_on_start_print: False # Set to True if you want an early check of MMU errors during the START_PRINT sequence. ################################################ ## Filter specific variables @@ -223,73 +225,26 @@ variable_purge_ooze_time: 10 # Time (in seconds) to wait after the purge to let variable_purgeclean_servo_angle_retracted: 0 variable_purgeclean_servo_angle_deployed: 90 - ## White light parameters (if installed in the machine) variable_light_intensity_start_print: 100 variable_light_intensity_printing: 30 variable_light_intensity_end_print: 0 +## Caselight LEDs ON at startup (caselight need to be installed in the machine) +variable_caselight_on_at_startup: False ## Patch the M190/M109 commands to avoid some wait time while the temperature ## settle on very low thermal latency devices (such as the BambuLabs hotend) variable_fix_heaters_temperature_settle: False - ## Resonnance testing position (if an accelerometer is installed in the machine) ## If test point is let to -1,-1, it default to the center of the bed at 50mm high variable_resonnance_test_point_xy: -1, -1 variable_resonnance_test_z_clearance: 50 -## SteathBurner minidisplay and case leds colors (if installed in the machine) -variable_status_leds_colors: { - 'logo': { - '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}, - 'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.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}, - 'error': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, - }, - 'nozzle': { - '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}, - 'error': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, - }, - 'caselight': { - '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}, - 'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.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}, - 'error': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, - }, - 'minidisplay': { - 'on': {'r': 0.0, 'g': 0.2, 'b': 0.4, 'w':1.0}, - 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, - 'error': {'r': 0.4, '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} - } - } - - +## ----------------------------------------------------------------------------------- +## ----------------------------------------------------------------------------------- ## Do not remove the next lines gcode: From 7e1ed944fca55eb2fe634ac8ddb63a9e4e6764c4 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:21:50 +0100 Subject: [PATCH 29/79] fix status leds at startup (#448) * Status leds on startup fix --- macros/miscs/startup.cfg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/macros/miscs/startup.cfg b/macros/miscs/startup.cfg index ab55531a5..bdaf367b5 100644 --- a/macros/miscs/startup.cfg +++ b/macros/miscs/startup.cfg @@ -37,6 +37,9 @@ gcode: _INIT_CHECK_MMU {% endif %} + ## Set the startup status LED + _INIT_LEDS + # User custom startup process. Define them in your overrides.cfg if needed :) _INIT_USERCUSTOM @@ -49,7 +52,7 @@ gcode: [gcode_macro _INIT_LEDS] gcode: - {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled or printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_enabled %} {% if printer["gcode_macro _USER_VARIABLES"].caselight_on_at_startup|default(False) %} STATUS_LEDS COLOR="READY" {% else %} From c07b5231fe7576d24d37bf824bc4417e555baa14 Mon Sep 17 00:00:00 2001 From: Elias Huwyler Date: Sun, 4 Feb 2024 18:31:31 +0100 Subject: [PATCH 30/79] display menu and V0 Display (#420) * Better display menu adapted to Klippain * V0 display support * Klippain boot logo --------- Co-authored-by: Elias Huwyler --- config/hardware/displays/BTT_mini12864.cfg | 12 +- .../displays/BTT_mini12864_inversed.cfg | 12 +- config/hardware/displays/Fysetc_mini12864.cfg | 6 +- .../displays/Fysetc_mini12864_inversed.cfg | 6 +- .../displays/Fysetc_mini12864_v1.2_v2.0.cfg | 1 + .../Fysetc_mini12864_v1.2_v2.0_inversed.cfg | 1 + config/hardware/displays/V0_display.cfg | 51 ++ config/hardware/lights/config_colors.cfg | 1 + config/software/boot_logo.cfg | 71 +++ config/software/display.cfg | 194 ++++++ config/software/klippain_glyphs.cfg | 600 ++++++++++++++++++ macros/base/control.cfg | 25 + macros/hardware_functions/status_leds.cfg | 14 +- macros/miscs/startup.cfg | 7 +- user_templates/printer.cfg | 3 + user_templates/variables.cfg | 1 + 16 files changed, 992 insertions(+), 13 deletions(-) create mode 100644 config/hardware/displays/V0_display.cfg create mode 100644 config/software/boot_logo.cfg create mode 100644 config/software/display.cfg create mode 100644 config/software/klippain_glyphs.cfg create mode 100644 macros/base/control.cfg diff --git a/config/hardware/displays/BTT_mini12864.cfg b/config/hardware/displays/BTT_mini12864.cfg index 659d4c068..cf51bf803 100644 --- a/config/hardware/displays/BTT_mini12864.cfg +++ b/config/hardware/displays/BTT_mini12864.cfg @@ -1,12 +1,16 @@ # Neopixel leds integrated in the BTT mini12864 display [gcode_macro _USER_VARIABLES] variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = True variable_status_leds_minidisplay_led_name: "btt_mini12864" +variable_status_leds_minidisplay_idx: '1,2' + gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] - +# Include adaptations to the menus +[include ../../../config/software/display.cfg] [display] lcd_type: uc1701 @@ -36,10 +40,10 @@ initial_BLUE: 0.0 color_order: RGB # Set RGB values on boot up for each Neopixel. -# Index 1 = display, Index 2 and 3 = Knob +# Index 3 = display, Index 1 and 2 = Knob [delayed_gcode setdisplayneopixel] initial_duration: 1 gcode: - SET_LED LED=btt_mini12864 RED=1 GREEN=1 BLUE=1 INDEX=1 TRANSMIT=0 + SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=1 TRANSMIT=0 SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=2 TRANSMIT=0 - SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=3 + SET_LED LED=btt_mini12864 RED=1 GREEN=1 BLUE=1 INDEX=3 diff --git a/config/hardware/displays/BTT_mini12864_inversed.cfg b/config/hardware/displays/BTT_mini12864_inversed.cfg index 8db250533..4eeb1225d 100644 --- a/config/hardware/displays/BTT_mini12864_inversed.cfg +++ b/config/hardware/displays/BTT_mini12864_inversed.cfg @@ -1,12 +1,16 @@ # Neopixel leds integrated in the BTT mini12864 display [gcode_macro _USER_VARIABLES] variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = True variable_status_leds_minidisplay_led_name: "btt_mini12864" +variable_status_leds_minidisplay_idx: '1,2' + gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] - +# Include adaptations to the menus +[include ../../../config/software/display.cfg] [display] lcd_type: uc1701 @@ -36,10 +40,10 @@ initial_BLUE: 0.0 color_order: RGB # Set RGB values on boot up for each Neopixel. -# Index 1 = display, Index 2 and 3 = Knob +# Index 3 = display, Index 1 and 2 = Knob [delayed_gcode setdisplayneopixel] initial_duration: 1 gcode: - SET_LED LED=btt_mini12864 RED=1 GREEN=1 BLUE=1 INDEX=1 TRANSMIT=0 + SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=1 TRANSMIT=0 SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=2 TRANSMIT=0 - SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=3 + SET_LED LED=btt_mini12864 RED=1 GREEN=1 BLUE=1 INDEX=3 diff --git a/config/hardware/displays/Fysetc_mini12864.cfg b/config/hardware/displays/Fysetc_mini12864.cfg index 6cd925c83..232304825 100644 --- a/config/hardware/displays/Fysetc_mini12864.cfg +++ b/config/hardware/displays/Fysetc_mini12864.cfg @@ -1,12 +1,16 @@ # Neopixel leds integrated in the Fysetc mini12864 display [gcode_macro _USER_VARIABLES] variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = True variable_status_leds_minidisplay_led_name: "fysetc_mini12864" +variable_status_leds_minidisplay_idx: '2,3' + gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] - +# Include adaptations to the menus +[include ../../../config/software/display.cfg] [display] lcd_type: uc1701 diff --git a/config/hardware/displays/Fysetc_mini12864_inversed.cfg b/config/hardware/displays/Fysetc_mini12864_inversed.cfg index c8a576c2c..2a09cbe20 100644 --- a/config/hardware/displays/Fysetc_mini12864_inversed.cfg +++ b/config/hardware/displays/Fysetc_mini12864_inversed.cfg @@ -1,12 +1,16 @@ # Neopixel leds integrated in the Fysetc mini12864 display [gcode_macro _USER_VARIABLES] variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = True variable_status_leds_minidisplay_led_name: "fysetc_mini12864" +variable_status_leds_minidisplay_idx: '2,3' + gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] - +# Include adaptations to the menus +[include ../../../config/software/display.cfg] [display] lcd_type: uc1701 diff --git a/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg index 037a75c46..98e25169f 100644 --- a/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg +++ b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0.cfg @@ -1,6 +1,7 @@ # Neopixel leds integrated in the Fysetc mini12864 display [gcode_macro _USER_VARIABLES] variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = False variable_status_leds_minidisplay_led_name: "fysetc_mini12864" gcode: diff --git a/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg index b84a888ab..bc2fe543d 100644 --- a/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg +++ b/config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg @@ -1,6 +1,7 @@ # Neopixel leds integrated in the Fysetc mini12864 display [gcode_macro _USER_VARIABLES] variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = False variable_status_leds_minidisplay_led_name: "fysetc_mini12864" gcode: diff --git a/config/hardware/displays/V0_display.cfg b/config/hardware/displays/V0_display.cfg new file mode 100644 index 000000000..6a7a35d8b --- /dev/null +++ b/config/hardware/displays/V0_display.cfg @@ -0,0 +1,51 @@ +# Neopixel leds integrated in the V0 Display +[gcode_macro _USER_VARIABLES] +variable_status_leds_minidisplay_enabled = True +variable_status_leds_minidisplay_knob_only = False +variable_status_leds_minidisplay_led_name: "v0_displaystatus" + +gcode: + +# Also include directly the leds control macros from here +[include ../../../macros/hardware_functions/status_leds.cfg] +# Include adaptations to the menus +[include ../../../config/software/display.cfg] + +[mcu v0_display] +#serial: **PASTE YOUR SERIAL PORT HERE AND UNCOMMENT** +restart_method: command + +[display] +lcd_type: sh1106 +i2c_mcu: v0_display +i2c_bus: i2c1a +# Set the direction of the encoder wheel +# Standard: Right (clockwise) scrolls down or increases values. Left (counter-clockwise scrolls up or decreases values. +encoder_pins: ^v0_display:PA3, ^v0_display:PA4 +# Reversed: Right (clockwise) scrolls up or decreases values. Left (counter-clockwise scrolls down or increases values. +#encoder_pins: ^display:PA4, ^display:PA3 +click_pin: ^!v0_display:PA1 +kill_pin: ^!v0_display:PA5 +#x_offset: 2 +# Use X offset to shift the display towards the right. Value can be 0 to 3 +#vcomh: 0 +# Set the Vcomh value on SSD1306/SH1106 displays. This value is +# associated with a "smearing" effect on some OLED displays. The +# value may range from 0 to 63. Default is 0. +# Adjust this value if you get some vertical stripes on your display. (31 seems to be a good value) + +[neopixel v0_displaystatus] +pin: v0_display:PA0 +chain_count: 1 +# Can be GRBW depending on the manufacturer of the display +color_order: GRB +initial_RED: 0.1 +initial_GREEN: 0.5 +initial_BLUE: 0.0 + +# Set RGB values on boot up for each Neopixel. +# Index 1 = display, Index 2 and 3 = Knob +[delayed_gcode setdisplayneopixel] +initial_duration: 1 +gcode: + SET_LED LED=v0_displaystatus RED=1 GREEN=0 BLUE=0 INDEX=1 TRANSMIT=0 diff --git a/config/hardware/lights/config_colors.cfg b/config/hardware/lights/config_colors.cfg index 681fcb60c..14a646bc7 100644 --- a/config/hardware/lights/config_colors.cfg +++ b/config/hardware/lights/config_colors.cfg @@ -46,6 +46,7 @@ variable_colors: { 'on': {'r': 0.0, 'g': 0.2, 'b': 0.4, 'w':1.0}, 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, 'error': {'r': 0.4, 'g': 0.0, 'b': 0.0, 'w':0.0}, + 'shutdown': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, }, 'thermal': { 'hot': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, diff --git a/config/software/boot_logo.cfg b/config/software/boot_logo.cfg new file mode 100644 index 000000000..dbd5d3655 --- /dev/null +++ b/config/software/boot_logo.cfg @@ -0,0 +1,71 @@ +[gcode_macro _USER_VARIABLES] +variable_minidisplay_bootlogo_enabled = True +variable_minidisplay_bootinfo_enabled = True +gcode: + +#### START SPLASH SCREEN +# Comment Out to Disable or Set 'custom' to New Name +[gcode_macro _INIT_BOOT_LOGO] +gcode: + {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootlogo_enabled %} + {% set custom1 = "_my_intro" %} + SET_DISPLAY_GROUP GROUP={custom1} + UPDATE_DELAYED_GCODE ID=START_INFO DURATION=4 + UPDATE_DELAYED_GCODE ID=clear_display DURATION=4.1 + {% endif %} + +#### START SPLASH SCREEN +# Comment Out to Disable or Set 'custom' to New Name +[delayed_gcode START_INFO] +initial_duration: 4 +gcode: + {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootinfo_enabled %} + {% set custom = "_my_info" %} + SET_DISPLAY_GROUP GROUP={custom} + UPDATE_DELAYED_GCODE ID=clear_display DURATION=4 + {% endif %} + +#### CLEAR MESSAGE AND SET DEFAULT DISPLAY GROUP +[delayed_gcode clear_display] +gcode: + M117 + SET_DISPLAY_GROUP GROUP={printer.configfile.settings.display.display_group} + +##################################### +# My Intro +##################################### + +[display_data _my_intro intro1] +position: 0, 0 +text: + ~kp00~~kp01~~kp02~~kp03~~kp04~~kp05~~kp06~~kp07~ + +[display_data _my_intro intro2] +position: 1, 0 +text: + ~kp10~~kp11~~kp12~~kp13~~kp14~~kp15~~kp16~~kp17~ + +[display_data _my_intro intro3] +position: 2, 0 +text: + ~kp20~~kp21~~kp22~~kp23~~kp24~~kp25~~kp26~~kp26~ + +[display_data _my_intro intro4] +position: 3, 0 +text: + ~kp30~~kp31~~kp32~~kp33~~kp34~~kp35~~kp36~~kp26~ + +##################################### +# My Info Override Printer Name with your own +##################################### +[display_data _my_info info1] +position: 1, 0 +text: + Klipper: + +[display_data _my_info info2] +position: 2, 0 +text: + {printer.mcu.mcu_version} + +[include klippain_glyphs.cfg] \ No newline at end of file diff --git a/config/software/display.cfg b/config/software/display.cfg new file mode 100644 index 000000000..676c56ec3 --- /dev/null +++ b/config/software/display.cfg @@ -0,0 +1,194 @@ +### Screen Menu ### +# default implementation: https://github.com/Klipper3d/klipper/blob/master/klippy/extras/display/menu.cfg +# Main: +# + Tune +# + Speed: 000% +# + Flow: 000% +# + Offset Z:00.00 +# + SD Card +# + Start printing +# + Resume printing +# + Pause printing +# + Cancel printing +# + ... (files) +# + Control +# + Park toolhead +# + Home All +# + Home Z +# + Home X/Y +# + Z Tilt +# + Quad Gantry Lvl +# + Bed Mesh +# + Steppers off +# + Fan: OFF +# + Fan speed: 000% +# + Lights: OFF +# + Lights: 000% +# + Move 10mm +# + Move X:000.0 +# + Move Y:000.0 +# + Move Z:000.0 +# + Move E:+000.0 +# + Move 1mm +# + Move X:000.0 +# + Move Y:000.0 +# + Move Z:000.0 +# + Move E:+000.0 +# + Move 0.1mm +# + Move X:000.0 +# + Move Y:000.0 +# + Move Z:000.0 +# + Move E:+000.0 +# + Temperature +# + Ex0:000 (0000) +# + Ex1:000 (0000) +# + Bed:000 (0000) +# + Preheat PLA +# + Preheat all +# + Preheat hotend +# + Preheat hotbed +# + Preheat ABS +# + Preheat all +# + Preheat hotend +# + Preheat hotbed +# + Cooldown +# + Cooldown all +# + Cooldown hotend +# + Cooldown hotbed +# + Filament +# + Ex0:000 (0000) +# + Load Filament +# + Unload Filament +# + Purge Filament +# + Clean Nozzel +# + Feed: 000.0 +# + Setup +# + Save config +# + Host control +# + Restart host +# + Restart FW +# + Shutdown host +# + PID tuning +# + Tune Hotend PID +# + Tune Hotbed PID +# + Calibration +# + Delta cal. auto +# + Delta cal. man +# + Start probing +# + Move Z: 000.00 +# + Test Z: ++ +# + Accept +# + Abort +# + Bed probe +# + Dump parameters + + + +# Shutdown and reboot +[menu __main __setup __restart] +type: list +enable: {not printer.idle_timeout.state == "Printing"} +name: Host control + + +# Add a park menu item. +[menu __main __control __park] +type: command +name: Park toolhead +enable: {printer.idle_timeout.state != "Printing" or + printer.pause_resume.is_paused} +index: 0 +gcode: + PARK + +[menu __main __setup __restart __shutdown] +type: command +enable: {not printer.idle_timeout.state == "Printing"} +name: Shutdown host +gcode: SHUTDOWN + +### menu octoprint ### +[menu __main __octoprint] +type: disabled + +[menu __main __control __caselightonoff] +type: input +enable: {'output_pin caselight' in printer} +name: Lights: {'ON ' if menu.input else 'OFF'} +input: {printer['output_pin caselight'].value} +input_min: 0 +input_max: 1 +input_step: 1 +gcode: + SET_PIN PIN=caselight VALUE={printer["gcode_macro _USER_VARIABLES"].light_intensity_start_print if menu.input else 0} + +[menu __main __control __caselightpwm] +type: input +enable: {'output_pin caselight' in printer} +name: Lights: {'%3d' % (menu.input*100)}% +input: {printer['output_pin caselight'].value} +input_min: 0.0 +input_max: 1.0 +input_step: 0.01 +realtime: True +gcode: + SET_PIN PIN=caselight VALUE={menu.input*100} + +################################################################################ +# Replace filament loading with our own macros. +################################################################################ +[menu __main __filament] +type: list +name: Filament +enable: {printer.idle_timeout.state != "Printing" or + printer.pause_resume.is_paused} + +# Hide the old load/unload commands. +[menu __main __filament __loadf] +type: command +name: Load Fil. fast +enable: False + +[menu __main __filament __loads] +type: command +name: Load Fil. slow +enable: False + +[menu __main __filament __unloadf] +type: command +name: Unload Fil.fast +enable: False + +[menu __main __filament __unloads] +type: command +name: Unload Fil.slow +enable: False + +# Add new load/unload using our macros. +[menu __main __filament __load] +type: command +index: 1 +name: Load Filament +gcode: + LOAD_FILAMENT + +[menu __main __filament __unload] +type: command +index: 2 +name: Unload Filament +gcode: + UNLOAD_FILAMENT + +[menu __main __filament __purge] +type: command +index: 3 +name: Purge Filament +gcode: + PURGE + +[menu __main __filament __clean] +type: command +index: 3 +name: Clean Nozzle +gcode: + CLEAN_NOZZLE \ No newline at end of file diff --git a/config/software/klippain_glyphs.cfg b/config/software/klippain_glyphs.cfg new file mode 100644 index 000000000..06494e001 --- /dev/null +++ b/config/software/klippain_glyphs.cfg @@ -0,0 +1,600 @@ +[display_glyph kp00] +data: + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .............*** + .......********* + ....************ + .*************** + + +[display_glyph kp01] +data: + ................ + ................ + ................ + ................ + ................ + ...............* + ...............* + ...............* + ..............** + ..............** + ..........*...** + .....******...** + ***********...** + ***********..*** + ***********..*** + ***********..*** + +[display_glyph kp02] +data: + ..************** + .*************** + .*************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + +[display_glyph kp03] +data: + ********......** + ********........ + ********..**.... + ********..****.. + *********..****. + **********.***** + **********..**** + **********...*** + **********.....* + **********...... + ***********..... + ***********..*.* + ********.....*.* + ******.......*.* + *****........*.* + ****....***..*.* + +[display_glyph kp04] +data: + .........******* + ........******** + ........******** + ........*******. + .......******... + ......*****..... + ......*........* + ..............** + .............*** + .......***..**** + .....****..***** + ***..***.*.***** + ***..**.*..***** + ***..*.**.****** + ***..*.**.****** + ***..*.*..****** + +[display_glyph kp05] +data: + **************** + *****.....****** + *............*** + ...............* + ...***...**..... + *****...*****... + ****..*.******.. + ****.*.********. + ***.**.********* + **.**..********* + **.**.********** + **.**.********** + **.*..********** + **...*********** + **...*********** + **..************ + +[display_glyph kp06] +data: + *...************ + *...************ + **...*********.. + **.............. + **...........*** + .**......******* + ..*......******* + .......********* + ........******** + ........******** + ........******** + ........******** + *.......******** + *............... + ..............** + ........******** + +[display_glyph kp07] +data: + ****...********* + **...*********** + ...************* + .*************** + ***************. + **************.* + ************..** + ***********..*** + **********..***. + ********..****.. + ******...***.... + ****...****..... + **...*****...... + ..******.......* + ******........*. + ***..........*.. + +[display_glyph kp10] +data: + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + ************.... + **********...*** + ********...***** + ******...******* + *****..********* + ****..********** + ***..*********** + **.************* + +[display_glyph kp11] +data: + **********...*** + **********...*** + **********...*** + **********...*** + **********...*** + ********.....*** + ****.........*** + .............*** + ..*******.....*. + ***********..... + ***********..... + ***********....* + **********....** + *********....*** + *********...**** + *********...**** + +[display_glyph kp12] +data: + ***************. + ************.... + **********...... + *********......* + *******.....**** + ******.....****. + *****....******. + *.......******.* + ........*****.** + ....*..******.** + .***...******.** + ***...*******.*. + **.*..*******.*. + **.*.********.*. + *.**.********..* + *.**.********..* + +[display_glyph kp13] +data: + ......***....*.* + .....***.......* + ....****.*.*.... + **..***.*..**... + ...***.**.****.. + ...***.**.****** + *.****.*..****** + ..****.*.******* + .****.**.******* + .****....******* + .*****..******** + .*****.********* + ******.********* + **************** + **************** + **************** + +[display_glyph kp14] +data: + ***..*.*..****** + **...*.*.******* + ....**...******* + ....**..******** + ..****..******** + ******.********* + **************** + **************** + **************** + **************** + ***************. + ************.... + **********...... + ********........ + *****........... + ***............. + +[display_glyph kp15] +data: + **.************* + ***************. + **************.. + *************... + ************.... + **********...... + ********........ + *****........... + ***............* + *..............* + ..............** + ..............** + .............*** + .............*.. + ............*... + ................ + +[display_glyph kp16] +data: + ........*******. + ...*............ + ...*............ + ...*............ + ..**............ + ..**........**** + .**.....*****... + ***............. + **.............. + *............... + *............... + ................ + ................ + ................ + ................ + ................ + +[display_glyph kp17] +data: + ...........**... + ..........*..... + ........**...... + ......**........ + ...***.......... + ***............. + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + + + +[display_glyph kp20] +data: + *..************* + ..************** + .*************** + ***************. + *************... + ************...* + ***********..*** + **********.****. + *********.***... + ********.***.... + *******.***..... + ******.***...... + ******.***...... + *****.***....... + ****..**........ + ****.***........ + +[display_glyph kp21] +data: + ********...***** + *****......***** + **.........***** + ...****....***** + .****......***** + ***........***** + ...........***** + ...........***** + ............**** + .............*** + ..............** + ................ + ................ + ...........*.*.. + ..........*..... + .......**....... + +[display_glyph kp22] +data: + *.*..********.** + *.*.************ + *...************ + *..************* + *..************* + *.************** + **************** + **************** + ***************. + ************.... + **********...... + *******......... + ................ + ................ + ................ + ................ + +[display_glyph kp23] +data: + **************** + ***************. + ************.... + **********...... + ********........ + *****........... + ***............. + *............... + ................ + ................ + ***............. + ...***.......... + ......*****..... + ............**** + ................ + ................ + +[display_glyph kp24] +data: + *............... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..............** + ............**.. + ........****.... + *******......... + ................ + ................ + +[display_glyph kp25] +data: + ...........*.... + ..........*..... + .........*...... + ........*....... + .......*........ + ......*......... + .....*.......... + ....*........... + ..**............ + **.............. + ................ + ................ + ................ + ................ + ................ + ................ + +[display_glyph kp26] +data: + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + +[display_glyph kp30] +data: + ***..**......... + ***.***......... + ***.**.......... + **.***.......... + **.***.......... + *..**........... + *.***........... + *.***..........* + ..**..........*. + .***............ + .***.........*.. + .**.........*... + ***.........*... + ***........*.... + ***........*.... + **........*..... + +[display_glyph kp31] +data: + ......*......... + .....*.......... + ....*.......***. + ..*.........***. + .*..........***. + .*..........**** + *...........**** + ............**** + ............**** + ............***. + ............***. + ............***. + ............***. + ............***. + ................ + ................ + +[display_glyph kp32] +data: + ................ + ................ + ...***..***..... + .*****..***..... + *****...***..... + ****....***..... + ***.....***..... + **......***..... + ***.....***..... + ****....***..... + .****...***..... + ..****..******** + ...***..******** + ....**..******** + ................ + ................ + +[display_glyph kp33] +data: + ................ + ................ + ..***..*****.... + ..***.*******..* + ..***.********.* + ..***.***...**.* + ..***.***...**.* + ..***.********.* + ..***.*******..* + ..***.*****....* + ..***.***......* + ..***.***......* + ..***.***......* + ..***.***......* + ................ + ................ + +[display_glyph kp34] +data: + ................ + ................ + ******.......*** + *******.....**** + ********....**** + **...***...***** + **...***...**..* + *******...***..* + *******...****** + *****....******* + **.......******* + **......****.... + **......***..... + **......**...... + ................ + ................ + +[display_glyph kp35] +data: + ................ + ................ + ......***..***.. + ......***..****. + *.....***..***** + *.....***..***** + **....***..***** + **....***..***** + ***...***..***.* + ***...***..***.. + ****..***..***.. + .***..***..***.. + .****.***..***.. + ..***.***..***.. + ................ + ................ + +[display_glyph kp36] +data: + ................ + ................ + ...***.......... + ...***.......... + ...***.......... + *..***.......... + **.***.......... + ******.......... + ******.......... + ******.......... + .*****.......... + ..****.......... + ...***.......... + ...***.......... + ................ + ................ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/macros/base/control.cfg b/macros/base/control.cfg new file mode 100644 index 000000000..a52cf3291 --- /dev/null +++ b/macros/base/control.cfg @@ -0,0 +1,25 @@ +[gcode_macro _OFF] +description: Turn off the printer +gcode: + {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} + {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} + {% set display_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_minidisplay_enabled %} + M84 ; turn steppers off + TURN_OFF_HEATERS ; turn bed / hotend off + M107 ; turn print cooling fan off + {% if light_enabled %} + LIGHT_OFF ; turn off light + {% endif %} + {% if status_leds_enabled %} + STATUS_LEDS COLOR="SHUTDOWN" ; turn off status LEDs + {% endif %} + {% if display_leds_enabled %} + _SET_ALLLEDS_BY_NAME LEDS="minidisplay" COLOR="shutdown" ; turn off all minidisplay LEDs even in knob only mode + {% endif %} + +[gcode_macro SHUTDOWN] +description: Turn off the printer and shutdown the host +gcode: + _OFF ; Shortcut to turn everything off (see above for this macro) + {action_respond_info('action:poweroff')} ; OctoPrint compatible host shutdown + {action_call_remote_method("shutdown_machine")} ; Moonraker compatible host shutdown \ No newline at end of file diff --git a/macros/hardware_functions/status_leds.cfg b/macros/hardware_functions/status_leds.cfg index 0e170653c..a26e2d482 100644 --- a/macros/hardware_functions/status_leds.cfg +++ b/macros/hardware_functions/status_leds.cfg @@ -184,7 +184,13 @@ gcode: 'nozzle': 'error', 'caselight': 'error', 'minidisplay': 'error' - } + }, + 'shutdown': { + 'logo': 'off', + 'nozzle': 'off', + 'caselight': 'off', + 'minidisplay': 'shutdown' + } } %} {% if not (color in status_color) %} @@ -210,5 +216,9 @@ gcode: {% endif %} {% if printer["gcode_macro _USER_VARIABLES"].status_leds_minidisplay_enabled %} - _SET_ALLLEDS_BY_NAME LEDS="minidisplay" COLOR={status_color[color].minidisplay} TRANSMIT=1 + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_minidisplay_knob_only %} + _SET_LEDS_BY_NAME LEDS="minidisplay" COLOR={status_color[color].minidisplay} TRANSMIT=1 + {% else %} + _SET_ALLLEDS_BY_NAME LEDS="minidisplay" COLOR={status_color[color].minidisplay} TRANSMIT=1 + {% endif %} {% endif %} diff --git a/macros/miscs/startup.cfg b/macros/miscs/startup.cfg index bdaf367b5..456b2ab9c 100644 --- a/macros/miscs/startup.cfg +++ b/macros/miscs/startup.cfg @@ -2,13 +2,18 @@ # and inits process used in Klippain [delayed_gcode KLIPPAIN_STARTUP] -initial_duration: 1 +initial_duration: 0.0001 gcode: _KLIPPAIN_STARTUP [gcode_macro _KLIPPAIN_STARTUP] gcode: + ## Set boot logo + {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootlogo_enabled %} + _INIT_BOOT_LOGO + {% endif %} + # Print system information using the system_info.py script to log them in the klippy.log RUN_SHELL_COMMAND CMD=system_info diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 2551bdbb7..db46f3d72 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -139,6 +139,9 @@ # [include config/hardware/displays/BTT_mini12864_inversed.cfg] # [include config/hardware/displays/Fysetc_mini12864_inversed.cfg] # [include config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg] + +### For V0 Display with standalone MCU don't forget to override the MCU serial port in your overrides.cfg file +# [include config/hardware/displays/V0_display.cfg] # ---------------------------------------------------------------------------------------- diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index a2bced1e3..0334a34e0 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -245,6 +245,7 @@ variable_resonnance_test_z_clearance: 50 ## ----------------------------------------------------------------------------------- ## ----------------------------------------------------------------------------------- + ## Do not remove the next lines gcode: From a866a360fc621ff59ca18b2498ead09ce9450ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Sun, 4 Feb 2024 19:20:29 +0100 Subject: [PATCH 31/79] improved display management structure --- config/hardware/displays/BTT_mini12864.cfg | 2 +- .../displays/BTT_mini12864_inversed.cfg | 2 +- config/hardware/displays/Fysetc_mini12864.cfg | 2 +- .../displays/Fysetc_mini12864_inversed.cfg | 2 +- config/hardware/displays/V0_display.cfg | 5 +- config/software/boot_logo.cfg | 71 --- config/software/{ => display}/display.cfg | 123 ++-- config/software/display/klippain_splash.cfg | 603 ++++++++++++++++++ config/software/klippain_glyphs.cfg | 600 ----------------- user_templates/printer.cfg | 2 +- user_templates/variables.cfg | 1 - 11 files changed, 648 insertions(+), 765 deletions(-) delete mode 100644 config/software/boot_logo.cfg rename config/software/{ => display}/display.cfg (53%) create mode 100644 config/software/display/klippain_splash.cfg delete mode 100644 config/software/klippain_glyphs.cfg diff --git a/config/hardware/displays/BTT_mini12864.cfg b/config/hardware/displays/BTT_mini12864.cfg index cf51bf803..17be931f3 100644 --- a/config/hardware/displays/BTT_mini12864.cfg +++ b/config/hardware/displays/BTT_mini12864.cfg @@ -10,7 +10,7 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] # Include adaptations to the menus -[include ../../../config/software/display.cfg] +[include ../../../config/software/display/display.cfg] [display] lcd_type: uc1701 diff --git a/config/hardware/displays/BTT_mini12864_inversed.cfg b/config/hardware/displays/BTT_mini12864_inversed.cfg index 4eeb1225d..e85610c48 100644 --- a/config/hardware/displays/BTT_mini12864_inversed.cfg +++ b/config/hardware/displays/BTT_mini12864_inversed.cfg @@ -10,7 +10,7 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] # Include adaptations to the menus -[include ../../../config/software/display.cfg] +[include ../../../config/software/display/display.cfg] [display] lcd_type: uc1701 diff --git a/config/hardware/displays/Fysetc_mini12864.cfg b/config/hardware/displays/Fysetc_mini12864.cfg index 232304825..fa295ecef 100644 --- a/config/hardware/displays/Fysetc_mini12864.cfg +++ b/config/hardware/displays/Fysetc_mini12864.cfg @@ -10,7 +10,7 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] # Include adaptations to the menus -[include ../../../config/software/display.cfg] +[include ../../../config/software/display/display.cfg] [display] lcd_type: uc1701 diff --git a/config/hardware/displays/Fysetc_mini12864_inversed.cfg b/config/hardware/displays/Fysetc_mini12864_inversed.cfg index 2a09cbe20..9aaafe815 100644 --- a/config/hardware/displays/Fysetc_mini12864_inversed.cfg +++ b/config/hardware/displays/Fysetc_mini12864_inversed.cfg @@ -10,7 +10,7 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] # Include adaptations to the menus -[include ../../../config/software/display.cfg] +[include ../../../config/software/display/display.cfg] [display] lcd_type: uc1701 diff --git a/config/hardware/displays/V0_display.cfg b/config/hardware/displays/V0_display.cfg index 6a7a35d8b..b301f4be2 100644 --- a/config/hardware/displays/V0_display.cfg +++ b/config/hardware/displays/V0_display.cfg @@ -9,10 +9,11 @@ gcode: # Also include directly the leds control macros from here [include ../../../macros/hardware_functions/status_leds.cfg] # Include adaptations to the menus -[include ../../../config/software/display.cfg] +[include ../../../config/software/display/display.cfg] +# You need to set the proper serial in your overrides.cfg file [mcu v0_display] -#serial: **PASTE YOUR SERIAL PORT HERE AND UNCOMMENT** +#serial: my-v0-display-serial restart_method: command [display] diff --git a/config/software/boot_logo.cfg b/config/software/boot_logo.cfg deleted file mode 100644 index dbd5d3655..000000000 --- a/config/software/boot_logo.cfg +++ /dev/null @@ -1,71 +0,0 @@ -[gcode_macro _USER_VARIABLES] -variable_minidisplay_bootlogo_enabled = True -variable_minidisplay_bootinfo_enabled = True -gcode: - -#### START SPLASH SCREEN -# Comment Out to Disable or Set 'custom' to New Name -[gcode_macro _INIT_BOOT_LOGO] -gcode: - {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootlogo_enabled %} - {% set custom1 = "_my_intro" %} - SET_DISPLAY_GROUP GROUP={custom1} - UPDATE_DELAYED_GCODE ID=START_INFO DURATION=4 - UPDATE_DELAYED_GCODE ID=clear_display DURATION=4.1 - {% endif %} - -#### START SPLASH SCREEN -# Comment Out to Disable or Set 'custom' to New Name -[delayed_gcode START_INFO] -initial_duration: 4 -gcode: - {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootinfo_enabled %} - {% set custom = "_my_info" %} - SET_DISPLAY_GROUP GROUP={custom} - UPDATE_DELAYED_GCODE ID=clear_display DURATION=4 - {% endif %} - -#### CLEAR MESSAGE AND SET DEFAULT DISPLAY GROUP -[delayed_gcode clear_display] -gcode: - M117 - SET_DISPLAY_GROUP GROUP={printer.configfile.settings.display.display_group} - -##################################### -# My Intro -##################################### - -[display_data _my_intro intro1] -position: 0, 0 -text: - ~kp00~~kp01~~kp02~~kp03~~kp04~~kp05~~kp06~~kp07~ - -[display_data _my_intro intro2] -position: 1, 0 -text: - ~kp10~~kp11~~kp12~~kp13~~kp14~~kp15~~kp16~~kp17~ - -[display_data _my_intro intro3] -position: 2, 0 -text: - ~kp20~~kp21~~kp22~~kp23~~kp24~~kp25~~kp26~~kp26~ - -[display_data _my_intro intro4] -position: 3, 0 -text: - ~kp30~~kp31~~kp32~~kp33~~kp34~~kp35~~kp36~~kp26~ - -##################################### -# My Info Override Printer Name with your own -##################################### -[display_data _my_info info1] -position: 1, 0 -text: - Klipper: - -[display_data _my_info info2] -position: 2, 0 -text: - {printer.mcu.mcu_version} - -[include klippain_glyphs.cfg] \ No newline at end of file diff --git a/config/software/display.cfg b/config/software/display/display.cfg similarity index 53% rename from config/software/display.cfg rename to config/software/display/display.cfg index 676c56ec3..83e2eb75c 100644 --- a/config/software/display.cfg +++ b/config/software/display/display.cfg @@ -1,96 +1,47 @@ -### Screen Menu ### -# default implementation: https://github.com/Klipper3d/klipper/blob/master/klippy/extras/display/menu.cfg -# Main: -# + Tune -# + Speed: 000% -# + Flow: 000% -# + Offset Z:00.00 -# + SD Card -# + Start printing -# + Resume printing -# + Pause printing -# + Cancel printing -# + ... (files) -# + Control -# + Park toolhead -# + Home All -# + Home Z -# + Home X/Y -# + Z Tilt -# + Quad Gantry Lvl -# + Bed Mesh -# + Steppers off -# + Fan: OFF -# + Fan speed: 000% -# + Lights: OFF -# + Lights: 000% -# + Move 10mm -# + Move X:000.0 -# + Move Y:000.0 -# + Move Z:000.0 -# + Move E:+000.0 -# + Move 1mm -# + Move X:000.0 -# + Move Y:000.0 -# + Move Z:000.0 -# + Move E:+000.0 -# + Move 0.1mm -# + Move X:000.0 -# + Move Y:000.0 -# + Move Z:000.0 -# + Move E:+000.0 -# + Temperature -# + Ex0:000 (0000) -# + Ex1:000 (0000) -# + Bed:000 (0000) -# + Preheat PLA -# + Preheat all -# + Preheat hotend -# + Preheat hotbed -# + Preheat ABS -# + Preheat all -# + Preheat hotend -# + Preheat hotbed -# + Cooldown -# + Cooldown all -# + Cooldown hotend -# + Cooldown hotbed -# + Filament -# + Ex0:000 (0000) -# + Load Filament -# + Unload Filament -# + Purge Filament -# + Clean Nozzel -# + Feed: 000.0 -# + Setup -# + Save config -# + Host control -# + Restart host -# + Restart FW -# + Shutdown host -# + PID tuning -# + Tune Hotend PID -# + Tune Hotbed PID -# + Calibration -# + Delta cal. auto -# + Delta cal. man -# + Start probing -# + Move Z: 000.00 -# + Test Z: ++ -# + Accept -# + Abort -# + Bed probe -# + Dump parameters +### Klippain display management ### + +[gcode_macro _USER_VARIABLES] +variable_minidisplay_bootlogo_enabled = True +variable_minidisplay_bootinfo_enabled = True +gcode: +[include klippain_splash.cfg] +#### START SPLASH SCREEN +[gcode_macro _INIT_BOOT_LOGO] +gcode: + {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootlogo_enabled %} + SET_DISPLAY_GROUP GROUP=_my_intro + UPDATE_DELAYED_GCODE ID=_INIT_BOOT_INFO DURATION=4 + UPDATE_DELAYED_GCODE ID=clear_display DURATION=4.1 + {% endif %} + +#### START SPLASH SCREEN +[delayed_gcode _INIT_BOOT_INFO] +initial_duration: 4 +gcode: + {% if printer["gcode_macro _USER_VARIABLES"].minidisplay_bootinfo_enabled %} + SET_DISPLAY_GROUP GROUP=_my_info + UPDATE_DELAYED_GCODE ID=clear_display DURATION=4 + {% endif %} + +[delayed_gcode clear_display] +gcode: + M117 + SET_DISPLAY_GROUP GROUP={printer.configfile.settings.display.display_group} + + + +### Menu changes to personalize it with Klippain macros +# default implementation: https://github.com/Klipper3d/klipper/blob/master/klippy/extras/display/menu.cfg + # Shutdown and reboot [menu __main __setup __restart] type: list enable: {not printer.idle_timeout.state == "Printing"} name: Host control - # Add a park menu item. [menu __main __control __park] type: command @@ -135,7 +86,7 @@ gcode: SET_PIN PIN=caselight VALUE={menu.input*100} ################################################################################ -# Replace filament loading with our own macros. +# Replace filament loading with our own macros ################################################################################ [menu __main __filament] type: list @@ -191,4 +142,4 @@ type: command index: 3 name: Clean Nozzle gcode: - CLEAN_NOZZLE \ No newline at end of file + CLEAN_NOZZLE diff --git a/config/software/display/klippain_splash.cfg b/config/software/display/klippain_splash.cfg new file mode 100644 index 000000000..bd41077e0 --- /dev/null +++ b/config/software/display/klippain_splash.cfg @@ -0,0 +1,603 @@ +[display_data _my_intro intro1] +position: 0, 0 +text: + ~kp00~~kp01~~kp02~~kp03~~kp04~~kp05~~kp06~~kp07~ + +[display_data _my_intro intro2] +position: 1, 0 +text: + ~kp10~~kp11~~kp12~~kp13~~kp14~~kp15~~kp16~~kp17~ + +[display_data _my_intro intro3] +position: 2, 0 +text: + ~kp20~~kp21~~kp22~~kp23~~kp24~~kp25~~kp26~~kp26~ + +[display_data _my_intro intro4] +position: 3, 0 +text: + ~kp30~~kp31~~kp32~~kp33~~kp34~~kp35~~kp36~~kp26~ + +[display_data _my_info info1] +position: 1, 0 +text: + Klipper: + +[display_data _my_info info2] +position: 2, 0 +text: + {printer.mcu.mcu_version} + + +[display_glyph kp00] +data: + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .............*** + .......********* + ....************ + .*************** + + +[display_glyph kp01] +data: + ................ + ................ + ................ + ................ + ................ + ...............* + ...............* + ...............* + ..............** + ..............** + ..........*...** + .....******...** + ***********...** + ***********..*** + ***********..*** + ***********..*** + +[display_glyph kp02] +data: + ..************** + .*************** + .*************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + +[display_glyph kp03] +data: + ********......** + ********........ + ********..**.... + ********..****.. + *********..****. + **********.***** + **********..**** + **********...*** + **********.....* + **********...... + ***********..... + ***********..*.* + ********.....*.* + ******.......*.* + *****........*.* + ****....***..*.* + +[display_glyph kp04] +data: + .........******* + ........******** + ........******** + ........*******. + .......******... + ......*****..... + ......*........* + ..............** + .............*** + .......***..**** + .....****..***** + ***..***.*.***** + ***..**.*..***** + ***..*.**.****** + ***..*.**.****** + ***..*.*..****** + +[display_glyph kp05] +data: + **************** + *****.....****** + *............*** + ...............* + ...***...**..... + *****...*****... + ****..*.******.. + ****.*.********. + ***.**.********* + **.**..********* + **.**.********** + **.**.********** + **.*..********** + **...*********** + **...*********** + **..************ + +[display_glyph kp06] +data: + *...************ + *...************ + **...*********.. + **.............. + **...........*** + .**......******* + ..*......******* + .......********* + ........******** + ........******** + ........******** + ........******** + *.......******** + *............... + ..............** + ........******** + +[display_glyph kp07] +data: + ****...********* + **...*********** + ...************* + .*************** + ***************. + **************.* + ************..** + ***********..*** + **********..***. + ********..****.. + ******...***.... + ****...****..... + **...*****...... + ..******.......* + ******........*. + ***..........*.. + +[display_glyph kp10] +data: + **************** + **************** + **************** + **************** + **************** + **************** + **************** + **************** + ************.... + **********...*** + ********...***** + ******...******* + *****..********* + ****..********** + ***..*********** + **.************* + +[display_glyph kp11] +data: + **********...*** + **********...*** + **********...*** + **********...*** + **********...*** + ********.....*** + ****.........*** + .............*** + ..*******.....*. + ***********..... + ***********..... + ***********....* + **********....** + *********....*** + *********...**** + *********...**** + +[display_glyph kp12] +data: + ***************. + ************.... + **********...... + *********......* + *******.....**** + ******.....****. + *****....******. + *.......******.* + ........*****.** + ....*..******.** + .***...******.** + ***...*******.*. + **.*..*******.*. + **.*.********.*. + *.**.********..* + *.**.********..* + +[display_glyph kp13] +data: + ......***....*.* + .....***.......* + ....****.*.*.... + **..***.*..**... + ...***.**.****.. + ...***.**.****** + *.****.*..****** + ..****.*.******* + .****.**.******* + .****....******* + .*****..******** + .*****.********* + ******.********* + **************** + **************** + **************** + +[display_glyph kp14] +data: + ***..*.*..****** + **...*.*.******* + ....**...******* + ....**..******** + ..****..******** + ******.********* + **************** + **************** + **************** + **************** + ***************. + ************.... + **********...... + ********........ + *****........... + ***............. + +[display_glyph kp15] +data: + **.************* + ***************. + **************.. + *************... + ************.... + **********...... + ********........ + *****........... + ***............* + *..............* + ..............** + ..............** + .............*** + .............*.. + ............*... + ................ + +[display_glyph kp16] +data: + ........*******. + ...*............ + ...*............ + ...*............ + ..**............ + ..**........**** + .**.....*****... + ***............. + **.............. + *............... + *............... + ................ + ................ + ................ + ................ + ................ + +[display_glyph kp17] +data: + ...........**... + ..........*..... + ........**...... + ......**........ + ...***.......... + ***............. + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + + + +[display_glyph kp20] +data: + *..************* + ..************** + .*************** + ***************. + *************... + ************...* + ***********..*** + **********.****. + *********.***... + ********.***.... + *******.***..... + ******.***...... + ******.***...... + *****.***....... + ****..**........ + ****.***........ + +[display_glyph kp21] +data: + ********...***** + *****......***** + **.........***** + ...****....***** + .****......***** + ***........***** + ...........***** + ...........***** + ............**** + .............*** + ..............** + ................ + ................ + ...........*.*.. + ..........*..... + .......**....... + +[display_glyph kp22] +data: + *.*..********.** + *.*.************ + *...************ + *..************* + *..************* + *.************** + **************** + **************** + ***************. + ************.... + **********...... + *******......... + ................ + ................ + ................ + ................ + +[display_glyph kp23] +data: + **************** + ***************. + ************.... + **********...... + ********........ + *****........... + ***............. + *............... + ................ + ................ + ***............. + ...***.......... + ......*****..... + ............**** + ................ + ................ + +[display_glyph kp24] +data: + *............... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..............** + ............**.. + ........****.... + *******......... + ................ + ................ + +[display_glyph kp25] +data: + ...........*.... + ..........*..... + .........*...... + ........*....... + .......*........ + ......*......... + .....*.......... + ....*........... + ..**............ + **.............. + ................ + ................ + ................ + ................ + ................ + ................ + +[display_glyph kp26] +data: + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + +[display_glyph kp30] +data: + ***..**......... + ***.***......... + ***.**.......... + **.***.......... + **.***.......... + *..**........... + *.***........... + *.***..........* + ..**..........*. + .***............ + .***.........*.. + .**.........*... + ***.........*... + ***........*.... + ***........*.... + **........*..... + +[display_glyph kp31] +data: + ......*......... + .....*.......... + ....*.......***. + ..*.........***. + .*..........***. + .*..........**** + *...........**** + ............**** + ............**** + ............***. + ............***. + ............***. + ............***. + ............***. + ................ + ................ + +[display_glyph kp32] +data: + ................ + ................ + ...***..***..... + .*****..***..... + *****...***..... + ****....***..... + ***.....***..... + **......***..... + ***.....***..... + ****....***..... + .****...***..... + ..****..******** + ...***..******** + ....**..******** + ................ + ................ + +[display_glyph kp33] +data: + ................ + ................ + ..***..*****.... + ..***.*******..* + ..***.********.* + ..***.***...**.* + ..***.***...**.* + ..***.********.* + ..***.*******..* + ..***.*****....* + ..***.***......* + ..***.***......* + ..***.***......* + ..***.***......* + ................ + ................ + +[display_glyph kp34] +data: + ................ + ................ + ******.......*** + *******.....**** + ********....**** + **...***...***** + **...***...**..* + *******...***..* + *******...****** + *****....******* + **.......******* + **......****.... + **......***..... + **......**...... + ................ + ................ + +[display_glyph kp35] +data: + ................ + ................ + ......***..***.. + ......***..****. + *.....***..***** + *.....***..***** + **....***..***** + **....***..***** + ***...***..***.* + ***...***..***.. + ****..***..***.. + .***..***..***.. + .****.***..***.. + ..***.***..***.. + ................ + ................ + +[display_glyph kp36] +data: + ................ + ................ + ...***.......... + ...***.......... + ...***.......... + *..***.......... + **.***.......... + ******.......... + ******.......... + ******.......... + .*****.......... + ..****.......... + ...***.......... + ...***.......... + ................ + ................ diff --git a/config/software/klippain_glyphs.cfg b/config/software/klippain_glyphs.cfg deleted file mode 100644 index 06494e001..000000000 --- a/config/software/klippain_glyphs.cfg +++ /dev/null @@ -1,600 +0,0 @@ -[display_glyph kp00] -data: - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .............*** - .......********* - ....************ - .*************** - - -[display_glyph kp01] -data: - ................ - ................ - ................ - ................ - ................ - ...............* - ...............* - ...............* - ..............** - ..............** - ..........*...** - .....******...** - ***********...** - ***********..*** - ***********..*** - ***********..*** - -[display_glyph kp02] -data: - ..************** - .*************** - .*************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - -[display_glyph kp03] -data: - ********......** - ********........ - ********..**.... - ********..****.. - *********..****. - **********.***** - **********..**** - **********...*** - **********.....* - **********...... - ***********..... - ***********..*.* - ********.....*.* - ******.......*.* - *****........*.* - ****....***..*.* - -[display_glyph kp04] -data: - .........******* - ........******** - ........******** - ........*******. - .......******... - ......*****..... - ......*........* - ..............** - .............*** - .......***..**** - .....****..***** - ***..***.*.***** - ***..**.*..***** - ***..*.**.****** - ***..*.**.****** - ***..*.*..****** - -[display_glyph kp05] -data: - **************** - *****.....****** - *............*** - ...............* - ...***...**..... - *****...*****... - ****..*.******.. - ****.*.********. - ***.**.********* - **.**..********* - **.**.********** - **.**.********** - **.*..********** - **...*********** - **...*********** - **..************ - -[display_glyph kp06] -data: - *...************ - *...************ - **...*********.. - **.............. - **...........*** - .**......******* - ..*......******* - .......********* - ........******** - ........******** - ........******** - ........******** - *.......******** - *............... - ..............** - ........******** - -[display_glyph kp07] -data: - ****...********* - **...*********** - ...************* - .*************** - ***************. - **************.* - ************..** - ***********..*** - **********..***. - ********..****.. - ******...***.... - ****...****..... - **...*****...... - ..******.......* - ******........*. - ***..........*.. - -[display_glyph kp10] -data: - **************** - **************** - **************** - **************** - **************** - **************** - **************** - **************** - ************.... - **********...*** - ********...***** - ******...******* - *****..********* - ****..********** - ***..*********** - **.************* - -[display_glyph kp11] -data: - **********...*** - **********...*** - **********...*** - **********...*** - **********...*** - ********.....*** - ****.........*** - .............*** - ..*******.....*. - ***********..... - ***********..... - ***********....* - **********....** - *********....*** - *********...**** - *********...**** - -[display_glyph kp12] -data: - ***************. - ************.... - **********...... - *********......* - *******.....**** - ******.....****. - *****....******. - *.......******.* - ........*****.** - ....*..******.** - .***...******.** - ***...*******.*. - **.*..*******.*. - **.*.********.*. - *.**.********..* - *.**.********..* - -[display_glyph kp13] -data: - ......***....*.* - .....***.......* - ....****.*.*.... - **..***.*..**... - ...***.**.****.. - ...***.**.****** - *.****.*..****** - ..****.*.******* - .****.**.******* - .****....******* - .*****..******** - .*****.********* - ******.********* - **************** - **************** - **************** - -[display_glyph kp14] -data: - ***..*.*..****** - **...*.*.******* - ....**...******* - ....**..******** - ..****..******** - ******.********* - **************** - **************** - **************** - **************** - ***************. - ************.... - **********...... - ********........ - *****........... - ***............. - -[display_glyph kp15] -data: - **.************* - ***************. - **************.. - *************... - ************.... - **********...... - ********........ - *****........... - ***............* - *..............* - ..............** - ..............** - .............*** - .............*.. - ............*... - ................ - -[display_glyph kp16] -data: - ........*******. - ...*............ - ...*............ - ...*............ - ..**............ - ..**........**** - .**.....*****... - ***............. - **.............. - *............... - *............... - ................ - ................ - ................ - ................ - ................ - -[display_glyph kp17] -data: - ...........**... - ..........*..... - ........**...... - ......**........ - ...***.......... - ***............. - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - - - -[display_glyph kp20] -data: - *..************* - ..************** - .*************** - ***************. - *************... - ************...* - ***********..*** - **********.****. - *********.***... - ********.***.... - *******.***..... - ******.***...... - ******.***...... - *****.***....... - ****..**........ - ****.***........ - -[display_glyph kp21] -data: - ********...***** - *****......***** - **.........***** - ...****....***** - .****......***** - ***........***** - ...........***** - ...........***** - ............**** - .............*** - ..............** - ................ - ................ - ...........*.*.. - ..........*..... - .......**....... - -[display_glyph kp22] -data: - *.*..********.** - *.*.************ - *...************ - *..************* - *..************* - *.************** - **************** - **************** - ***************. - ************.... - **********...... - *******......... - ................ - ................ - ................ - ................ - -[display_glyph kp23] -data: - **************** - ***************. - ************.... - **********...... - ********........ - *****........... - ***............. - *............... - ................ - ................ - ***............. - ...***.......... - ......*****..... - ............**** - ................ - ................ - -[display_glyph kp24] -data: - *............... - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ..............** - ............**.. - ........****.... - *******......... - ................ - ................ - -[display_glyph kp25] -data: - ...........*.... - ..........*..... - .........*...... - ........*....... - .......*........ - ......*......... - .....*.......... - ....*........... - ..**............ - **.............. - ................ - ................ - ................ - ................ - ................ - ................ - -[display_glyph kp26] -data: - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - -[display_glyph kp30] -data: - ***..**......... - ***.***......... - ***.**.......... - **.***.......... - **.***.......... - *..**........... - *.***........... - *.***..........* - ..**..........*. - .***............ - .***.........*.. - .**.........*... - ***.........*... - ***........*.... - ***........*.... - **........*..... - -[display_glyph kp31] -data: - ......*......... - .....*.......... - ....*.......***. - ..*.........***. - .*..........***. - .*..........**** - *...........**** - ............**** - ............**** - ............***. - ............***. - ............***. - ............***. - ............***. - ................ - ................ - -[display_glyph kp32] -data: - ................ - ................ - ...***..***..... - .*****..***..... - *****...***..... - ****....***..... - ***.....***..... - **......***..... - ***.....***..... - ****....***..... - .****...***..... - ..****..******** - ...***..******** - ....**..******** - ................ - ................ - -[display_glyph kp33] -data: - ................ - ................ - ..***..*****.... - ..***.*******..* - ..***.********.* - ..***.***...**.* - ..***.***...**.* - ..***.********.* - ..***.*******..* - ..***.*****....* - ..***.***......* - ..***.***......* - ..***.***......* - ..***.***......* - ................ - ................ - -[display_glyph kp34] -data: - ................ - ................ - ******.......*** - *******.....**** - ********....**** - **...***...***** - **...***...**..* - *******...***..* - *******...****** - *****....******* - **.......******* - **......****.... - **......***..... - **......**...... - ................ - ................ - -[display_glyph kp35] -data: - ................ - ................ - ......***..***.. - ......***..****. - *.....***..***** - *.....***..***** - **....***..***** - **....***..***** - ***...***..***.* - ***...***..***.. - ****..***..***.. - .***..***..***.. - .****.***..***.. - ..***.***..***.. - ................ - ................ - -[display_glyph kp36] -data: - ................ - ................ - ...***.......... - ...***.......... - ...***.......... - *..***.......... - **.***.......... - ******.......... - ******.......... - ******.......... - .*****.......... - ..****.......... - ...***.......... - ...***.......... - ................ - ................ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index db46f3d72..971aa6302 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -140,7 +140,7 @@ # [include config/hardware/displays/Fysetc_mini12864_inversed.cfg] # [include config/hardware/displays/Fysetc_mini12864_v1.2_v2.0_inversed.cfg] -### For V0 Display with standalone MCU don't forget to override the MCU serial port in your overrides.cfg file +### For a V0 display with an integrated MCU, don't forget to override the MCU serial port in your overrides.cfg file # [include config/hardware/displays/V0_display.cfg] # ---------------------------------------------------------------------------------------- diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index 0334a34e0..a2bced1e3 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -245,7 +245,6 @@ variable_resonnance_test_z_clearance: 50 ## ----------------------------------------------------------------------------------- ## ----------------------------------------------------------------------------------- - ## Do not remove the next lines gcode: From ce74c3258c58467d1ace4e41ce6d4ef9eda0710e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Sun, 4 Feb 2024 19:23:04 +0100 Subject: [PATCH 32/79] fixed MMU includes for HappyHare symlink --- config/hardware/mmu.cfg | 1 - user_templates/printer.cfg | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/hardware/mmu.cfg b/config/hardware/mmu.cfg index 1df0ad5f7..ab9ca8228 100644 --- a/config/hardware/mmu.cfg +++ b/config/hardware/mmu.cfg @@ -11,5 +11,4 @@ max_extrude_cross_section: 50.0 # Also include directly the MMU macros and config from here -[include ../../mmu/base/mmu_*.cfg] [include ../../macros/hardware_functions/mmu.cfg] diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 971aa6302..b9921210e 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -202,11 +202,13 @@ # ---------------------------------------------------------------------------------------- -# --------------------------------------------------------------------------- MMU/ERCF ----> You can select multiple lines +# --------------------------------------------------------------------------- MMU/ERCF ----> You need to select both lines or none ### -------------------------------------------------------------------------------------- ### Klippain is designed to be used with the MMU/ERCF HappyHare software backend: https://github.com/moggieuk/Happy-Hare ### Please refer to the corresponding Klippain documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md # [include config/hardware/mmu.cfg] +# [include mmu/base/mmu_*.cfg] + # [include mmu/optional/mmu_menu.cfg] # Optional: use it if you also have a Mini12864 display and want to add the MMU/ERCF menu entries # ---------------------------------------------------------------------------------------- From 7964dbef71086096403d042dc70a2ada9d9ea84a Mon Sep 17 00:00:00 2001 From: Neil Smith <8648114+nmsmith22389@users.noreply.github.com> Date: Thu, 8 Feb 2024 00:38:14 -0600 Subject: [PATCH 33/79] Add BLTouch support (#450) --- config/hardware/probes/bltouch.cfg | 28 ++++++++++++++++++++++++++++ macros/miscs/startup.cfg | 2 ++ user_templates/printer.cfg | 3 +++ 3 files changed, 33 insertions(+) create mode 100644 config/hardware/probes/bltouch.cfg diff --git a/config/hardware/probes/bltouch.cfg b/config/hardware/probes/bltouch.cfg new file mode 100644 index 000000000..c3110d89f --- /dev/null +++ b/config/hardware/probes/bltouch.cfg @@ -0,0 +1,28 @@ +# This probe type is for an BLTouch probe used directly as a virtual Z endstop rather than +# with an existing physical endstop. This configuration is common if you are running a +# Voron Switchwire or other "bed slinger" that does not have a fixed Z endstop at bed +# height. + +[gcode_macro _USER_VARIABLES] +variable_probe_type_enabled: "bltouch" +variable_startprint_actions: "bed_soak", "extruder_preheating", "chamber_soak", "tilt_calib", "extruder_heating", "purge", "clean", "z_offset", "bedmesh", "primeline" +gcode: + +# The BLTouch probe definition also includes the probe management and +# overides directly from here +[include ../../../macros/base/probing/generic_probe.cfg] + +[bltouch] +sensor_pin: ^PROBE_INPUT +control_pin: SERVO_PIN +x_offset: 0.0 +y_offset: 0.0 +z_offset: 0 +samples: 1 +sample_retract_dist: 3.0 +samples_result: median +samples_tolerance: 0.004 +samples_tolerance_retries: 1 + +[stepper_z] +endstop_pin: probe:z_virtual_endstop diff --git a/macros/miscs/startup.cfg b/macros/miscs/startup.cfg index 456b2ab9c..7e5806c60 100644 --- a/macros/miscs/startup.cfg +++ b/macros/miscs/startup.cfg @@ -112,6 +112,8 @@ gcode: {% if zcalib_plugin_enabled %} {% if probe_type_enabled == "vorontap" %} { action_raise_error("Voron TAP Probe and Z calibration plugin cannot be used at the same time in Klippain!") } + {% elif probe_type_enabled == "bltouch" %} + { action_raise_error("BLTouch Probe and Z calibration plugin cannot be used at the same time in Klippain!") } {% elif probe_type_enabled == "inductive" %} { action_raise_error("Inductive probe and Z calibration plugin cannot be used at the same time in Klippain!") } {% elif probe_type_enabled == "dockable_virtual" or probe_type_enabled == "inductive_virtual" %} diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index b9921210e..682d482d9 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -103,6 +103,9 @@ ## Beacon probe also used as virtual Z endstop. Do not forget to install the plugin and add the [beacon] section to make it work! # [include config/hardware/probes/beacon_virtual.cfg] + +## BLTouch probe also used as virtual Z endstop. +# [include config/hardware/probes/bltouch.cfg] # ---------------------------------------------------------------------------------------- From 3468ad66f9c132b9d61ccfd6e8ebcb03389d0047 Mon Sep 17 00:00:00 2001 From: claudioguareschi <33001685+claudioguareschi@users.noreply.github.com> Date: Thu, 8 Feb 2024 01:53:21 -0500 Subject: [PATCH 34/79] fixed nozzle and status led on/off. (#454) --- config/hardware/lights/neopixel_caselight.cfg | 1 + .../hardware/lights/neopixel_caselight_effects.cfg | 3 ++- config/hardware/lights/status_leds.cfg | 1 + config/hardware/lights/status_leds_effects.cfg | 5 +++-- config/hardware/lights/status_leds_rainbow_barf.cfg | 1 + .../lights/status_leds_rainbow_barf_effects.cfg | 5 +++-- macros/hardware_functions/status_leds.cfg | 12 ++++++++---- moonraker/base.conf | 2 +- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/config/hardware/lights/neopixel_caselight.cfg b/config/hardware/lights/neopixel_caselight.cfg index 5894e325d..331ef9c89 100644 --- a/config/hardware/lights/neopixel_caselight.cfg +++ b/config/hardware/lights/neopixel_caselight.cfg @@ -2,6 +2,7 @@ [gcode_macro _USER_VARIABLES] variable_status_leds_caselight_enabled = True +variable_status_leds_effects_enabled = False variable_status_leds_caselight_led_name: "caselight" gcode: diff --git a/config/hardware/lights/neopixel_caselight_effects.cfg b/config/hardware/lights/neopixel_caselight_effects.cfg index 6d593d236..748e20814 100644 --- a/config/hardware/lights/neopixel_caselight_effects.cfg +++ b/config/hardware/lights/neopixel_caselight_effects.cfg @@ -3,7 +3,8 @@ [gcode_macro _USER_VARIABLES] variable_status_leds_caselight_enabled = True -variable_status_leds_caselight_led_name: "caselight_effects" +variable_status_leds_effects_enabled = True +variable_status_leds_caselight_led_name: "caselight" gcode: # Also include directly the leds control macros from here diff --git a/config/hardware/lights/status_leds.cfg b/config/hardware/lights/status_leds.cfg index 7494e7864..683e371b7 100644 --- a/config/hardware/lights/status_leds.cfg +++ b/config/hardware/lights/status_leds.cfg @@ -2,6 +2,7 @@ [gcode_macro _USER_VARIABLES] variable_status_leds_enabled: True +variable_status_leds_effects_enabled: False variable_status_leds_logo_led_name: "status_leds" variable_status_leds_logo_idx: '1' variable_status_leds_nozzle_led_name: "status_leds" diff --git a/config/hardware/lights/status_leds_effects.cfg b/config/hardware/lights/status_leds_effects.cfg index 8cf00f0e1..f14cbe7bf 100644 --- a/config/hardware/lights/status_leds_effects.cfg +++ b/config/hardware/lights/status_leds_effects.cfg @@ -3,9 +3,10 @@ [gcode_macro _USER_VARIABLES] variable_status_leds_enabled: True -variable_status_leds_logo_led_name: "status_leds_effects" +variable_status_leds_effects_enabled: True +variable_status_leds_logo_led_name: "status_leds" variable_status_leds_logo_idx: '1' -variable_status_leds_nozzle_led_name: "status_leds_effects" +variable_status_leds_nozzle_led_name: "status_leds" variable_status_leds_nozzle_idx: '2,3' gcode: diff --git a/config/hardware/lights/status_leds_rainbow_barf.cfg b/config/hardware/lights/status_leds_rainbow_barf.cfg index 2463794ce..828037ee6 100644 --- a/config/hardware/lights/status_leds_rainbow_barf.cfg +++ b/config/hardware/lights/status_leds_rainbow_barf.cfg @@ -3,6 +3,7 @@ [gcode_macro _USER_VARIABLES] variable_status_leds_enabled: True +variable_status_leds_effects_enabled: False variable_status_leds_logo_led_name: "status_leds" variable_status_leds_logo_idx: '1,2,3,4,5,6,7,8' variable_status_leds_nozzle_led_name: "status_leds" diff --git a/config/hardware/lights/status_leds_rainbow_barf_effects.cfg b/config/hardware/lights/status_leds_rainbow_barf_effects.cfg index 9221b5080..14c7e6e9f 100644 --- a/config/hardware/lights/status_leds_rainbow_barf_effects.cfg +++ b/config/hardware/lights/status_leds_rainbow_barf_effects.cfg @@ -3,9 +3,10 @@ [gcode_macro _USER_VARIABLES] variable_status_leds_enabled: True -variable_status_leds_logo_led_name: "status_leds_effects" +variable_status_leds_effects_enabled: True +variable_status_leds_logo_led_name: "status_leds" variable_status_leds_logo_idx: '1,2,3,4,5,6,7,8' -variable_status_leds_nozzle_led_name: "status_leds_effects" +variable_status_leds_nozzle_led_name: "status_leds" variable_status_leds_nozzle_idx: '9,10' gcode: diff --git a/macros/hardware_functions/status_leds.cfg b/macros/hardware_functions/status_leds.cfg index a26e2d482..a2acdd0c4 100644 --- a/macros/hardware_functions/status_leds.cfg +++ b/macros/hardware_functions/status_leds.cfg @@ -22,6 +22,10 @@ gcode: {% set led = params.LED|string %} {% set idx = (params.IDX|string).split(',') %} {% set transmit_last = params.TRANSMIT|default(1) %} + + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_effects_enabled %} + STOP_LED_EFFECTS LEDS="neopixel:"{led}" ("{params.IDX}")" + {% endif %} {% for led_index in idx %} {% set transmit=transmit_last if loop.last else 0 %} @@ -198,19 +202,19 @@ gcode: {% endif %} {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} - {% if printer["gcode_macro _USER_VARIABLES"].status_leds_logo_led_name == "status_leds"%} + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_effects_enabled == False %} _SET_LEDS_BY_NAME LEDS="logo" COLOR={status_color[color].logo} TRANSMIT={logo_transmit} _SET_LEDS_BY_NAME LEDS="nozzle" COLOR={status_color[color].nozzle} TRANSMIT=1 - {% elif printer["gcode_macro _USER_VARIABLES"].status_leds_logo_led_name == "status_leds_effects"%} + {% else %} SET_LED_EFFECT EFFECT={"sb_logo_" + status_color[color].logo} REPLACE=1 FADETIME=0.5 SET_LED_EFFECT EFFECT={"sb_nozzle_" + status_color[color].nozzle} REPLACE=1 FADETIME=0.5 {% endif %} {% endif %} {% if printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_enabled%} - {% if printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_led_name == "caselight"%} + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_effects_enabled == False %} _SET_ALLLEDS_BY_NAME LEDS="caselight" COLOR={status_color[color].caselight} TRANSMIT=1 - {% elif printer["gcode_macro _USER_VARIABLES"].status_leds_caselight_led_name == "caselight_effects"%} + {% else %} SET_LED_EFFECT EFFECT={"cl_" + status_color[color].caselight} REPLACE=1 FADETIME=0.5 {% endif %} {% endif %} diff --git a/moonraker/base.conf b/moonraker/base.conf index e6ac5a6bb..40bff791c 100644 --- a/moonraker/base.conf +++ b/moonraker/base.conf @@ -40,6 +40,6 @@ enable_auto_refresh: True type: git_repo path: ~/klippain_config origin: https://github.com/Frix-x/klippain.git -primary_branch: main +primary_branch: develop managed_services: moonraker klipper install_script: install.sh From 4a4199b65cc6a953e87d0fcb3d81692241baf049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Thu, 8 Feb 2024 07:56:16 +0100 Subject: [PATCH 35/79] reverted update manager to main branch --- moonraker/base.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moonraker/base.conf b/moonraker/base.conf index 40bff791c..e6ac5a6bb 100644 --- a/moonraker/base.conf +++ b/moonraker/base.conf @@ -40,6 +40,6 @@ enable_auto_refresh: True type: git_repo path: ~/klippain_config origin: https://github.com/Frix-x/klippain.git -primary_branch: develop +primary_branch: main managed_services: moonraker klipper install_script: install.sh From 2fc0ee91a1383039e2f1fb075c66fbecc7bc5d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Thu, 8 Feb 2024 08:03:39 +0100 Subject: [PATCH 36/79] followed naming scheme for bltouch include as virtual --- config/hardware/probes/{bltouch.cfg => bltouch_virtual.cfg} | 0 user_templates/printer.cfg | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) rename config/hardware/probes/{bltouch.cfg => bltouch_virtual.cfg} (100%) diff --git a/config/hardware/probes/bltouch.cfg b/config/hardware/probes/bltouch_virtual.cfg similarity index 100% rename from config/hardware/probes/bltouch.cfg rename to config/hardware/probes/bltouch_virtual.cfg diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 682d482d9..7f9c74c97 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -101,11 +101,11 @@ ## Voron TAP, also used naturally as a virtual Z endstop # [include config/hardware/probes/voron_tap.cfg] +## BLTouch probe also used as virtual Z endstop +# [include config/hardware/probes/bltouch_virtual.cfg] + ## Beacon probe also used as virtual Z endstop. Do not forget to install the plugin and add the [beacon] section to make it work! # [include config/hardware/probes/beacon_virtual.cfg] - -## BLTouch probe also used as virtual Z endstop. -# [include config/hardware/probes/bltouch.cfg] # ---------------------------------------------------------------------------------------- From 246e318a27b5a74a49e7bbe0186cf939c47a5418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Thu, 8 Feb 2024 14:09:49 +0100 Subject: [PATCH 37/79] moved the machine.cfg include and included additional thermistor defs --- .../temperature_sensors/custom_thermistors.cfg | 9 +++++++++ config/kinematics/cartesian.cfg | 4 ++++ config/kinematics/corexy.cfg | 4 ++++ config/kinematics/corexz.cfg | 4 ++++ config/machine.cfg | 14 ++++++++++---- user_templates/printer.cfg | 1 - 6 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 config/hardware/temperature_sensors/custom_thermistors.cfg diff --git a/config/hardware/temperature_sensors/custom_thermistors.cfg b/config/hardware/temperature_sensors/custom_thermistors.cfg new file mode 100644 index 000000000..7706b954b --- /dev/null +++ b/config/hardware/temperature_sensors/custom_thermistors.cfg @@ -0,0 +1,9 @@ +# This is a custom thermistor definition that is +# commonly found in some MCU boards like the Picobilical +[thermistor CMFB103F3950FANT] +temperature1: 0.0 +resistance1: 32116.0 +temperature2: 40.0 +resistance2: 5309.0 +temperature3: 80.0 +resistance3: 1228.0 diff --git a/config/kinematics/cartesian.cfg b/config/kinematics/cartesian.cfg index 7a676034a..6537b5726 100644 --- a/config/kinematics/cartesian.cfg +++ b/config/kinematics/cartesian.cfg @@ -5,3 +5,7 @@ max_accel: 3000 max_z_velocity: 30 max_z_accel: 500 square_corner_velocity: 5.0 + +# And add directly all the machines standard includes here +# to put them above the rest from printer.cfg +[include ../machine.cfg] diff --git a/config/kinematics/corexy.cfg b/config/kinematics/corexy.cfg index 1a5fb2863..80cf0e099 100644 --- a/config/kinematics/corexy.cfg +++ b/config/kinematics/corexy.cfg @@ -5,3 +5,7 @@ max_accel: 8000 max_z_velocity: 30 max_z_accel: 500 square_corner_velocity: 5.0 + +# And add directly all the machines standard includes here +# to put them above the rest from printer.cfg +[include ../machine.cfg] diff --git a/config/kinematics/corexz.cfg b/config/kinematics/corexz.cfg index 8d95ff504..8ed2a919f 100644 --- a/config/kinematics/corexz.cfg +++ b/config/kinematics/corexz.cfg @@ -5,3 +5,7 @@ max_accel: 1000 max_z_velocity: 200 max_z_accel: 1000 square_corner_velocity: 5.0 + +# And add directly all the machines standard includes here +# to put them above the rest from printer.cfg +[include ../machine.cfg] diff --git a/config/machine.cfg b/config/machine.cfg index 06e87e844..367bcf792 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -34,8 +34,17 @@ enable_force_move: True resolution: 0.1 -# include all the remaining macros (not already included in config files) and scripts +# ----------------------------------------------------------------------------------- +# Include all the remaining files (not already included in config files) and scripts # from here to avoid to include them in the main printer.cfg and avoid user confusion +# ----------------------------------------------------------------------------------- + +[include hardware/temperature_sensors/custom_thermistors.cfg] + +[include software/shaketune.cfg] + +[include ../scripts/*.cfg] + [include ../macros/base/*.cfg] [include ../macros/base/homing/homing_*.cfg] @@ -50,6 +59,3 @@ resolution: 0.1 [include ../macros/miscs/compatibility.cfg] [include ../macros/miscs/debugging.cfg] [include ../macros/miscs/startup.cfg] - -[include ../scripts/*.cfg] -[include software/shaketune.cfg] diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 7f9c74c97..39f6fddeb 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -297,7 +297,6 @@ ################################### ### DO NOT EDIT BELOW THIS LINE ### ################################### -[include config/machine.cfg] [include variables.cfg] [include mcu.cfg] [include overrides.cfg] From 45a447d6ccc596c9d82c956dcc5d7bbbdd5d05cb Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:46:35 +0100 Subject: [PATCH 38/79] Mellow fly super8 template (#463) --- .../main/Mellow_Fly_Super8_v1.x.cfg | 50 +++++++++++++++++ .../main/Mellow_Fly_Super8_v1.x.cfg | 55 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 config/mcu_definitions/main/Mellow_Fly_Super8_v1.x.cfg create mode 100644 user_templates/mcu_defaults/main/Mellow_Fly_Super8_v1.x.cfg diff --git a/config/mcu_definitions/main/Mellow_Fly_Super8_v1.x.cfg b/config/mcu_definitions/main/Mellow_Fly_Super8_v1.x.cfg new file mode 100644 index 000000000..b2f03a7de --- /dev/null +++ b/config/mcu_definitions/main/Mellow_Fly_Super8_v1.x.cfg @@ -0,0 +1,50 @@ +[board_pins mcu_manufacturer] +aliases: + MCU_DRIVE0_STEP=PE2 , MCU_DRIVE0_DIR=PC5 , MCU_DRIVE0_EN=PF11 , MCU_DRIVE0_UART=PC4 , + MCU_DRIVE1_STEP=PE3 , MCU_DRIVE1_DIR=PF13 , MCU_DRIVE1_EN=PF14 , MCU_DRIVE1_UART=PF12 , + MCU_DRIVE2_STEP=PE4 , MCU_DRIVE2_DIR=PG0 , MCU_DRIVE2_EN=PG1 , MCU_DRIVE2_UART=PF15 , + MCU_DRIVE3_STEP=PE14 , MCU_DRIVE3_DIR=PE8 , MCU_DRIVE3_EN=PE9 , MCU_DRIVE3_UART=PE7 , + MCU_DRIVE4_STEP=PE15 , MCU_DRIVE4_DIR=PE11 , MCU_DRIVE4_EN=PF2 , MCU_DRIVE4_UART=PE10 , + MCU_DRIVE5_STEP=PE1 , MCU_DRIVE5_DIR=PF0 , MCU_DRIVE5_EN=PC15 , MCU_DRIVE5_UART=PF1 , + MCU_DRIVE6_STEP=PE0 , MCU_DRIVE6_DIR=PG3 , MCU_DRIVE6_EN=PG4 , MCU_DRIVE6_UART=PG2 , + MCU_DRIVE7_STEP=PE6 , MCU_DRIVE7_DIR=PG6 , MCU_DRIVE7_EN=PG7 , MCU_DRIVE7_UART=PG5 , + MCU_TMC_MOSI=PB5 , MCU_TMC_MISO=PB4 , MCU_TMC_SCK=PB3 , + + MCU_IO0=PG12 , MCU_IO1=PG11 , MCU_IO2=PG10 , MCU_IO3=PG9 , MCU_IO4=PD7 , MCU_IO5=PD6 , MCU_IO6=PA8 , + MCU_IN7=PF8 , + MCU_HV_IN=PF3 , + MCU_ADC_0=PF4 , MCU_ADC_1=PF5 , MCU_ADC_2=PF9 , MCU_ADC_3=PF10 , MCU_ADC_4=PC0 , MCU_ADC_5=PC1 , + + MCU_HEAT0=PB0 , MCU_HEAT1=PB1 , MCU_HEAT2=PC7 , MCU_HEAT3=PF7 , MCU_HEAT4=PF6 , + + MCU_BED=PE5 , + + # BLTOUCH + MCU_SERVO=PC6 , # Pin 3 + MCU_PROBE=PC3 , # Pin 5 + + # ACCELEROMETER + MCU_ACCELEROMETER_1=<5V> , MCU_ACCELEROMETER_2= , MCU_ACCELEROMETER_3=PD0 , MCU_ACCELEROMETER_4=PD1 , MCU_ACCELEROMETER_5=PD3 , MCU_ACCELEROMETER_6=PD4 , MCU_ACCELEROMETER_7=PD5 , + + # ST-LINK + MCU_STLINK_1= , MCU_STLINK_2=PA14 , MCU_STLINK_3=PA13 , MCU_STLINK_4= , MCU_STLINK_5=<3.3V> , MCU_STLINK_6=<5V> , + + # SCREEN + MCU_SCREEN_1=PA10 , MCU_SCREEN_2=PA9 , MCU_SCREEN_3= , MCU_SCREEN_4=<5V> , + + MCU_FAN0=PA0 , MCU_FAN1=PA1 , MCU_FAN2=PA2 , MCU_FAN3=PA3 , MCU_FAN4=PA15 , + MCU_FAN5=PB11 , MCU_FAN6=PB10 , MCU_FAN7=PD12 , MCU_FAN8=PD14 , MCU_FAN9=PD15 , + + # EXP1 header + EXP1_1=PE12 , EXP1_2=PE13 , + EXP1_3=PB2 , EXP1_4=PG8 , + EXP1_5=PC14 , EXP1_6=PC13 , # Slot in the socket on this side + EXP1_7=PG14 , EXP1_8=PG13 , + EXP1_9= , EXP1_10=<5V> , + + # EXP2 header + EXP2_1=PA6 , EXP2_2=PA5 , + EXP2_3=PB7 , EXP2_4=PA4 , + EXP2_5=PB6 , EXP2_6=PA7 , # Slot in the socket on this side + EXP2_7=PG15 , EXP2_8= , + EXP2_9= , EXP2_10=<5V> , diff --git a/user_templates/mcu_defaults/main/Mellow_Fly_Super8_v1.x.cfg b/user_templates/mcu_defaults/main/Mellow_Fly_Super8_v1.x.cfg new file mode 100644 index 000000000..7b656092e --- /dev/null +++ b/user_templates/mcu_defaults/main/Mellow_Fly_Super8_v1.x.cfg @@ -0,0 +1,55 @@ + +#------------------------------------------# +#### CUSTOM TEMPLATE MCU definition ######## +#------------------------------------------# + +# This template file is a pre-filled file with Klippain pins alias conventions +# that can be used if your MCU board is not yet officially supported. Just fill +# in your MCU pins and you will be good to go :) + +[mcu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/Mellow_Fly_Super8_v1.x.cfg] # Do not remove this line +[board_pins fly_Super8_mcu] +mcu: mcu +aliases: + X_STEP=MCU_DRIVE0_STEP , X_DIR=MCU_DRIVE0_DIR , X_ENABLE=MCU_DRIVE0_EN , X_TMCUART=MCU_DRIVE0_UART , + Y_STEP=MCU_DRIVE1_STEP , Y_DIR=MCU_DRIVE1_DIR , Y_ENABLE=MCU_DRIVE1_EN , Y_TMCUART=MCU_DRIVE1_UART , + + Z_STEP=MCU_DRIVE3_STEP , Z_DIR=MCU_DRIVE3_DIR , Z_ENABLE=MCU_DRIVE3_EN , Z_TMCUART=MCU_DRIVE3_UART , + Z1_STEP=MCU_DRIVE4_STEP , Z1_DIR=MCU_DRIVE4_DIR , Z1_ENABLE=MCU_DRIVE4_EN , Z1_TMCUART=MCU_DRIVE4_UART , + Z2_STEP=MCU_DRIVE5_STEP , Z2_DIR=MCU_DRIVE5_DIR , Z2_ENABLE=MCU_DRIVE5_EN , Z2_TMCUART=MCU_DRIVE5_UART , + Z3_STEP=MCU_DRIVE6_STEP , Z3_DIR=MCU_DRIVE6_DIR , Z3_ENABLE=MCU_DRIVE6_EN , Z3_TMCUART=MCU_DRIVE6_UART , + + E_STEP=MCU_DRIVE2_STEP , E_DIR=MCU_DRIVE2_DIR , E_ENABLE=MCU_DRIVE2_EN , E_TMCUART=MCU_DRIVE2_UART , + + DRIVER_SPI_MOSI=MCU_TMC_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MISO=MCU_TMC_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_SCK=MCU_TMC_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 + + X_STOP=MCU_IO0 , Y_STOP=MCU_IO1 , Z_STOP=MCU_IO3 , + PROBE_INPUT=MCU_HV_IN , + RUNOUT_SENSOR=MCU_IO4 , + + E_HEATER=MCU_HEAT0 , E_TEMPERATURE=MCU_ADC_0 , + BED_HEATER=MCU_BED , BED_TEMPERATURE=MCU_ADC_5 , + + PART_FAN=MCU_FAN0 , E_FAN=MCU_FAN1 , + CONTROLLER_FAN=MCU_FAN2 , + EXHAUST_FAN=MCU_FAN3 , + FILTER_FAN=MCU_FAN4 , + HOST_CONTROLLER_FAN=MCU_FAN5 , + + CHAMBER_TEMPERATURE=MCU_ADC_1 , + ELECTRICAL_CABINET_TEMPERATURE=MCU_ADC_2 , + + LIGHT_OUTPUT=MCU_HEAT1 , +# LIGHT_NEOPIXEL= , +# STATUS_NEOPIXEL= , + + SERVO_PIN=MCU_SERVO , + From e350d0c98f1c9a0ef822adeb5ab482310f851c74 Mon Sep 17 00:00:00 2001 From: Reiner Uhry <24939566+reineruhry@users.noreply.github.com> Date: Wed, 14 Feb 2024 07:27:25 -0300 Subject: [PATCH 39/79] Support for TMC5160 on Z Axis (#469) --- .../hardware/axis/Z/TMC/TMC5160_1-Motor.cfg | 18 +++++++++++++++ .../hardware/axis/Z/TMC/TMC5160_3-Motors.cfg | 23 +++++++++++++++++++ .../hardware/axis/Z/TMC/TMC5160_4-Motors.cfg | 12 ++++++++++ user_templates/mcu.cfg | 3 +++ 4 files changed, 56 insertions(+) create mode 100644 config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg create mode 100644 config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg create mode 100644 config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg diff --git a/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg b/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg new file mode 100644 index 000000000..84bbe5207 --- /dev/null +++ b/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg @@ -0,0 +1,18 @@ +# Z TMC5160 definition + +# User variable only needed here as they are called recursively +[gcode_macro _USER_VARIABLES] +variable_z_driver: "tmc5160" +gcode: + + +[tmc5160 stepper_z] +cs_pin: Z_TMCUART +spi_speed: 500000 +spi_software_sclk_pin: DRIVER_SPI_SCK +spi_software_mosi_pin: DRIVER_SPI_MOSI +spi_software_miso_pin: DRIVER_SPI_MISO +interpolate: True +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 \ No newline at end of file diff --git a/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg b/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg new file mode 100644 index 000000000..54cbeaa83 --- /dev/null +++ b/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg @@ -0,0 +1,23 @@ +[include TMC5160_1-Motor.cfg] + +[tmc5160 stepper_z1] +cs_pin: Z1_TMCUART +spi_speed: 500000 +spi_software_sclk_pin: DRIVER_SPI_SCK +spi_software_mosi_pin: DRIVER_SPI_MOSI +spi_software_miso_pin: DRIVER_SPI_MISO +interpolate: True +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +[tmc5160 stepper_z2] +cs_pin: Z2_TMCUART +spi_speed: 500000 +spi_software_sclk_pin: DRIVER_SPI_SCK +spi_software_mosi_pin: DRIVER_SPI_MOSI +spi_software_miso_pin: DRIVER_SPI_MISO +interpolate: True +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 \ No newline at end of file diff --git a/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg b/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg new file mode 100644 index 000000000..4fb3eec64 --- /dev/null +++ b/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg @@ -0,0 +1,12 @@ +[include TMC5160_3-Motors.cfg] + +[tmc5160 stepper_z3] +cs_pin: Z3_TMCUART +spi_speed: 500000 +spi_software_sclk_pin: DRIVER_SPI_SCK +spi_software_mosi_pin: DRIVER_SPI_MOSI +spi_software_miso_pin: DRIVER_SPI_MISO +interpolate: True +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 \ No newline at end of file diff --git a/user_templates/mcu.cfg b/user_templates/mcu.cfg index c69d4b8c4..cd9439758 100644 --- a/user_templates/mcu.cfg +++ b/user_templates/mcu.cfg @@ -36,6 +36,9 @@ # [include config/hardware/axis/Z/TMC/TMC2240_1-Motor.cfg] # [include config/hardware/axis/Z/TMC/TMC2240_3-Motors.cfg] # [include config/hardware/axis/Z/TMC/TMC2240_4-Motors.cfg] +# [include config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg] +# [include config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg] +# [include config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg] # ---------------------------------------------------------------------------------------- From 4fde96d519c38652dc04e3e2673d39b1a693c283 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:57:16 +0100 Subject: [PATCH 40/79] added fix to prevent issues when updating Klippain without MMU (#462) --- macros/base/end_print.cfg | 2 +- macros/base/start_print.cfg | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index dd7d5cce2..afd29f51f 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -6,7 +6,7 @@ gcode: {% set safe_extruder_temp = printer["gcode_macro _USER_VARIABLES"].safe_extruder_temp|float %} {% set light_intensity_end_print = printer["gcode_macro _USER_VARIABLES"].light_intensity_end_print %} {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} - {% set mmu_unload = params.MMU_UNLOAD_AT_END|default(printer["gcode_macro _USER_VARIABLES"].mmu_unload_on_end_print)|int %} + {% set mmu_unload = params.MMU_UNLOAD_AT_END|default(printer["gcode_macro _USER_VARIABLES"].mmu_unload_on_end_print)|default(0)|int %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} {% set light_enabled = printer["gcode_macro _USER_VARIABLES"].light_enabled %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 5ba892879..0718ed89c 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -25,7 +25,7 @@ gcode: {% set INITIAL_TOOL = params.INITIAL_TOOL|default(0)|int %} # Initial tool (for the MMU/ERCF initialization) {% set MATERIAL = params.MATERIAL|default(printer["gcode_macro _USER_VARIABLES"].print_default_material)|string %} # Material type set in the slicer {% set FL_SIZE = params.SIZE|default("0_0_0_0")|string %} # Get bounding box of the first layer for the adaptive bed mesh - {% set CHECK_GATES = params.CHECK_GATES|default(printer['gcode_macro _USER_VARIABLES'].mmu_check_gates_on_start_print)|int %} # Check if MMU gates are availables + {% set CHECK_GATES = params.CHECK_GATES|default(printer['gcode_macro _USER_VARIABLES'].mmu_check_gates_on_start_print)|default(0)|int %} # Check if MMU gates are availables {% set TOOLS_USED = params.TOOLS_USED|default("")|string %} # Check if MMU gates (used in gcode file) are availables {% set SYNC_MMU_EXTRUDER = params.SYNC_MMU_EXTRUDER|default(0)|int %} # set MMU gear motor and extruder synchronization during print TODO {% set BED_MESH_PROFILE = params.MESH|default("")|string %} # Bed mesh profile to load @@ -57,7 +57,6 @@ gcode: {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} {% set force_homing_in_start_print = printer["gcode_macro _USER_VARIABLES"].force_homing_in_start_print %} {% set klippain_mmu_enabled = printer["gcode_macro _USER_VARIABLES"].klippain_mmu_enabled %} - {% set mmu_force_homing_in_start_print = printer["gcode_macro _USER_VARIABLES"].mmu_force_homing_in_start_print %} {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set firmware_retraction_enabled = printer["gcode_macro _USER_VARIABLES"].firmware_retraction_enabled %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} From a2e8b5256f9d648e1261590ca0dcd0cbc922b487 Mon Sep 17 00:00:00 2001 From: lokiagent <75763148+lokiagent@users.noreply.github.com> Date: Tue, 20 Feb 2024 07:00:57 -0800 Subject: [PATCH 41/79] Add configs for Fysetc SB Can TH boards (#464) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Boisselier --- .../adxl345_Fysetc_SB_Can_TH.cfg | 9 ++ .../toolhead/Fysetc_SB_Can_TH_v1.x.cfg | 16 ++++ .../toolhead/Fysetc_SB_Can_TH_v1.x.cfg | 85 +++++++++++++++++++ user_templates/printer.cfg | 1 + 4 files changed, 111 insertions(+) create mode 100644 config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg create mode 100644 config/mcu_definitions/toolhead/Fysetc_SB_Can_TH_v1.x.cfg create mode 100644 user_templates/mcu_defaults/toolhead/Fysetc_SB_Can_TH_v1.x.cfg diff --git a/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg b/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg new file mode 100644 index 000000000..3dce3260e --- /dev/null +++ b/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg @@ -0,0 +1,9 @@ +[include generics/adxl345_software_spi.cfg] + +# As it's a toolhead ADXL, we add some default pins overrides from here +[adxl345] +cs_pin: toolhead:ADXL_CS +spi_software_sclk_pin: toolhead:ADXL_SCLK +spi_software_mosi_pin: toolhead:ADXL_MOSI +spi_software_miso_pin: toolhead:ADXL_MISO +axes_map: -y,z,-x diff --git a/config/mcu_definitions/toolhead/Fysetc_SB_Can_TH_v1.x.cfg b/config/mcu_definitions/toolhead/Fysetc_SB_Can_TH_v1.x.cfg new file mode 100644 index 000000000..63b87b10d --- /dev/null +++ b/config/mcu_definitions/toolhead/Fysetc_SB_Can_TH_v1.x.cfg @@ -0,0 +1,16 @@ +[board_pins toolhead_manufacturer] +mcu: toolhead +aliases: + MCU_TMCDRIVER_STEP=PA7 , MCU_TMCDRIVER_DIR=PA5 , MCU_TMCDRIVER_ENABLE=PB4 , MCU_TMCDRIVER_UART=PA10 , + MCU_EXT_DIAG=PB5 , MCU_TMCDRIVER_TX=PA9 , + + MCU_PROBE=PB6 , MCU_IO1=PB11 , MCU_IO2=PB7 , + + MCU_HE0=PA8 , + MCU_TE0=PA0 , + + MCU_FAN0_PWM=PA2 , MCU_FAN1_PWM=PA3 , + + MCU_RGB=PB1 , MCU_STATUS=PA1 , + + MCU_ADXL345_CSPIN=PB12 , MCU_ADXL345_CLK=PB13 , MCU_ADXL345_MISO=PB14 , MCU_ADXL345_MOSI=PB15 , diff --git a/user_templates/mcu_defaults/toolhead/Fysetc_SB_Can_TH_v1.x.cfg b/user_templates/mcu_defaults/toolhead/Fysetc_SB_Can_TH_v1.x.cfg new file mode 100644 index 000000000..8a1b7d612 --- /dev/null +++ b/user_templates/mcu_defaults/toolhead/Fysetc_SB_Can_TH_v1.x.cfg @@ -0,0 +1,85 @@ +#--------------------------------------------# +#### Fysetc SB Can TH v1.3 MCU definition #### +#--------------------------------------------# + +[mcu toolhead] +##-------------------------------------------------------------------- +canbus_uuid=change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +# If you want to override the wiring of the Fysetc SB Can TH, keep in mind that this +# board is defined using the "toolhead" name. So you should use "pin: toolhead:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/toolhead/Fysetc_SB_Can_TH_v1.x.cfg] # Do not remove this line + +[board_pins fysetc_mcu] +mcu: toolhead +aliases: + E_STEP=MCU_TMCDRIVER_STEP , E_DIR=MCU_TMCDRIVER_DIR , E_ENABLE=MCU_TMCDRIVER_ENABLE , E_TMCUART=MCU_TMCDRIVER_UART , + E_TXPIN=MCU_TMCDRIVER_TX , + + X_STOP=MCU_IO1 , Y_STOP=MCU_IO2 , + PROBE_INPUT=MCU_PROBE , + + E_HEATER=MCU_HE0 , E_TEMPERATURE=MCU_TE0 , + + PART_FAN=MCU_FAN0_PWM , E_FAN=MCU_FAN1_PWM , + + STATUS_NEOPIXEL=MCU_RGB , + + ADXL_CS=MCU_ADXL345_CSPIN , ADXL_SCLK=MCU_ADXL345_CLK , ADXL_MISO=MCU_ADXL345_MISO , ADXL_MOSI=MCU_ADXL345_MOSI , + +#----------------------------------------# +# Fysetc SB Can TH v1.3 pins remapping # +#----------------------------------------# + +# These pins overrides are automatically added when you select a CANbus +# toolhead MCU during the installation process. They should provide a +# good base to work with. Feel free to adapt to your board if needed! + +[extruder] +step_pin: toolhead:E_STEP +dir_pin: !toolhead:E_DIR +enable_pin: !toolhead:E_ENABLE +heater_pin: toolhead:E_HEATER +sensor_pin: toolhead:E_TEMPERATURE + +[tmc2209 extruder] +uart_pin: toolhead:E_TMCUART +tx_pin: toolhead:E_TXPIN + +## Uncomment the following line if using a prove for bed mesh +#[probe] +#pin: ^toolhead:PROBE_INPUT + +[fan] +pin: toolhead:PART_FAN + +[heater_fan hotend_fan] +pin: toolhead:E_FAN + +## Uncomment the following line if not using sensorless homing +## and having the X endstop plugged to the toolhead MCU. Make sure +## X endstop is plugged in to IO.1 on the board. +# [stepper_x] +# endstop_pin: ^toolhead:X_STOP + +## Uncomment the following line if not using sensorless homing +## and having the Y endstop plugged to the toolhead MCU. Make sure +## Yendstop is plugged in to IO.2 on the board. +# [stepper_y] +# endstop_pin: ^toolhead:Y_STOP + +[neopixel status_leds] +pin: toolhead:STATUS_NEOPIXEL + +[tmc2209 extruder] +uart_pin: toolhead:E_TMCUART + +[temperature_sensor toolhead_mcu] +sensor_type: temperature_mcu +sensor_mcu: toolhead + +[output_pin activity_led] +pin: toolhead:MCU_STATUS diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 39f6fddeb..3018c889c 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -193,6 +193,7 @@ # [include config/hardware/accelerometers/adxl345_ebb.cfg] # For ADXL plugged in BTT EBB36 or EBB42 boards # [include config/hardware/accelerometers/adxl345_sht.cfg] # For ADXL plugged in Mellow SHT36 or SHT42 boards # [include config/hardware/accelerometers/adxl345_BTT_SB22xx.cfg] # For ADXL plugged in BTT SB2209 or SB2240 boards +# [include config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg] # For ADXL plugged in Fysetc SB Can TH boards # [include config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg] # For BTT S2DW V1.0, ... # ---------------------------------------------------------------------------------------- From e0a170e0824ac1a40ef543f0eb278a1fff53e182 Mon Sep 17 00:00:00 2001 From: Arcadien Date: Tue, 20 Feb 2024 16:03:11 +0100 Subject: [PATCH 42/79] fix: make prime line height a variable parameter (#466) Fix #465 --- macros/helpers/prime_line.cfg | 25 +++++++++++++++++-------- user_templates/variables.cfg | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index f10bd3daf..baa83e2df 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -4,6 +4,11 @@ gcode: {% set prime_line_length = params.LINE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_length)|float %} {% set prime_line_purge_distance = params.PURGE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_purge_distance)|float %} {% set prime_line_flowrate = params.FLOWRATE|default(printer["gcode_macro _USER_VARIABLES"].prime_line_flowrate)|float %} + {% if printer["gcode_macro _USER_VARIABLES"].prime_line_height %} + {% set prime_line_height = params.LINE_HEIGHT|default(printer["gcode_macro _USER_VARIABLES"].prime_line_height)|float %} + {% else %} + {% set prime_line_height = params.LINE_HEIGHT|default(0.6)|float %} + {% endif %} # Set internal macro vars {% set prime_line_x, prime_line_y = printer["gcode_macro _USER_VARIABLES"].prime_line_xy|map('float') %} @@ -20,40 +25,44 @@ gcode: {% set max_extrude_cross_section = printer["configfile"].config["extruder"]["max_extrude_cross_section"]|float %} {% set filament_diameter = printer["configfile"].config["extruder"]["filament_diameter"]|float %} - {% set line_height = 0.6 %} - # some more Macro parameters after retrieving defaults {% set prime_line_x = params.START_X|default(prime_line_x)|float %} {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} + {% if verbose %} + {action_respond_info("Prime line length: %.4f" % prime_line_length)} + {action_respond_info("Prime line eight: %.4f" % prime_line_height)} + {action_respond_info("prime line extrusion length: %4.f" % prime_line_purge_distance)} + {% endif %} + # We first compute the width of the prime line {% set purge_volume = prime_line_purge_distance * 3.14159 * (filament_diameter / 2)**2 %} - {% set line_width = purge_volume / (line_height * prime_line_length) %} + {% set line_width = purge_volume / (prime_line_height * prime_line_length) %} # Then we check that the prime line cross section will not be problematic (exceeding Klipper max_extrude_cross_section) # or, if it's the case, we warn the user and add a correction to the length of filament to be purged - {% if (line_height * line_width) > max_extrude_cross_section %} + {% if (prime_line_height * line_width) > max_extrude_cross_section %} {% if verbose %} {action_respond_info("The prime_line_purge_distance of %.4f mm is too high and will exceed the max_extrude_cross_section!" % prime_line_purge_distance)} {% endif %} {% set prime_line_purge_distance = 0.98 * (max_extrude_cross_section * prime_line_length) / (3.14159 * (filament_diameter / 2)**2) %} {% set purge_volume = prime_line_purge_distance * 3.14159 * (filament_diameter / 2)**2 %} - {% set line_width = purge_volume / (line_height * prime_line_length) %} + {% set line_width = purge_volume / (prime_line_height * prime_line_length) %} {% if verbose %} {action_respond_info("Klippain corrected the prime_line_purge_distance to %.4f mm" % prime_line_purge_distance)} {% endif %} {% endif %} # We then compute the height to width ratio and validate that the prime line will not be too thin - {% if (line_height / line_width) >= 0.5 %} # TODO: validate this 1/2 ratio is good for all + {% if (prime_line_height / line_width) >= 0.5 %} # TODO: validate this 1/2 ratio is good for all {% if verbose %} {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length! Aborting...")} {% endif %} {% endif %} # Finally we compute the speed to get the correct flowrate for the prime line - {% set speed = (prime_line_flowrate / (line_height * line_width)) * 60 |float %} + {% set speed = (prime_line_flowrate / (prime_line_height * line_width)) * 60 |float %} {% if klippain_mmu_enabled %} _KLIPPAIN_MMU_SET_CLOGDETECTION STATE=0 @@ -75,7 +84,7 @@ gcode: # Starting position G90 G0 X{prime_line_x} Y{prime_line_y} F{St} - G1 Z{line_height} F{Sz|int / 2} + G1 Z{prime_line_height} F{Sz|int / 2} # Add pressure in the nozzle G92 E0 diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index a2bced1e3..070d80531 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -60,6 +60,7 @@ variable_prime_line_direction: "X" # can also be set to "Y" variable_prime_line_length: 40 # length of the prime line on the bed (in mm) variable_prime_line_purge_distance: 30 # length of filament to purge (in mm) variable_prime_line_flowrate: 10 # mm3/s used for the prime line +variable_prime_line_height: 0.6 # mm, used for actual cross section computation ## Park position used when pause, end_print, etc... variable_park_position_xy: -1, -1 From 7631b57eaa7ffdf839e25863bccf9833fb3dbc80 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:22:24 +0100 Subject: [PATCH 43/79] fix for extrude when temperature is too low (#480) --- macros/base/cancel_print.cfg | 2 +- macros/base/end_print.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index 9bc7d521a..177a84b45 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -21,7 +21,7 @@ gcode: # Unload filament and park the MMU MMU_EJECT {% endif %} - {% else %} + {% elif printer.extruder.can_extrude %} # Pull back the filament a little bit G92 E0 G1 E-10 F2100 diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index afd29f51f..ce191eb45 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -21,7 +21,7 @@ gcode: # unload filament and park into MMU. Or just unload filament out of extruder if using bypass. MMU_EJECT {% endif %} - {% else %} + {% elif printer.extruder.can_extrude %} # pull back the filament a little bit G92 E0 G1 E-10 F2100 From fbf07e2c91e638e5904be56b14c82f2f23a5ad81 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:29:50 +0100 Subject: [PATCH 44/79] Add BTT Kraken MCU support (#476) --- .../mcu_definitions/main/BTT_Kraken_v1.0.cfg | 54 +++++++++++++++++++ .../mcu_defaults/main/BTT_Kraken_v1.0.cfg | 53 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 config/mcu_definitions/main/BTT_Kraken_v1.0.cfg create mode 100644 user_templates/mcu_defaults/main/BTT_Kraken_v1.0.cfg diff --git a/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg b/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg new file mode 100644 index 000000000..0f31bee84 --- /dev/null +++ b/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg @@ -0,0 +1,54 @@ +[board_pins mcu_manufacturer] +aliases: + MCU_S1_STEP=PC14 , MCU_S1_DIR=PC13 , MCU_S1_ENABLE=PE6 , MCU_S1_UART=PD6 , + MCU_S2_STEP=PE5 , MCU_S2_DIR=PE4 , MCU_S2_ENABLE=PE3 , MCU_S2_UART=PD5 , + MCU_S3_STEP=PE2 , MCU_S3_DIR=PE1 , MCU_S3_ENABLE=PE0 , MCU_S3_UART=PD4 , + MCU_S4_STEP=PB9 , MCU_S4_DIR=PB8 , MCU_S4_ENABLE=PB7 , MCU_S4_UART=PD3 , + MCU_S5_STEP=PG9 , MCU_S5_DIR=PG10 , MCU_S5_ENABLE=PG13 , MCU_S5_UART=PD2 , + MCU_S6_STEP=PG11 , MCU_S6_DIR=PD7 , MCU_S6_ENABLE=PG12 , MCU_S6_UART=PA15 , + MCU_S7_STEP=PB4 , MCU_S7_DIR=PB3 , MCU_S7_ENABLE=PB5 , MCU_S7_UART=PA9 , + MCU_S8_STEP=PG15 , MCU_S8_DIR=PB6 , MCU_S8_ENABLE=PG14 , MCU_S8_UART=PA10 , + MCU_MOSI=PC8 , MCU_MISO=PC7 , MCU_SCK=PC6 , + + MCU_MOTOR_SERVO=PE7 , + MCU_RGB1=PF10 , MCU_RGB2=PF11 , + MCU_MIN1=PC15 , MCU_MIN2=PF0 , MCU_MIN3=PF1 , MCU_MIN4=PF2 , + MCU_MIN5=PF3 , MCU_MIN6=PF4 , MCU_MIN7=PF10 , MCU_MIN8=PC0 , + + MCU_HE0=PF6 , MCU_HE1=PF7 , MCU_HE2=PF9 , MCU_HE3=PF8 , + + MCU_BED_OUT=PF5 , + + MCU_TB=PB0 , + MCU_T0=PB1 , MCU_T1=PC5 , MCU_T2=PC4 , MCU_T3=PA7 , + + MCU_FAN0=PA0 , MCU_FAN1=PA1 , MCU_FAN2=PA2 , MCU_FAN3=PA3 , MCU_FAN4=PA4 , MCU_FAN5=PA5 , + MCU_FAN6=PA6 , MCU_FAN7=PE8 , + MCU_FAN6_TACH=PC1 , MCU_FAN7_TACH=PG0 , + + MCU_PS_ON=PD10 , + MCU_FWS1=PC2 , MCU_FWS2=PC3 , + + MCU_IND_DET=PD11 , + # PROBE header + MCU_PROBE=PC1 , MCU_PROBE_SERVO=PE9 , + + # SPI header + MCU_SPI_1=<5V> , MCU_SPI_2= , + MCU_SPI_3=PE10 , MCU_SPI_4=PE12 , + MCU_SPI_5=PE14 , MCU_SPI_6=PE13 , + MCU_SPI_7=<3.3V> , MCU_SPI_8= , + + # EXP1 header + EXP1_1=PG5 , EXP1_2=PG4 , + EXP1_3=PG3 , EXP1_4=PG2 , + EXP1_5=PD15 , EXP1_6=PD14 , # Slot in the socket on this side + EXP1_7=PD13 , EXP1_8=PD12 , + EXP1_9= , EXP1_10=<5V> , + + # EXP2 header + EXP2_1=PE13 , EXP2_2=PE12 , + EXP2_3=PG8 , EXP2_4=PE11 , + EXP2_5=PG7 , EXP2_6=PE14 , # Slot in the socket on this side + EXP2_7=PG6 , EXP2_8= , + EXP2_9= , EXP2_10=<5V> , diff --git a/user_templates/mcu_defaults/main/BTT_Kraken_v1.0.cfg b/user_templates/mcu_defaults/main/BTT_Kraken_v1.0.cfg new file mode 100644 index 000000000..4b29f6c91 --- /dev/null +++ b/user_templates/mcu_defaults/main/BTT_Kraken_v1.0.cfg @@ -0,0 +1,53 @@ + +#--------------------------------------# +##### BTT Kraken MCU definition ######## +#--------------------------------------# + +[mcu] +##-------------------------------------------------------------------- +# This board work by using a serial connection by default. If you +# want to use CAN, invert the commented lines and use canbus_uuid. + +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/BTT_Kraken_v1.0.cfg] # Do not remove this line +[board_pins kraken_mcu] +mcu: mcu +aliases: + X_STEP=MCU_S1_STEP , X_DIR=MCU_S1_DIR , X_ENABLE=MCU_S1_ENABLE , X_TMCUART=MCU_S1_UART , + Y_STEP=MCU_S2_STEP , Y_DIR=MCU_S2_DIR , Y_ENABLE=MCU_S2_ENABLE , Y_TMCUART=MCU_S2_UART , + + Z_STEP=MCU_S5_STEP , Z_DIR=MCU_S5_DIR , Z_ENABLE=MCU_S5_ENABLE , Z_TMCUART=MCU_S5_UART , + Z1_STEP=MCU_S6_STEP , Z1_DIR=MCU_S6_DIR , Z1_ENABLE=MCU_S6_ENABLE , Z1_TMCUART=MCU_S6_UART , + Z2_STEP=MCU_S7_STEP , Z2_DIR=MCU_S7_DIR , Z2_ENABLE=MCU_S7_ENABLE , Z2_TMCUART=MCU_S7_UART , + Z3_STEP=MCU_S8_STEP , Z3_DIR=MCU_S8_DIR , Z3_ENABLE=MCU_S8_ENABLE , Z3_TMCUART=MCU_S8_UART , + + E_STEP=MCU_S3_STEP , E_DIR=MCU_S3_DIR , E_ENABLE=MCU_S3_ENABLE , E_TMCUART=MCU_S3_UART , + + DRIVER_SPI_MOSI=MCU_MOSI , # Used in case of SPI drivers + DRIVER_SPI_MISO=MCU_MISO , # Used in case of SPI drivers + DRIVER_SPI_SCK=MCU_SCK , # Used in case of SPI drivers + + X_STOP= MCU_MIN1 , Y_STOP=MCU_MIN2 , Z_STOP=MCU_MIN5 , + PROBE_INPUT=MCU_IND_DET , + RUNOUT_SENSOR=MCU_MIN4 , + + E_HEATER=MCU_HE0 , E_TEMPERATURE=MCU_T0 , + BED_HEATER=MCU_BED_OUT , BED_TEMPERATURE=MCU_TB , + + PART_FAN=MCU_FAN7 , E_FAN=MCU_FAN6 , + CONTROLLER_FAN=MCU_FAN2 , + EXHAUST_FAN=MCU_FAN3 , + FILTER_FAN=MCU_FAN4 , + HOST_CONTROLLER_FAN=MCU_FAN5 , + + CHAMBER_TEMPERATURE=MCU_T1 , ELECTRICAL_CABINET_TEMPERATURE=MCU_T2 , + + LIGHT_OUTPUT=MCU_HE2 , + LIGHT_NEOPIXEL=MCU_RGB1 , + STATUS_NEOPIXEL=MCU_RGB2 , + + SERVO_PIN=MCU_MOTOR_SERVO , + From ed5ff00bdc1650efbe0d797325c75fed387d75b6 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:14:15 +0100 Subject: [PATCH 45/79] Update Fysetc_Spider_v3.x.cfg to fix fan ports (#474) --- user_templates/mcu_defaults/main/Fysetc_Spider_v3.x.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/user_templates/mcu_defaults/main/Fysetc_Spider_v3.x.cfg b/user_templates/mcu_defaults/main/Fysetc_Spider_v3.x.cfg index 0069a89ff..68f7e8550 100644 --- a/user_templates/mcu_defaults/main/Fysetc_Spider_v3.x.cfg +++ b/user_templates/mcu_defaults/main/Fysetc_Spider_v3.x.cfg @@ -39,10 +39,10 @@ aliases: BED_HEATER=MCU_BED_OUT , BED_TEMPERATURE=MCU_TB , PART_FAN=MCU_FAN1 , E_FAN=MCU_FAN0 , - CONTROLLER_FAN=MCU_FAN2 , - EXHAUST_FAN=MCU_HEAT2 , - FILTER_FAN=MCU_RGB_R , - HOST_CONTROLLER_FAN=MCU_RGB_G , + CONTROLLER_FAN=MCU_FAN2 , + EXHAUST_FAN=MCU_HEAT2 , + FILTER_FAN=MCU_FAN4 , + HOST_CONTROLLER_FAN=MCU_FAN3 , CHAMBER_TEMPERATURE=MCU_TE1 , ELECTRICAL_CABINET_TEMPERATURE=MCU_TE2 , From 795fb3f94f8db0050f82fc5b61b5574d3c7cf3b0 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:23:47 +0100 Subject: [PATCH 46/79] fix BTT_MMB pin (#486) --- config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg b/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg index 8cab0186d..559e548a2 100644 --- a/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg +++ b/config/mcu_definitions/mmu/BTT_MMB_CAN_v1.0.cfg @@ -8,8 +8,8 @@ aliases: MCU_MISO=PA6 , MCU_SCK=PA5 , MCU_MOSI=PA7 , - MCU_STP1=PA3 , MCU_STP2=PA4 , MCU_STP3=PB8 , # Shared with Steppers Diag pins 1-2-4 so it's better to use STP 4-11 for others servos/sensors - MCU_STP4=PB7 , MCU_STP5=PC15 , MCU_STP6=PC13 , MCU_STP7=PC14 , MCU_STP8=PB12 , MCU_STP9=PB11 , MCU_STP10=PB10 , MCU_STP11=PB2 , + MCU_STP1=PA3 , MCU_STP2=PA4 , MCU_STP3=PB9 , # Shared with Steppers Diag pins 1-2-4 so it's better to use STP 4-11 for others servos/sensors + MCU_STP4=PB8 , MCU_STP5=PC15 , MCU_STP6=PC13 , MCU_STP7=PC14 , MCU_STP8=PB12 , MCU_STP9=PB11 , MCU_STP10=PB10 , MCU_STP11=PB2 , MCU_MOT=PA0 , From 5b1763b00e4c6c8df54520999489caa56a6b8838 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:18:31 +0100 Subject: [PATCH 47/79] added fix for rsense for TMC5160 (#489) --- config/hardware/axis/X/TMC/TMC5160.cfg | 2 +- config/hardware/axis/Y/TMC/TMC5160.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/hardware/axis/X/TMC/TMC5160.cfg b/config/hardware/axis/X/TMC/TMC5160.cfg index 98bb51a57..248485e34 100644 --- a/config/hardware/axis/X/TMC/TMC5160.cfg +++ b/config/hardware/axis/X/TMC/TMC5160.cfg @@ -11,5 +11,5 @@ spi_software_mosi_pin: DRIVER_SPI_MOSI spi_software_miso_pin: DRIVER_SPI_MISO interpolate: True run_current: 0.8 -sense_resistor: 0.110 +sense_resistor: 0.075 stealthchop_threshold: 0 diff --git a/config/hardware/axis/Y/TMC/TMC5160.cfg b/config/hardware/axis/Y/TMC/TMC5160.cfg index 90598c190..92fe211d7 100644 --- a/config/hardware/axis/Y/TMC/TMC5160.cfg +++ b/config/hardware/axis/Y/TMC/TMC5160.cfg @@ -11,5 +11,5 @@ spi_software_mosi_pin: DRIVER_SPI_MOSI spi_software_miso_pin: DRIVER_SPI_MISO interpolate: True run_current: 0.8 -sense_resistor: 0.110 +sense_resistor: 0.075 stealthchop_threshold: 0 From 4dd8a61329961a57a4403c0bbacbbf7ffd965260 Mon Sep 17 00:00:00 2001 From: Tyler Olson Date: Thu, 22 Feb 2024 03:21:39 -0500 Subject: [PATCH 48/79] Add support for dockable probes with separate retainer (#401) This is needed for probes like https://github.com/kevinakasam/KlackEnder-Probe --- macros/base/probing/dockable_probe.cfg | 12 ++++++++++-- .../probing/overides/dockable_probe_overides.cfg | 8 ++++++++ user_templates/variables.cfg | 5 +++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/macros/base/probing/dockable_probe.cfg b/macros/base/probing/dockable_probe.cfg index d3739b7e7..42659ca21 100644 --- a/macros/base/probing/dockable_probe.cfg +++ b/macros/base/probing/dockable_probe.cfg @@ -211,6 +211,9 @@ gcode: {% set probe_servo_enabled = printer["gcode_macro _USER_VARIABLES"].probe_servo_enabled %} + # Probe stow height + {% set probe_stow_z_height = printer["gcode_macro _USER_VARIABLES"].probe_stow_z_height|default(None) %} + _ENTRY_POINT FUNCTION=DOCK_PROBE @@ -247,7 +250,7 @@ gcode: {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{probe_dock_accel} - # Probe entry location + # Move to probe entry location _PROBE_MOVE_TO LOCATION={probe_before_dock_position} DISTANCE={probe_move_dock_length} SPEED={travel_speed} # Deploy dock using the servo (if available) @@ -255,9 +258,14 @@ gcode: _SERVO_DEPLOY ITEM="probe" {% endif %} - # Pickup from Probe location + # Move probe into dock _PROBE_MOVE_TO LOCATION='dock' SPEED={probe_dock_speed} + # Move probe to stow z height if defined + {% if probe_stow_z_height is not none %} + G0 Z{probe_stow_z_height} F{z_drop_speed} + {% endif %} + # Get detach probe _PROBE_MOVE_TO LOCATION={probe_after_dock_position} DISTANCE={probe_move_dock_length} SPEED={probe_dock_speed} diff --git a/macros/base/probing/overides/dockable_probe_overides.cfg b/macros/base/probing/overides/dockable_probe_overides.cfg index 8eb4ae744..e2f574881 100644 --- a/macros/base/probing/overides/dockable_probe_overides.cfg +++ b/macros/base/probing/overides/dockable_probe_overides.cfg @@ -46,6 +46,10 @@ gcode: %}{'%s=%s ' % (p, params[p])}{% endfor %} + # Save nozzle location before dock + M400 + _ENTRY_POINT FUNCTION=PROBE_CALIBRATE + DEACTIVATE_PROBE # Restore nozzle location again at the end @@ -95,6 +99,10 @@ gcode: %}{'%s=%s ' % (p, params[p])}{% endfor %} + # Save nozzle location before dock + M400 + _ENTRY_POINT FUNCTION=PROBE_CALIBRATE + DEACTIVATE_PROBE # Restore nozzle location again at the end diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index c6f0468ed..74cecfad6 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -84,6 +84,11 @@ variable_max_bed_xy: 9999, 9999 ## Minimum safe Z height to attach/detach probe variable_probe_min_z_travel: 20 +## Z height to move to when detaching probe +## Setting to 'None' or removing this variable will prevent any +## change in z position when detaching the probe +variable_probe_stow_z_height: None + ## Position of the probe dock variable_probe_dock_location_xy: -1, -1 From 0589d244c15789b1a82e51eb0facb7d09519e462 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Thu, 22 Feb 2024 21:43:44 +0100 Subject: [PATCH 49/79] fix for rsense on TMC5160 Z (#490) --- config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg | 2 +- config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg | 4 ++-- config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg b/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg index 84bbe5207..991470198 100644 --- a/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg +++ b/config/hardware/axis/Z/TMC/TMC5160_1-Motor.cfg @@ -14,5 +14,5 @@ spi_software_mosi_pin: DRIVER_SPI_MOSI spi_software_miso_pin: DRIVER_SPI_MISO interpolate: True run_current: 0.8 -sense_resistor: 0.110 +sense_resistor: 0.075 stealthchop_threshold: 0 \ No newline at end of file diff --git a/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg b/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg index 54cbeaa83..4a6b57679 100644 --- a/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg +++ b/config/hardware/axis/Z/TMC/TMC5160_3-Motors.cfg @@ -8,7 +8,7 @@ spi_software_mosi_pin: DRIVER_SPI_MOSI spi_software_miso_pin: DRIVER_SPI_MISO interpolate: True run_current: 0.8 -sense_resistor: 0.110 +sense_resistor: 0.075 stealthchop_threshold: 0 [tmc5160 stepper_z2] @@ -19,5 +19,5 @@ spi_software_mosi_pin: DRIVER_SPI_MOSI spi_software_miso_pin: DRIVER_SPI_MISO interpolate: True run_current: 0.8 -sense_resistor: 0.110 +sense_resistor: 0.075 stealthchop_threshold: 0 \ No newline at end of file diff --git a/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg b/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg index 4fb3eec64..a47270201 100644 --- a/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg +++ b/config/hardware/axis/Z/TMC/TMC5160_4-Motors.cfg @@ -8,5 +8,5 @@ spi_software_mosi_pin: DRIVER_SPI_MOSI spi_software_miso_pin: DRIVER_SPI_MISO interpolate: True run_current: 0.8 -sense_resistor: 0.110 +sense_resistor: 0.075 stealthchop_threshold: 0 \ No newline at end of file From ef862adede0bf1f40211df3474e0bf6d61f3b9c1 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:04:19 +0100 Subject: [PATCH 50/79] Create stale action workflow (#449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Boisselier --- .github/workflows/stale.yml | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..9e70ab55a --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,40 @@ +name: Mark and Manage Stale Issues and Pull Requests + +on: + schedule: + - cron: '30 7 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v9.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-stale: 30 + days-before-close: 14 + stale-issue-message: > + 📌 **This issue has been marked as stale because it has not had activity in the past 30 days.** + + To keep it open, please respond to this message or add new information. Otherwise, this will be closed in 14 days. + + Thank you for your contributions! + stale-pr-message: > + 📌 **This pull request has been marked as stale because it has not had activity in the past 30 days.** + + Please update the PR or comment to keep it active. Otherwise, this will be closed in 14 days. + + We appreciate your contribution! + stale-issue-label: 'stale' + stale-pr-label: 'stale, reviewer-needed' + exempt-issue-labels: 'tracking' + exempt-pr-labels: 'tracking' + close-issue-message: 'This issue was closed due to inactivity for 14 days. Feel free to reopen it if you think it was an error or if there's new information or progress.' + close-pr-message: 'This pull request was closed due to inactivity for 14 days. Please reopen it if you think it was an error or if you wish to continue the contribution.' + exempt-all-milestones: true + exempt-all-assignees: true + exempt-draft-prs: true From 7de5d57e2ba1274d0f1018f6fa5be2b360c341bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Thu, 22 Feb 2024 23:22:26 +0100 Subject: [PATCH 51/79] fixed K-Shake&Tune integration --- config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg | 1 - config/hardware/accelerometers/adxl345_rpi.cfg | 2 +- config/hardware/accelerometers/adxl345_usb.cfg | 2 +- config/hardware/accelerometers/adxl345_usb_rampon.cfg | 2 +- config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg | 2 +- .../accelerometers/generics/adxl345_hardware_spi1.cfg | 2 +- .../accelerometers/generics/adxl345_hardware_ssp1.cfg | 2 +- .../accelerometers/generics/adxl345_software_spi.cfg | 2 +- config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg | 5 ++--- 9 files changed, 9 insertions(+), 11 deletions(-) diff --git a/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg b/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg index 3dce3260e..9f06e9d80 100644 --- a/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg +++ b/config/hardware/accelerometers/adxl345_Fysetc_SB_Can_TH.cfg @@ -6,4 +6,3 @@ cs_pin: toolhead:ADXL_CS spi_software_sclk_pin: toolhead:ADXL_SCLK spi_software_mosi_pin: toolhead:ADXL_MOSI spi_software_miso_pin: toolhead:ADXL_MISO -axes_map: -y,z,-x diff --git a/config/hardware/accelerometers/adxl345_rpi.cfg b/config/hardware/accelerometers/adxl345_rpi.cfg index 172ff2980..b65ff26dc 100644 --- a/config/hardware/accelerometers/adxl345_rpi.cfg +++ b/config/hardware/accelerometers/adxl345_rpi.cfg @@ -21,4 +21,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../scripts/K-ShakeTune/*.cfg] +[include ../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/adxl345_usb.cfg b/config/hardware/accelerometers/adxl345_usb.cfg index b73e4043f..0bd2edb72 100644 --- a/config/hardware/accelerometers/adxl345_usb.cfg +++ b/config/hardware/accelerometers/adxl345_usb.cfg @@ -22,4 +22,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../scripts/K-ShakeTune/*.cfg] +[include ../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/adxl345_usb_rampon.cfg b/config/hardware/accelerometers/adxl345_usb_rampon.cfg index 20947d46f..0dcb97bb5 100644 --- a/config/hardware/accelerometers/adxl345_usb_rampon.cfg +++ b/config/hardware/accelerometers/adxl345_usb_rampon.cfg @@ -21,4 +21,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../scripts/K-ShakeTune/*.cfg] +[include ../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg b/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg index 2eb968368..f03a7e46c 100644 --- a/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg +++ b/config/hardware/accelerometers/adxl345_usb_rp2040_spi1.cfg @@ -25,4 +25,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../scripts/K-ShakeTune/*.cfg] +[include ../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg b/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg index f1906ee06..7906be329 100644 --- a/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg +++ b/config/hardware/accelerometers/generics/adxl345_hardware_spi1.cfg @@ -21,4 +21,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../../macros/helpers/resonance_override.cfg] -[include ../../../../scripts/K-ShakeTune/*.cfg] +[include ../../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg b/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg index c5bf2a71f..9089059c4 100644 --- a/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg +++ b/config/hardware/accelerometers/generics/adxl345_hardware_ssp1.cfg @@ -18,4 +18,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../../macros/helpers/resonance_override.cfg] -[include ../../../../scripts/K-ShakeTune/*.cfg] +[include ../../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/generics/adxl345_software_spi.cfg b/config/hardware/accelerometers/generics/adxl345_software_spi.cfg index 2c279e581..9318acf80 100644 --- a/config/hardware/accelerometers/generics/adxl345_software_spi.cfg +++ b/config/hardware/accelerometers/generics/adxl345_software_spi.cfg @@ -22,4 +22,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../../macros/helpers/resonance_override.cfg] -[include ../../../../scripts/K-ShakeTune/*.cfg] +[include ../../../../scripts/K-ShakeTune/K-SnT_*.cfg] diff --git a/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg b/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg index a9063b3fa..fdba7f843 100644 --- a/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg +++ b/config/hardware/accelerometers/lis2dw_usb_rp2040_spi1.cfg @@ -11,7 +11,7 @@ serial: /dev/serial/by-id/xxx [lis2dw] cs_pin: lis2dw_mcu:gpio9 spi_bus: spi1a -axes_map: -y,x,-z +axes_map: x,y,z [resonance_tester] accel_chip: lis2dw @@ -22,5 +22,4 @@ probe_points: # Include the IS calibration macros to unlock them when # an accelerometer is installed on the machine [include ../../../macros/helpers/resonance_override.cfg] -[include ../../../macros/calibration/IS_shaper_calibrate.cfg] -[include ../../../macros/calibration/IS_vibrations_measurement.cfg] +[include ../../../scripts/K-ShakeTune/K-SnT_*.cfg] From 405a98e99bc7126b6cae3046913d26058bfa10a0 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:11:58 +0100 Subject: [PATCH 52/79] Avoid cooling hotend in extruder_preheating #495 (#496) --- macros/base/start_print.cfg | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 0718ed89c..e98859a1c 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -414,6 +414,7 @@ gcode: # Preheat the nozzle to safe probing temperature. {% set safe_extruder_temp = printer["gcode_macro _USER_VARIABLES"].safe_extruder_temp|float %} {% set status_leds_enabled = printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} + {% set probe_type_enabled = printer["gcode_macro _USER_VARIABLES"].probe_type_enabled %} {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} {% if status_leds_enabled %} @@ -423,10 +424,22 @@ gcode: RESPOND MSG="Pre-heating the nozzle to a safe temperature..." {% endif %} - M109 S{safe_extruder_temp} - - {% if verbose %} - RESPOND MSG="Extruder at safe temperature of {safe_extruder_temp} degrees" + {% if probe_type_enabled == "vorontap" %} + M109 S{safe_extruder_temp} + {% if verbose %} + RESPOND MSG="Extruder at safe temperature of {safe_extruder_temp} degrees" + {% endif %} + {% else %} + {% if printer.extruder.target < safe_extruder_temp %} + M104 S{safe_extruder_temp} + {% if verbose %} + RESPOND MSG="Extruder is heating at temperature of {safe_extruder_temp} degrees" + {% endif %} + {% else %} + {% if verbose %} + RESPOND MSG="Extruder is already hot" + {% endif %} + {% endif %} {% endif %} From 9e50375c034d054e6fb705d6eb110722198deb76 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Sun, 25 Feb 2024 17:37:35 +0100 Subject: [PATCH 53/79] Add a park front macro for toolhead maintenance (#494) --- macros/base/park.cfg | 62 +++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/macros/base/park.cfg b/macros/base/park.cfg index 0c1196925..b6b24c212 100644 --- a/macros/base/park.cfg +++ b/macros/base/park.cfg @@ -24,30 +24,44 @@ gcode: {% set z_safe = max_z %} {% endif %} - {% if printer.toolhead.homed_axes != "xyz" %} - RESPOND MSG="Cannot park because XYZ not homed" - {% else %} # retract filament before move up toolhead - {% if printer.extruder.can_extrude %} - {% if firmware_retraction_enabled %} # use firmware_retraction parameter for retract (in case firmware retraction is selected in printer.cfg) - {% if verbose %} - RESPOND MSG="Firmware retraction enabled, Extruder retraction = {printer.firmware_retraction.retract_length}" - {% endif %} - G10 - {% else %} # otherwise: - {% if MATERIAL != "XXX" %} # use material parameter if available for retract, otherwise use default value - {% set material = printer["gcode_macro _USER_VARIABLES"].material_parameters[MATERIAL] %} - {% set E = material.retract_length %} - {% endif %} - {% if verbose %} - RESPOND MSG="Firmware retraction disabled, Extruder retraction = {E}" - {% endif %} - G92 E0 - G1 E-{E} F2100 + _CG28 ; home if not already homed + + {% if printer.extruder.can_extrude %} + {% if firmware_retraction_enabled %} # use firmware_retraction parameter for retract (in case firmware retraction is selected in printer.cfg) + {% if verbose %} + RESPOND MSG="Firmware retraction enabled, Extruder retraction = {printer.firmware_retraction.retract_length}" + {% endif %} + G10 + {% else %} # otherwise: + {% if MATERIAL != "XXX" %} # use material parameter if available for retract, otherwise use default value + {% set material = printer["gcode_macro _USER_VARIABLES"].material_parameters[MATERIAL] %} + {% set E = material.retract_length %} + {% endif %} + {% if verbose %} + RESPOND MSG="Firmware retraction disabled, Extruder retraction = {E}" {% endif %} - {% else %} - RESPOND MSG="no extruder retraction because extruder temperature ({printer.extruder.temperature}) is lower than min_extrude_temp ({printer.configfile.config.extruder.min_extrude_temp})" + G92 E0 + G1 E-{E} F2100 {% endif %} - G90 - G1 Z{z_safe} F{Sz} - G0 X{Px} Y{Py} F{St} + {% else %} + RESPOND MSG="no extruder retraction because extruder temperature ({printer.extruder.temperature}) is lower than min_extrude_temp ({printer.configfile.config.extruder.min_extrude_temp})" {% endif %} + + G90 + G1 Z{z_safe} F{Sz} + G0 X{Px} Y{Py} F{St} + + +[gcode_macro PARK_FRONT] +description: Park the toolhead on the front of the printer for maintenance +gcode: + {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed * 60 %} + {% set Sz = printer["gcode_macro _USER_VARIABLES"].z_drop_speed * 60 %} + + _CG28 ; home if not already homed + + SAVE_GCODE_STATE NAME=PARK_FRONT + G90 ; absolute positioning + G0 Z{printer.toolhead.axis_maximum.z/3*2} F{Sz} + G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+10} F{St} + RESTORE_GCODE_STATE NAME=PARK_FRONT From b14490afe84b86331b7c3b1cfd3cc82fb1afc606 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Sun, 25 Feb 2024 17:41:20 +0100 Subject: [PATCH 54/79] Update MMU include order to allow overriding default HH defs (#497) --- user_templates/printer.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index 3018c889c..a6485d270 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -210,10 +210,11 @@ ### -------------------------------------------------------------------------------------- ### Klippain is designed to be used with the MMU/ERCF HappyHare software backend: https://github.com/moggieuk/Happy-Hare ### Please refer to the corresponding Klippain documentation: https://github.com/Frix-x/klippain/blob/main/docs/mmu.md -# [include config/hardware/mmu.cfg] # [include mmu/base/mmu_*.cfg] +# [include config/hardware/mmu.cfg] # [include mmu/optional/mmu_menu.cfg] # Optional: use it if you also have a Mini12864 display and want to add the MMU/ERCF menu entries +# [include mmu/addons/mmu_erec_cutter.cfg] # Optional: only for EREC Filament Cutter Support # ---------------------------------------------------------------------------------------- From 69b453bf0e01956541786923613a1140557b5175 Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Sun, 25 Feb 2024 18:08:43 +0100 Subject: [PATCH 55/79] avoid led effect flashing on startup if leds desabled on startup (#500) --- config/hardware/lights/neopixel_caselight_effects.cfg | 2 +- config/hardware/lights/status_leds_effects.cfg | 2 +- config/hardware/lights/status_leds_rainbow_barf_effects.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/hardware/lights/neopixel_caselight_effects.cfg b/config/hardware/lights/neopixel_caselight_effects.cfg index 748e20814..21c6bc8f9 100644 --- a/config/hardware/lights/neopixel_caselight_effects.cfg +++ b/config/hardware/lights/neopixel_caselight_effects.cfg @@ -168,7 +168,7 @@ layers: [led_effect cl_startup] leds: neopixel:caselight -autostart: true +autostart: false frame_rate: 24 layers: gradient 0.3 1 add (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0) diff --git a/config/hardware/lights/status_leds_effects.cfg b/config/hardware/lights/status_leds_effects.cfg index f14cbe7bf..dfa7db8df 100644 --- a/config/hardware/lights/status_leds_effects.cfg +++ b/config/hardware/lights/status_leds_effects.cfg @@ -213,7 +213,7 @@ layers: [led_effect startup] leds: neopixel:status_leds -autostart: true +autostart: false frame_rate: 24 layers: gradient 0.3 1 add (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0) diff --git a/config/hardware/lights/status_leds_rainbow_barf_effects.cfg b/config/hardware/lights/status_leds_rainbow_barf_effects.cfg index 14c7e6e9f..f8bbe2662 100644 --- a/config/hardware/lights/status_leds_rainbow_barf_effects.cfg +++ b/config/hardware/lights/status_leds_rainbow_barf_effects.cfg @@ -213,7 +213,7 @@ layers: [led_effect startup] leds: neopixel:status_leds -autostart: true +autostart: false frame_rate: 24 layers: gradient 0.3 1 add (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0) From 9fc555d2580e7dd4c9fc4a4fd98f0feeb4c488b3 Mon Sep 17 00:00:00 2001 From: tsk-2222 <111063724+tsk-2222@users.noreply.github.com> Date: Mon, 26 Feb 2024 05:10:02 -0500 Subject: [PATCH 56/79] Added BTT SKR2 board template (#503) --- config/mcu_definitions/main/BTT_SKR_2.cfg | 75 +++++++++++++++++++ .../mcu_defaults/main/BTT_SKR_2.cfg | 44 +++++++++++ 2 files changed, 119 insertions(+) create mode 100644 config/mcu_definitions/main/BTT_SKR_2.cfg create mode 100644 user_templates/mcu_defaults/main/BTT_SKR_2.cfg diff --git a/config/mcu_definitions/main/BTT_SKR_2.cfg b/config/mcu_definitions/main/BTT_SKR_2.cfg new file mode 100644 index 000000000..838159102 --- /dev/null +++ b/config/mcu_definitions/main/BTT_SKR_2.cfg @@ -0,0 +1,75 @@ +#-----------------------------------------# +#### BTT SKR2 MCU Board Pin definition #### +#-----------------------------------------# + +# This file contains pin mappings for the BTT SKR2 board. To +# use this config, during "make menuconfig" select the STM32F407 or STM32F429 processor with +# a "32KiB bootloader" offset, 8Mhz Clock reference, and USB PA11 PA12 communication. + +# To flash this firmware: copy "out/klipper.bin" to an SD card, rename it to "firmware.bin", and +# turn on the printer with the card inserted. Upon successful upload, the firmware will be +# renamed to firmware.cur. + +# https://github.com/bigtreetech/SKR-2/blob/master/Hardware/BIGTREETECH%20SKR%202-Pin.pdf +# https://github.com/bigtreetech/SKR-2/blob/master/Hardware/BIGTREETECH%20SKR%202-SCH.pdf + +[board_pins mcu_manufacturer] +aliases: + MCU_XM_STEP=PE2 , MCU_XM_DIR=PE1 , MCU_XM_ENABLE=PE3 , MCU_XM_UART=PE0 , + MCU_YM_STEP=PD5 , MCU_YM_DIR=PD4 , MCU_YM_ENABLE=PD6 , MCU_YM_UART=PD3 , + MCU_ZM_STEP=PA15 , MCU_ZM_DIR=PA8 , MCU_ZM_ENABLE=PD1 , MCU_ZM_UART=PD0 , + MCU_E0M_STEP=PD15 , MCU_E0M_DIR=PD14 , MCU_E0M_ENABLE=PC7 , MCU_E0M_UART=PC6 , + MCU_E1M_STEP=PD11 , MCU_E1M_DIR=PD10 , MCU_E1M_ENABLE=PD13 , MCU_E1M_UART=PD12 , + + MCU_MOTSPI_MISO=PA14 , MCU_MOTSPI_MOSI=PE14 , MCU_MOTSPI_SCK=PE15 , + + MCU_XSTOP=PC1 , MCU_YSTOP=PC3 , MCU_ZSTOP=PC0 , + MCU_E0DET=PC2 , MCU_E1DET=PA0 , MCU_PWRDET=PC15 , + + MCU_HE0=PB3 , MCU_HE1=PB4 , + MCU_BED=PD7 , + + MCU_PSON=PE8 , MCU_MPWR=PC13 , + + MCU_TB=PA1 , MCU_TH0=PA2 , MCU_TH1=PA3 , + + MCU_FAN0=PB7 , MCU_FAN1=PB6 , MCU_FAN2=PB5 , + + MCU_RGB=PE6 , + + MCU_SERVOS=PE5 , MCU_PROBE=PE4 , + + # EXP1 header + EXP1_1=PC5 , EXP1_2=PB0 , + EXP1_3=PB1 , EXP1_4=PB9 , + EXP1_5=PE10 , EXP1_6=PE11 , # Key in the socket on this side + EXP1_7=PE12 , EXP1_8=PE13 , + EXP1_9= , EXP1_10=<5V> , + + # EXP2 header + EXP2_1=PA6 , EXP2_2=PA5 , + EXP2_3=PE7 , EXP2_4=PA4 , + EXP2_5=PB2 , EXP2_6=PA7 , # Key in the socket on this side + EXP2_7=PC4 , EXP2_8= , + EXP2_9= , EXP2_10= , + + # TFT header + MCU_TFT_1=<5V> , + MCU_TFT_2= , + MCU_TFT_3=PA9 , + MCU_TFT_4=PA10 , + MCU_TFT_5= , + + # Mini-SD + MCU_MINISD_DATA1=PC9 , MCU_MINISD_DATA0=PC8 , MCU_MINISD_CLK=PC12 , MCU_MINISD_CMD=PD2 , MCU_MINISD_DATA3=PC11 , MCU_MINISD_DATA2=PC10 , + + # WIFI + MCU_WIFI_GND= , MCU_WIFI_VCC=<3.3V> , + MCU_WIFI_IO15=PB12 , MCU_WIFI_IO13=PB15 , + MCU_WIFI_IO2= , MCU_WIFI_IO12=PB14 , + MCU_WIFI_IO0=PB10 , MCU_WIFI_IO14=PB13 , + MCU_WIFI_IO4=PB11 , MCU_WIFI_IO16= , + MCU_WIFI_IO5= , MCU_WIFI_EN= , + MCU_WIFI_RXD=PD8 , MCU_WIFI_ADC= , + MCU_WIFI_TXD=PD9 , MCU_WIFI_RST=PC14 , + diff --git a/user_templates/mcu_defaults/main/BTT_SKR_2.cfg b/user_templates/mcu_defaults/main/BTT_SKR_2.cfg new file mode 100644 index 000000000..a3bfe70a6 --- /dev/null +++ b/user_templates/mcu_defaults/main/BTT_SKR_2.cfg @@ -0,0 +1,44 @@ +#-------------------------------# +#### BTT SKR2 MCU definition #### +#-------------------------------# + +[mcu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/BTT_SKR_2.cfg] # Do not remove this line +[board_pins SKR_2_mcu] +mcu: mcu +aliases: + X_STEP=MCU_XM_STEP , X_DIR=MCU_XM_DIR , X_ENABLE=MCU_XM_ENABLE , X_TMCUART=MCU_XM_UART , + Y_STEP=MCU_YM_STEP , Y_DIR=MCU_YM_DIR , Y_ENABLE=MCU_YM_ENABLE , Y_TMCUART=MCU_YM_UART , + Z_STEP=MCU_ZM_STEP , Z_DIR=MCU_ZM_DIR , Z_ENABLE=MCU_ZM_ENABLE , Z_TMCUART=MCU_ZM_UART , + E_STEP=MCU_E0M_STEP , E_DIR=MCU_E0M_DIR , E_ENABLE=MCU_E0M_ENABLE , E_TMCUART=MCU_E0M_UART , + E1_STEP=MCU_E1M_STEP , E1_DIR=MCU_E1M_DIR , E1_ENABLE=MCU_E1M_ENABLE , E1_TMCUART=MCU_E1M_UART , + + X_STOP=MCU_XSTOP , Y_STOP=MCU_YSTOP , Z_STOP=MCU_ZSTOP , + RUNOUT_SENSOR=MCU_E0DET , RUNOUT_SENSOR1=MCU_E1DET , POWER_DETECT=MCU_PWRDET , + PROBE_INPUT=MCU_PROBE , + SERVO_PIN=MCU_SERVOS , + + E_HEATER=MCU_HE0 , E_TEMPERATURE=MCU_TH0 , E1_HEATER=MCU_HE1 , E1_TEMPERATURE=MCU_TH1 , + BED_HEATER=MCU_BED , BED_TEMPERATURE=MCU_TB , + + PART_FAN=MCU_FAN0 , E_FAN=MCU_FAN1 , CONTROLLER_FAN=MCU_FAN2 , + + STATUS_NEOPIXEL=MCU_RGB , + # LIGHT_NEOPIXEL=MCU_RGB , + +######################################## +# Motor Power Pin +######################################## +# Due to BTT implementing a Marlin-specific safety feature, +# "anti-reversal stepper protection", this pin needs pulling +# high to pass power to stepper drivers and most FETs + +[output_pin motor_power] +pin: MCU_MPWR +value: 1 + From 0ecc550a594b38fb9530bbd33858169937decbe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Mon, 26 Feb 2024 16:51:23 +0000 Subject: [PATCH 57/79] fixed the regression introduced in startup call --- macros/miscs/startup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros/miscs/startup.cfg b/macros/miscs/startup.cfg index 7e5806c60..e9ebc2258 100644 --- a/macros/miscs/startup.cfg +++ b/macros/miscs/startup.cfg @@ -2,7 +2,7 @@ # and inits process used in Klippain [delayed_gcode KLIPPAIN_STARTUP] -initial_duration: 0.0001 +initial_duration: 1 gcode: _KLIPPAIN_STARTUP From a031aa1623db1e2878f6a0defe427fa2b0b39447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Mon, 26 Feb 2024 18:01:27 +0100 Subject: [PATCH 58/79] fix typo in stale.yml --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 9e70ab55a..4d54ca315 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -33,7 +33,7 @@ jobs: stale-pr-label: 'stale, reviewer-needed' exempt-issue-labels: 'tracking' exempt-pr-labels: 'tracking' - close-issue-message: 'This issue was closed due to inactivity for 14 days. Feel free to reopen it if you think it was an error or if there's new information or progress.' + close-issue-message: 'This issue was closed due to inactivity for 14 days. Feel free to reopen it if you think it was an error or if you have new information or progress to share' close-pr-message: 'This pull request was closed due to inactivity for 14 days. Please reopen it if you think it was an error or if you wish to continue the contribution.' exempt-all-milestones: true exempt-all-assignees: true From a8bf8bc75271c361335339a829e7aea6bac54562 Mon Sep 17 00:00:00 2001 From: Jan-Gerrit Drexhage <102791900+Surion79@users.noreply.github.com> Date: Mon, 26 Feb 2024 18:03:01 +0100 Subject: [PATCH 59/79] fixed probe pin for BTT_SB2209_RP2040_v1.0 (#507) --- .../mcu_defaults/toolhead/BTT_SB2209_RP2040_v1.0.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user_templates/mcu_defaults/toolhead/BTT_SB2209_RP2040_v1.0.cfg b/user_templates/mcu_defaults/toolhead/BTT_SB2209_RP2040_v1.0.cfg index 05dedc0e1..44748bd9f 100644 --- a/user_templates/mcu_defaults/toolhead/BTT_SB2209_RP2040_v1.0.cfg +++ b/user_templates/mcu_defaults/toolhead/BTT_SB2209_RP2040_v1.0.cfg @@ -19,8 +19,8 @@ aliases: E_STEP=MCU_E0_STEP , E_DIR=MCU_E0_DIR , E_ENABLE=MCU_E0_EN , E_TMCUART=MCU_E0_UART , X_STOP=MCU_ENDSTOP , - PROBE_INPUT=MCU_IND_FAN , - TOOLHEAD_SENSOR=MCU_PROBE2 , + PROBE_INPUT=MCU_PROBE2 , + TOOLHEAD_SENSOR=MCU_PROBE1 , E_HEATER=MCU_HE0 , E_TEMPERATURE=MCU_TH0 , CHAMBER_TEMPERATURE=MCU_ONBOARD_NTCK100K , From 742d474e5d4ec4a5872d0f9c0531bb262863f1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Mon, 26 Feb 2024 23:37:03 +0100 Subject: [PATCH 60/79] LDO Nitehawk MCU template and tachometer management (#505) Co-authored-by: Meindert <19568018+mvdveer@users.noreply.github.com> Co-authored-by: Akash Patel --- .../hardware/fans/hotend_fan_tachometer.cfg | 14 ++++ config/hardware/fans/part_fan_tachometer.cfg | 12 +++ .../toolhead/LDO_Nitehawk-SB_v1.0.cfg | 20 +++++ docs/pinout.md | 2 + macros/base/cancel_print.cfg | 5 ++ macros/base/end_print.cfg | 5 ++ macros/base/start_print.cfg | 15 ++++ macros/helpers/tachometer_check.cfg | 44 ++++++++++ .../mcu_defaults/main/BTT_SKR_3.cfg | 1 + .../mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg | 1 + .../main/MY-OWN-CUSTOM-TEMPLATE.cfg | 4 +- .../toolhead/LDO_Nitehawk-SB_v1.0.cfg | 84 +++++++++++++++++++ user_templates/printer.cfg | 6 +- 13 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 config/hardware/fans/hotend_fan_tachometer.cfg create mode 100644 config/hardware/fans/part_fan_tachometer.cfg create mode 100644 config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg create mode 100644 macros/helpers/tachometer_check.cfg create mode 100644 user_templates/mcu_defaults/toolhead/LDO_Nitehawk-SB_v1.0.cfg diff --git a/config/hardware/fans/hotend_fan_tachometer.cfg b/config/hardware/fans/hotend_fan_tachometer.cfg new file mode 100644 index 000000000..dbf370a8c --- /dev/null +++ b/config/hardware/fans/hotend_fan_tachometer.cfg @@ -0,0 +1,14 @@ +[gcode_macro _USER_VARIABLES] +variable_hotend_fan_tach_enabled: True +gcode: + +[heater_fan hotend_fan] +pin: E_FAN +max_power: 1.0 +kick_start_time: 0.100 +heater: extruder +heater_temp: 50.0 +tachometer_pin: E_FAN_TACHO + +# And we also include the tachometer check macros from here +[include ../../../macros/helpers/tachometer_check.cfg] diff --git a/config/hardware/fans/part_fan_tachometer.cfg b/config/hardware/fans/part_fan_tachometer.cfg new file mode 100644 index 000000000..675ec97bd --- /dev/null +++ b/config/hardware/fans/part_fan_tachometer.cfg @@ -0,0 +1,12 @@ +[gcode_macro _USER_VARIABLES] +variable_part_fan_tach_enabled: True +gcode: + +[fan] +pin: PART_FAN +kick_start_time: 0.100 +cycle_time: 0.010 +tachometer_pin: PART_FAN_TACHO + +# And we also include the tachometer check macros from here +[include ../../../macros/helpers/tachometer_check.cfg] diff --git a/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg b/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg new file mode 100644 index 000000000..c41f4f6bf --- /dev/null +++ b/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg @@ -0,0 +1,20 @@ +[board_pins toolhead_manufacturer] +mcu: toolhead +aliases: + MCU_EMOT_EN=gpio25 , MCU_EMOT_STEP=gpio23 , MCU_EMOT_DIR=gpio24 , MCU_EMOT_UART=gpio0 , MCU_EMOT_TX=gpio1 , + + MCU_ENDSTOP_X=gpio13 , MCU_ENDSTOP_Y=gpio12 , + MCU_HV_ENDSTOP=gpio10 , + + MCU_FAN0=gpio5 , MCU_FAN1=gpio6 , + MCU_PWM0=gpio16 , MCU_PWM1=gpio17 , + + MCU_TEMP=gpio29 , + + MCU_HEAT=gpio9 , MCU_HEAT_CHAMBER=gpio28 , MCU_NH_TEMP=gpio26 , + + MCU_RGB=gpio17 , MCU_ACTIVITY_LED=gpio8 , + + MCU_ADXL_CS=gpio21 , MCU_ADXL_SCK=gpio18 , MCU_ADXL_MOSI=gpio20 , MCU_ADXL_MISO=gpio19 , + + MCU_FS=gpio3 , MCU_SU=gpio2 , MCU_ST_UART_TX=gpio1 , MCU_ST_UART_RX=gpio0 , diff --git a/docs/pinout.md b/docs/pinout.md index 2501a75b6..e8a681136 100644 --- a/docs/pinout.md +++ b/docs/pinout.md @@ -57,7 +57,9 @@ Here is a list of all the "Frix-x names" available to use in your own board_pins #### Fans - `E_FAN`: hotend fan. This fan should stay at 100% whenever the hotend is hot, so a PWM capable pin is not mandatory + - `E_FAN_TACHO`: tachometer of the hotend fan, optional and used to validate that the fan is spinning as a safety feature - `PART_FAN`: part fan used during the print. This pin should be a PWM capable pin to allow modulation of the fan speed + - `PART_FAN_TACHO`: tachometer of the part fan, optional and used to validate that the fan is spinning as a safety feature - `EXHAUST_FAN`: for an exhaust filter (such as the Voron basic exhaust). This pin should be a PWM capable pin to allow modulation of the fan speed - `FILTER_FAN`: for a filter (such as a Nevermore filter). This pin should be a PWM capable pin to allow modulation of the fan speed - `CONTROLLER_FAN`: to cool down your MCUs or electronic bay diff --git a/macros/base/cancel_print.cfg b/macros/base/cancel_print.cfg index 177a84b45..82c3a8ade 100644 --- a/macros/base/cancel_print.cfg +++ b/macros/base/cancel_print.cfg @@ -13,6 +13,7 @@ gcode: {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} + {% set hotend_fan_tach_enabled = printer["gcode_macro _USER_VARIABLES"].hotend_fan_tach_enabled %} PARK @@ -33,6 +34,10 @@ gcode: SET_HEATER_TEMPERATURE HEATER=extruder TARGET={safe_extruder_temp} {% endif %} + {% if hotend_fan_tach_enabled %} + UPDATE_DELAYED_GCODE ID=_BACKGROUND_HOTEND_TACHO_CHECK DURATION=0 + {% endif %} + M107 M400 diff --git a/macros/base/end_print.cfg b/macros/base/end_print.cfg index ce191eb45..5228ba43a 100644 --- a/macros/base/end_print.cfg +++ b/macros/base/end_print.cfg @@ -13,6 +13,7 @@ gcode: {% set bed_mesh_enabled = printer["gcode_macro _USER_VARIABLES"].bed_mesh_enabled %} {% set filter_default_time = printer["gcode_macro _USER_VARIABLES"].filter_default_time_on_end_print|default(600)|int %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set hotend_fan_tach_enabled = printer["gcode_macro _USER_VARIABLES"].hotend_fan_tach_enabled %} PARK @@ -33,6 +34,10 @@ gcode: SET_HEATER_TEMPERATURE HEATER=extruder TARGET={safe_extruder_temp} {% endif %} + {% if hotend_fan_tach_enabled %} + UPDATE_DELAYED_GCODE ID=_BACKGROUND_HOTEND_TACHO_CHECK DURATION=0 + {% endif %} + M107 M400 diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index e98859a1c..54416b635 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -61,6 +61,8 @@ gcode: {% set firmware_retraction_enabled = printer["gcode_macro _USER_VARIABLES"].firmware_retraction_enabled %} {% set filter_enabled = printer["gcode_macro _USER_VARIABLES"].filter_enabled %} {% set filament_sensor_enabled = printer["gcode_macro _USER_VARIABLES"].filament_sensor_enabled %} + {% set part_fan_tach_enabled = printer["gcode_macro _USER_VARIABLES"].part_fan_tach_enabled %} + {% set hotend_fan_tach_enabled = printer["gcode_macro _USER_VARIABLES"].hotend_fan_tach_enabled %} {% if MATERIAL not in printer["gcode_macro _USER_VARIABLES"].material_parameters %} RESPOND MSG="Material '{MATERIAL}' is unknown!" @@ -96,6 +98,19 @@ gcode: STOP_FILTER {% endif %} + # If a tachometer is enabled on one of the fans, we check them: + # - It's done only once for the part fan to be sure nothing block it before starting the print + # - And as a safety feature, we start a monitoring loop for the hotend fan (that is automatically stopped at the end of a print) + {% if part_fan_tach_enabled %} + M106 S255 + G4 P2000 + _PART_FAN_CHECK + M106 S0 + {% endif %} + {% if hotend_fan_tach_enabled %} + UPDATE_DELAYED_GCODE ID=_BACKGROUND_HOTEND_TACHO_CHECK DURATION=1 + {% endif %} + SET_GCODE_OFFSET Z=0 M221 S100 M220 S100 diff --git a/macros/helpers/tachometer_check.cfg b/macros/helpers/tachometer_check.cfg new file mode 100644 index 000000000..a39d9f84a --- /dev/null +++ b/macros/helpers/tachometer_check.cfg @@ -0,0 +1,44 @@ +## This config file contains macros that are used in conjuction with tacho-enabled hotend and part fans + +# Monitoring loop for hotend fan safety check +[delayed_gcode _BACKGROUND_HOTEND_TACHO_CHECK] +gcode: + _HOTEND_FAN_CHECK + UPDATE_DELAYED_GCODE ID=_BACKGROUND_HOTEND_TACHO_CHECK DURATION=3 + +[gcode_macro _HOTEND_FAN_CHECK] +description: Check the hotend fan tachometer to verify that it is running effectively +variable_he_stop_count: 0 +gcode: + {% set min_rpm = 1000|float %} # This is a relatively low value adapted to all fans to check that they are effectively running + {% set max_consecutive_stops = 3 %} + {% set rpm = printer['heater_fan hotend_fan'].rpm|float %} + {% set he_target = printer[printer.toolhead.extruder].target|float %} + {% set he_temp = printer[printer.toolhead.extruder].temperature|float %} + {% set fan_on_temp = printer.configfile.settings['heater_fan hotend_fan'].heater_temp|float %} + {% set he_stop_count = printer["gcode_macro _HOTEND_FAN_CHECK"].he_stop_count|int %} + + {% if (he_target >= fan_on_temp) and (rpm < min_rpm) and (he_temp >= fan_on_temp) %} + SET_GCODE_VARIABLE MACRO=_HOTEND_FAN_CHECK VARIABLE=he_stop_count VALUE={he_stop_count + 1} + RESPOND MSG="Hotend fan stoppage detected for {(he_stop_count+1)*3}sec (max {max_consecutive_stops*3}sec allowed)" + M400 + {% if printer["gcode_macro _HOTEND_FAN_CHECK"].he_stop_count|int >= max_consecutive_stops-1 %} + CANCEL_PRINT + {% endif %} + {% else %} + SET_GCODE_VARIABLE MACRO=_HOTEND_FAN_CHECK VARIABLE=he_stop_count VALUE=0 + {% endif %} + + +[gcode_macro _PART_FAN_CHECK] +description: Check the part fan tachometer to verify that it is running effectively +gcode: + {% if printer.fan.rpm is not none %} + {% if printer.fan.rpm > 1000 %} # This is a relatively low value adapted to all fans to check that they are effectively running + {action_respond_info("Part fan OK!")} + {% else %} + M400 + CANCEL_PRINT + {action_raise_error("Hotend fan stoppage detected, print was canceled!")} + {% endif %} + {% endif %} diff --git a/user_templates/mcu_defaults/main/BTT_SKR_3.cfg b/user_templates/mcu_defaults/main/BTT_SKR_3.cfg index 1215052dd..47d4addcf 100644 --- a/user_templates/mcu_defaults/main/BTT_SKR_3.cfg +++ b/user_templates/mcu_defaults/main/BTT_SKR_3.cfg @@ -1,3 +1,4 @@ + #-------------------------------------# #### BTT SKR3 definition #### #-------------------------------------# diff --git a/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg b/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg index 3fa28618d..0d24e295a 100644 --- a/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg +++ b/user_templates/mcu_defaults/main/BTT_SKR_Pro_V1.2.cfg @@ -1,3 +1,4 @@ + #----------------------------------------# #### BTT SKR Pro v1.2 definition ######## #----------------------------------------# diff --git a/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg b/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg index 40b1f8f95..0ba4765fe 100644 --- a/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg +++ b/user_templates/mcu_defaults/main/MY-OWN-CUSTOM-TEMPLATE.cfg @@ -37,7 +37,9 @@ aliases: E_HEATER= , E_TEMPERATURE= , BED_HEATER= , BED_TEMPERATURE= , - PART_FAN= , E_FAN= , + PART_FAN= , E_FAN= , + PART_FAN_TACHO , E_FAN_TACHO , + CONTROLLER_FAN= , EXHAUST_FAN= , FILTER_FAN= , diff --git a/user_templates/mcu_defaults/toolhead/LDO_Nitehawk-SB_v1.0.cfg b/user_templates/mcu_defaults/toolhead/LDO_Nitehawk-SB_v1.0.cfg new file mode 100644 index 000000000..4fd4d99b0 --- /dev/null +++ b/user_templates/mcu_defaults/toolhead/LDO_Nitehawk-SB_v1.0.cfg @@ -0,0 +1,84 @@ + +#-------------------------------------------------------# +#### LDO Nighthawk SB toolhead v1 MCU definition ######## +#-------------------------------------------------------# + +[mcu toolhead] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0 ##### <--- change-me-to-the-correct-serial hint: ls /dev/serial/by-id/* # +##-------------------------------------------------------------------- + +# If you want to override the wiring of the LDO Nighthawk, keep in mind that this +# board is defined using the "toolhead" name. So you should use "pin: toolhead:PIN_NAME" +# in your own overrides.cfg files. + +[include config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg] # Do not remove this line +[board_pins nitehawk_mcu] +mcu: toolhead +aliases: + E_STEP=MCU_EMOT_STEP , E_DIR=MCU_EMOT_DIR , E_ENABLE=MCU_EMOT_EN , E_TMCUART=MCU_EMOT_UART , + + X_STOP=MCU_ENDSTOP_X , + PROBE_INPUT=MCU_HV_ENDSTOP , + + E_HEATER=MCU_HEAT , E_TEMPERATURE=MCU_TEMP , CHAMBER_TEMPERATURE=MCU_HEAT_CHAMBER , + NH_MCU_TEMP=MCU_NH_TEMP , + + PART_FAN=MCU_FAN1 , E_FAN=MCU_FAN0 , + PART_FAN_TACHO=MCU_PWM0 , E_FAN_TACHO=MCU_PWM1 , + + STATUS_NEOPIXEL=MCU_RGB , STATUS_BOARD=MCU_ACTIVITY_LED , + + ADXL_CS=MCU_ADXL_CS , ADXL_SCLK=MCU_ADXL_SCK , ADXL_MOSI=MCU_ADXL_MOSI , ADXL_MISO=MCU_ADXL_MISO , + + TX_PIN=MCU_ST_UART_TX , + + +#----------------------------------------# +# LDO Nighthawk-SB v1 pins remapping # +#----------------------------------------# + +# These pins overrides are automatically added when you select the LDO +# toolhead MCU during the installation process. They should provide a +# good base to work with. Feel free to adapt to your board if needed! + +[extruder] +step_pin: toolhead:E_STEP +dir_pin: toolhead:E_DIR +enable_pin: !toolhead:E_ENABLE +heater_pin: toolhead:E_HEATER +sensor_pin: toolhead:E_TEMPERATURE +pullup_resistor: 2200 + +[tmc2209 extruder] +uart_pin: toolhead:E_TMCUART +tx_pin: toolhead:TX_PIN +sense_resistor: 0.100 + +[probe] +pin: ^toolhead:PROBE_INPUT + +[fan] +pin: toolhead:PART_FAN +#tachometer_pin: toolhead:PART_FAN_TACHO + +[heater_fan hotend_fan] +pin: toolhead:E_FAN +# tachometer_pin: toolhead:E_FAN_TACHO + +## Uncomment the following line if not using sensorless homing +## and having the X endstop plugged to the toolhead MCU +# [stepper_x] +# endstop_pin: ^toolhead:X_STOP + +[neopixel status_leds] +pin: toolhead:STATUS_NEOPIXEL + +## Nitehawk PCB temperature sensor +[temperature_sensor nh_temp] +sensor_type: CMFB103F3950FANT +sensor_pin: toolhead:NH_MCU_TEMP +pullup_resistor: 2200 +min_temp: 0 +max_temp: 100 + diff --git a/user_templates/printer.cfg b/user_templates/printer.cfg index a6485d270..738bafea8 100644 --- a/user_templates/printer.cfg +++ b/user_templates/printer.cfg @@ -113,6 +113,10 @@ ### -------------------------------------------------------------------------------------- # [include config/hardware/fans/hotend_fan.cfg] # [include config/hardware/fans/part_fan.cfg] + +# [include config/hardware/fans/hotend_fan_tachometer.cfg] # When having a tachometer monitoring hotend fan speed +# [include config/hardware/fans/part_fan_tachometer.cfg] # When having a tachometer monitoring part fan speed + # [include config/hardware/fans/controller_fan.cfg] # [include config/hardware/fans/rpi_fan.cfg] # ---------------------------------------------------------------------------------------- @@ -156,7 +160,7 @@ # [include config/hardware/temperature_sensors/cabinet_temp.cfg] # [include config/hardware/temperature_sensors/chamber_temp.cfg] # [include config/hardware/temperature_sensors/chamber_temp_ds18b20.cfg] # Specific for DS18B20 directly connected to the Pi -# [include config/hardware/temperature_sensors/chamber_temp_toolhead.cfg] # This is not recommended as toolhead board temperature sensors are not accurate +# [include config/hardware/temperature_sensors/chamber_temp_toolhead.cfg] # This is to use a toolhead integrated temperature sensor (or an external one as it's done on the LDO Nitehawk) # ---------------------------------------------------------------------------------------- From 20f41e8383cbf0381c546a4b1ba5f1bc546c2ae7 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:54:50 +0100 Subject: [PATCH 61/79] update primeline to make it adaptive (#498) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Frédéric Beaucamp <88246672+fbeauKmi@users.noreply.github.com> Co-authored-by: Félix Boisselier --- macros/base/start_print.cfg | 13 +++++- macros/helpers/prime_line.cfg | 74 ++++++++++++++++++++++++----------- user_templates/variables.cfg | 1 + 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 54416b635..8e0eec159 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -29,6 +29,7 @@ gcode: {% set TOOLS_USED = params.TOOLS_USED|default("")|string %} # Check if MMU gates (used in gcode file) are availables {% set SYNC_MMU_EXTRUDER = params.SYNC_MMU_EXTRUDER|default(0)|int %} # set MMU gear motor and extruder synchronization during print TODO {% set BED_MESH_PROFILE = params.MESH|default("")|string %} # Bed mesh profile to load + {% set ADAPTIVE_PRIMELINE = params.ADAPTIVE_PRIMELINE|default(1)|int %} # Weither to do or not an adaptive prime line near the real print zone # Set the variables to be used in all the modules based on the slicer parameters SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_temp VALUE={BED_TEMP} @@ -43,6 +44,7 @@ gcode: SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=material VALUE='"{MATERIAL}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=fl_size VALUE='"{FL_SIZE}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_mesh_profile VALUE='"{BED_MESH_PROFILE}"' + SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=adaptive_primeline VALUE={ADAPTIVE_PRIMELINE} {% if params.TOTAL_LAYER %} # total layers count (if provided by the slicer) SET_PRINT_STATS_INFO TOTAL_LAYER={params.TOTAL_LAYER|int} @@ -208,7 +210,15 @@ gcode: [gcode_macro _MODULE_PRIMELINE] gcode: - PRIMELINE + # ----- PRIME LINE ------------------------------------------- + {% set FL_SIZE = printer["gcode_macro START_PRINT"].fl_size %} + {% set ADAPTIVE_PRIMELINE = printer["gcode_macro START_PRINT"].adaptive_primeline %} + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + + {% if verbose %} + RESPOND MSG="Executing a primeline..." + {% endif %} + PRIMELINE SIZE={FL_SIZE} ADAPTIVE_MODE={ADAPTIVE_PRIMELINE} [gcode_macro _MODULE_HEATSOAK_BED] @@ -413,7 +423,6 @@ gcode: {% if verbose %} RESPOND MSG="Bed mesh measurement..." {% endif %} - ADAPTIVE_BED_MESH SIZE={FL_SIZE} {% else %} {% if verbose %} diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index baa83e2df..549a56914 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -1,18 +1,53 @@ [gcode_macro PRIMELINE] gcode: - # Macro parameters + # Base macro parameters {% set prime_line_length = params.LINE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_length)|float %} {% set prime_line_purge_distance = params.PURGE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_purge_distance)|float %} {% set prime_line_flowrate = params.FLOWRATE|default(printer["gcode_macro _USER_VARIABLES"].prime_line_flowrate)|float %} - {% if printer["gcode_macro _USER_VARIABLES"].prime_line_height %} - {% set prime_line_height = params.LINE_HEIGHT|default(printer["gcode_macro _USER_VARIABLES"].prime_line_height)|float %} - {% else %} - {% set prime_line_height = params.LINE_HEIGHT|default(0.6)|float %} + {% set prime_line_height = params.LINE_HEIGHT|default(printer["gcode_macro _USER_VARIABLES"].prime_line_height)|default(0.6)|float %} + {% set prime_line_adaptive = params.ADAPTIVE_MODE|default(1)|int %} + {% set prime_line_margin = params.LINE_MARGIN|default(printer["gcode_macro _USER_VARIABLES"].prime_line_margin)|default(5.0)|float %} # Used only in adaptive mode + + # If the SIZE parameter is defined and not a dummy placeholder, we use it to do the adaptive bed mesh logic + {% set coordinatesFound = false %} + {% if params.SIZE is defined and params.SIZE != "0_0_0_0" %} + {% set xMinSpec, yMinSpec, xMaxSpec, yMaxSpec = params.SIZE.split('_')|map('trim')|map('int') %} + {% set coordinatesFound = true %} + {% elif printer.exclude_object is defined %} + {% if printer.exclude_object.objects %} + # Else if SIZE is not defined, we fallback to use the [exclude_object] tags + # This method is derived from Kyleisah KAMP repository: https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging) + {% set eo_points = printer.exclude_object.objects|map(attribute='polygon')|sum(start=[]) %} + {% set xMinSpec = eo_points|map(attribute=0)|min %} + {% set yMinSpec = eo_points|map(attribute=1)|min %} + {% set xMaxSpec = eo_points|map(attribute=0)|max %} + {% set yMaxSpec = eo_points|map(attribute=1)|max %} + {% set coordinatesFound = true %} + {% endif %} {% endif %} - # Set internal macro vars + # We get the default prime line position parameters {% set prime_line_x, prime_line_y = printer["gcode_macro _USER_VARIABLES"].prime_line_xy|map('float') %} - {% set prime_line_direction = printer["gcode_macro _USER_VARIABLES"].prime_line_direction|string|upper %} + {% set prime_line_x = params.START_X|default(prime_line_x)|float %} + {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} + {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} + + {% set center_x, center_y = [printer.toolhead.axis_maximum.x / 2, printer.toolhead.axis_maximum.y / 2]|map("float") %} + + # If first layer coordinates are retrieved and adaptive mode is enabled, then we replace the coordinates to + # do an adaptive purge while being careful to have the line stay on the bed when the first layer + # is in an opposite bed quadrant than the prime line initial coordinates (due to mirrored coordinates from center axes)... + {% if coordinatesFound and prime_line_adaptive == 1 %} + {% set prime_line_x = 2*center_x - prime_line_x if (prime_line_x > center_x and xMaxSpec < center_x) or (prime_line_x < center_x and xMinSpec > center_x) + else prime_line_x %} + {% set prime_line_y = 2*center_y - prime_line_y if (prime_line_y > center_y and yMaxSpec < center_y) or (prime_line_y < center_y and yMinSpec > center_y) + else prime_line_y %} + {% set prime_line_x = [[prime_line_x, xMinSpec - prime_line_margin]|max, xMaxSpec + prime_line_margin]|min %} + {% set prime_line_y = [[prime_line_y, yMinSpec - prime_line_margin]|max, yMaxSpec + prime_line_margin]|min %} + {% endif %} + + # Choose the way of printing the primeline (in + or -) alongside the direction to avoid going outside the bed boundaries + {% set prime_line_way = -1 if (prime_line_direction == "X" and prime_line_x > center_x) or (prime_line_direction == "Y" and prime_line_y > center_y) else 1 %} {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed * 60 %} {% set Sz = printer["gcode_macro _USER_VARIABLES"].z_drop_speed * 60 %} @@ -25,17 +60,6 @@ gcode: {% set max_extrude_cross_section = printer["configfile"].config["extruder"]["max_extrude_cross_section"]|float %} {% set filament_diameter = printer["configfile"].config["extruder"]["filament_diameter"]|float %} - # some more Macro parameters after retrieving defaults - {% set prime_line_x = params.START_X|default(prime_line_x)|float %} - {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} - {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} - - {% if verbose %} - {action_respond_info("Prime line length: %.4f" % prime_line_length)} - {action_respond_info("Prime line eight: %.4f" % prime_line_height)} - {action_respond_info("prime line extrusion length: %4.f" % prime_line_purge_distance)} - {% endif %} - # We first compute the width of the prime line {% set purge_volume = prime_line_purge_distance * 3.14159 * (filament_diameter / 2)**2 %} {% set line_width = purge_volume / (prime_line_height * prime_line_length) %} @@ -56,9 +80,7 @@ gcode: # We then compute the height to width ratio and validate that the prime line will not be too thin {% if (prime_line_height / line_width) >= 0.5 %} # TODO: validate this 1/2 ratio is good for all - {% if verbose %} - {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length! Aborting...")} - {% endif %} + {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length!")} {% endif %} # Finally we compute the speed to get the correct flowrate for the prime line @@ -93,9 +115,9 @@ gcode: # Prime line G92 E0 {% if prime_line_direction == "X" %} - G1 X{prime_line_x + prime_line_length} E{prime_line_purge_distance} F{speed} + G1 X{prime_line_x + prime_line_way*prime_line_length} E{prime_line_purge_distance} F{speed} {% elif prime_line_direction == "Y" %} - G1 Y{prime_line_y + prime_line_length} E{prime_line_purge_distance} F{speed} + G1 Y{prime_line_y + prime_line_way*prime_line_length} E{prime_line_purge_distance} F{speed} {% else %} { action_respond_error("Prime line direction is not valid. Choose either X or Y in the variables.cfg file!") } {% endif %} @@ -105,6 +127,12 @@ gcode: G1 E-0.2 F2100 G92 E0 G1 Z3 F{Sz} + + # Additional small movement to get out of the line as some slicers directly emmit + # a Z- move as a first step that make the toolhead crash back in the line and get dirty + G91 + G1 X2 Y2 F{St} + G90 # Flushing Klipper's buffer to ensure the primeline sequence is done before continuing M400 diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index 817d621df..63c9b1390 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -61,6 +61,7 @@ variable_prime_line_length: 40 # length of the prime line on the bed (in mm) variable_prime_line_purge_distance: 30 # length of filament to purge (in mm) variable_prime_line_flowrate: 10 # mm3/s used for the prime line variable_prime_line_height: 0.6 # mm, used for actual cross section computation +variable_prime_line_margin: 5 # distance of purge line from fl_size rectangle ## Park position used when pause, end_print, etc... variable_park_position_xy: -1, -1 From 658e024c2f641e8a503c0847ddd57c1a8382a9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Wed, 28 Feb 2024 08:57:30 +0000 Subject: [PATCH 62/79] fixed missing adaptive primeline variable --- macros/base/start_print.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 8e0eec159..b5f05a782 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -14,6 +14,7 @@ variable_material: "XXX" variable_fl_size: "0_0_0_0" variable_bed_mesh_profile: "" variable_total_layer: 0 +variable_adaptive_primeline: 1 gcode: # Get all the parameters passed from the slicer {% set BED_TEMP = params.BED_TEMP|default(printer["gcode_macro _USER_VARIABLES"].print_default_bed_temp)|float %} # Bed temperature From 5e785811f6b3618bd09129cf9f342c1669d9e965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Wed, 28 Feb 2024 11:11:38 +0000 Subject: [PATCH 63/79] remplaced CANCEL_PRINT by PARK in the automated error management gcode --- config/machine.cfg | 2 +- macros/base/park.cfg | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/config/machine.cfg b/config/machine.cfg index 367bcf792..0f239a2a6 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -7,7 +7,7 @@ on_error_gcode: {% if printer["gcode_macro _USER_VARIABLES"].probe_type_enabled == "dockable" %} _PROBE_ON_ERROR_ACTION {% endif %} - CANCEL_PRINT + PARK [idle_timeout] timeout: 1800 diff --git a/macros/base/park.cfg b/macros/base/park.cfg index b6b24c212..dca0db2d5 100644 --- a/macros/base/park.cfg +++ b/macros/base/park.cfg @@ -43,8 +43,6 @@ gcode: G92 E0 G1 E-{E} F2100 {% endif %} - {% else %} - RESPOND MSG="no extruder retraction because extruder temperature ({printer.extruder.temperature}) is lower than min_extrude_temp ({printer.configfile.config.extruder.min_extrude_temp})" {% endif %} G90 From 9cf27c3b76b9df9ca9a160e6c53f22f7b8c867fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Wed, 28 Feb 2024 14:34:51 +0000 Subject: [PATCH 64/79] fixed typo in LDO Nitehawk manufacturer template --- config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg b/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg index c41f4f6bf..c98d9d27b 100644 --- a/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg +++ b/config/mcu_definitions/toolhead/LDO_Nitehawk-SB_v1.0.cfg @@ -13,7 +13,7 @@ aliases: MCU_HEAT=gpio9 , MCU_HEAT_CHAMBER=gpio28 , MCU_NH_TEMP=gpio26 , - MCU_RGB=gpio17 , MCU_ACTIVITY_LED=gpio8 , + MCU_RGB=gpio7 , MCU_ACTIVITY_LED=gpio8 , MCU_ADXL_CS=gpio21 , MCU_ADXL_SCK=gpio18 , MCU_ADXL_MOSI=gpio20 , MCU_ADXL_MISO=gpio19 , From 893bef95ba9052c83beb47664d7b34a852241a05 Mon Sep 17 00:00:00 2001 From: Birkemosen Date: Thu, 29 Feb 2024 15:33:07 +0100 Subject: [PATCH 65/79] Add support for Manta_M5P v1.0 and 0.9 degree steppers on Trident Z axis (#514) --- .../hardware/axis/Z/Trident_TR8x8_0.9deg.cfg | 18 ++++++++ .../main/BTT_Manta_M5P_v1.0.cfg | 39 ++++++++++++++++ .../mcu_defaults/main/BTT_Manta_M5P_v1.0.cfg | 46 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 config/hardware/axis/Z/Trident_TR8x8_0.9deg.cfg create mode 100644 config/mcu_definitions/main/BTT_Manta_M5P_v1.0.cfg create mode 100644 user_templates/mcu_defaults/main/BTT_Manta_M5P_v1.0.cfg diff --git a/config/hardware/axis/Z/Trident_TR8x8_0.9deg.cfg b/config/hardware/axis/Z/Trident_TR8x8_0.9deg.cfg new file mode 100644 index 000000000..7ffd97f5e --- /dev/null +++ b/config/hardware/axis/Z/Trident_TR8x8_0.9deg.cfg @@ -0,0 +1,18 @@ +[stepper_z] +rotation_distance: 8 +microsteps: 32 +full_steps_per_rotation: 400 + +[stepper_z1] +rotation_distance: 8 +microsteps: 32 +full_steps_per_rotation: 400 + +[stepper_z2] +rotation_distance: 8 +microsteps: 32 +full_steps_per_rotation: 400 + +# We also include the default wiring and speeds from here to avoid duplicating +[include default_wiring_3M.cfg] +[include default_speed.cfg] diff --git a/config/mcu_definitions/main/BTT_Manta_M5P_v1.0.cfg b/config/mcu_definitions/main/BTT_Manta_M5P_v1.0.cfg new file mode 100644 index 000000000..8e4139197 --- /dev/null +++ b/config/mcu_definitions/main/BTT_Manta_M5P_v1.0.cfg @@ -0,0 +1,39 @@ +[board_pins mcu_manufacturer] +aliases: + MCU_M1_STEP=PC8 , MCU_M1_DIR=PC9 , MCU_M1_EN=PA15 , MCU_M1_CS=PD9 , + MCU_M2_STEP=PA10 , MCU_M2_DIR=PA14 , MCU_M2_EN=PA13 , MCU_M2_CS=PD8 , + MCU_M3_STEP=PC6 , MCU_M3_DIR=PC7 , MCU_M3_EN=PA9 , MCU_M3_CS=PB10 , + MCU_M4_STEP=PB12 , MCU_M4_DIR=PB11 , MCU_M4_EN=PA8 , MCU_M4_CS=PB2 , + MCU_M5_STEP=PB0 , MCU_M5_DIR=PB1 , MCU_M5_EN=PC4 , MCU_M5_CS=PA6 , + + MCU_M1_STOP=PD3 , MCU_M2_STOP=PD2 , MCU_M3_STOP=PC3 , MCU_M4_STOP=PC2 , + + MCU_HE0=PC5 , MCU_HE1=PA7 , + + MCU_BED_OUT=PA5 , + + MCU_THB=PA0 , MCU_TH0=PA1 , MCU_TH1=PA2 , + + MCU_FAN0=PA4 , MCU_FAN1=PA3 , + + MCU_RGB1=PC11 , MCU_RGB2=PC14 , + + MCU_PROBE1=PC15 , MCU_PROBE2=PC13 , + MCU_IND_PROBE=PC15 , + + MCU_SPI2_MOSI=PB15 , MCU_SPI2_MISO=PB14 , MCU_SPI2_SCK=PB13 , MCU_SPI2_CS=PC0 , + + + # EXP1 header + EXP1_1=PD5 , EXP1_2=PD4 , + EXP1_3=PB3 , EXP1_4=PD6 , + EXP1_5=PB5 , EXP1_6=PB4 , # Slot in the socket on this side + EXP1_7=PB7 , EXP1_8=PB6 , + EXP1_9= , EXP1_10=<5V> , + + # EXP2 header + EXP2_1=PB14 , EXP2_2=PB13 , + EXP2_3=PB8 , EXP2_4=PB9 , + EXP2_5=PC10 , EXP2_6=PB15 , # Slot in the socket on this side + EXP2_7=PC12 , EXP2_8=PF2 , + EXP2_9= , EXP2_10= , diff --git a/user_templates/mcu_defaults/main/BTT_Manta_M5P_v1.0.cfg b/user_templates/mcu_defaults/main/BTT_Manta_M5P_v1.0.cfg new file mode 100644 index 000000000..6716040f7 --- /dev/null +++ b/user_templates/mcu_defaults/main/BTT_Manta_M5P_v1.0.cfg @@ -0,0 +1,46 @@ +#--------------------------------------------# +#### BTT MANTA M5P v1.0 MCU definition ##### +#--------------------------------------------# +[mcu] +##-------------------------------------------------------------------- +# This board works by using a serial connection by default. If you +# want to use CAN, invert the commented lines and use canbus_uuid. + +#serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/BTT_Manta_M5P_v1.0.cfg] # Do not remove this line +[board_pins mantam5p10_mcu] +mcu: mcu +aliases: + X_STEP=MCU_M1_STEP , X_DIR=MCU_M1_DIR , X_ENABLE=MCU_M1_EN , X_TMCUART=MCU_M1_CS , + Y_STEP=MCU_M2_STEP , Y_DIR=MCU_M2_DIR , Y_ENABLE=MCU_M2_EN , Y_TMCUART=MCU_M2_CS , + + Z_STEP=MCU_M3_STEP , Z_DIR=MCU_M3_DIR , Z_ENABLE=MCU_M3_EN , Z_TMCUART=MCU_M3_CS , + Z1_STEP=MCU_M4_STEP , Z1_DIR=MCU_M4_DIR , Z1_ENABLE=MCU_M4_EN , Z1_TMCUART=MCU_M4_CS , + Z2_STEP=MCU_M5_STEP , Z2_DIR=MCU_M5_DIR , Z2_ENABLE=MCU_M5_EN , Z2_TMCUART=MCU_M5_CS , + + #E_STEP=MCU_M5_STEP , E_DIR=MCU_M5_DIR , E_ENABLE=MCU_M5_EN , E_TMCUART=MCU_M5_CS , + + DRIVER_SPI_MOSI=MCU_SPI2_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MISO=MCU_SPI2_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_SCK=MCU_SPI2_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 + + X_STOP=MCU_M1_STOP , Y_STOP=MCU_M3_STOP , Z_STOP=MCU_M4_STOP , + PROBE_INPUT=MCU_PROBE2 , + RUNOUT_SENSOR=MCU_M4_STOP , + + E_HEATER=MCU_HE0 , E_TEMPERATURE=MCU_TH0 , + BED_HEATER=MCU_BED_OUT , BED_TEMPERATURE=MCU_THB , + + FILTER_FAN=MCU_FAN0 , + CONTROLLER_FAN=MCU_FAN1 , + + CHAMBER_TEMPERATURE=MCU_TH1 , + + LIGHT_OUTPUT=MCU_HE1 , + STATUS_NEOPIXEL=MCU_RGB1 , + MCU_PS_ON=MCU_RGB2 , + + SERVO_PIN=MCU_PROBE1 , From 5b4675f1ed3faf1369c8dca7547c8c39fd71bc87 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:41:08 +0100 Subject: [PATCH 66/79] fix homing check for PARK in error gcode (#513) --- config/machine.cfg | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/config/machine.cfg b/config/machine.cfg index 0f239a2a6..734cb60f5 100644 --- a/config/machine.cfg +++ b/config/machine.cfg @@ -1,13 +1,18 @@ [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: - {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} - STATUS_LEDS COLOR="ERROR" - {% endif %} - {% if printer["gcode_macro _USER_VARIABLES"].probe_type_enabled == "dockable" %} - _PROBE_ON_ERROR_ACTION - {% endif %} - PARK + {% if printer["gcode_macro _USER_VARIABLES"].status_leds_enabled %} + STATUS_LEDS COLOR="ERROR" + {% endif %} + {% if printer["gcode_macro _USER_VARIABLES"].probe_type_enabled == "dockable" or printer["gcode_macro _USER_VARIABLES"].probe_type_enabled == "dockable_virtual" %} + _PROBE_ON_ERROR_ACTION + {% endif %} + + # Park only if printer is homed + {% if "xyz" in printer.toolhead.homed_axes %} + PARK + {% endif %} + [idle_timeout] timeout: 1800 From e2ebb2c451beaefc1435e4b8e4149e653fa4c3cd Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:44:03 +0100 Subject: [PATCH 67/79] fix typo in Fysetc_ERCF_ERB.cfg (#519) --- user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg b/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg index e9465512c..7e92e2fed 100644 --- a/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg +++ b/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg @@ -13,7 +13,7 @@ serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path # board is defined using the "mmu" name. So you should use "pin: mmu:PIN_NAME" # in your own overrides.cfg files. -[include config/mcu_definitions/mmu/Mellow_fly_ERCF.cfg] # Do not remove this line +[include config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg] # Do not remove this line [board_pins mmu_mcu] mcu: mmu aliases: From 5dac93c30ff6af7a8bf61511d22f00bf38a2ced6 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 1 Mar 2024 15:33:01 -0500 Subject: [PATCH 68/79] Update BTT_Kraken_v1.0.cfg, RGB1 fix listed as PF10, but should be PF12 (pf10 is mcu_min7 already, an endstop) verified rest of pins as well --- config/mcu_definitions/main/BTT_Kraken_v1.0.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg b/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg index 0f31bee84..3feba64d0 100644 --- a/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg +++ b/config/mcu_definitions/main/BTT_Kraken_v1.0.cfg @@ -11,7 +11,7 @@ aliases: MCU_MOSI=PC8 , MCU_MISO=PC7 , MCU_SCK=PC6 , MCU_MOTOR_SERVO=PE7 , - MCU_RGB1=PF10 , MCU_RGB2=PF11 , + MCU_RGB1=PF12 , MCU_RGB2=PF11 , MCU_MIN1=PC15 , MCU_MIN2=PF0 , MCU_MIN3=PF1 , MCU_MIN4=PF2 , MCU_MIN5=PF3 , MCU_MIN6=PF4 , MCU_MIN7=PF10 , MCU_MIN8=PC0 , From 228f5bc4422c9c89c9c067255c3fb54a97c98907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Mon, 4 Mar 2024 09:07:20 +0000 Subject: [PATCH 69/79] reverted PARK and PARK_FRONT to fail if axis are not homed --- macros/base/control.cfg | 2 +- macros/base/park.cfg | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/macros/base/control.cfg b/macros/base/control.cfg index a52cf3291..0f857bcd3 100644 --- a/macros/base/control.cfg +++ b/macros/base/control.cfg @@ -22,4 +22,4 @@ description: Turn off the printer and shutdown the host gcode: _OFF ; Shortcut to turn everything off (see above for this macro) {action_respond_info('action:poweroff')} ; OctoPrint compatible host shutdown - {action_call_remote_method("shutdown_machine")} ; Moonraker compatible host shutdown \ No newline at end of file + {action_call_remote_method("shutdown_machine")} ; Moonraker compatible host shutdown diff --git a/macros/base/park.cfg b/macros/base/park.cfg index dca0db2d5..4374a096b 100644 --- a/macros/base/park.cfg +++ b/macros/base/park.cfg @@ -24,7 +24,9 @@ gcode: {% set z_safe = max_z %} {% endif %} - _CG28 ; home if not already homed + {% if printer.toolhead.homed_axes != "xyz" %} + {action_raise_error("Cannot park the toolhead because axis are not homed!")} + {% endif %} {% if printer.extruder.can_extrude %} {% if firmware_retraction_enabled %} # use firmware_retraction parameter for retract (in case firmware retraction is selected in printer.cfg) @@ -56,7 +58,9 @@ gcode: {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed * 60 %} {% set Sz = printer["gcode_macro _USER_VARIABLES"].z_drop_speed * 60 %} - _CG28 ; home if not already homed + {% if printer.toolhead.homed_axes != "xyz" %} + {action_raise_error("Cannot park the toolhead in maintenance position because axis are not homed!")} + {% endif %} SAVE_GCODE_STATE NAME=PARK_FRONT G90 ; absolute positioning From 3bcc2df874208dc68594e59ca0dc103c4daeb752 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:10:32 +0100 Subject: [PATCH 70/79] fix PARK with overriden param E (#515) --- macros/base/park.cfg | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/macros/base/park.cfg b/macros/base/park.cfg index dca0db2d5..c0b994b27 100644 --- a/macros/base/park.cfg +++ b/macros/base/park.cfg @@ -2,8 +2,7 @@ description: Park the toolhead at the back and retract some filament if the nozzle is hot gcode: {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} - {% set E = params.E|default(1.7)|float|abs %} - {% set MATERIAL = printer['gcode_macro START_PRINT'].material %} + {% set material = printer['gcode_macro START_PRINT'].material %} {% set Px, Py = printer["gcode_macro _USER_VARIABLES"].park_position_xy|map('float') %} {% set Px = params.X|default(Px)|float %} @@ -24,22 +23,37 @@ gcode: {% set z_safe = max_z %} {% endif %} + SAVE_GCODE_STATE NAME=PARK + _CG28 ; home if not already homed {% if printer.extruder.can_extrude %} - {% if firmware_retraction_enabled %} # use firmware_retraction parameter for retract (in case firmware retraction is selected in printer.cfg) - {% if verbose %} - RESPOND MSG="Firmware retraction enabled, Extruder retraction = {printer.firmware_retraction.retract_length}" - {% endif %} - G10 - {% else %} # otherwise: - {% if MATERIAL != "XXX" %} # use material parameter if available for retract, otherwise use default value - {% set material = printer["gcode_macro _USER_VARIABLES"].material_parameters[MATERIAL] %} - {% set E = material.retract_length %} - {% endif %} + {% if params.E is defined %} + {% set E = params.E|float|abs %} + {% if verbose %} - RESPOND MSG="Firmware retraction disabled, Extruder retraction = {E}" + RESPOND MSG="Retraction overrided with parameter, Extruder retraction = {E}" + {% endif %} + {% else %} + {% if firmware_retraction_enabled %} # use firmware_retraction parameter for retract (in case firmware retraction is selected in printer.cfg) + {% if verbose %} + RESPOND MSG="Firmware retraction enabled, Extruder retraction = {printer.firmware_retraction.retract_length}" + {% endif %} + G10 + {% else %} # otherwise: + {% if printer["gcode_macro _USER_VARIABLES"].material_parameters[material] is defined %} # use material parameter if available for retract, otherwise use default value + {% set E = printer["gcode_macro _USER_VARIABLES"].material_parameters[material].retract_length|default(1.7) %} + {% else %} + {% set E = 1.7 %} + {% endif %} + + {% if verbose %} + RESPOND MSG="Firmware retraction disabled, Extruder retraction = {E}" + {% endif %} {% endif %} + {% endif %} + + {% if E is defined and E > 0 %} G92 E0 G1 E-{E} F2100 {% endif %} @@ -48,7 +62,8 @@ gcode: G90 G1 Z{z_safe} F{Sz} G0 X{Px} Y{Py} F{St} - + + RESTORE_GCODE_STATE NAME=PARK [gcode_macro PARK_FRONT] description: Park the toolhead on the front of the printer for maintenance From bad68da9c8b02ad7be96e69159453a7c20ddbb33 Mon Sep 17 00:00:00 2001 From: Magne Rasmussen Date: Mon, 4 Mar 2024 10:41:18 +0100 Subject: [PATCH 71/79] install and uninstall scripts improvement (#511) * Don't fail uninstall if the backup folder has been removed * Make uninstall work when backup has sub-directories * Make sure we don't fail making a backup when there is no current user config folder --- install.sh | 8 ++++++-- uninstall.sh | 7 ++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index a551732ad..27b7d9f03 100755 --- a/install.sh +++ b/install.sh @@ -80,7 +80,6 @@ function check_download { if [ ! -d "${FRIX_CONFIG_PATH}" ]; then echo "[DOWNLOAD] Downloading Klippain repository..." if git -C $frixtemppath clone -b $frixbranchname https://github.com/Frix-x/klippain.git $frixreponame; then - chmod +x ${FRIX_CONFIG_PATH}/install.sh printf "[DOWNLOAD] Download complete!\n\n" else echo "[ERROR] Download of Klippain git repository failed!" @@ -94,6 +93,11 @@ function check_download { # Step 3: Backup the old Klipper configuration function backup_config { + if [ ! -e "${USER_CONFIG_PATH}" ]; then + printf "[BACKUP] No previous config found, skipping backup...\n\n" + return 0 + fi + mkdir -p ${BACKUP_DIR} # Copy every files from the user config ("2>/dev/null || :" allow it to fail silentely in case the config dir doesn't exist) @@ -104,7 +108,7 @@ function backup_config { # If Klippain is not already installed (we check for .VERSION in the backup to detect it), # we need to remove, wipe and clean the current user config folder... if [ ! -f "${BACKUP_DIR}/.VERSION" ]; then - rm -R ${USER_CONFIG_PATH} + rm -fR ${USER_CONFIG_PATH} fi printf "[BACKUP] Backup of current user config files done in: ${BACKUP_DIR}\n\n" diff --git a/uninstall.sh b/uninstall.sh index 71d543575..378e251ea 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -82,6 +82,11 @@ function delete_current_klippain { function restore_latest_backup { local restore_backup latest_backup + if [[ ! -e "${BACKUP_PATH}" ]]; then + printf "[RESTORE] No backup folder found! Skipping...\n\n" + return + fi + read < /dev/tty -rp "[RESTORE] Would you like to restore your last config backup? This script will look for the last one before running Klippain (Y/n) " restore_backup if [[ -z "$restore_backup" ]]; then restore_backup="y" @@ -94,7 +99,7 @@ function restore_latest_backup { return fi - latest_backup=$(find ${BACKUP_PATH} -type d -not -path "${BACKUP_PATH}" -exec sh -c 'if [ ! -f "$1/.VERSION" ]; then echo "$1"; fi' sh {} \; | sort -r | head -n 1) + latest_backup=$(find ${BACKUP_PATH} -maxdepth 1 -type d -not -path "${BACKUP_PATH}" -exec sh -c 'if [ ! -f "$1/.VERSION" ]; then echo "$1"; fi' sh {} \; | sort -r | head -n 1) if [ -n "${latest_backup}" ]; then cp -fa ${latest_backup}/. ${USER_CONFIG_PATH} 2>/dev/null || : printf "[RESTORE] Latest backup restored from: ${latest_backup}\n\n" From 87e810a1fe2b9a283a65944e4d69de44467c7330 Mon Sep 17 00:00:00 2001 From: Parker Date: Mon, 4 Mar 2024 10:25:15 -0500 Subject: [PATCH 72/79] added Mellow Fly Gemini v3 MCU template (#527) --- .../main/Mellow_Fly_Gemini_v3.cfg | 42 +++++++++++++++++++ docs/pinout.md | 1 + .../main/Mellow_Fly_Gemini_v3.cfg | 37 ++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 config/mcu_definitions/main/Mellow_Fly_Gemini_v3.cfg create mode 100644 user_templates/mcu_defaults/main/Mellow_Fly_Gemini_v3.cfg diff --git a/config/mcu_definitions/main/Mellow_Fly_Gemini_v3.cfg b/config/mcu_definitions/main/Mellow_Fly_Gemini_v3.cfg new file mode 100644 index 000000000..270715478 --- /dev/null +++ b/config/mcu_definitions/main/Mellow_Fly_Gemini_v3.cfg @@ -0,0 +1,42 @@ +[board_pins mcu_manufacturer] +aliases: + # Stepper drivers + MCU_DRIVE0_EN=PA3, MCU_DRIVE0_STEP=PC13, MCU_DRIVE0_DIR=PC1, MCU_DRIVE0_UART=PB11, # X + MCU_DRIVE1_EN=PD2, MCU_DRIVE1_STEP=PC14, MCU_DRIVE1_DIR=PC4, MCU_DRIVE1_UART=PC10, # Y + MCU_DRIVE2_EN=PC12, MCU_DRIVE2_STEP=PC15, MCU_DRIVE2_DIR=PC5, MCU_DRIVE2_UART=PB7, # Z + MCU_DRIVE3_EN=PC11, MCU_DRIVE3_STEP=PC3, MCU_DRIVE3_DIR=PC8, MCU_DRIVE3_UART=PB6, # E + + # Heaters + MCU_BED=PA2, + MCU_HEAT0=PA0, + + # Thermisors + MCU_THB=PC2, + MCU_TH0=PC0, + + # Fans + MCU_FAN0=PC6, MCU_FAN1=PC7, + + # End stops + MCU_DRIVE0_STOP=PA4, MCU_DRIVE1_STOP=PA5, MCU_DRIVE2_STOP=PA6, MCU_DRIVE3_STOP=PB1, + + # TMC SPI + MCU_TMC_MOSI=PB5, MCU_TMC_MISO=PB4, MCU_TMC_SCK=PB3, + + # CAN TX RX + MCU_CAN_LOW=PB8 , MCU_CAN_HIGH=PB9 , + + # ST-LINK + MCU_STLINK_1= , MCU_STLINK_2=PA14 , MCU_STLINK_3=PA13 , MCU_STLINK_4= , MCU_STLINK_5=<3.3V> , MCU_STLINK_6=<5V> , + + # EXP1 header + EXP1_1=PC9, EXP1_3=PA13, EXP1_5=PA9, EXP1_7=, EXP1_9=, + EXP1_2=PB10, EXP1_4=PA10, EXP1_6=PA8, EXP1_8=, EXP1_10=<5V>, + # EXP2 header + EXP2_1=PB14, EXP2_3=PA15, EXP2_5=PA14, EXP2_7=PA7, EXP2_9=, + EXP2_2=PB13, EXP2_4=PB12, EXP2_6=PB15, EXP2_8=, EXP2_10=, + + + # BL Touch + MCU_SERVO=PB0, # BL Touch servo pin + MCU_PROBE=PA1 # BL Touch end stop pin \ No newline at end of file diff --git a/docs/pinout.md b/docs/pinout.md index e8a681136..ea752c01e 100644 --- a/docs/pinout.md +++ b/docs/pinout.md @@ -93,3 +93,4 @@ For more information on the boards and pinouts, please see directly the manufact - [BTT EBB](https://github.com/bigtreetech/EBB) - [BTT SKR Mini E3](https://github.com/bigtreetech/BIGTREETECH-SKR-mini-E3) - [Fysetc S6](https://github.com/FYSETC/FYSETC-S6) + - [Fly Gemini v3](https://mellow-3d.github.io/fly-gemini_v3_pins.html) \ No newline at end of file diff --git a/user_templates/mcu_defaults/main/Mellow_Fly_Gemini_v3.cfg b/user_templates/mcu_defaults/main/Mellow_Fly_Gemini_v3.cfg new file mode 100644 index 000000000..d2f9073ac --- /dev/null +++ b/user_templates/mcu_defaults/main/Mellow_Fly_Gemini_v3.cfg @@ -0,0 +1,37 @@ + +#------------------------------------------# +#### Mellow Fly Gemini V3 MCU definition ### +#------------------------------------------# + +[mcu] +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path +# canbus_uuid: change-me-to-the-correct-canbus-id +##-------------------------------------------------------------------- + +[include config/mcu_definitions/main/Mellow_Fly_Gemini_v3.cfg] # Do not remove this line +[board_pins fly_Gemini_v3_mcu] +mcu: mcu +aliases: + X_STEP=MCU_DRIVE0_STEP , X_DIR=MCU_DRIVE0_DIR , X_ENABLE=MCU_DRIVE0_EN , X_TMCUART=MCU_DRIVE0_UART , + Y_STEP=MCU_DRIVE1_STEP , Y_DIR=MCU_DRIVE1_DIR , Y_ENABLE=MCU_DRIVE1_EN , Y_TMCUART=MCU_DRIVE1_UART , + Z_STEP=MCU_DRIVE2_STEP , Z_DIR=MCU_DRIVE2_DIR , Z_ENABLE=MCU_DRIVE2_EN , Z_TMCUART=MCU_DRIVE2_UART , + + E_STEP=MCU_DRIVE3_STEP , E_DIR=MCU_DRIVE3_DIR , E_ENABLE=MCU_DRIVE3_EN , E_TMCUART=MCU_DRIVE3_UART , + + DRIVER_SPI_MOSI=MCU_TMC_MOSI , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_MISO=MCU_TMC_MISO , # Used in case of SPI drivers such as TMC2240 or TMC5160 + DRIVER_SPI_SCK=MCU_TMC_SCK , # Used in case of SPI drivers such as TMC2240 or TMC5160 + + X_STOP=MCU_DRIVE0_STOP , Y_STOP=MCU_DRIVE1_STOP , Z_STOP=MCU_DRIVE2_STOP , + PROBE_INPUT=MCU_PROBE , + RUNOUT_SENSOR=MCU_DRIVE3_STOP , + + E_HEATER=MCU_HEAT0 , E_TEMPERATURE=MCU_TH0 , + BED_HEATER=MCU_BED , BED_TEMPERATURE=MCU_THB , + + PART_FAN=MCU_FAN0 , E_FAN=MCU_FAN2 , # MCU_FAN2 is always on + CONTROLLER_FAN=MCU_FAN1 , + + SERVO_PIN=MCU_SERVO , + From 6be3873c4e80175bd923dd8306368ae96dc4f03a Mon Sep 17 00:00:00 2001 From: Benoitone <63300355+Benoitone@users.noreply.github.com> Date: Mon, 4 Mar 2024 20:50:15 +0100 Subject: [PATCH 73/79] fix pinout for Fysetc_ERB board (#530) --- .../mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg | 15 ++++---- .../mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg | 38 +++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg b/config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg index c19425156..e7f01e7d4 100644 --- a/config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg +++ b/config/mcu_definitions/mmu/Fysetc_ERCF_ERB.cfg @@ -12,10 +12,11 @@ aliases: MCU_ENCODER=gpio22 , MCU_RGB=gpio21 , - MCU_UART0_TX=gpio0 , MCU_UART0_RX=gpio1 , - MCU_SPI0_SCK=gpio2 , MCU_SPI0_MISO=gpio3 , - MCU_SPI0_MOSI=gpio4 , MCU_SPI0_CS=gpio5 , - MCU_I2C1_SDA=gpio6 , MCU_I2C1_SCL=gpio7 , - MCU_ADC0=gpio26 , MCU_ADC1=gpio27 , - MCU_ADC2=gpio28 , MCU_ADC3=gpio29 , - GND= , 5V=<5V> , + # EXTRA PINS header + MCU_0=gpio0 , MCU_1=gpio1 , + MCU_2=gpio2 , MCU_3=gpio3 , + MCU_4=gpio4 , MCU_5=gpio5 , + MCU_6=gpio6 , MCU_7=gpio7 , + MCU_26=gpio26 , MCU_27=gpio27 , + MCU_28=gpio28 , MCU_29=gpio29 , + GND= , 5V=<5V> , diff --git a/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg b/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg index 7e92e2fed..592b77464 100644 --- a/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg +++ b/user_templates/mcu_defaults/mmu/Fysetc_ERCF_ERB.cfg @@ -1,6 +1,6 @@ #---------------------------------------------# -#### Mellow Fly ERCF MCU definition ########### +#### Fysetc ERCF ERB MCU definition ########### #---------------------------------------------# [mcu mmu] @@ -9,7 +9,7 @@ serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path # canbus_uuid: change-me-to-the-correct-canbus-id ##-------------------------------------------------------------------- -# If you want to override the wiring of the Mellow Fly ERCF board, keep in mind that this +# If you want to override the wiring of the Fysetc ERCF ERB board, keep in mind that this # board is defined using the "mmu" name. So you should use "pin: mmu:PIN_NAME" # in your own overrides.cfg files. @@ -17,21 +17,21 @@ serial: /dev/serial/by-id/change-me-to-the-correct-mcu-path [board_pins mmu_mcu] mcu: mmu aliases: - MMU_GEAR_STEP=MCU_GEAR_STEP , MMU_GEAR_DIR=MCU_GEAR_DIR , MMU_GEAR_ENABLE=MCU_GEAR_EN , MMU_GEAR_UART=MCU_GEAR_UART , - MMU_GEAR_DIAG=MCU_GEAR_DIAG , - MMU_SEL_STEP=MCU_SELECTOR_STEP , MMU_SEL_DIR=MCU_SELECTOR_DIR , MMU_SEL_ENABLE=MCU_SELECTOR_EN , MMU_SEL_UART=MCU_SELECTOR_UART , - MMU_SEL_DIAG=MCU_SELECTOR_DIAG , - - MMU_SEL_ENDSTOP=MCU_ENDSTOP , - MMU_SERVO=MCU_SERVO , - MMU_ENCODER=MCU_ENCODER , - MMU_GATE_SENSOR=MCU_EXTRA , - - SPI_SCLK=MCU_SCK , SPI_MOSI=MCU_MOSI , SPI_MISO=MCU_MISO , - - MMU_PRE_GATE_0=MCU_IO26 , MMU_PRE_GATE_1=MCU_IO10 , - MMU_PRE_GATE_2=MCU_IO27 , MMU_PRE_GATE_3=MCU_IO11 , - MMU_PRE_GATE_4=MCU_IO28 , MMU_PRE_GATE_5=MCU_IO12 , - MMU_PRE_GATE_6=MCU_IO29 , MMU_PRE_GATE_7=MCU_IO24 , - MMU_PRE_GATE_8=MCU_IO25 , MMU_PRE_GATE_9=MCU_IO13 , + MMU_GEAR_STEP=MCU_GEAR_MOTOR_STEP , MMU_GEAR_DIR=MCU_GEAR_MOTOR_DIR , MMU_GEAR_ENABLE=MCU_GEAR_MOTOR_EN , MMU_GEAR_UART=MCU_GEAR_MOTOR_UART , + MMU_GEAR_DIAG=MCU_GEAR_MOTOR_DIAG , + MMU_SEL_STEP=MCU_SELECTOR_MOTOR_STEP , MMU_SEL_DIR=MCU_SELECTOR_MOTOR_DIR , MMU_SEL_ENABLE=MCU_SELECTOR_MOTOR_EN , MMU_SEL_UART=MCU_SELECTOR_MOTOR_UART , + MMU_SEL_DIAG=MCU_SELECTOR_MOTOR_DIAG , + + MMU_SEL_ENDSTOP=MCU_ENDSTOP , + MMU_SERVO=MCU_SERVO , + MMU_ENCODER=MCU_ENCODER , + MMU_GATE_SENSOR=MCU_HALL_SENSOR , + MMU_NEOPIXEL=MCU_RGB , + + MMU_PRE_GATE_0=MCU_0 , MMU_PRE_GATE_1=MCU_1 , + MMU_PRE_GATE_2=MCU_2 , MMU_PRE_GATE_3=MCU_3 , + MMU_PRE_GATE_4=MCU_4 , MMU_PRE_GATE_5=MCU_5 , + MMU_PRE_GATE_6=MMCU_6 , MMU_PRE_GATE_7=MCU_7 , + MMU_PRE_GATE_8=MCU_26 , MMU_PRE_GATE_9=MCU_27 , + MMU_PRE_GATE_10=MCU_28 , MMU_PRE_GATE_11=MCU_29 , From 51216e45f696359d54a4e1bbba2041b320361d50 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 5 Mar 2024 03:08:33 -0500 Subject: [PATCH 74/79] updated homing_override to improve sensorless homing (#531) by using M400 vs the old 2 second dwell time that is not required anymore --- macros/base/homing/homing_override.cfg | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/macros/base/homing/homing_override.cfg b/macros/base/homing/homing_override.cfg index 3171a585c..94544779c 100644 --- a/macros/base/homing/homing_override.cfg +++ b/macros/base/homing/homing_override.cfg @@ -107,8 +107,8 @@ gcode: SET_KINEMATIC_POSITION X=0 Y=0 Z=0 G0 Z{homing_zhop} F{z_drop_speed} {% if sensorless_homing_enabled and kinematics == "corexz" %} - # Wait for 2s for stallguard registers to clear - G4 P2000 + # Wait for stallguard registers to clear + M400 {% endif %} {% set X, Y, Z = True, True, True %} {% endif %} @@ -147,11 +147,11 @@ gcode: G1 X{x_position_endstop + x_homing_backoff} F{homing_travel_speed} {% if sensorless_homing_enabled %} {% if kinematics == "corexy" %} - G4 P2000 + M400 SET_TMC_CURRENT STEPPER=stepper_x CURRENT={old_current_x} SET_TMC_CURRENT STEPPER=stepper_y CURRENT={old_current_y} {% elif kinematics == "corexz" %} - G4 P2000 + M400 SET_TMC_CURRENT STEPPER=stepper_x CURRENT={old_current_x} SET_TMC_CURRENT STEPPER=stepper_z CURRENT={old_current_z} {% elif kinematics == "cartesian" %} @@ -188,7 +188,7 @@ gcode: G1 Y{y_position_endstop + y_homing_backoff} F{homing_travel_speed} {% if sensorless_homing_enabled %} {% if kinematics == "corexy" %} - G4 P2000 + M400 SET_TMC_CURRENT STEPPER=stepper_x CURRENT={old_current_x} SET_TMC_CURRENT STEPPER=stepper_y CURRENT={old_current_y} {% elif kinematics == "corexz" %} @@ -229,7 +229,7 @@ gcode: G1 Y{y_position_endstop + y_homing_backoff} F{homing_travel_speed} {% if sensorless_homing_enabled %} {% if kinematics == "corexy" %} - G4 P2000 + M400 SET_TMC_CURRENT STEPPER=stepper_x CURRENT={old_current_x} SET_TMC_CURRENT STEPPER=stepper_y CURRENT={old_current_y} {% elif kinematics == "corexz" %} @@ -271,11 +271,11 @@ gcode: G1 X{x_position_endstop + x_homing_backoff} F{homing_travel_speed} {% if sensorless_homing_enabled %} {% if kinematics == "corexy" %} - G4 P2000 + M400 SET_TMC_CURRENT STEPPER=stepper_x CURRENT={old_current_x} SET_TMC_CURRENT STEPPER=stepper_y CURRENT={old_current_y} {% elif kinematics == "corexz" %} - G4 P2000 + M400 SET_TMC_CURRENT STEPPER=stepper_x CURRENT={old_current_x} SET_TMC_CURRENT STEPPER=stepper_z CURRENT={old_current_z} {% elif kinematics == "cartesian" %} From 5cfd2800650697669c9e0eeb3308f32f83b79d0c Mon Sep 17 00:00:00 2001 From: Parker Date: Tue, 5 Mar 2024 11:10:58 -0500 Subject: [PATCH 75/79] fixed v0_display pin and improved overrides docs (#535) --- config/hardware/displays/V0_display.cfg | 2 +- docs/features.md | 4 +++- docs/overrides.md | 13 ++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/config/hardware/displays/V0_display.cfg b/config/hardware/displays/V0_display.cfg index b301f4be2..5b0984321 100644 --- a/config/hardware/displays/V0_display.cfg +++ b/config/hardware/displays/V0_display.cfg @@ -24,7 +24,7 @@ i2c_bus: i2c1a # Standard: Right (clockwise) scrolls down or increases values. Left (counter-clockwise scrolls up or decreases values. encoder_pins: ^v0_display:PA3, ^v0_display:PA4 # Reversed: Right (clockwise) scrolls up or decreases values. Left (counter-clockwise scrolls down or increases values. -#encoder_pins: ^display:PA4, ^display:PA3 +#encoder_pins: ^v0_display:PA4, ^v0_display:PA3 click_pin: ^!v0_display:PA1 kill_pin: ^!v0_display:PA5 #x_offset: 2 diff --git a/docs/features.md b/docs/features.md index 442749bc0..cef910a15 100644 --- a/docs/features.md +++ b/docs/features.md @@ -22,4 +22,6 @@ Here you can find a list of all the custom features availables in the macros or ## Hardware This config support out of the box a lot of different machine hardware configurations. -More info will be added in this section later... + +Please see [How to write an override](./overrides.md#how-to-write-an-override) in docs/overrides.md for more information on customizing your configuration. + diff --git a/docs/overrides.md b/docs/overrides.md index e8273c4a7..99dcf29ba 100644 --- a/docs/overrides.md +++ b/docs/overrides.md @@ -24,7 +24,18 @@ Additionally, if you want to add a new macro to Klippain or even replace an exis The following examples should help you add all the overrides you need to customize Klippain and make it work correctly with your printer! -Let's say you want to change the motor current for the X-axis. You'll need to override the `[tmc2209 stepper_x]` section because that's where the current is defined. To do this, simply add the following to your `overrides.cfg` file: +If something in your hardware isn't working as expected, first inspect the relevant default configuration file for your hardware. For example if your v0 display encoder is rotating in the opposite direction: +`cd ~/printer_data/config` then `less config/hardware/displays/V0_display.cfg`, copy the relevant portion then edit to suit in your `overrides.cfg`: +``` +[display] +# Set the direction of the encoder wheel +# Standard: Right (clockwise) scrolls down or increases values. Left (counter-clockwise scrolls up or decreases values. +#encoder_pins: ^v0_display:PA3, ^v0_display:PA4 +# Reversed: Right (clockwise) scrolls up or decreases values. Left (counter-clockwise scrolls down or increases values. +encoder_pins: ^v0_display:PA4, ^v0_display:PA3 +``` + +Or let's say you want to change the motor current for the X-axis. You'll need to override the `[tmc2209 stepper_x]` section because that's where the current is defined. To do this, simply add the following to your `overrides.cfg` file: ``` [tmc2209 stepper_x] run_current: ... From 40418051caf8d6b80e4282ddabb13065a6a5dacc Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 8 Mar 2024 20:22:09 -0500 Subject: [PATCH 76/79] Update rpi_temp.cfg Format with _ so a space is in the name, like other temps --- config/hardware/temperature_sensors/rpi_temp.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hardware/temperature_sensors/rpi_temp.cfg b/config/hardware/temperature_sensors/rpi_temp.cfg index 68bfcb90e..f2f44f476 100644 --- a/config/hardware/temperature_sensors/rpi_temp.cfg +++ b/config/hardware/temperature_sensors/rpi_temp.cfg @@ -1,2 +1,2 @@ -[temperature_sensor RaspberryPi] +[temperature_sensor Raspberry_Pi] sensor_type: temperature_host From a2e6ca8f04bf5a6e3549a827c075f1f2b74f39e3 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 8 Mar 2024 20:22:37 -0500 Subject: [PATCH 77/79] Update cabinet_temp.cfg --- config/hardware/temperature_sensors/cabinet_temp.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hardware/temperature_sensors/cabinet_temp.cfg b/config/hardware/temperature_sensors/cabinet_temp.cfg index 6237ad4b7..9addc0606 100644 --- a/config/hardware/temperature_sensors/cabinet_temp.cfg +++ b/config/hardware/temperature_sensors/cabinet_temp.cfg @@ -1,3 +1,3 @@ -[temperature_sensor ElectricalCabinet] +[temperature_sensor Electrical_Cabinet] sensor_type: ATC Semitec 104GT-2 sensor_pin: ELECTRICAL_CABINET_TEMPERATURE From f0873e1381abb5215602ce97d5c60e070741811c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Thu, 14 Mar 2024 13:30:12 +0000 Subject: [PATCH 78/79] switched to the new minimum_cruise_ratio Klipper parameter --- config/kinematics/cartesian.cfg | 1 + config/kinematics/corexy.cfg | 1 + config/kinematics/corexz.cfg | 1 + macros/base/homing/homing_override.cfg | 3 +-- macros/base/probing/dockable_probe.cfg | 6 ++---- macros/base/probing/overrides/qgl.cfg | 3 +-- macros/base/probing/overrides/z_tilt.cfg | 3 +-- macros/calibration/test_speed.cfg | 6 +++--- macros/helpers/nozzle_cleaning.cfg | 3 +-- macros/miscs/compatibility.cfg | 6 ++---- user_templates/variables.cfg | 3 --- 11 files changed, 14 insertions(+), 22 deletions(-) diff --git a/config/kinematics/cartesian.cfg b/config/kinematics/cartesian.cfg index 6537b5726..4314fd3d7 100644 --- a/config/kinematics/cartesian.cfg +++ b/config/kinematics/cartesian.cfg @@ -4,6 +4,7 @@ max_velocity: 200 max_accel: 3000 max_z_velocity: 30 max_z_accel: 500 +minimum_cruise_ratio: 0.5 square_corner_velocity: 5.0 # And add directly all the machines standard includes here diff --git a/config/kinematics/corexy.cfg b/config/kinematics/corexy.cfg index 80cf0e099..0f7cba4dd 100644 --- a/config/kinematics/corexy.cfg +++ b/config/kinematics/corexy.cfg @@ -4,6 +4,7 @@ max_velocity: 400 max_accel: 8000 max_z_velocity: 30 max_z_accel: 500 +minimum_cruise_ratio: 0.5 square_corner_velocity: 5.0 # And add directly all the machines standard includes here diff --git a/config/kinematics/corexz.cfg b/config/kinematics/corexz.cfg index 8ed2a919f..e2be6ebf9 100644 --- a/config/kinematics/corexz.cfg +++ b/config/kinematics/corexz.cfg @@ -4,6 +4,7 @@ max_velocity: 400 max_accel: 1000 max_z_velocity: 200 max_z_accel: 1000 +minimum_cruise_ratio: 0.5 square_corner_velocity: 5.0 # And add directly all the machines standard includes here diff --git a/macros/base/homing/homing_override.cfg b/macros/base/homing/homing_override.cfg index 94544779c..02f605d9b 100644 --- a/macros/base/homing/homing_override.cfg +++ b/macros/base/homing/homing_override.cfg @@ -73,7 +73,6 @@ gcode: # Set the homing acceleration prior to any movement {% set saved_accel = printer.toolhead.max_accel %} - {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{homing_travel_accel} {% if bed_mesh_enabled %} @@ -340,7 +339,7 @@ gcode: {% endif %} # Reset acceleration values to what it was before - SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} + SET_VELOCITY_LIMIT ACCEL={saved_accel} {% if probe_type_enabled == "dockable" or probe_type_enabled == "dockable_virtual" %} _EXIT_POINT FUNCTION=homing_override diff --git a/macros/base/probing/dockable_probe.cfg b/macros/base/probing/dockable_probe.cfg index 42659ca21..5d3b68782 100644 --- a/macros/base/probing/dockable_probe.cfg +++ b/macros/base/probing/dockable_probe.cfg @@ -138,7 +138,6 @@ gcode: # Set the dock/undock acceleration prior to any movement {% set saved_accel = printer.toolhead.max_accel %} - {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{probe_dock_accel} # Probe entry location @@ -161,7 +160,7 @@ gcode: {% endif %} # Reset acceleration values to what it was before - SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} + SET_VELOCITY_LIMIT ACCEL={saved_accel} _CHECK_PROBE action=attach @@ -247,7 +246,6 @@ gcode: # Set the dock/undock acceleration prior to any movement {% set saved_accel = printer.toolhead.max_accel %} - {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{probe_dock_accel} # Move to probe entry location @@ -275,7 +273,7 @@ gcode: {% endif %} # Reset acceleration values to what it was before - SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} + SET_VELOCITY_LIMIT ACCEL={saved_accel} G4 P500 _CHECK_PROBE action=dock diff --git a/macros/base/probing/overrides/qgl.cfg b/macros/base/probing/overrides/qgl.cfg index 6b5d6b953..872b5f332 100644 --- a/macros/base/probing/overrides/qgl.cfg +++ b/macros/base/probing/overrides/qgl.cfg @@ -25,13 +25,12 @@ gcode: # Set the tilting acceleration prior to any movement {% set saved_accel = printer.toolhead.max_accel %} - {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{tilting_travel_accel} _BASE_QUAD_GANTRY_LEVEL {% for p in params %}{'%s=%s ' % (p, params[p])}{% endfor %} # Reset acceleration values to what it was before - SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} + SET_VELOCITY_LIMIT ACCEL={saved_accel} DEACTIVATE_PROBE diff --git a/macros/base/probing/overrides/z_tilt.cfg b/macros/base/probing/overrides/z_tilt.cfg index 548b40ce3..28b75b68a 100644 --- a/macros/base/probing/overrides/z_tilt.cfg +++ b/macros/base/probing/overrides/z_tilt.cfg @@ -26,13 +26,12 @@ gcode: # Set the tilting acceleration prior to any movement {% set saved_accel = printer.toolhead.max_accel %} - {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{tilting_travel_accel} _BASE_Z_TILT_ADJUST {% for p in params %}{'%s=%s ' % (p, params[p])}{% endfor %} # Reset acceleration values to what it was before - SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} + SET_VELOCITY_LIMIT ACCEL={saved_accel} DEACTIVATE_PROBE diff --git a/macros/calibration/test_speed.cfg b/macros/calibration/test_speed.cfg index 4ba6d9075..51e5f32c6 100644 --- a/macros/calibration/test_speed.cfg +++ b/macros/calibration/test_speed.cfg @@ -63,7 +63,7 @@ gcode: G0 X{x_min} Y{y_min} Z{bound + 10} F{speed*60} # Set new limits - SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} ACCEL_TO_DECEL={accel / 2} + SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} {% for i in range(iterations) %} # Large pattern diagonals @@ -95,8 +95,8 @@ gcode: G0 X{x_center_max} Y{y_center_min} F{speed*60} {% endfor %} - # Restore max speed/accel/accel_to_decel to their configured values - 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} + # Restore max speed/accel to their configured values + SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} # Re-home and get position again for comparison: M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66 diff --git a/macros/helpers/nozzle_cleaning.cfg b/macros/helpers/nozzle_cleaning.cfg index 8cb799f28..e2869681e 100644 --- a/macros/helpers/nozzle_cleaning.cfg +++ b/macros/helpers/nozzle_cleaning.cfg @@ -25,7 +25,6 @@ gcode: # Set the cleaning acceleration prior to any movement {% set saved_accel = printer.toolhead.max_accel %} - {% set saved_decel = printer.toolhead.max_accel_to_decel %} M204 S{brush_clean_accel} # Move to purge zone (left side) @@ -53,7 +52,7 @@ gcode: G90 # Reset acceleration values to what it was before - SET_VELOCITY_LIMIT ACCEL={saved_accel} ACCEL_TO_DECEL={saved_decel} + SET_VELOCITY_LIMIT ACCEL={saved_accel} {% if purgeclean_servo_enabled %} _SERVO_RETRACT ITEM="clean" diff --git a/macros/miscs/compatibility.cfg b/macros/miscs/compatibility.cfg index 3a1c9b665..5f3bbc73c 100644 --- a/macros/miscs/compatibility.cfg +++ b/macros/miscs/compatibility.cfg @@ -30,14 +30,12 @@ gcode: {% endif %} [gcode_macro M204] -description: Map M204 to SET_VELOCITY_LIMIT for ACCEL and ACCEL_TO_DECEL +description: Map M204 to SET_VELOCITY_LIMIT for ACCEL rename_existing: M204.1 gcode: - {% set F = params.F|default(printer["gcode_macro _USER_VARIABLES"].accel_to_decel_factor)|float %} - {% if 'S' in params %} {% set S = params.S|float %} - SET_VELOCITY_LIMIT ACCEL={S} ACCEL_TO_DECEL={S * F} + SET_VELOCITY_LIMIT ACCEL={S} {% endif %} [gcode_macro M205] diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index 63c9b1390..f2e62f2e9 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -20,9 +20,6 @@ variable_tilting_travel_accel: 3000 variable_brush_clean_accel: 1500 variable_probe_dock_accel: 2000 -## Accel to decel scale factor (default is 75% of the accel) -variable_accel_to_decel_factor: 0.75 - ################################################# # Homing, start_print and end_print variables From 1c5c6623d711aa88dc78d0d87bce0d958c680dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Thu, 14 Mar 2024 13:33:51 +0000 Subject: [PATCH 79/79] commented the default minimum_cruise_ratio to not break older Klipper versions --- config/kinematics/cartesian.cfg | 2 +- config/kinematics/corexy.cfg | 2 +- config/kinematics/corexz.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/kinematics/cartesian.cfg b/config/kinematics/cartesian.cfg index 4314fd3d7..344afcb08 100644 --- a/config/kinematics/cartesian.cfg +++ b/config/kinematics/cartesian.cfg @@ -4,7 +4,7 @@ max_velocity: 200 max_accel: 3000 max_z_velocity: 30 max_z_accel: 500 -minimum_cruise_ratio: 0.5 +# minimum_cruise_ratio: 0.5 # This left commented to not break older Klipper versions square_corner_velocity: 5.0 # And add directly all the machines standard includes here diff --git a/config/kinematics/corexy.cfg b/config/kinematics/corexy.cfg index 0f7cba4dd..b7573a2f1 100644 --- a/config/kinematics/corexy.cfg +++ b/config/kinematics/corexy.cfg @@ -4,7 +4,7 @@ max_velocity: 400 max_accel: 8000 max_z_velocity: 30 max_z_accel: 500 -minimum_cruise_ratio: 0.5 +# minimum_cruise_ratio: 0.5 # This left commented to not break older Klipper versions square_corner_velocity: 5.0 # And add directly all the machines standard includes here diff --git a/config/kinematics/corexz.cfg b/config/kinematics/corexz.cfg index e2be6ebf9..a11c6bfdf 100644 --- a/config/kinematics/corexz.cfg +++ b/config/kinematics/corexz.cfg @@ -4,7 +4,7 @@ max_velocity: 400 max_accel: 1000 max_z_velocity: 200 max_z_accel: 1000 -minimum_cruise_ratio: 0.5 +# minimum_cruise_ratio: 0.5 # This left commented to not break older Klipper versions square_corner_velocity: 5.0 # And add directly all the machines standard includes here

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%0D$A=QIeA{3SB3K2pwKKI9mO!Q- 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 E{1e|e%Z(1^uBhna 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