commit 888a1297de6d5ae07aa28c19890eff4bd2a1cc45 Author: Adam Bissen Date: Sat Jan 17 17:27:06 2026 -0600 Add initial files. diff --git a/KlipperScreen.conf b/KlipperScreen.conf new file mode 100644 index 0000000..2a2160f --- /dev/null +++ b/KlipperScreen.conf @@ -0,0 +1,7 @@ + +#~# --- Do not edit below this line. This section is auto generated --- #~# +#~# +#~# [main] +#~# 24htime = False +#~# print_sort_dir = date_desc +#~# diff --git a/My_Examples/Formbot_example_printer.cfg b/My_Examples/Formbot_example_printer.cfg new file mode 100644 index 0000000..023d6a1 --- /dev/null +++ b/My_Examples/Formbot_example_printer.cfg @@ -0,0 +1,492 @@ +[include mainsail.cfg] + +[mcu] +canbus_uuid: YOU_DIDNT_CHANGE_ME_YET # Insert the CANbus-UUID of your Manta from the firmware flashing steps + +[mcu EBBCan] +canbus_uuid: YOU_DIDNT_CHANGE_ME_YET # Insert the CANbus-UUID of your SB2209 RP2040 from the firmware flashing steps + +[printer] +kinematics: corexy +max_velocity: 300 +max_accel: 10000 +max_z_velocity: 30 +max_z_accel: 350 +square_corner_velocity: 5.0 + +[temperature_sensor MCU] +sensor_type: temperature_mcu + +[temperature_sensor SoC] +sensor_type: temperature_host + +##################################################################### +# X/Y Stepper Settings +##################################################################### + +## X Stepper on Motor1 (B Motor) +[stepper_x] +step_pin: PE6 +dir_pin: PE5 +enable_pin: !PC14 +microsteps: 16 +rotation_distance: 40 +full_steps_per_rotation:200 #set to 400 for 0.9 degree stepper +endstop_pin: ^EBBCan:gpio24 +position_min: 0 +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#position_endstop: 250 +#position_max: 250 + +## Uncomment for 300mm build +#position_endstop: 300 +#position_max: 300 + +## Uncomment for 350mm build +#position_endstop: 350 +#position_max: 350 + +##-------------------------------------------------------------------- +homing_speed: 25 +homing_retract_dist: 5 +homing_positive_dir: true + + +[tmc2209 stepper_x] +uart_pin: PC13 +interpolate: True +run_current: 0.9 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Y Stepper on Motor2 (A Motor) +[stepper_y] +step_pin: PE2 +dir_pin: PE1 +enable_pin: !PE4 +microsteps: 16 +rotation_distance: 40 +endstop_pin: ^PF3 +full_steps_per_rotation:200 #set to 400 for 0.9 degree stepper +position_min: 0 +##-------------------------------------------------------------------- + +## Uncomment for 250mm build +#position_endstop: 250 +#position_max: 250 + +## Uncomment for 300mm build +#position_endstop: 300 +#position_max: 300 + +## Uncomment for 350mm build +#position_endstop: 350 +#position_max: 350 + +##-------------------------------------------------------------------- +homing_speed: 25 +homing_retract_dist: 5 +homing_positive_dir: true + + +[tmc2209 stepper_y] +uart_pin: PE3 +interpolate: True +run_current: 0.9 +sense_resistor: 0.110 +stealthchop_threshold: 0 + + +##################################################################### +# Z Stepper Settings +##################################################################### + +## Z0 Stepper - Front Left on MOTOR3_A +[stepper_z] +step_pin: PB8 +dir_pin: PB7 +enable_pin: !PE0 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 +endstop_pin: probe:z_virtual_endstop +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#position_max: 240 + +## Uncomment below for 300mm build +#position_max: 290 + +## Uncomment below for 350mm build +#position_max: 340 + +##-------------------------------------------------------------------- +position_min: -5 +homing_speed: 8 +second_homing_speed: 3 +homing_retract_dist: 3 + + +[tmc2209 stepper_z] +uart_pin: PB9 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z1 Stepper - Rear Left on Motor5 +[stepper_z1] +step_pin: PB4 +dir_pin: !PB3 +enable_pin: !PB6 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + + +[tmc2209 stepper_z1] +uart_pin: PB5 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z2 Stepper - Rear Right on Motor6 +[stepper_z2] +step_pin: PG13 +dir_pin: PG12 +enable_pin: !PG15 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + + +[tmc2209 stepper_z2] +uart_pin: PG14 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z3 Stepper - Front Right on Motor7 +[stepper_z3] +step_pin: PG9 +dir_pin: !PD7 +enable_pin: !PG11 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + + +[tmc2209 stepper_z3] +uart_pin: PG10 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +##################################################################### +# Extruder +##################################################################### + +# E0 on SB2209 +[extruder] +step_pin: EBBCan:gpio18 +dir_pin: EBBCan:gpio19 +enable_pin: !EBBCan:gpio17 +microsteps: 16 +rotation_distance: 22.905740611 +gear_ratio: 50:10 +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: EBBCan:gpio7 +control: pid +min_temp: 0 +max_extrude_only_distance: 105 +max_extrude_cross_section: 2 +pid_kp: 57.369 +pid_ki: 2.533 +pid_kd: 324.854 +sensor_type: MAX31865 +sensor_pin: EBBCan:gpio9 +spi_software_sclk_pin: EBBCan:gpio10 +spi_software_mosi_pin: EBBCan:gpio8 +spi_software_miso_pin: EBBCan:gpio11 +rtd_nominal_r: 100 +rtd_reference_r: 430 +rtd_num_of_wires: 2 + +[tmc2209 extruder] +uart_pin: EBBCan:gpio20 +run_current: 0.65 +stealthchop_threshold: 0 + + +##################################################################### +# Bed Heater +##################################################################### + +[heater_bed] +heater_pin: PA1 +sensor_type: Generic 3950 +sensor_pin: PB1 +max_power: 1.0 +min_temp: 0 +max_temp: 115 +control: pid +pid_kp: 58.437 +pid_ki: 2.347 +pid_kd: 363.769 + + +##################################################################### +# Probe +##################################################################### + +[probe] +pin: ^EBBCan:gpio22 +x_offset: 0 +y_offset: 0 +#z_offset: 0 +lift_speed: 30 +activate_gcode: + {% set PROBE_TEMP = 150 %} + {% set MAX_TEMP = PROBE_TEMP + 5 %} + {% set ACTUAL_TEMP = printer.extruder.temperature %} + {% set TARGET_TEMP = printer.extruder.target %} + + {% if TARGET_TEMP > PROBE_TEMP %} + { action_respond_info('Extruder temperature target of %.1fC is too high, lowering to %.1fC' % (TARGET_TEMP, PROBE_TEMP)) } + M109 S{ PROBE_TEMP } + {% else %} + # Temperature target is already low enough, but nozzle may still be too hot. + {% if ACTUAL_TEMP > MAX_TEMP %} + { action_respond_info('Extruder temperature %.1fC is still too high, waiting until below %.1fC' % (ACTUAL_TEMP, MAX_TEMP)) } + TEMPERATURE_WAIT SENSOR=extruder MAXIMUM={ MAX_TEMP } + {% endif %} + {% endif %} + +##################################################################### +# Fan Control +##################################################################### + +[fan] +pin: EBBCan:gpio13 + +[heater_fan hotend_fan] +pin: EBBCan:gpio14 +heater: extruder +heater_temp: 70.0 + + +[fan_generic nevermore] +## Print Cooling Fan - CNC_FAN0 +pin: PF8 +kick_start_time: 0.5 +off_below: 0.10 + +[controller_fan controller_fan_1] +## Hotend Fan - CNC_FAN1 +pin: PF9 +max_power: 1.0 +kick_start_time: 0.5 +fan_speed: 0.66 + + +[heater_fan controller_fan_2] +## Controller fan - CNC_FAN2 +pin: PF6 +kick_start_time: 0.5 +heater: heater_bed +heater_temp: 80 +fan_speed: 0.66 + +[fan_generic exhaust_fan] +# Exhaust fan - CNC_FAN0 +pin: PF7 +max_power: 1.0 +shutdown_speed: 0.0 +kick_start_time: 0.5 + +##################################################################### +# LED Control +##################################################################### + +[neopixel toolhead_light] +pin: EBBCan:gpio16 +chain_count: 3 +color_order: GRBW + +[output_pin caselight] +#Chamber Lighting - HE3 Connector +pin: PA3 +pwm:true +shutdown_value: 0 +cycle_time: 0.01 + +##################################################################### +# Homing and Gantry Adjustment Routines +##################################################################### + +[idle_timeout] +timeout: 3300 + +[safe_z_home] +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#home_xy_position: 125,125 + +## Uncomment below for 300mm build +#home_xy_position: 150,150 + +## Uncomment below for 350mm build +#home_xy_position: 175,175 + +##-------------------------------------------------------------------- +speed: 100 +z_hop: 10 + +[quad_gantry_level] +## Use QUAD_GANTRY_LEVEL to level a gantry. +## Min & Max gantry corners - measure from nozzle at MIN (0,0) and +## MAX (250, 250), (300,300), or (350,350) depending on your printer size +## to respective belt positions + +#-------------------------------------------------------------------- +## Gantry Corners for 250mm Build +## Uncomment for 250mm build +#gantry_corners: +# -60,-10 +# 310, 320 +## Probe points +#points: +# 50,25 +# 50,175 +# 200,175 +# 200,25 + +## Gantry Corners for 300mm Build +## Uncomment for 300mm build +#gantry_corners: +# -60,-10 +# 360,370 +## Probe points +#points: +# 50,25 +# 50,225 +# 250,225 +# 250,25 + +## Gantry Corners for 350mm Build +## Uncomment for 350mm build +gantry_corners: + -60,-10 + 410,420 +# Probe points +points: + 50,25 + 50,275 + 300,275 + 300,25 + +#-------------------------------------------------------------------- +speed: 100 +horizontal_move_z: 10 +retries: 10 +retry_tolerance: 0.0075 +max_adjust: 10 + +[bed_mesh] +mesh_min: 10,10 +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#mesh_max: 240,240 + +## Uncomment below for 300mm build +mesh_max: 290,290 + + +## Uncomment below for 350mm build +#mesh_max: 340,340 + +##-------------------------------------------------------------------- + + + + +[board_pins] +aliases: + # EXP1 header + EXP1_1=PE7, EXP1_2=PG1, + EXP1_3=PG0, EXP1_4=PF15, + EXP1_5=PF14, EXP1_6=PF13, # Slot in the socket on this side + EXP1_7=PF12, EXP1_8=PF11, + EXP1_9=, EXP1_10=<5V>, + + # EXP2 header + EXP2_1=PE13, EXP2_2=PE12, + EXP2_3=PE15, EXP2_4=PE11, + EXP2_5=PE10, EXP2_6=PE14, # Slot in the socket on this side + EXP2_7=PE8, EXP2_8=, + EXP2_9=, EXP2_10= + + +##################################################################### +# Macros +##################################################################### + +[gcode_macro G32] +gcode: + BED_MESH_CLEAR + G28 + QUAD_GANTRY_LEVEL + G28 + ## Uncomment for for your size printer: + #-------------------------------------------------------------------- + ## Uncomment for 250mm build + #G0 X125 Y125 Z30 F3600 + + ## Uncomment for 300 build + #G0 X150 Y150 Z30 F3600 + + ## Uncomment for 350mm build + #G0 X175 Y175 Z30 F3600 + #-------------------------------------------------------------------- + +[gcode_macro PRINT_START] +# Use PRINT_START for the slicer starting script - please customise for your slicer of choice +gcode: + G32 ; home all axes + G1 Z20 F3000 ; move nozzle away from bed + + +[gcode_macro PRINT_END] +# Use PRINT_END for the slicer ending script - please customise for your slicer of choice +gcode: + SAVE_GCODE_STATE NAME=STATE_PRINT_END + + M400 ; wait for buffer to clear + G92 E0 ; zero the extruder + G1 E-10.0 F3600 ; retract filament + + G91 ; relative positioning + G0 Z1.00 X20.0 Y20.0 F20000 ; move nozzle to remove stringing + TURN_OFF_HEATERS + M107 ; turn off fan + G1 Z2 F3000 ; move nozzle up 2mm + G90 ; absolute positioning + G0 X125 Y250 F3600 ; park nozzle at rear + BED_MESH_CLEAR + + # The purpose of the SAVE_GCODE_STATE/RESTORE_GCODE_STATE + # command pair is to restore the printer's coordinate system + # and speed settings since the commands above change them. + # However, to prevent any accidental, unintentional toolhead + # moves when restoring the state, explicitly set MOVE=0. + RESTORE_GCODE_STATE NAME=STATE_PRINT_END MOVE=0 + diff --git a/My_Examples/Voron2_M8P-v2.0_config.cfg b/My_Examples/Voron2_M8P-v2.0_config.cfg new file mode 100644 index 0000000..ea94838 --- /dev/null +++ b/My_Examples/Voron2_M8P-v2.0_config.cfg @@ -0,0 +1,561 @@ +# This file contains common pin mappings for the BIGTREETECH Manta M8P V2.0 +# To use this config, the firmware should be compiled for the +# STM32H723 with a "8KiB bootloader" and USB communication. + +# This config is currently only correct for V2.0 boards +# +# See docs/Config_Reference.md for a description of parameters. + +[mcu] +## [X in MOTOR1] - B Motor +## [Y in MOTOR2] - A Motor +## [E in MOTOR8] - Extruder +## Obtain definition by "ls /dev/serial/by-id/*" then unplug to verify +##-------------------------------------------------------------------- +serial: /dev/serial/by-id/YOU_DIDNT_CHANGE_ME_YET +#restart_method: command +##-------------------------------------------------------------------- + +[printer] +kinematics: corexy +max_velocity: 300 +max_accel: 3000 #Max 4000 +max_z_velocity: 15 #Max 15 for 12V TMC Drivers, can increase for 24V +max_z_accel: 350 +square_corner_velocity: 5.0 + +[temperature_sensor MCU] +sensor_type: temperature_mcu + +[temperature_sensor SoC] +sensor_type: temperature_host + +##################################################################### +# X/Y Stepper Settings +##################################################################### + +## X Stepper on Motor1(B Motor) +[stepper_x] +step_pin: PE6 +dir_pin: PE5 +enable_pin: !PC14 +microsteps: 16 +rotation_distance: 40 +full_steps_per_rotation:200 #set to 400 for 0.9 degree stepper +endstop_pin: ^PF4 +position_min: 0 +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#position_endstop: 250 +#position_max: 250 + +## Uncomment for 300mm build +#position_endstop: 300 +#position_max: 300 + +## Uncomment for 350mm build +#position_endstop: 350 +#position_max: 350 + +##-------------------------------------------------------------------- +homing_speed: 25 #Max 100 +homing_retract_dist: 5 +homing_positive_dir: true + +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 stepper_x] +uart_pin: PC13 +interpolate: True +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Y Stepper on Motor2 (A Motor) +[stepper_y] +step_pin: PE2 +dir_pin: PE1 +enable_pin: !PE4 +microsteps: 16 +rotation_distance: 40 +endstop_pin: ^PF3 +full_steps_per_rotation:200 #set to 400 for 0.9 degree stepper +position_min: 0 +##-------------------------------------------------------------------- + +## Uncomment for 250mm build +#position_endstop: 250 +#position_max: 250 + +## Uncomment for 300mm build +#position_endstop: 300 +#position_max: 300 + +## Uncomment for 350mm build +#position_endstop: 350 +#position_max: 350 + +##-------------------------------------------------------------------- +homing_speed: 25 #Max 100 +homing_retract_dist: 5 +homing_positive_dir: true + +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 stepper_y] +uart_pin: PE3 +interpolate: True +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +##################################################################### +# Z Stepper Settings +##################################################################### + +## Z0 Stepper - Front Left on MOTOR3_A +[stepper_z] +step_pin: PB8 +dir_pin: PB7 +enable_pin: !PE0 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 +endstop_pin: ^PF2 +## Z-position of nozzle (in mm) to z-endstop trigger point relative to print surface (Z0) +## (+) value = endstop above Z0, (-) value = endstop below +## Increasing position_endstop brings nozzle closer to the bed +## After you run Z_ENDSTOP_CALIBRATE, position_endstop will be stored at the very end of your config +#position_endstop: -0.5 +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#position_max: 240 + +## Uncomment below for 300mm build +#position_max: 290 + +## Uncomment below for 350mm build +#position_max: 340 + +##-------------------------------------------------------------------- +position_min: -5 +homing_speed: 8 +second_homing_speed: 3 +homing_retract_dist: 3 + +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 stepper_z] +uart_pin: PB9 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z1 Stepper - Rear Left on Motor5 +[stepper_z1] +step_pin: PG13 +dir_pin: !PG12 +enable_pin: !PG15 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 stepper_z1] +uart_pin: PG14 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z2 Stepper - Rear Right on Motor6 +[stepper_z2] +step_pin: PG9 +dir_pin: PD7 +enable_pin: !PG11 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 stepper_z2] +uart_pin: PG10 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z3 Stepper - Front Right on Motor7 +[stepper_z3] +step_pin: PD4 +dir_pin: !PD3 +enable_pin: !PD6 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 stepper_z3] +uart_pin: PD5 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +##################################################################### +# Extruder +##################################################################### + +# E0 on Motor8 +[extruder] +step_pin: PC7 +dir_pin: PC8 +enable_pin: !PD2 +## Update value below when you perform extruder calibration +## If you ask for 100mm of filament, but in reality it is 98mm: +## rotation_distance = * / 100 +## 22.6789511 is a good starting point +rotation_distance: 22.6789511 #Bondtech 5mm Drive Gears +## Update Gear Ratio depending on your Extruder Type +## Use 50:10 for Stealthburner/Clockwork 2 +## Use 50:17 for Afterburner/Clockwork (BMG Gear Ratio) +## Use 80:20 for M4, M3.1 +gear_ratio: 50:10 +microsteps: 16 +full_steps_per_rotation: 200 #200 for 1.8 degree, 400 for 0.9 degree +nozzle_diameter: 0.400 +filament_diameter: 1.75 +heater_pin: PA0 +## Validate the following thermistor type to make sure it is correct + +## Check what thermistor type you have. See https://www.klipper3d.org/Config_Reference.html#common-thermistors for common thermistor types. +## Use "Generic 3950" for NTC 100k 3950 thermistors +#sensor_type: + +sensor_pin: PB0 +min_temp: 10 +max_temp: 270 +max_power: 1.0 +min_extrude_temp: 170 +control = pid +pid_kp = 26.213 +pid_ki = 1.304 +pid_kd = 131.721 +## Try to keep pressure_advance below 1.0 +#pressure_advance: 0.05 +## Default is 0.040, leave stock +#pressure_advance_smooth_time: 0.040 + +## E0 on Motor7 +## Make sure to update below for your relevant driver (2208 or 2209) +[tmc2209 extruder] +uart_pin: PC6 +interpolate: false +run_current: 0.5 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +#[filament_switch_sensor material_0] +#switch_pin: PC1 + +#[filament_switch_sensor material_1] +#switch_pin: PC2 + +##################################################################### +# Bed Heater +##################################################################### + +[heater_bed] +## SSR Pin - HE1 +heater_pin: PA1 +## Check what thermistor type you have. See https://www.klipper3d.org/Config_Reference.html#common-thermistors for common thermistor types. +## Use "Generic 3950" for NTC 100k 3950 thermistors +#sensor_type: +sensor_pin: PB1 +## Adjust max_power so it doesn't exceed the SSR rating. The Omron G3NA-210B-DC5 SSR is rated at 4 amps without a heatsink. +## The formula is "4 / (Wattage_of_bed_heater / Mains_voltage) = max_power" +## If max_power is greater than 1.0, use 1.0 +max_power: 0.6 +min_temp: 0 +max_temp: 120 +control: pid +pid_kp: 58.437 +pid_ki: 2.347 +pid_kd: 363.769 + +##################################################################### +# Probe +##################################################################### + +[probe] +## Inductive Probe +## This probe is not used for Z height, only Quad Gantry Leveling +## NPN and PNP proximity switch types can be set by jumper +pin: PF1 #M4-STOP +x_offset: 0 +y_offset: 25.0 +z_offset: 0 +speed: 10.0 +samples: 3 +samples_result: median +sample_retract_dist: 3.0 +samples_tolerance: 0.006 +samples_tolerance_retries: 3 + +##################################################################### +# Fan Control +##################################################################### + +[fan] +## Print Cooling Fan - CNC_FAN0 +pin: PF7 +kick_start_time: 0.5 +## Depending on your fan, you may need to increase this value +## if your fan will not start. Can change cycle_time (increase) +## if your fan is not able to slow down effectively +off_below: 0.10 + +[heater_fan hotend_fan] +## Hotend Fan - CNC_FAN1 +pin: PF9 +max_power: 1.0 +kick_start_time: 0.5 +heater: extruder +heater_temp: 50.0 +## If you are experiencing back flow, you can reduce fan_speed +#fan_speed: 1.0 + +[heater_fan controller_fan] +## Controller fan - CNC_FAN2 +pin: PF6 +kick_start_time: 0.5 +heater: heater_bed +heater_temp: 45.0 + +#[heater_fan exhaust_fan] +## Exhaust fan - CNC_FAN3 +#pin: PF8 +#max_power: 1.0 +#shutdown_speed: 0.0 +#kick_start_time: 5.0 +#heater: heater_bed +#heater_temp: 60 +#fan_speed: 1.0 + +#[heater_fan fan4] +#pin: PA4 + +#[heater_fan fan5] +#pin: PA6 +#tachometer_pin: PC2 + +#[heater_fan fan6] +#pin: PA2 +#tachometer_pin: PC1 + +##################################################################### +# LED Control +##################################################################### + +#[output_pin caselight] +# Chamber Lighting - HE2 Connector (Optional) +#pin: PA3 +#pwm:true +#shutdown_value: 0 +#value:1 +#cycle_time: 0.01 + +##################################################################### +# Homing and Gantry Adjustment Routines +##################################################################### + +[idle_timeout] +timeout: 1800 + +[safe_z_home] +## XY Location of the Z Endstop Switch +## Update -10,-10 to the XY coordinates of your endstop pin +## (such as 157,305) after going through Z Endstop Pin +## Location Definition step. +home_xy_position:170,170 +speed:100 +z_hop:10 + +[quad_gantry_level] +## Use QUAD_GANTRY_LEVEL to level a gantry. +## Min & Max gantry corners - measure from nozzle at MIN (0,0) and +## MAX (250, 250), (300,300), or (350,350) depending on your printer size +## to respective belt positions + +#-------------------------------------------------------------------- +## Gantry Corners for 250mm Build +## Uncomment for 250mm build +#gantry_corners: +# -60,-10 +# 310, 320 +## Probe points +#points: +# 50,25 +# 50,175 +# 200,175 +# 200,25 + +## Gantry Corners for 300mm Build +## Uncomment for 300mm build +#gantry_corners: +# -60,-10 +# 360,370 +## Probe points +#points: +# 50,25 +# 50,225 +# 250,225 +# 250,25 + +## Gantry Corners for 350mm Build +## Uncomment for 350mm build +gantry_corners: + -60,-10 + 410,420 +# Probe points +points: + 50,25 + 50,275 + 300,275 + 300,25 + +#-------------------------------------------------------------------- +speed: 100 +horizontal_move_z: 10 +retries: 5 +retry_tolerance: 0.0075 +max_adjust: 10 + +[board_pins] +aliases: + # EXP1 header + EXP1_1=PE7, EXP1_2=PG1, + EXP1_3=PG0, EXP1_4=PF15, + EXP1_5=PF14, EXP1_6=PF13, # Slot in the socket on this side + EXP1_7=PF12, EXP1_8=PF11, + EXP1_9=, EXP1_10=<5V>, + + # EXP2 header + EXP2_1=PE13, EXP2_2=PE12, + EXP2_3=PE15, EXP2_4=PE11, + EXP2_5=PE10, EXP2_6=PE14, # Slot in the socket on this side + EXP2_7=PE8, EXP2_8=, + EXP2_9=, EXP2_10= + +# See the sample-lcd.cfg file for definitions of common LCD displays. + +##################################################################### +# Displays +##################################################################### + +## Uncomment the display that you have +#-------------------------------------------------------------------- + +#[display] +## RepRapDiscount 128x64 Full Graphic Smart Controller +#lcd_type: st7920 +#cs_pin: EXP1_4 +#sclk_pin: EXP1_5 +#sid_pin: EXP1_3 +#menu_timeout: 40 +#encoder_pins: ^EXP2_5, ^EXP2_3 +#click_pin: ^!EXP1_2 + +#[output_pin beeper] +#pin: EXP1_1 + +#-------------------------------------------------------------------- + +[display] +# mini12864 LCD Display +lcd_type: uc1701 +cs_pin: EXP1_3 +a0_pin: EXP1_4 +rst_pin: EXP1_5 +encoder_pins: ^EXP2_5, ^EXP2_3 +click_pin: ^!EXP1_2 +contrast: 63 +spi_software_miso_pin: EXP2_1 +spi_software_mosi_pin: EXP2_6 +spi_software_sclk_pin: EXP2_2 + +[neopixel btt_mini12864] +# To control Neopixel RGB in mini12864 display +pin: EXP1_6 +chain_count: 3 +initial_RED: 0.1 +initial_GREEN: 0.5 +initial_BLUE: 0.0 +color_order: RGB + +## 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=btt_mini12864 RED=1 GREEN=1 BLUE=1 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 + +#-------------------------------------------------------------------- + + +##################################################################### +# Macros +##################################################################### + +[gcode_macro G32] +gcode: + BED_MESH_CLEAR + G28 + QUAD_GANTRY_LEVEL + G28 + ## Uncomment for for your size printer: + #-------------------------------------------------------------------- + ## Uncomment for 250mm build + #G0 X125 Y125 Z30 F3600 + + ## Uncomment for 300 build + #G0 X150 Y150 Z30 F3600 + + ## Uncomment for 350mm build + #G0 X175 Y175 Z30 F3600 + #-------------------------------------------------------------------- + +[gcode_macro PRINT_START] +# Use PRINT_START for the slicer starting script - please customise for your slicer of choice +gcode: + G32 ; home all axes + G1 Z20 F3000 ; move nozzle away from bed + + +[gcode_macro PRINT_END] +# Use PRINT_END for the slicer ending script - please customise for your slicer of choice +gcode: + SAVE_GCODE_STATE NAME=STATE_PRINT_END + + M400 ; wait for buffer to clear + G92 E0 ; zero the extruder + G1 E-10.0 F3600 ; retract filament + + G91 ; relative positioning + G0 Z1.00 X20.0 Y20.0 F20000 ; move nozzle to remove stringing + TURN_OFF_HEATERS + M107 ; turn off fan + G1 Z2 F3000 ; move nozzle up 2mm + G90 ; absolute positioning + G0 X125 Y250 F3600 ; park nozzle at rear + BED_MESH_CLEAR + + # The purpose of the SAVE_GCODE_STATE/RESTORE_GCODE_STATE + # command pair is to restore the printer's coordinate system + # and speed settings since the commands above change them. + # However, to prevent any accidental, unintentional toolhead + # moves when restoring the state, explicitly set MOVE=0. + RESTORE_GCODE_STATE NAME=STATE_PRINT_END MOVE=0 + diff --git a/My_Examples/generic-bigtreetech-manta-m8p-V2_0.cfg b/My_Examples/generic-bigtreetech-manta-m8p-V2_0.cfg new file mode 100644 index 0000000..efa6431 --- /dev/null +++ b/My_Examples/generic-bigtreetech-manta-m8p-V2_0.cfg @@ -0,0 +1,338 @@ +# This file contains common pin mappings for the BIGTREETECH Manta M8P V2.0 +# To use this config, the firmware should be compiled for the +# STM32H723 with a "128KiB bootloader" "25 MHz crystal" +# and "USB (on PA11/PA12)", "CAN bus (on PD0/PD1)" or Serial (on USART1 PA10/PA9). + +# See docs/Config_Reference.md for a description of parameters. + +# Motor1 +[stepper_x] +step_pin: PE6 +dir_pin: PE5 +enable_pin: !PC14 +microsteps: 16 +rotation_distance: 40 +endstop_pin: ^PF4 +position_endstop: 0 +position_max: 235 +homing_speed: 50 + +# Motor2 +[stepper_y] +step_pin: PE2 +dir_pin: PE1 +enable_pin: !PE4 +microsteps: 16 +rotation_distance: 40 +endstop_pin: ^PF3 +position_endstop: 0 +position_max: 235 +homing_speed: 50 + +# Motor3 +[stepper_z] +step_pin: PB8 +dir_pin: !PB7 +enable_pin: !PE0 +microsteps: 16 +rotation_distance: 8 +endstop_pin: ^PF2 +position_endstop: 0 +position_max: 270 +position_min: -5.0 +homing_speed: 8 +second_homing_speed: 3 +homing_retract_dist: 3 + +## Motor4 +# The M8P only has 4 heater outputs which leaves an extra stepper +# This can be used for a second Z stepper, dual_carriage, extruder co-stepper, +# or other accesory such as an MMU +#[stepper_] +#step_pin: PB4 +#dir_pin: PB3 +#enable_pin: !PB6 +#endstop_pin: ^PF1 +#... + +# Motor5 +[extruder] +step_pin: PG13 +dir_pin: PG12 +enable_pin: !PG15 +microsteps: 16 +rotation_distance: 33.500 +nozzle_diameter: 0.4 +filament_diameter: 1.75 +heater_pin: PA0 # HE0 +sensor_pin: PB0 # T0 +sensor_type: Generic 3950 +control: pid +pid_Kp: 22.2 +pid_Ki: 1.08 +pid_Kd: 114 +min_temp: 0 +max_temp: 250 + +## End-Stop 5 +#[filament_switch_sensor material_0] +#switch_pin: PF0 + +## Motor6 +#[extruder1] +#step_pin: PG9 +#dir_pin: PD7 +#enable_pin: !PG11 +#heater_pin: PA1 # HE1 +#sensor_pin: PC5 # T1 +#... + +## End-Stop 6 +#[filament_switch_sensor material_1] +#switch_pin: PC15 + +## Motor7 +#[extruder2] +#step_pin: PD4 +#dir_pin: PD3 +#enable_pin: !PD6 +#heater_pin: PA3 # HE2 +#sensor_pin: PC4 # T2 +#... + +## Motor8 +#[extruder3] +#step_pin: PC7 +#dir_pin: PC8 +#enable_pin: !PD2 +#heater_pin: PA5 # HE3 +#sensor_pin: PA7 # T3 +#... + +[heater_bed] +heater_pin: PF5 +sensor_pin: PB1 # TB +sensor_type: ATC Semitec 104GT-2 +control: watermark +min_temp: 0 +max_temp: 130 + +#[fan_generic soc-fan] +#pin: host:gpio79 #CB1 +#pin: host:gpio26 #CM4 + +# Fan0 +[fan] +pin: PF7 + +## Fan1 +#[heater_fan fan1] +#pin: PF9 + +## Fan2 +#[heater_fan fan2] +#pin: PF6 + +## Fan3 +#[heater_fan fan3] +#pin: PF8 + +## Fan4 +#[heater_fan fan4] +#pin: PA4 + +## Fan5 +#[heater_fan fan5] +#pin: PA6 +#tachometer_pin: PC2 + +## Fan6 +#[heater_fan fan6] +#pin: PA2 +#tachometer_pin: PC1 + +[mcu] +serial: /dev/serial/by-id/usb-Klipper_Klipper_firmware_12345-if00 + +[printer] +kinematics: cartesian +max_velocity: 300 +max_accel: 3000 +max_z_velocity: 5 +max_z_accel: 100 + +######################################## +# TMC2209 configuration +######################################## + +## Motor1 +#[tmc2209 stepper_x] +#uart_pin: PC13 +##diag_pin: PF4 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor2 +#[tmc2209 stepper_y] +#uart_pin: PE3 +##diag_pin: PF3 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor3 +#[tmc2209 stepper_z] +#uart_pin: PB9 +##diag_pin: PF2 +#run_current: 0.650 +#stealthchop_threshold: 999999 + +## Motor4 +#[tmc2209 stepper_] +#uart_pin: PB5 +##diag_pin: PF1 +#run_current: 0.650 +#stealthchop_threshold: 999999 + +## Motor5 +#[tmc2209 extruder] +#uart_pin: PG14 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor6 +#[tmc2209 extruder1] +#uart_pin: PG10 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor7 +#[tmc2209 extruder2] +#uart_pin: PD5 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor8 +#[tmc2209 extruder3] +#uart_pin: PC6 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +######################################## +# TMC2130 configuration +######################################## + +## Motor1 +#[tmc2130 stepper_x] +#cs_pin: PC13 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +##diag1_pin: PF4 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor2 +#[tmc2130 stepper_y] +#cs_pin: PE3 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +##diag1_pin: PF3 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor3 +#[tmc2130 stepper_z] +#cs_pin: PB9 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +##diag1_pin: PF2 +#run_current: 0.650 +#stealthchop_threshold: 999999 + +## Motor4 +#[tmc2130 stepper_] +#cs_pin: PB5 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +##diag1_pin: PF1 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor5 +#[tmc2130 extruder] +#cs_pin: PG14 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor6 +#[tmc2130 extruder1] +#cs_pin: PG10 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor7 +#[tmc2130 extruder2] +#cs_pin: PD5 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +## Motor8 +#[tmc2130 extruder3] +#cs_pin: PC6 +#spi_software_mosi_pin: PG6 +#spi_software_miso_pin: PG7 +#spi_software_sclk_pin: PG8 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +[board_pins] +aliases: + # EXP1 header + EXP1_1=PE7, EXP1_2=PG1, + EXP1_3=PG0, EXP1_4=PF15, + EXP1_5=PF14, EXP1_6=PF13, # Slot in the socket on this side + EXP1_7=PF12, EXP1_8=PF11, + EXP1_9=, EXP1_10=<5V>, + + # EXP2 header + EXP2_1=PE13, EXP2_2=PE12, + EXP2_3=PE15, EXP2_4=PE11, + EXP2_5=PE10, EXP2_6=PE14, # Slot in the socket on this side + EXP2_7=PE8, EXP2_8=, + EXP2_9=, EXP2_10= + +# See the sample-lcd.cfg file for definitions of common LCD displays. + +#[adxl345] +#cs_pin: PA15 +#spi_bus: spi3a + +#[bltouch] +#sensor_pin: PD13 +#control_pin: PD12 + +## Proximity switch +#[probe] +#pin: PD8 + +#[output_pin ps_on_pin] +#pin: PD14 + +#[neopixel my_neopixel_1] +#pin: PD15 + +#[hall_filament_width_sensor] +#adc1: PC0 +#adc2: PF10 diff --git a/My_Examples/sample-bigtreetech-ebb-sb-rp2040-canbus-v1.0.cfg b/My_Examples/sample-bigtreetech-ebb-sb-rp2040-canbus-v1.0.cfg new file mode 100644 index 0000000..37b3e3f --- /dev/null +++ b/My_Examples/sample-bigtreetech-ebb-sb-rp2040-canbus-v1.0.cfg @@ -0,0 +1,81 @@ +# This file contains common pin mappings for the BIGTREETECH EBBCan +# Canbus board. To use this config, the firmware should be compiled for the +# RP2040 with "USB" or "CAN bus (on gpio4/gpio5)". +# The "EBB Can" micro-controller will be used to control the components on the nozzle. + +# See docs/Config_Reference.md for a description of parameters. + +[mcu EBBCan] +serial: /dev/serial/by-id/usb-Klipper_Klipper_firmware_12345-if00 +#canbus_uuid: 0e0d81e4210c + +[temperature_sensor EBB_NTC] +sensor_type: Generic 3950 +sensor_pin: EBBCan:gpio28 + +[adxl345] +cs_pin: EBBCan:gpio1 +spi_software_sclk_pin: EBBCan:gpio2 +spi_software_mosi_pin: EBBCan:gpio0 +spi_software_miso_pin: EBBCan:gpio3 +axes_map: z,-y,x + +[resonance_tester] +probe_points: 100, 100, 20 +accel_chip: adxl345 + +[extruder] +step_pin: EBBCan:gpio18 +dir_pin: !EBBCan:gpio19 +enable_pin: !EBBCan:gpio17 +microsteps: 16 +rotation_distance: 33.500 +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: EBBCan:gpio7 +sensor_type: EPCOS 100K B57560G104F +sensor_pin: EBBCan:gpio27 +control: pid +pid_Kp: 21.527 +pid_Ki: 1.063 +pid_Kd: 108.982 +min_temp: 0 +max_temp: 250 + +# sensor_type: MAX31865 +# sensor_pin: EBBCan:gpio9 +# spi_software_sclk_pin: EBBCan:gpio10 +# spi_software_mosi_pin: EBBCan:gpio8 +# spi_software_miso_pin: EBBCan:gpio11 +# rtd_nominal_r: 100 +# rtd_reference_r: 430 +# rtd_num_of_wires: 2 + +[tmc2209 extruder] +uart_pin: EBBCan:gpio20 +run_current: 0.650 +stealthchop_threshold: 999999 + +[fan] +pin: EBBCan:gpio13 + +[heater_fan hotend_fan] +pin: EBBCan:gpio14 +heater: extruder +heater_temp: 50.0 + +[fan_generic 4W_FAN0] +pin: EBBCan:gpio15 +tachometer_pin: EBBCan:gpio12 +#tachometer_ppr: 1 + +[neopixel hotend_rgb] +pin: EBBCan:gpio16 + +[bltouch] +sensor_pin: ^EBBCan:gpio21 +control_pin: EBBCan:gpio22 + +## NPN and PNP proximity switch types can be set by jumper +#[probe] +#pin: ^EBBCan:gpio6 diff --git a/crowsnest.conf b/crowsnest.conf new file mode 100644 index 0000000..b548262 --- /dev/null +++ b/crowsnest.conf @@ -0,0 +1,48 @@ +#### crowsnest.conf +#### This is a typical default config. +#### Also used as default in mainsail / MainsailOS +#### See: +#### https://github.com/mainsail-crew/crowsnest/blob/master/README.md +#### for details to configure to your needs. + + +##################################################################### +#### ##### +#### Information about ports and according URL's ##### +#### ##### +##################################################################### +#### ##### +#### Port 8080 equals /webcam/?action=[stream/snapshot] ##### +#### Port 8081 equals /webcam2/?action=[stream/snapshot] ##### +#### Port 8082 equals /webcam3/?action=[stream/snapshot] ##### +#### Port 8083 equals /webcam4/?action=[stream/snapshot] ##### +#### ##### +#### Note: These ports are default for most Mainsail ##### +#### installations. To use any other port would involve ##### +#### changing the proxy configuration or using directly ##### +#### http://:/?action=[stream/snapshot] ##### +#### ##### +##################################################################### +#### RTSP Stream URL: ( if enabled and supported ) ##### +#### rtsp://:/stream.h264 ##### +##################################################################### + + +[crowsnest] +log_path: /home/biqu/printer_data/logs/crowsnest.log +log_level: verbose # Valid Options are quiet/verbose/debug +delete_log: false # Deletes log on every restart, if set to true +no_proxy: false + +[cam 1] +mode: ustreamer # ustreamer - Provides mjpg and snapshots. (All devices) +#mode: camera-streamer # camera-streamer - Provides webrtc, mjpg and snapshots. (rpi + Raspi OS based only) +enable_rtsp: false # If camera-streamer is used, this enables also usage of an rtsp server +rtsp_port: 8554 # Set different ports for each device! +port: 8080 # HTTP/MJPG Stream/Snapshot Port +device: /dev/video0 # See Log for available ... +#resolution: 640x480 # widthxheight format +resolution: 1280x720 +max_fps: 15 # If Hardware Supports this it will be forced, otherwise ignored/coerced. +#custom_flags: # You can run the Stream Services with custom flags. +#v4l2ctl: # Add v4l2-ctl parameters to setup your camera, see Log what your cam is capable of. diff --git a/mainsail.cfg b/mainsail.cfg new file mode 100644 index 0000000..83eaf8d --- /dev/null +++ b/mainsail.cfg @@ -0,0 +1,313 @@ +## Client klipper macro definitions +## +## Copyright (C) 2022 Alex Zellner +## +## This file may be distributed under the terms of the GNU GPLv3 license +## +## !!! This file is read-only. Maybe the used editor indicates that. !!! +## +## Customization: +## 1) copy the gcode_macro _CLIENT_VARIABLE (see below) to your printer.cfg +## 2) remove the comment mark (#) from all lines +## 3) change any value in there to your needs +## +## Use the PAUSE macro direct in your M600: +## e.g. with a different park position front left and a minimal height of 50 +## [gcode_macro M600] +## description: Filament change +## gcode: PAUSE X=10 Y=10 Z_MIN=50 +## Z_MIN will park the toolhead at a minimum of 50 mm above to bed to make it easier for you to swap filament. +## +## Client variable macro for your printer.cfg +#[gcode_macro _CLIENT_VARIABLE] +#variable_use_custom_pos : False ; use custom park coordinates for x,y [True/False] +#variable_custom_park_x : 0.0 ; custom x position; value must be within your defined min and max of X +#variable_custom_park_y : 0.0 ; custom y position; value must be within your defined min and max of Y +#variable_custom_park_dz : 2.0 ; custom dz value; the value in mm to lift the nozzle when move to park position +#variable_retract : 1.0 ; the value to retract while PAUSE +#variable_cancel_retract : 5.0 ; the value to retract while CANCEL_PRINT +#variable_speed_retract : 35.0 ; retract speed in mm/s +#variable_unretract : 1.0 ; the value to unretract while RESUME +#variable_speed_unretract : 35.0 ; unretract speed in mm/s +#variable_speed_hop : 15.0 ; z move speed in mm/s +#variable_speed_move : 100.0 ; move speed in mm/s +#variable_park_at_cancel : False ; allow to move the toolhead to park while execute CANCEL_PRINT [True/False] +#variable_park_at_cancel_x : None ; different park position during CANCEL_PRINT [None/Position as Float]; park_at_cancel must be True +#variable_park_at_cancel_y : None ; different park position during CANCEL_PRINT [None/Position as Float]; park_at_cancel must be True +## !!! Caution [firmware_retraction] must be defined in the printer.cfg if you set use_fw_retract: True !!! +#variable_use_fw_retract : False ; use fw_retraction instead of the manual version [True/False] +#variable_idle_timeout : 0 ; time in sec until idle_timeout kicks in. Value 0 means that no value will be set or restored +#variable_runout_sensor : "" ; If a sensor is defined, it will be used to cancel the execution of RESUME in case no filament is detected. +## Specify the config name of the runout sensor e.g "filament_switch_sensor runout". Hint use the same as in your printer.cfg +## !!! Custom macros, please use with care and review the section of the corresponding macro. +## These macros are for simple operations like setting a status LED. Please make sure your macro does not interfere with the basic macro functions. +## Only single line commands are supported, please create a macro if you need more than one command. +#variable_user_pause_macro : "" ; Everything inside the "" will be executed after the klipper base pause (PAUSE_BASE) function +#variable_user_resume_macro: "" ; Everything inside the "" will be executed before the klipper base resume (RESUME_BASE) function +#variable_user_cancel_macro: "" ; Everything inside the "" will be executed before the klipper base cancel (CANCEL_PRINT_BASE) function +#gcode: + +[virtual_sdcard] +path: ~/printer_data/gcodes +on_error_gcode: CANCEL_PRINT + +[pause_resume] +#recover_velocity: 50. +# When capture/restore is enabled, the speed at which to return to +# the captured position (in mm/s). Default is 50.0 mm/s. + +[display_status] + +[respond] + +[gcode_macro CANCEL_PRINT] +description: Cancel the actual running print +rename_existing: CANCEL_PRINT_BASE +gcode: + ##### get user parameters or use default ##### + {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} + {% set allow_park = client.park_at_cancel|default(false)|lower == 'true' %} + {% set retract = client.cancel_retract|default(5.0)|abs %} + ##### define park position ##### + {% set park_x = "" if (client.park_at_cancel_x|default(none) is none) + else "X=" ~ client.park_at_cancel_x %} + {% set park_y = "" if (client.park_at_cancel_y|default(none) is none) + else "Y=" ~ client.park_at_cancel_y %} + {% set custom_park = park_x|length > 0 or park_y|length > 0 %} + ##### end of definitions ##### + # restore idle_timeout time if needed + {% if printer['gcode_macro RESUME'].restore_idle_timeout > 0 %} + SET_IDLE_TIMEOUT TIMEOUT={printer['gcode_macro RESUME'].restore_idle_timeout} + {% endif %} + {% if (custom_park or not printer.pause_resume.is_paused) and allow_park %} _TOOLHEAD_PARK_PAUSE_CANCEL {park_x} {park_y} {% endif %} + _CLIENT_RETRACT LENGTH={retract} + TURN_OFF_HEATERS + M106 S0 + {client.user_cancel_macro|default("")} + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False + # clear pause_next_layer and pause_at_layer as preparation for next print + SET_PAUSE_NEXT_LAYER ENABLE=0 + SET_PAUSE_AT_LAYER ENABLE=0 LAYER=0 + CANCEL_PRINT_BASE + +[gcode_macro PAUSE] +description: Pause the actual running print +rename_existing: PAUSE_BASE +gcode: + ##### get user parameters or use default ##### + {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} + {% set idle_timeout = client.idle_timeout|default(0) %} + {% set temp = printer[printer.toolhead.extruder].target if printer.toolhead.extruder != '' else 0 %} + {% set restore = False if printer.toolhead.extruder == '' + else True if params.RESTORE|default(1)|int == 1 else False %} + ##### end of definitions ##### + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=last_extruder_temp VALUE="{{'restore': restore, 'temp': temp}}" + # set a new idle_timeout value + {% if idle_timeout > 0 %} + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=restore_idle_timeout VALUE={printer.configfile.settings.idle_timeout.timeout} + SET_IDLE_TIMEOUT TIMEOUT={idle_timeout} + {% endif %} + PAUSE_BASE + {client.user_pause_macro|default("")} + _TOOLHEAD_PARK_PAUSE_CANCEL {rawparams} + +[gcode_macro RESUME] +description: Resume the actual running print +rename_existing: RESUME_BASE +variable_last_extruder_temp: {'restore': False, 'temp': 0} +variable_restore_idle_timeout: 0 +variable_idle_state: False +gcode: + ##### get user parameters or use default ##### + {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} + {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} + {% set sp_move = client.speed_move|default(velocity) %} + {% set runout_resume = True if client.runout_sensor|default("") == "" # no runout + else True if not printer[client.runout_sensor].enabled # sensor is disabled + else printer[client.runout_sensor].filament_detected %} # sensor status + {% set can_extrude = True if printer.toolhead.extruder == '' # no extruder defined in config + else printer[printer.toolhead.extruder].can_extrude %} # status of active extruder + {% set do_resume = False %} + {% set prompt_txt = [] %} + ##### end of definitions ##### + #### Printer comming from timeout idle state #### + {% if printer.idle_timeout.state|upper == "IDLE" or idle_state %} + SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False + {% if last_extruder_temp.restore %} + # we need to use the unicode (\u00B0) for the ° as py2 env's would throw an error otherwise + RESPOND TYPE=echo MSG='{"Restoring \"%s\" temperature to %3.1f\u00B0C, this may take some time" % (printer.toolhead.extruder, last_extruder_temp.temp) }' + M109 S{last_extruder_temp.temp} + {% set do_resume = True %} + {% elif can_extrude %} + {% set do_resume = True %} + {% else %} + RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder}' + {% set _d = prompt_txt.append("\"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder) %} + {% endif %} + #### Printer comming out of regular PAUSE state #### + {% elif can_extrude %} + {% set do_resume = True %} + {% else %} + RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder}' + {% set _d = prompt_txt.append("\"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder) %} + {% endif %} + {% if runout_resume %} + {% if do_resume %} + {% if restore_idle_timeout > 0 %} SET_IDLE_TIMEOUT TIMEOUT={restore_idle_timeout} {% endif %} # restore idle_timeout time + {client.user_resume_macro|default("")} + _CLIENT_EXTRUDE + RESUME_BASE VELOCITY={params.VELOCITY|default(sp_move)} + {% endif %} + {% else %} + RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" detects no filament, please load filament and press RESUME" % (client.runout_sensor.split(" "))[1]}' + {% set _d = prompt_txt.append("\"%s\" detects no filament, please load filament and press RESUME" % (client.runout_sensor.split(" "))[1]) %} + {% endif %} + ##### Generate User Information box in case of abort ##### + {% if not (runout_resume and do_resume) %} + RESPOND TYPE=command MSG="action:prompt_begin RESUME aborted !!!" + {% for element in prompt_txt %} + RESPOND TYPE=command MSG='{"action:prompt_text %s" % element}' + {% endfor %} + RESPOND TYPE=command MSG="action:prompt_footer_button Ok|RESPOND TYPE=command MSG=action:prompt_end|info" + RESPOND TYPE=command MSG="action:prompt_show" + {% endif %} + +# Usage: SET_PAUSE_NEXT_LAYER [ENABLE=[0|1]] [MACRO=] +[gcode_macro SET_PAUSE_NEXT_LAYER] +description: Enable a pause if the next layer is reached +gcode: + {% set pause_next_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_next_layer %} + {% set ENABLE = params.ENABLE|default(1)|int != 0 %} + {% set MACRO = params.MACRO|default(pause_next_layer.call, True) %} + SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{{ 'enable': ENABLE, 'call': MACRO }}" + +# Usage: SET_PAUSE_AT_LAYER [ENABLE=[0|1]] [LAYER=] [MACRO=] +[gcode_macro SET_PAUSE_AT_LAYER] +description: Enable/disable a pause if a given layer number is reached +gcode: + {% set pause_at_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_at_layer %} + {% set ENABLE = params.ENABLE|int != 0 if params.ENABLE is defined + else params.LAYER is defined %} + {% set LAYER = params.LAYER|default(pause_at_layer.layer)|int %} + {% set MACRO = params.MACRO|default(pause_at_layer.call, True) %} + SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{{ 'enable': ENABLE, 'layer': LAYER, 'call': MACRO }}" + +# Usage: SET_PRINT_STATS_INFO [TOTAL_LAYER=] [CURRENT_LAYER= ] +[gcode_macro SET_PRINT_STATS_INFO] +rename_existing: SET_PRINT_STATS_INFO_BASE +description: Overwrite, to get pause_next_layer and pause_at_layer feature +variable_pause_next_layer: { 'enable': False, 'call': "PAUSE" } +variable_pause_at_layer : { 'enable': False, 'layer': 0, 'call': "PAUSE" } +gcode: + {% if pause_next_layer.enable %} + RESPOND TYPE=echo MSG='{"%s, forced by pause_next_layer" % pause_next_layer.call}' + {pause_next_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE + SET_PAUSE_NEXT_LAYER ENABLE=0 + {% elif pause_at_layer.enable and params.CURRENT_LAYER is defined and params.CURRENT_LAYER|int == pause_at_layer.layer %} + RESPOND TYPE=echo MSG='{"%s, forced by pause_at_layer [%d]" % (pause_at_layer.call, pause_at_layer.layer)}' + {pause_at_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE + SET_PAUSE_AT_LAYER ENABLE=0 + {% endif %} + SET_PRINT_STATS_INFO_BASE {rawparams} + +##### internal use ##### +[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL] +description: Helper: park toolhead used in PAUSE and CANCEL_PRINT +gcode: + ##### get user parameters or use default ##### + {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} + {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} + {% set use_custom = client.use_custom_pos|default(false)|lower == 'true' %} + {% set custom_park_x = client.custom_park_x|default(0.0) %} + {% set custom_park_y = client.custom_park_y|default(0.0) %} + {% set park_dz = client.custom_park_dz|default(2.0)|abs %} + {% set sp_hop = client.speed_hop|default(15) * 60 %} + {% set sp_move = client.speed_move|default(velocity) * 60 %} + ##### get config and toolhead values ##### + {% set origin = printer.gcode_move.homing_origin %} + {% set act = printer.gcode_move.gcode_position %} + {% set max = printer.toolhead.axis_maximum %} + {% set cone = printer.toolhead.cone_start_z|default(max.z) %} ; height as long the toolhead can reach max and min of an delta + {% set round_bed = True if printer.configfile.settings.printer.kinematics is in ['delta','polar','rotary_delta','winch'] + else False %} + ##### define park position ##### + {% set z_min = params.Z_MIN|default(0)|float %} + {% set z_park = [[(act.z + park_dz), z_min]|max, (max.z - origin.z)]|min %} + {% set x_park = params.X if params.X is defined + else custom_park_x if use_custom + else 0.0 if round_bed + else (max.x - 5.0) %} + {% set y_park = params.Y if params.Y is defined + else custom_park_y if use_custom + else (max.y - 5.0) if round_bed and z_park < cone + else 0.0 if round_bed + else (max.y - 5.0) %} + ##### end of definitions ##### + _CLIENT_RETRACT + {% if "xyz" in printer.toolhead.homed_axes %} + G90 + G1 Z{z_park} F{sp_hop} + G1 X{x_park} Y{y_park} F{sp_move} + {% if not printer.gcode_move.absolute_coordinates %} G91 {% endif %} + {% else %} + RESPOND TYPE=echo MSG='Printer not homed' + {% endif %} + +[gcode_macro _CLIENT_EXTRUDE] +description: Extrudes, if the extruder is hot enough +gcode: + ##### get user parameters or use default ##### + {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} + {% set use_fw_retract = (client.use_fw_retract|default(false)|lower == 'true') and (printer.firmware_retraction is defined) %} + {% set length = params.LENGTH|default(client.unretract)|default(1.0)|float %} + {% set speed = params.SPEED|default(client.speed_unretract)|default(35) %} + {% set absolute_extrude = printer.gcode_move.absolute_extrude %} + ##### end of definitions ##### + {% if printer.toolhead.extruder != '' %} + {% if printer[printer.toolhead.extruder].can_extrude %} + {% if use_fw_retract %} + {% if length < 0 %} + G10 + {% else %} + G11 + {% endif %} + {% else %} + M83 + G1 E{length} F{(speed|float|abs) * 60} + {% if absolute_extrude %} + M82 + {% endif %} + {% endif %} + {% else %} + RESPOND TYPE=echo MSG='{"\"%s\" not hot enough" % printer.toolhead.extruder}' + {% endif %} + {% endif %} + +[gcode_macro _CLIENT_RETRACT] +description: Retracts, if the extruder is hot enough +gcode: + {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} + {% set length = params.LENGTH|default(client.retract)|default(1.0)|float %} + {% set speed = params.SPEED|default(client.speed_retract)|default(35) %} + + _CLIENT_EXTRUDE LENGTH=-{length|float|abs} SPEED={speed|float|abs} + +[gcode_macro _CLIENT_LINEAR_MOVE] +description: Linear move with save and restore of the gcode state +gcode: + {% set x_move = "X" ~ params.X if params.X is defined else "" %} + {% set y_move = "Y" ~ params.Y if params.Y is defined else "" %} + {% set z_move = "Z" ~ params.Z if params.Z is defined else "" %} + {% set e_move = "E" ~ params.E if params.E is defined else "" %} + {% set rate = "F" ~ params.F if params.F is defined else "" %} + {% set ABSOLUTE = params.ABSOLUTE | default(0) | int != 0 %} + {% set ABSOLUTE_E = params.ABSOLUTE_E | default(0) | int != 0 %} + SAVE_GCODE_STATE NAME=_client_movement + {% if x_move or y_move or z_move %} + G9{ 0 if ABSOLUTE else 1 } + {% endif %} + {% if e_move %} + M8{ 2 if ABSOLUTE_E else 3 } + {% endif %} + G1 { x_move } { y_move } { z_move } { e_move } { rate } + RESTORE_GCODE_STATE NAME=_client_movement diff --git a/moonraker.conf b/moonraker.conf new file mode 100644 index 0000000..9d90bdb --- /dev/null +++ b/moonraker.conf @@ -0,0 +1,82 @@ +[server] +host: 0.0.0.0 +port: 7125 +klippy_uds_address: /home/biqu/printer_data/comms/klippy.sock + +[authorization] +trusted_clients: + 192.168.0.0/16 + 10.0.0.0/8 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.168.0.0/16 + FE80::/10 + ::1/128 +cors_domains: + *.lan + *.local + *://localhost + *://localhost:* + *://my.mainsail.xyz + *://app.fluidd.xyz + +[octoprint_compat] + +[history] + +[update_manager] +channel: dev +refresh_interval: 168 + +[update_manager mainsail] +path: /home/biqu/mainsail +repo: mainsail-crew/mainsail +channel: stable +type: web + +[update_manager mainsail-config] +managed_services: klipper +origin: https://github.com/mainsail-crew/mainsail-config.git +path: /home/biqu/mainsail-config +primary_branch: master +type: git_repo + +[update_manager KlipperScreen] +install_script: /home/biqu/KlipperScreen/scripts/KlipperScreen-install.sh +requirements: /home/biqu/KlipperScreen/scripts/KlipperScreen-requirements.txt +env: /home/biqu/.KlipperScreen-env/bin/python +managed_services: KlipperScreen +origin: https://github.com/KlipperScreen/KlipperScreen.git +path: /home/biqu/KlipperScreen +type: git_repo + +# Crowsnest update_manager entry +[update_manager crowsnest] +type: git_repo +path: ~/crowsnest +origin: https://github.com/mainsail-crew/crowsnest.git +managed_services: crowsnest +install_script: tools/pkglist.sh + +# Sonar update_manager entry +[update_manager sonar] +type: git_repo +path: ~/sonar +origin: https://github.com/mainsail-crew/sonar.git +primary_branch: main +managed_services: sonar +install_script: tools/install.sh + +[update_manager timelapse] +type: git_repo +primary_branch: main +path: ~/moonraker-timelapse +origin: https://github.com/mainsail-crew/moonraker-timelapse.git +managed_services: klipper moonraker + +[update_manager print_area_bed_mesh] +type: git_repo +path: ~/print_area_bed_mesh +origin: https://github.com/Turge08/print_area_bed_mesh.git +is_system_service: False diff --git a/print_area_bed_mesh.cfg b/print_area_bed_mesh.cfg new file mode 100644 index 0000000..aece099 --- /dev/null +++ b/print_area_bed_mesh.cfg @@ -0,0 +1,166 @@ +[gcode_macro BED_MESH_CALIBRATE] +# print surface bed mesh calibrate +# Works with Klicky Probe on Voron +# November 24, 2021 +# Steve Turgeon +rename_existing: _BED_MESH_CALIBRATE + +variable_buffer: 20 + +; Do not change any of the existing values below. +variable_last_area_start_x: -1 ; Do not change +variable_last_area_start_y: -1 ; Do not change +variable_last_area_end_x: -1 ; Do not change +variable_last_area_end_y: -1 ; Do not change + +gcode: + + {% if params.FORCE_NEW_MESH != null %} + { action_respond_info("Force New Mesh: %s" % (params.FORCE_NEW_MESH)) } + {% endif %} + {% if printer["bed_mesh"].profile_name == '' %} + { action_respond_info("No existing bed mesh found.") } + {% set last_area_end_x=-1 %} + {% endif %} + + {% if printer.toolhead.homed_axes != "xyz" %} + G28 + {% endif %} + + {% set klicky_available = printer['gcode_macro _Probe_Variables'] != null %} + {% set euclid_available = printer['gcode_macro EuclidProbe'] != null %}; Requires v5 macros https://github.com/nionio6915/Euclid_Probe/blob/main/Firmware_Examples/Klipper/00-euclid_exampleV5.cfg + {% if params.PRINT_MIN %} + { action_respond_info("print_min: %s" % params.PRINT_MIN) } + { action_respond_info("print_max: %s" % params.PRINT_MAX) } + + {% set blTouchConfig = printer['configfile'].config["bltouch"] %} + {% if blTouchConfig %} + {% set OffsetX = blTouchConfig.x_offset|default(0)|float %} + {% set OffsetY = blTouchConfig.y_offset|default(0)|float %} + {% endif %} + + {% set probeConfig = printer['configfile'].config["probe"] %} + {% if probeConfig %} + {% set OffsetX = probeConfig.x_offset|default(0)|float %} + {% set OffsetY = probeConfig.y_offset|default(0)|float %} + {% endif %} + + {% set print_min_x = params.PRINT_MIN.split(",")[0]|float %} + {% set print_min_y = params.PRINT_MIN.split(",")[1]|float %} + {% set print_max_x = params.PRINT_MAX.split(",")[0]|float %} + {% set print_max_y = params.PRINT_MAX.split(",")[1]|float %} + + {% if last_area_start_x > 0 %} + { action_respond_info("last_bed_mesh: %s,%s %s,%s" % (last_area_start_x, last_area_start_y, last_area_end_x, last_area_end_y)) } + {% endif %} + + {% if (params.FORCE_NEW_MESH != null) or (print_min_x < last_area_start_x) or (print_max_x > last_area_end_x) or (print_min_y < last_area_start_y) or (print_max_y > last_area_end_y) %} + {% if klicky_available %} + _CheckProbe action=query + Attach_Probe + {% elif euclid_available %} + DEPLOY_PROBE + {% endif %} + {% if (print_min_x < print_max_x) and (print_min_y < print_max_y) %} + + # Get bed_mesh config (probe count, mesh_min and mesh_max for x and y + {% set bedMeshConfig = printer['configfile'].config["bed_mesh"] %} + {% set minimum_probe_count = 3 %} + {% if bedMeshConfig.algorithm == "bicubic" %} + {% set minimum_probe_count = 5 %} + {% endif %} + {% set probe_count = bedMeshConfig.probe_count.split(",") %} + {% set probe_count_x = probe_count[0]|int %} + {% if probe_count.__len__() > 1 %} + {% set probe_count_y = probe_count[1]|int %} + {% else %} + {% set probe_count_y = probe_count_x|int %} + {% endif %} + {% set relative_reference_index = bedMeshConfig.relative_reference_index %} + {% set mesh_min_x = bedMeshConfig.mesh_min.split(",")[0]|float %} + {% set mesh_min_y = bedMeshConfig.mesh_min.split(",")[1]|float %} + {% set mesh_max_x = bedMeshConfig.mesh_max.split(",")[0]|float %} + {% set mesh_max_y = bedMeshConfig.mesh_max.split(",")[1]|float %} + + # If print area X is smaller than 50% of the bed size, change to to 3 probe counts for X instead of the default + {% if print_max_x - print_min_x < (mesh_max_x - mesh_min_x) * 0.50 %} + {% set probe_count_x = minimum_probe_count %} + {% endif %} + + # If print area Y is smaller than 50% of the bed size, change to to 3 probe counts for Y instead of the default + {% if print_max_y - print_min_y < (mesh_max_y - mesh_min_y) * 0.50 %} + {% set probe_count_y = minimum_probe_count %} + {% endif %} + + {% if print_min_x - buffer >= mesh_min_x %} + {% set mesh_min_x = print_min_x - buffer %} + {% endif %} + + {% if print_min_y - buffer >= mesh_min_y %} + {% set mesh_min_y = print_min_y - buffer %} + {% endif %} + + {% if print_max_x + buffer <= mesh_max_x %} + {% set mesh_max_x = print_max_x + buffer %} + {% endif %} + + {% if print_max_y + buffer <= mesh_max_y %} + {% set mesh_max_y = print_max_y + buffer %} + {% endif %} + + { action_respond_info("mesh_min: %s,%s" % (mesh_min_x, mesh_min_y)) } + { action_respond_info("mesh_max: %s,%s" % (mesh_max_x, mesh_max_y)) } + { action_respond_info("probe_count: %s,%s" % (probe_count_x,probe_count_y)) } + + ; Set variables so they're available outside of macro + SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_start_x VALUE={print_min_x} + SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_start_y VALUE={print_min_y} + SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_end_x VALUE={print_max_x} + SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_end_y VALUE={print_max_y} + + {% if printer["gcode_macro status_meshing"] != null %} + status_meshing + {% endif %} + + {% if relative_reference_index == 0 or relative_reference_index == null %} + _BED_MESH_CALIBRATE mesh_min={mesh_min_x},{mesh_min_y} mesh_max={mesh_max_x},{mesh_max_y} probe_count={probe_count_x},{probe_count_y} + {% else %} + {% set relative_reference_index = ((probe_count_x * probe_count_y - 1) / 2)|int %} + { action_respond_info("relative_reference_index: %s" % relative_reference_index) } + _BED_MESH_CALIBRATE mesh_min={mesh_min_x},{mesh_min_y} mesh_max={mesh_max_x},{mesh_max_y} probe_count={probe_count_x},{probe_count_y} relative_reference_index={relative_reference_index} + {% endif %} + {% else %} + {% if printer["gcode_macro status_meshing"] != null %} + status_meshing + {% endif %} + _BED_MESH_CALIBRATE + {% endif %} + {% if klicky_available %} + Dock_Probe + {% elif euclid_available %} + STOW_PROBE + {% endif %} + {% else %} + { action_respond_info("No need to recreate Bed Mesh since it's same as current mesh or smaller") } + {% endif %} + {% else %} + {% if klicky_available %} + _CheckProbe action=query + Attach_Probe + {% elif euclid_available %} + STOW_PROBE + {% endif %} + {% if printer["gcode_macro status_meshing"] != null %} + status_meshing + {% endif %} + _BED_MESH_CALIBRATE + {% if klicky_available %} + Dock_Probe + {% endif %} + {% if euclid_available %} + STOW_PROBE + {% endif %} + {% endif %} + {% if printer["gcode_macro status_ready"] != null %} + status_ready + {% endif %} diff --git a/printer.cfg b/printer.cfg new file mode 100644 index 0000000..5fbfc87 --- /dev/null +++ b/printer.cfg @@ -0,0 +1,585 @@ +[include mainsail.cfg] + +[mcu] +canbus_uuid: 52a031bd2939 + +[mcu EBBCan] +canbus_uuid: 29e87b131cca + +[printer] +kinematics: corexy +max_velocity: 300 +max_accel: 10000 +max_z_velocity: 30 +max_z_accel: 350 +square_corner_velocity: 5.0 + +[temperature_sensor MCU] +sensor_type: temperature_mcu + +[temperature_sensor SoC] +sensor_type: temperature_host + +##################################################################### +# X/Y Stepper Settings +##################################################################### + +## X Stepper on Motor1 (B Motor) +[stepper_x] +step_pin: PE6 +dir_pin: PE5 +enable_pin: !PC14 +microsteps: 16 +rotation_distance: 40 +full_steps_per_rotation:200 #set to 400 for 0.9 degree stepper +endstop_pin: ^EBBCan:gpio24 +position_min: 0 +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#position_endstop: 250 +#position_max: 250 + +## Uncomment for 300mm build +position_endstop: 300 +position_max: 300 + +## Uncomment for 350mm build +#position_endstop: 350 +#position_max: 350 + +##-------------------------------------------------------------------- +homing_speed: 25 +homing_retract_dist: 5 +homing_positive_dir: true + + +[tmc2209 stepper_x] +uart_pin: PC13 +interpolate: True +run_current: 0.9 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Y Stepper on Motor2 (A Motor) +[stepper_y] +step_pin: PE2 +dir_pin: PE1 +enable_pin: !PE4 +microsteps: 16 +rotation_distance: 40 +endstop_pin: ^PF3 +full_steps_per_rotation:200 #set to 400 for 0.9 degree stepper +position_min: 0 +##-------------------------------------------------------------------- + +## Uncomment for 250mm build +#position_endstop: 250 +#position_max: 250 + +## Uncomment for 300mm build +position_endstop: 300 +position_max: 300 + +## Uncomment for 350mm build +#position_endstop: 350 +#position_max: 350 + +##-------------------------------------------------------------------- +homing_speed: 25 +homing_retract_dist: 5 +homing_positive_dir: true + + +[tmc2209 stepper_y] +uart_pin: PE3 +interpolate: True +run_current: 0.9 +sense_resistor: 0.110 +stealthchop_threshold: 0 + + +##################################################################### +# Z Stepper Settings +##################################################################### + +## Z0 Stepper - Front Left on MOTOR3_A +[stepper_z] +step_pin: PB8 +dir_pin: PB7 +enable_pin: !PE0 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 +endstop_pin: probe:z_virtual_endstop +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#position_max: 240 + +## Uncomment below for 300mm build +position_max: 290 + +## Uncomment below for 350mm build +#position_max: 340 + +##-------------------------------------------------------------------- +position_min: -5 +homing_speed: 8 +second_homing_speed: 3 +homing_retract_dist: 3 + + +[tmc2209 stepper_z] +uart_pin: PB9 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z1 Stepper - Rear Left on Motor5 +[stepper_z1] +step_pin: PB4 +dir_pin: !PB3 +enable_pin: !PB6 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + + +[tmc2209 stepper_z1] +uart_pin: PB5 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z2 Stepper - Rear Right on Motor6 +[stepper_z2] +step_pin: PG13 +dir_pin: PG12 +enable_pin: !PG15 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + + +[tmc2209 stepper_z2] +uart_pin: PG14 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +## Z3 Stepper - Front Right on Motor7 +[stepper_z3] +step_pin: PG9 +dir_pin: !PD7 +enable_pin: !PG11 +rotation_distance: 40 +gear_ratio: 80:16 +microsteps: 16 + + +[tmc2209 stepper_z3] +uart_pin: PG10 +interpolate: true +run_current: 0.8 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +##################################################################### +# Extruder +##################################################################### + +# E0 on SB2209 +[extruder] +step_pin: EBBCan:gpio18 +dir_pin: EBBCan:gpio19 +enable_pin: !EBBCan:gpio17 +microsteps: 16 +rotation_distance: 22.905740611 +gear_ratio: 50:10 +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: EBBCan:gpio7 +#control: pid +min_temp: 0 +max_temp: 300 +max_extrude_only_distance: 105 +max_extrude_cross_section: 2 +#pid_kp: 57.369 +#pid_ki: 2.533 +#pid_kd: 324.854 +sensor_type: MAX31865 +sensor_pin: EBBCan:gpio9 +spi_software_sclk_pin: EBBCan:gpio10 +spi_software_mosi_pin: EBBCan:gpio8 +spi_software_miso_pin: EBBCan:gpio11 +rtd_nominal_r: 100 +rtd_reference_r: 430 +rtd_num_of_wires: 2 +pressure_advance: 0.03 + +[tmc2209 extruder] +uart_pin: EBBCan:gpio20 +run_current: 0.65 +stealthchop_threshold: 0 + + +##################################################################### +# Bed Heater +##################################################################### + +[heater_bed] +heater_pin: PA1 +sensor_type: Generic 3950 +sensor_pin: PB1 +max_power: 1.0 +min_temp: 0 +max_temp: 115 +#control: pid +#pid_kp: 58.437 +#pid_ki: 2.347 +#pid_kd: 363.769 + + +##################################################################### +# Probe +##################################################################### + +[probe] +pin: ^EBBCan:gpio22 +x_offset: 0 +y_offset: 0 +#z_offset: 0 +lift_speed: 30 +activate_gcode: + {% set PROBE_TEMP = 150 %} + {% set MAX_TEMP = PROBE_TEMP + 5 %} + {% set ACTUAL_TEMP = printer.extruder.temperature %} + {% set TARGET_TEMP = printer.extruder.target %} + + {% if TARGET_TEMP > PROBE_TEMP %} + { action_respond_info('Extruder temperature target of %.1fC is too high, lowering to %.1fC' % (TARGET_TEMP, PROBE_TEMP)) } + M109 S{ PROBE_TEMP } + {% else %} + # Temperature target is already low enough, but nozzle may still be too hot. + {% if ACTUAL_TEMP > MAX_TEMP %} + { action_respond_info('Extruder temperature %.1fC is still too high, waiting until below %.1fC' % (ACTUAL_TEMP, MAX_TEMP)) } + TEMPERATURE_WAIT SENSOR=extruder MAXIMUM={ MAX_TEMP } + {% endif %} + {% endif %} + +##################################################################### +# Fan Control +##################################################################### + +[fan] +pin: EBBCan:gpio13 + +[heater_fan hotend_fan] +pin: EBBCan:gpio14 +heater: extruder +heater_temp: 70.0 + + +[fan_generic nevermore] +## Print Cooling Fan - CNC_FAN0 +pin: PF8 +kick_start_time: 0.5 +off_below: 0.10 + +[controller_fan controller_fan_1] +## Hotend Fan - CNC_FAN1 +pin: PF9 +max_power: 1.0 +kick_start_time: 0.5 +fan_speed: 0.66 + + +[heater_fan controller_fan_2] +## Controller fan - CNC_FAN2 +pin: PF6 +kick_start_time: 0.5 +heater: heater_bed +heater_temp: 80 +fan_speed: 0.66 + +[fan_generic exhaust_fan] +# Exhaust fan - CNC_FAN0 +pin: PF7 +max_power: 1.0 +shutdown_speed: 0.0 +kick_start_time: 0.5 + +##################################################################### +# LED Control +##################################################################### + +#[neopixel toolhead_light] +#pin: EBBCan:gpio16 +#chain_count: 3 +#color_order: GRBW +[include stealthburner_leds.cfg] + +[output_pin caselight] +#Chamber Lighting - HE3 Connector +pin: PA3 +pwm:true +shutdown_value: 0 +cycle_time: 0.01 + +##################################################################### +# Homing and Gantry Adjustment Routines +##################################################################### + +[idle_timeout] +timeout: 3300 + +[safe_z_home] +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#home_xy_position: 125,125 + +## Uncomment below for 300mm build +home_xy_position: 150,150 + +## Uncomment below for 350mm build +#home_xy_position: 175,175 + +##-------------------------------------------------------------------- +speed: 100 +z_hop: 10 + +[quad_gantry_level] +## Use QUAD_GANTRY_LEVEL to level a gantry. +## Min & Max gantry corners - measure from nozzle at MIN (0,0) and +## MAX (250, 250), (300,300), or (350,350) depending on your printer size +## to respective belt positions + +#-------------------------------------------------------------------- +## Gantry Corners for 250mm Build +## Uncomment for 250mm build +#gantry_corners: +# -60,-10 +# 310, 320 +## Probe points +#points: +# 50,25 +# 50,175 +# 200,175 +# 200,25 + +## Gantry Corners for 300mm Build +## Uncomment for 300mm build +gantry_corners: + -60,-10 + 360,370 +# Probe points +points: + 50,25 + 50,225 + 250,225 + 250,25 + +## Gantry Corners for 350mm Build +## Uncomment for 350mm build +#gantry_corners: +# -60,-10 +# 410,420 +## Probe points +#points: +# 50,25 +# 50,275 +# 300,275 +# 300,25 + +#-------------------------------------------------------------------- +speed: 100 +horizontal_move_z: 10 +retries: 10 +retry_tolerance: 0.0075 +max_adjust: 10 + +[bed_mesh] +mesh_min: 10,10 +##-------------------------------------------------------------------- + +## Uncomment below for 250mm build +#mesh_max: 240,240 + +## Uncomment below for 300mm build +mesh_max: 290,290 + + +## Uncomment below for 350mm build +#mesh_max: 340,340 + +##-------------------------------------------------------------------- + +[adxl345] +cs_pin: EBBCan:gpio1 +spi_software_sclk_pin: EBBCan:gpio2 +spi_software_mosi_pin: EBBCan:gpio0 +spi_software_miso_pin: EBBCan:gpio3 +axes_map: z,-y,x + + +[board_pins] +aliases: + # EXP1 header + EXP1_1=PE7, EXP1_2=PG1, + EXP1_3=PG0, EXP1_4=PF15, + EXP1_5=PF14, EXP1_6=PF13, # Slot in the socket on this side + EXP1_7=PF12, EXP1_8=PF11, + EXP1_9=, EXP1_10=<5V>, + + # EXP2 header + EXP2_1=PE13, EXP2_2=PE12, + EXP2_3=PE15, EXP2_4=PE11, + EXP2_5=PE10, EXP2_6=PE14, # Slot in the socket on this side + EXP2_7=PE8, EXP2_8=, + EXP2_9=, EXP2_10= + + +##################################################################### +# Macros +##################################################################### + +# Conditional G28 (home if not already homed) +[gcode_macro CG28] +gcode: + {% if "x" not in printer.toolhead.homed_axes or "y" not in printer.toolhead.homed_axes or "z" not in printer.toolhead.homed_axes %} + M117 Homing + G28 + {% endif %} + + + +#[gcode_macro G32] +#gcode: +# BED_MESH_CLEAR +# CG28 ; Home if not homed to get everything turned on +# QUAD_GANTRY_LEVEL ; Level +# #G28 X Y ; Home the X and Y +# G0 X130 Y355 Z2 F9000 ; Move to brush +# G0 X75 F750 ; Move across the brush +# G0 X130 F750 ; Move across the brush +# G28 Z ; Home the Z now that nozzle is clean +# G0 X150 Y150 Z20 F6000 ; Return to center of bed + + +[gcode_macro G32] +gcode: + + STATUS_HOMING + BED_MESH_CLEAR + CG28 + + STATUS_LEVELING + M117 Leveling Gantry + QUAD_GANTRY_LEVEL + G28 + ## Uncomment for for your size printer: + #-------------------------------------------------------------------- + ## Uncomment for 250mm build + #G0 X125 Y125 Z30 F3600 + + ## Uncomment for 300 build + G0 X150 Y150 Z30 F3600 + + ## Uncomment for 350mm build + #G0 X175 Y175 Z30 F3600 + #-------------------------------------------------------------------- + + M117 + STATUS_READY + +[gcode_macro PRINT_START] +gcode: + {% set BED = params.BED|default(60)|int %} + {% set EXTRUDER = params.EXTRUDER|default(210)|int %} + + SAVE_GCODE_STATE NAME=start + + SET_PIN pin=caselight value=0.50 + + STATUS_HEATING + M117 Starting warmup + M140 S{BED} + CG28 + G1 Z20 F3000 ; move nozzle away from bed + + # Heat bed first + # Heat nozzle to 140 + STATUS_HEATING + M104 S140 + M190 S{BED} + + # Home and QGL while nozzle is cold + M117 Homing + G32 + + # Now heat nozzle + M117 Heating Nozzle + STATUS_HEATING + M109 S{EXTRUDER} + + M117 #Clear Status + STATUS_PRINTING + + RESTORE_GCODE_STATE NAME=start + + +[gcode_macro PRINT_END] +# Use PRINT_END for the slicer ending script - please customise for your slicer of choice +gcode: + SAVE_GCODE_STATE NAME=STATE_PRINT_END + + M400 ; wait for buffer to clear + G92 E0 ; zero the extruder + G1 E-10.0 F3600 ; retract filament + + G91 ; relative positioning + G0 Z1.00 X20.0 Y20.0 F20000 ; move nozzle to remove stringing + TURN_OFF_HEATERS + M107 ; turn off fan + G1 Z2 F3000 ; move nozzle up 2mm + G90 ; absolute positioning + G0 X125 Y250 F3600 ; park nozzle at rear + + SET_PIN pin=caselight value=0.03 + + BED_MESH_CLEAR + + STATUS_READY + + # The purpose of the SAVE_GCODE_STATE/RESTORE_GCODE_STATE + # command pair is to restore the printer's coordinate system + # and speed settings since the commands above change them. + # However, to prevent any accidental, unintentional toolhead + # moves when restoring the state, explicitly set MOVE=0. + RESTORE_GCODE_STATE NAME=STATE_PRINT_END MOVE=0 + +[force_move] + enable_force_move: true + +#*# <---------------------- SAVE_CONFIG ----------------------> +#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated. +#*# +#*# [heater_bed] +#*# control = pid +#*# pid_kp = 63.521 +#*# pid_ki = 2.900 +#*# pid_kd = 347.777 +#*# +#*# [extruder] +#*# control = pid +#*# pid_kp = 16.710 +#*# pid_ki = 1.061 +#*# pid_kd = 65.795 +#*# +#*# [probe] +#*# z_offset = -1.575 diff --git a/sonar.conf b/sonar.conf new file mode 100644 index 0000000..7ca59c0 --- /dev/null +++ b/sonar.conf @@ -0,0 +1,17 @@ +#### Sonar - A WiFi Keepalive daemon +#### +#### Written by Stephan Wendel aka KwadFan +#### Copyright 2022 +#### https://github.com/mainsail-crew/sonar +#### +#### This File is distributed under GPLv3 +#### + +[sonar] +enable: false # false to disable till next reboot (will stop again if not set to true) +debug_log: false # if set to true, sonar will log ever ping with triptime and date/time +persistent_log: false # If true logs in /var/log/sonar.log, false logs to systemd +target: auto # IP Address, URL or auto as ping target +count: 3 # How often should be pinged? +interval: 60 # Ping again after X seconds +restart_threshold: 10 # If failed, restart WiFi after X seconds diff --git a/stealthburner_leds.cfg b/stealthburner_leds.cfg new file mode 100644 index 0000000..5e39001 --- /dev/null +++ b/stealthburner_leds.cfg @@ -0,0 +1,254 @@ +# Macros for setting the status leds on the Voron StealthBurner toolhead (or for any neopixel-type leds). +# +# You will need to configure a neopixel (or other addressable led, such as dotstar). See +# https://www.klipper3d.org/Config_Reference.html#neopixel for configuration details. + + +##################################### +# INSTRUCTIONS # +##################################### +# How to use all this stuff: +# +# 1. Copy this .cfg file into your Klipper config directory and then add [include stealthburner_leds.cfg] +# to the top of your printer.cfg in order to register the LEDs and macros with Klipper. +# 2. Define your LEDs by editing [neopixel sb_leds] below and entering the data pin from your control board +# as well as the color order. +# +# Note: RGB and RGBW are different and must be defined explicitly. RGB and RGBW are also not able to +# be mix-and-matched in the same chain. A separate data line would be needed for proper functioning. +# +# RGBW LEDs will have a visible yellow-ish phosphor section to the chip. If your LEDs do not have +# this yellow portion, you have RGB LEDs. +# +# 3. Save your config and restart Klipper. +# +# Note: We set RED and BLUE to 1.0 to make it easier for users and supporters to detect +# misconfigurations or miswiring. The default color format is for Neopixels with a dedicated +# white LED. On startup, all three SB LEDs should light up. +# +# If you get random colors across your LEDs, change the color_order to GRB and restart. Then +# omit the W for each suggested color_order in the next paragraph. +# +# If you get MAGENTA, your color order is correct. If you get CYAN, you need to use RGBW. If +# you get YELLOW, you need to use BRGW (note that BRG is only supported in the latest Klipper +# version). +# +# 4. Once you have confirmed that the LEDs are set up correctly, you must now decide where you want +# these macros called up...which means adding them to your existing gcode macros. NOTHING will happen +# unless you add the STATUS_????? macros to your existing gcode macros. +# +# Example: add STATUS_LEVELING to the beginning of your QGL gcode macro, and then add STATUS_READY +# to the end of it to set the logo LED and nozzle LEDs back to the `ready` state. +# +# Example: add STATUS_CLEANING to the beginning of your nozzle-cleaning macro, and then STATUS_READY +# to the end of it to return the LEDs back to `ready` state. +# +# 5. Feel free to change colors of each macro, create new ones if you have a need to. The macros provided below +# are just an example of what is possible. If you want to try some more complex animations, you will most +# likely have to use WLED with Moonraker and a small micro-controller +# +##################################### +# END INSTRUCTRUCTIONS # +##################################### + + +[neopixel sb_leds] +pin: EBBCan:gpio16 +# The pin connected to the neopixel. This parameter must be provided. +chain_count: 3 +# The number of Neopixel chips that are "daisy chained" to the +# provided pin. The default is 1 (which indicates only a single +# Neopixel is connected to the pin). +color_order: GRBW +# Set the pixel order required by the LED hardware. Options are GRB, +# RGB, GRBW, or RGBW. The default is GRB. +initial_RED: 1.0 +initial_GREEN: 0.0 +initial_BLUE: 1.0 +initial_WHITE: 0.0 +# Sets the initial LED color of the Neopixel. Each value should be +# between 0.0 and 1.0. The WHITE option is only available on RGBW +# LEDs. The default for each color is 0.# + +# Most configuration for the macros can be done by modifying the variables in the _sb_vars macro +# at the start of this file. + +########## +# MACROS # +########## + +# The following status macros are available (these go inside of your macros): +# +# STATUS_READY +# STATUS_OFF +# STATUS_BUSY +# STATUS_HEATING +# STATUS_LEVELING +# STATUS_HOMING +# STATUS_CLEANING +# STATUS_MESHING +# STATUS_CALIBRATING_Z +# +# With additional macros for basic control: +# +# SET_NOZZLE_LEDS_ON +# SET_LOGO_LEDS_OFF +# SET_NOZZLE_LEDS_OFF +# +# Contributed by Voron discord users wile.e, Tetsunosuke, and etherwalker + + +[gcode_macro _sb_vars] +# User settings for the StealthBurner status leds. You can change the status colors and led +# configurations for the logo and nozzle here. +variable_colors: { + 'logo': { # Colors for logo states + 'busy': {'r': 0.4, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'cleaning': {'r': 0.0, 'g': 0.02, 'b': 0.5, 'w': 0.0}, + 'calibrating_z': {'r': 0.8, 'g': 0., 'b': 0.35, 'w': 0.0}, + 'heating': {'r': 0.3, 'g': 0.18, 'b': 0.0, 'w': 0.0}, + 'homing': {'r': 0.0, 'g': 0.6, 'b': 0.2, 'w': 0.0}, + 'leveling': {'r': 0.5, 'g': 0.1, 'b': 0.4, 'w': 0.0}, + 'meshing': {'r': 0.2, 'g': 1.0, 'b': 0.0, 'w': 0.0}, + 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'printing': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'standby': {'r': 0.01, 'g': 0.01, 'b': 0.01, 'w': 0.1}, + }, + 'nozzle': { # Colors for nozzle states + 'heating': {'r': 0.8, 'g': 0.35, 'b': 0.0, 'w':0.0}, + 'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.0}, + 'standby': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0}, + }, + 'thermal': { + 'hot': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0}, + 'cold': {'r': 0.3, 'g': 0.0, 'b': 0.3, 'w': 0.0} + } + } +variable_logo_led_name: "sb_leds" +# The name of the addressable LED chain that contains the logo LED(s) +variable_logo_idx: "1" +# A comma-separated list of indexes LEDs in the logo +variable_nozzle_led_name: "sb_leds" +# The name of the addressable LED chain that contains the nozzle LED(s). This will +# typically be the same LED chain as the logo. +variable_nozzle_idx: "2,3" +# A comma-separated list of indexes of LEDs in the nozzle +gcode: + # This section is required. Do Not Delete. + + +[gcode_macro _set_sb_leds] +gcode: + {% set red = params.RED|default(0)|float %} + {% set green = params.GREEN|default(0)|float %} + {% set blue = params.BLUE|default(0)|float %} + {% set white = params.WHITE|default(0)|float %} + {% set led = params.LED|string %} + {% set idx = (params.IDX|string).split(',') %} + {% set transmit_last = params.TRANSMIT|default(1) %} + + {% for led_index in idx %} + {% set transmit=transmit_last if loop.last else 0 %} + set_led led={led} red={red} green={green} blue={blue} white={white} index={led_index} transmit={transmit} + {% endfor %} + +[gcode_macro _set_sb_leds_by_name] +gcode: + {% set leds_name = params.LEDS %} + {% set color_name = params.COLOR %} + {% set color = printer["gcode_macro _sb_vars"].colors[leds_name][color_name] %} + {% set led = printer["gcode_macro _sb_vars"][leds_name + "_led_name"] %} + {% set idx = printer["gcode_macro _sb_vars"][leds_name + "_idx"] %} + {% set transmit = params.TRANSMIT|default(1) %} + + _set_sb_leds led={led} red={color.r} green={color.g} blue={color.b} white={color.w} idx="{idx}" transmit={transmit} + +[gcode_macro _set_logo_leds] +gcode: + {% set red = params.RED|default(0)|float %} + {% set green = params.GREEN|default(0)|float %} + {% set blue = params.BLUE|default(0)|float %} + {% set white = params.WHITE|default(0)|float %} + {% set led = printer["gcode_macro _sb_vars"].logo_led_name %} + {% set idx = printer["gcode_macro _sb_vars"].logo_idx %} + {% set transmit=params.TRANSMIT|default(1) %} + + _set_sb_leds led={led} red={red} green={green} blue={blue} white={white} idx="{idx}" transmit={transmit} + +[gcode_macro _set_nozzle_leds] +gcode: + {% set red = params.RED|default(0)|float %} + {% set green = params.GREEN|default(0)|float %} + {% set blue = params.BLUE|default(0)|float %} + {% set white = params.WHITE|default(0)|float %} + {% set led = printer["gcode_macro _sb_vars"].nozzle_led_name %} + {% set idx = printer["gcode_macro _sb_vars"].nozzle_idx %} + {% set transmit=params.TRANSMIT|default(1) %} + + _set_sb_leds led={led} red={red} green={green} blue={blue} white={white} idx="{idx}" transmit={transmit} + +[gcode_macro set_logo_leds_off] +gcode: + {% set transmit=params.TRANSMIT|default(1) %} + _set_logo_leds red=0 blue=0 green=0 white=0 transmit={transmit} + +[gcode_macro set_nozzle_leds_on] +gcode: + {% set transmit=params.TRANSMIT|default(1) %} + _set_sb_leds_by_name leds="nozzle" color="on" transmit={transmit} + +[gcode_macro set_nozzle_leds_off] +gcode: + {% set transmit=params.TRANSMIT|default(1) %} + _set_sb_leds_by_name leds="nozzle" color="off" transmit={transmit} + +[gcode_macro status_off] +gcode: + set_logo_leds_off transmit=0 + set_nozzle_leds_off + +[gcode_macro status_ready] +gcode: + _set_sb_leds_by_name leds="logo" color="standby" transmit=0 + _set_sb_leds_by_name leds="nozzle" color="standby" transmit=1 + +[gcode_macro status_busy] +gcode: + _set_sb_leds_by_name leds="logo" color="busy" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_heating] +gcode: + _set_sb_leds_by_name leds="logo" color="heating" transmit=0 + _set_sb_leds_by_name leds="nozzle" color="heating" transmit=1 + +[gcode_macro status_leveling] +gcode: + _set_sb_leds_by_name leds="logo" color="leveling" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_homing] +gcode: + _set_sb_leds_by_name leds="logo" color="homing" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_cleaning] +gcode: + _set_sb_leds_by_name leds="logo" color="cleaning" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_meshing] +gcode: + _set_sb_leds_by_name leds="logo" color="meshing" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_calibrating_z] +gcode: + _set_sb_leds_by_name leds="logo" color="calibrating_z" transmit=0 + set_nozzle_leds_on + +[gcode_macro status_printing] +gcode: + _set_sb_leds_by_name leds="logo" color="printing" transmit=0 + set_nozzle_leds_on diff --git a/timelapse.cfg b/timelapse.cfg new file mode 100644 index 0000000..c821f39 --- /dev/null +++ b/timelapse.cfg @@ -0,0 +1,427 @@ +# Timelapse klipper macro definition +# +# Copyright (C) 2021 Christoph Frei +# Copyright (C) 2021 Alex Zellner +# +# This file may be distributed under the terms of the GNU GPLv3 license +# +# Macro version 1.15 +# + +##### DO NOT CHANGE ANY MACRO!!! ##### + +########################################################################## +# # +# GET_TIMELAPSE_SETUP: Print the Timelapse setup to console # +# # +########################################################################## + +[gcode_macro GET_TIMELAPSE_SETUP] +description: Print the Timelapse setup +gcode: + {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %} + {% set output_txt = ["Timelapse Setup:"] %} + {% set _dummy = output_txt.append("enable: %s" % tl.enable) %} + {% set _dummy = output_txt.append("park: %s" % tl.park.enable) %} + {% if tl.park.enable %} + {% set _dummy = output_txt.append("park position: %s time: %s s" % (tl.park.pos, tl.park.time)) %} + {% set _dummy = output_txt.append("park cord x:%s y:%s dz:%s" % (tl.park.coord.x, tl.park.coord.y, tl.park.coord.dz)) %} + {% set _dummy = output_txt.append("travel speed: %s mm/s" % tl.speed.travel) %} + {% endif %} + {% set _dummy = output_txt.append("fw_retract: %s" % tl.extruder.fw_retract) %} + {% if not tl.extruder.fw_retract %} + {% set _dummy = output_txt.append("retract: %s mm speed: %s mm/s" % (tl.extruder.retract, tl.speed.retract)) %} + {% set _dummy = output_txt.append("extrude: %s mm speed: %s mm/s" % (tl.extruder.extrude, tl.speed.extrude)) %} + {% endif %} + {% set _dummy = output_txt.append("verbose: %s" % tl.verbose) %} + {action_respond_info(output_txt|join("\n"))} + +################################################################################################ +# # +# Use _SET_TIMELAPSE_SETUP [ENABLE=value] [VERBOSE=value] [PARK_ENABLE=value] [PARK_POS=value] # +# [PARK_TIME=value] [CUSTOM_POS_X=value] [CUSTOM_POS_Y=value] # +# [CUSTOM_POS_DZ=value][TRAVEL_SPEED=value] [RETRACT_SPEED=value] # +# [EXTRUDE_SPEED=value] [EXTRUDE_DISTANCE=value] # +# [RETRACT_DISTANCE=value] [FW_RETRACT=value] # +# # +################################################################################################ + +[gcode_macro _SET_TIMELAPSE_SETUP] +description: Set user parameters for timelapse +gcode: + {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %} + ##### get min and max bed size ##### + {% set min = printer.toolhead.axis_minimum %} + {% set max = printer.toolhead.axis_maximum %} + {% set round_bed = True if printer.configfile.settings.printer.kinematics is in ['delta','polar','rotary_delta','winch'] + else False %} + {% set park = {'min' : {'x': (min.x / 1.42)|round(3) if round_bed else min.x|round(3), + 'y': (min.y / 1.42)|round(3) if round_bed else min.y|round(3)}, + 'max' : {'x': (max.x / 1.42)|round(3) if round_bed else max.x|round(3), + 'y': (max.y / 1.42)|round(3) if round_bed else max.y|round(3)}, + 'center': {'x': (max.x-(max.x-min.x)/2)|round(3), + 'y': (max.y-(max.y-min.y)/2)|round(3)}} %} + ##### set new values ##### + {% if params.ENABLE %} + {% if params.ENABLE|lower is in ['true', 'false'] %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=enable VALUE={True if params.ENABLE|lower == 'true' else False} + {% else %} + {action_raise_error("ENABLE=%s not supported. Allowed values are [True, False]" % params.ENABLE|capitalize)} + {% endif %} + {% endif %} + {% if params.VERBOSE %} + {% if params.VERBOSE|lower is in ['true', 'false'] %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=verbose VALUE={True if params.VERBOSE|lower == 'true' else False} + {% else %} + {action_raise_error("VERBOSE=%s not supported. Allowed values are [True, False]" % params.VERBOSE|capitalize)} + {% endif %} + {% endif %} + {% if params.CUSTOM_POS_X %} + {% if params.CUSTOM_POS_X|float >= min.x and params.CUSTOM_POS_X|float <= max.x %} + {% set _dummy = tl.park.custom.update({'x':params.CUSTOM_POS_X|float|round(3)}) %} + {% else %} + {action_raise_error("CUSTOM_POS_X=%s must be within [%s - %s]" % (params.CUSTOM_POS_X, min.x, max.x))} + {% endif %} + {% endif %} + {% if params.CUSTOM_POS_Y %} + {% if params.CUSTOM_POS_Y|float >= min.y and params.CUSTOM_POS_Y|float <= max.y %} + {% set _dummy = tl.park.custom.update({'y':params.CUSTOM_POS_Y|float|round(3)}) %} + {% else %} + {action_raise_error("CUSTOM_POS_Y=%s must be within [%s - %s]" % (params.CUSTOM_POS_Y, min.y, max.y))} + {% endif %} + {% endif %} + {% if params.CUSTOM_POS_DZ %} + {% if params.CUSTOM_POS_DZ|float >= min.z and params.CUSTOM_POS_DZ|float <= max.z %} + {% set _dummy = tl.park.custom.update({'dz':params.CUSTOM_POS_DZ|float|round(3)}) %} + {% else %} + {action_raise_error("CUSTOM_POS_DZ=%s must be within [%s - %s]" % (params.CUSTOM_POS_DZ, min.z, max.z))} + {% endif %} + {% endif %} + {% if params.PARK_ENABLE %} + {% if params.PARK_ENABLE|lower is in ['true', 'false'] %} + {% set _dummy = tl.park.update({'enable':True if params.PARK_ENABLE|lower == 'true' else False}) %} + {% else %} + {action_raise_error("PARK_ENABLE=%s not supported. Allowed values are [True, False]" % params.PARK_ENABLE|capitalize)} + {% endif %} + {% endif %} + {% if params.PARK_POS %} + {% if params.PARK_POS|lower is in ['center','front_left','front_right','back_left','back_right','custom','x_only','y_only'] %} + {% set dic = {'center' : {'x': park.center.x , 'y': park.center.y , 'dz': 1 }, + 'front_left' : {'x': park.min.x , 'y': park.min.y , 'dz': 0 }, + 'front_right' : {'x': park.max.x , 'y': park.min.y , 'dz': 0 }, + 'back_left' : {'x': park.min.x , 'y': park.max.y , 'dz': 0 }, + 'back_right' : {'x': park.max.x , 'y': park.max.y , 'dz': 0 }, + 'custom' : {'x': tl.park.custom.x, 'y': tl.park.custom.y, 'dz': tl.park.custom.dz}, + 'x_only' : {'x': tl.park.custom.x, 'y': 'none' , 'dz': tl.park.custom.dz}, + 'y_only' : {'x': 'none' , 'y': tl.park.custom.y, 'dz': tl.park.custom.dz}} %} + {% set _dummy = tl.park.update({'pos':params.PARK_POS|lower}) %} + {% set _dummy = tl.park.update({'coord':dic[tl.park.pos]}) %} + {% else %} + {action_raise_error("PARK_POS=%s not supported. Allowed values are [CENTER, FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, CUSTOM, X_ONLY, Y_ONLY]" + % params.PARK_POS|upper)} + {% endif %} + {% endif %} + {% if params.PARK_TIME %} + {% if params.PARK_TIME|float >= 0.0 %} + {% set _dummy = tl.park.update({'time':params.PARK_TIME|float|round(3)}) %} + {% else %} + {action_raise_error("PARK_TIME=%s must be a positive number" % params.PARK_TIME)} + {% endif %} + {% endif %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=park VALUE="{tl.park}" + {% if params.TRAVEL_SPEED %} + {% if params.TRAVEL_SPEED|float > 0.0 %} + {% set _dummy = tl.speed.update({'travel':params.TRAVEL_SPEED|float|round(3)}) %} + {% else %} + {action_raise_error("TRAVEL_SPEED=%s must be larger than 0" % params.TRAVEL_SPEED)} + {% endif %} + {% endif %} + {% if params.RETRACT_SPEED %} + {% if params.RETRACT_SPEED|float > 0.0 %} + {% set _dummy = tl.speed.update({'retract':params.RETRACT_SPEED|float|round(3)}) %} + {% else %} + {action_raise_error("RETRACT_SPEED=%s must be larger than 0" % params.RETRACT_SPEED)} + {% endif %} + {% endif %} + {% if params.EXTRUDE_SPEED %} + {% if params.EXTRUDE_SPEED|float > 0.0 %} + {% set _dummy = tl.speed.update({'extrude':params.EXTRUDE_SPEED|float|round(3)}) %} + {% else %} + {action_raise_error("EXTRUDE_SPEED=%s must be larger than 0" % params.EXTRUDE_SPEED)} + {% endif %} + {% endif %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=speed VALUE="{tl.speed}" + {% if params.EXTRUDE_DISTANCE %} + {% if params.EXTRUDE_DISTANCE|float >= 0.0 %} + {% set _dummy = tl.extruder.update({'extrude':params.EXTRUDE_DISTANCE|float|round(3)}) %} + {% else %} + {action_raise_error("EXTRUDE_DISTANCE=%s must be specified as positiv number" % params.EXTRUDE_DISTANCE)} + {% endif %} + {% endif %} + {% if params.RETRACT_DISTANCE %} + {% if params.RETRACT_DISTANCE|float >= 0.0 %} + {% set _dummy = tl.extruder.update({'retract':params.RETRACT_DISTANCE|float|round(3)}) %} + {% else %} + {action_raise_error("RETRACT_DISTANCE=%s must be specified as positiv number" % params.RETRACT_DISTANCE)} + {% endif %} + {% endif %} + {% if params.FW_RETRACT %} + {% if params.FW_RETRACT|lower is in ['true', 'false'] %} + {% if 'firmware_retraction' in printer.configfile.settings %} + {% set _dummy = tl.extruder.update({'fw_retract': True if params.FW_RETRACT|lower == 'true' else False}) %} + {% else %} + {% set _dummy = tl.extruder.update({'fw_retract':False}) %} + {% if params.FW_RETRACT|capitalize == 'True' %} + {action_raise_error("[firmware_retraction] not defined in printer.cfg. Can not enable fw_retract")} + {% endif %} + {% endif %} + {% else %} + {action_raise_error("FW_RETRACT=%s not supported. Allowed values are [True, False]" % params.FW_RETRACT|capitalize)} + {% endif %} + {% endif %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=extruder VALUE="{tl.extruder}" + {% if printer.configfile.settings['gcode_macro pause'] is defined %} + {% set _dummy = tl.macro.update({'pause': printer.configfile.settings['gcode_macro pause'].rename_existing}) %} + {% endif %} + {% if printer.configfile.settings['gcode_macro resume'] is defined %} + {% set _dummy = tl.macro.update({'resume': printer.configfile.settings['gcode_macro resume'].rename_existing}) %} + {% endif %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=macro VALUE="{tl.macro}" + +########################################################################## +# # +# TIMELAPSE_TAKE_FRAME: take the next picture # +# # +########################################################################## + +######################### definition ######################### +## enable: enable or disable the next frame. Valid inputs: [True, False] +## takingframe: internal use. Valid inputs: [True, False] +## +## park.enable: enable or disable to park the head while taking a picture. Valid inputs: [True, False] +## park.pos : used position for parking. Valid inputs: [center, front_left, front_right, back_left, back_right, custom, x_only, y_only] +## park.time : used for the debug macro. Time in s +## park.custom.x, park.custom.y: coordinates of the custom parkposition. Unit [mm] +## park.custom.dz : custom z hop for the picture. Unit [mm] +## park.coord : internal use +## +## extruder.fw_retract: enable disable fw retraction [True,False] +## extruder.extrude : filament extruded at the end of park. Unit [mm] +## extruder.retract : filament retract at the start of park. Unit [mm] +## +## speed.travel : used speed for travel from and to the park positon. Unit: [mm/min] +## speed.retract: used speed for retract [mm/min] +## speed.extrude: used speed for extrude [mm/min] +## +## verbose: Enable mesage output of TIMELAPSE_TAKE_FRAME +## +## check_time: time when the status of the taken picture is checked. Default 0.5 sec +## +## restore.absolute.coordinates: internal use +## restore.absolute.extrude : internal use +## restore.speed : internal use +## restore.e : internal use +## restore.factor.speed : internal use +## restore.factor.extrude : internal use +## +## macro.pause : internal use +## macro.resume : internal use +## +## is_paused: internal use +############################################################### +[gcode_macro TIMELAPSE_TAKE_FRAME] +description: Take Timelapse shoot +variable_enable: False +variable_takingframe: False +variable_park: {'enable': False, + 'pos' : 'center', + 'time' : 0.1, + 'custom': {'x': 0, 'y': 0, 'dz': 0}, + 'coord' : {'x': 0, 'y': 0, 'dz': 0}} +variable_extruder: {'fw_retract': False, + 'retract': 1.0, + 'extrude': 1.0} +variable_speed: {'travel': 100, + 'retract': 15, + 'extrude': 15} +variable_verbose: True +variable_check_time: 0.5 +variable_restore: {'absolute': {'coordinates': True, 'extrude': True}, 'speed': 1500, 'e':0, 'factor': {'speed': 1.0, 'extrude': 1.0}} +variable_macro: {'pause': 'PAUSE', 'resume': 'RESUME'} +variable_is_paused: False +gcode: + {% set hyperlapse = True if params.HYPERLAPSE and params.HYPERLAPSE|lower =='true' else False %} + {% if enable %} + {% if (hyperlapse and printer['gcode_macro HYPERLAPSE'].run) or + (not hyperlapse and not printer['gcode_macro HYPERLAPSE'].run) %} + {% if park.enable %} + {% set pos = {'x': 'X' + park.coord.x|string if park.pos != 'y_only' else '', + 'y': 'Y' + park.coord.y|string if park.pos != 'x_only' else '', + 'z': 'Z'+ [printer.gcode_move.gcode_position.z + park.coord.dz, printer.toolhead.axis_maximum.z]|min|string} %} + {% set restore = {'absolute': {'coordinates': printer.gcode_move.absolute_coordinates, + 'extrude' : printer.gcode_move.absolute_extrude}, + 'speed' : printer.gcode_move.speed, + 'e' : printer.gcode_move.gcode_position.e, + 'factor' : {'speed' : printer.gcode_move.speed_factor, + 'extrude': printer.gcode_move.extrude_factor}} %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=restore VALUE="{restore}" + {% if not printer[printer.toolhead.extruder].can_extrude %} + {% if verbose %}{action_respond_info("Timelapse: Warning, minimum extruder temperature not reached!")}{% endif %} + {% else %} + {% if extruder.fw_retract %} + G10 + {% else %} + M83 ; insure relative extrusion + G0 E-{extruder.retract} F{speed.retract * 60} + {% endif %} + {% endif %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=is_paused VALUE=True + {macro.pause} ; execute the klipper PAUSE command + SET_GCODE_OFFSET X=0 Y=0 ; this will insure that the head parks always at the same position in a multi setup + G90 ; insure absolute move + {% if "xyz" not in printer.toolhead.homed_axes %} + {% if verbose %}{action_respond_info("Timelapse: Warning, axis not homed yet!")}{% endif %} + {% else %} + G0 {pos.x} {pos.y} {pos.z} F{speed.travel * 60} + {% endif %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=takingframe VALUE=True + UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_TAKE_FRAME DURATION={check_time} + M400 + {% endif %} + _TIMELAPSE_NEW_FRAME HYPERLAPSE={hyperlapse} + {% endif %} + {% else %} + {% if verbose %}{action_respond_info("Timelapse: disabled, take frame ignored")}{% endif %} + {% endif %} + +[gcode_macro _TIMELAPSE_NEW_FRAME] +description: action call for timelapse shoot. must be a seperate macro +gcode: + {action_call_remote_method("timelapse_newframe", + macropark=printer['gcode_macro TIMELAPSE_TAKE_FRAME'].park, + hyperlapse=params.HYPERLAPSE)} + +[delayed_gcode _WAIT_TIMELAPSE_TAKE_FRAME] +gcode: + {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %} + {% set factor = {'speed': printer.gcode_move.speed_factor, 'extrude': printer.gcode_move.extrude_factor} %} + {% if tl.takingframe %} + UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_TAKE_FRAME DURATION={tl.check_time} + {% else %} + {tl.macro.resume} VELOCITY={tl.speed.travel} ; execute the klipper RESUME command + SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=is_paused VALUE=False + {% if not printer[printer.toolhead.extruder].can_extrude %} + {action_respond_info("Timelapse: Warning minimum extruder temperature not reached!")} + {% else %} + {% if tl.extruder.fw_retract %} + G11 + {% else %} + G0 E{tl.extruder.extrude} F{tl.speed.extrude * 60} + G0 F{tl.restore.speed} + {% if tl.restore.absolute.extrude %} + M82 + G92 E{tl.restore.e} + {% endif %} + {% endif %} + {% endif %} + {% if tl.restore.factor.speed != factor.speed %} M220 S{(factor.speed*100)|round(0)} {% endif %} + {% if tl.restore.factor.extrude != factor.extrude %} M221 S{(factor.extrude*100)|round(0)} {% endif %} + {% if not tl.restore.absolute.coordinates %} G91 {% endif %} + {% endif %} + +#################################################################################################### +# # +# HYPERLAPSE: Starts or stops a Hyperlapse video # +# Usage: HYPERLAPSE ACTION=START [CYCLE=time] starts a hyperlapse with cycle time (default 30 sec) # +# HYPERLAPSE ACTION=STOP stops the hyperlapse recording # +# # +#################################################################################################### + +######################### definition ######################### +## cycle: cycle time in seconds +## run: internal use [True/False] +############################################################### +[gcode_macro HYPERLAPSE] +description: Start/Stop a hyperlapse recording +variable_cycle: 0 +variable_run: False +gcode: + {% set cycle = params.CYCLE|default(30)|int %} + {% if params.ACTION and params.ACTION|lower == 'start' %} + {action_respond_info("Hyperlapse: frames started (Cycle %d sec)" % cycle)} + SET_GCODE_VARIABLE MACRO=HYPERLAPSE VARIABLE=run VALUE=True + SET_GCODE_VARIABLE MACRO=HYPERLAPSE VARIABLE=cycle VALUE={cycle} + UPDATE_DELAYED_GCODE ID=_HYPERLAPSE_LOOP DURATION={cycle} + TIMELAPSE_TAKE_FRAME HYPERLAPSE=True + {% elif params.ACTION and params.ACTION|lower == 'stop' %} + {% if run %}{action_respond_info("Hyperlapse: frames stopped")}{% endif %} + SET_GCODE_VARIABLE MACRO=HYPERLAPSE VARIABLE=run VALUE=False + UPDATE_DELAYED_GCODE ID=_HYPERLAPSE_LOOP DURATION=0 + {% else %} + {action_raise_error("Hyperlapse: No valid input parameter + Use: + - HYPERLAPSE ACTION=START [CYCLE=time] + - HYPERLAPSE ACTION=STOP")} + {% endif %} + +[delayed_gcode _HYPERLAPSE_LOOP] +gcode: + UPDATE_DELAYED_GCODE ID=_HYPERLAPSE_LOOP DURATION={printer["gcode_macro HYPERLAPSE"].cycle} + TIMELAPSE_TAKE_FRAME HYPERLAPSE=True + +########################################################################## +# # +# TIMELAPSE_RENDER: Render the video at print end # +# # +########################################################################## + +######################### definition ######################### +## render: internal use. Valid inputs: [True, False] +## run_identifier: internal use. Valid input [0 .. 3] +############################################################### +[gcode_macro TIMELAPSE_RENDER] +description: Render Timelapse video and wait for the result +variable_render: False +variable_run_identifier: 0 +gcode: + {action_respond_info("Timelapse: Rendering started")} + {action_call_remote_method("timelapse_render", byrendermacro="True")} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_RENDER VARIABLE=render VALUE=True + {printer.configfile.settings['gcode_macro pause'].rename_existing} ; execute the klipper PAUSE command + UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_RENDER DURATION=0.5 + +[delayed_gcode _WAIT_TIMELAPSE_RENDER] +gcode: + {% set ri = printer['gcode_macro TIMELAPSE_RENDER'].run_identifier % 4 %} + SET_GCODE_VARIABLE MACRO=TIMELAPSE_RENDER VARIABLE=run_identifier VALUE={ri + 1} + {% if printer['gcode_macro TIMELAPSE_RENDER'].render %} + M117 Rendering {['-','\\','|','/'][ri]} + UPDATE_DELAYED_GCODE ID=_WAIT_TIMELAPSE_RENDER DURATION=0.5 + {% else %} + {action_respond_info("Timelapse: Rendering finished")} + M117 + {printer.configfile.settings['gcode_macro resume'].rename_existing} ; execute the klipper RESUME command + {% endif %} + +########################################################################## +# # +# TEST_STREAM_DELAY: Helper macro to find stream and park delay # +# # +########################################################################## + +[gcode_macro TEST_STREAM_DELAY] +description: Helper macro to find stream and park delay +gcode: + {% set min = printer.toolhead.axis_minimum %} + {% set max = printer.toolhead.axis_maximum %} + {% set act = printer.toolhead.position %} + {% set tl = printer['gcode_macro TIMELAPSE_TAKE_FRAME'] %} + {% if act.z > 5.0 %} + G0 X{min.x + 5.0} F{tl.speed.travel|int * 60} + G0 X{(max.x-min.x)/2} + G4 P{tl.park.time|float * 1000} + _TIMELAPSE_NEW_FRAME HYPERLAPSE=FALSE + G0 X{max.x - 5.0} + {% else %} + {action_raise_error("Toolhead z %.3f to low. Please place head above z = 5.0" % act.z)} + {% endif %}