commit 52353666dcdaba37549f517826e811c54036d591 Author: Iaphetes Date: Wed Nov 5 20:59:20 2025 +0100 first commit 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/printer.cfg b/printer.cfg new file mode 100644 index 0000000..ff87fb5 --- /dev/null +++ b/printer.cfg @@ -0,0 +1,393 @@ +# This file contains common pin mappings for the BigTreeTech Octopus +# Pro v1.0 board. + +# Important! Do not use this config with an Octopus Pro v1.1 board as +# doing so could result in a heater being inadvertently enabled. + +# To use this config, start by identifying the micro-controller on the +# board - it may be an STM32F446, STM32F429, or an STM32H723. Select +# the appropriate micro-controller in "make menuconfig" and select +# "Enable low-level configuration options". For STM32F446 boards the +# firmware should be compiled with a "32KiB bootloader" and a "12MHz +# crystal" clock reference. For STM32F429 boards use a "32KiB +# bootloader" and an "8MHz crystal". For STM32H723 boards use a +# "128KiB bootloader" and a "25Mhz crystal". + +# See docs/Config_Reference.md for a description of parameters. + +[include mainsail.cfg] +[exclude_object] +[mcu] +serial: /dev/serial/by-id/usb-Klipper_stm32f446xx_210041001550535556323420-if00 +restart_method: command + +[mcu scanner] +serial: /dev/serial/by-id/usb-Cartographer_614e_20000A000443303459323220-if00 + + +[printer] +kinematics: corexy +max_velocity: 400 +square_corner_velocity: 5 +#max_accel: 3000 +max_accel: 6900 +max_z_velocity: 50 +max_z_accel: 30 + +[input_shaper] +smoother_freq_x: 76.9 +shaper_type_x: smooth_2hump_ei +smoother_freq_y: 48.9 +shaper_type_y: smooth_mzv + + +# Driver0 +[stepper_x] +step_pin: PF13 +dir_pin: PF12 +enable_pin: !PF14 +microsteps: 16 +rotation_distance: 39.89030167040638 +endstop_pin: tmc2209_stepper_x:virtual_endstop +position_endstop: -3 +position_min: -3 +position_max: 330# for bed mesh +homing_speed: 70 +homing_retract_dist: 0 + + +[tmc2209 stepper_x] +uart_pin: PC4 +diag_pin: PG6 +run_current: 1.4 +driver_SGTHRS: 110 # 255 is most sensitive value, 0 is least sensitive +interpolate: False +sense_resistor: 0.110 +# Driver1 +[stepper_y] +step_pin: PG0 +dir_pin: PG1 +enable_pin: !PF15 +microsteps: 16 +rotation_distance: 39.825762289981334 +endstop_pin: tmc2209_stepper_y:virtual_endstop +position_endstop: -9 +position_min: -9 +position_max: 320 +homing_retract_dist: 0 +homing_speed: 70.0 + + +[tmc2209 stepper_y] +uart_pin: PD11 +diag_pin: PG9 +run_current: 1.4 +driver_SGTHRS: 120 # 255 is most sensitive value, 0 is least sensitive +interpolate: False +sense_resistor: 0.110 +# Driver2 +[stepper_z] +step_pin: PF11 +dir_pin: !PG3 +enable_pin: !PG5 +microsteps: 16 +rotation_distance: 8 +endstop_pin: probe:z_virtual_endstop +position_max: 400 +position_min: -8 +homing_retract_dist: 0 + +[tmc2130 stepper_z] +cs_pin: PC6 +spi_bus: spi1 +run_current: .6 +stealthchop_threshold: 999999 +sense_resistor: 0.110 + + +#[tmc2130 stepper_] +#cs_pin: PC7 +#spi_bus: spi1 +##diag1_pin: PG11 +#run_current: 0.800 +#stealthchop_threshold: 999999 + +# Driver3 +# The Octopus 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_z1] +step_pin: PG4 +dir_pin: !PC1 +enable_pin: !PA0 +microsteps: 16 +rotation_distance: 8 +endstop_pin: probe:z_virtual_endstop + +[tmc2130 stepper_z1] +cs_pin: PC7 +spi_bus: spi1 +run_current: .6 +stealthchop_threshold: 999999 +sense_resistor: 0.110 + +# Driver4 +[extruder] +step_pin: PF9 +dir_pin: PF10 +enable_pin: !PG2 +microsteps: 16 +rotation_distance: 4.5714 +# full_steps_per_rotation: 200 +nozzle_diameter: 0.400 +filament_diameter: 1.750 +heater_pin: PA2 # HE0 +sensor_pin: PF4 # T0 +sensor_type: ATC Semitec 104NT-4-R025H42G +#control: pid +#pid_Kp: 18.831 +#pid_Ki: 0.821 +#pid_Kd: 108.044 +min_temp: 0 +max_temp: 350 +max_extrude_only_distance: 60 +pressure_advance: 0.075 + +[tmc2209 extruder] +uart_pin: PF2 +interpolate: True +run_current: 0.800 +stealthchop_threshold: 999999 +sense_resistor: 0.110 +[heater_bed] +heater_pin: PA1 +sensor_pin: PF3 # TB +sensor_type: EPCOS 100K B57560G104F +#control: pid +#pid_Kp: 66.746 +#pid_Ki: 3.504 +#pid_Kd: 317.878 +min_temp: 0 +max_temp: 130 + + +[fan] +pin: PB0 +kick_start_time: 0.5 + +[heater_fan hotend_fan] +pin: PA8 + + +[safe_z_home] +home_xy_position: 165,165 +# speed: 50 +z_hop: 10 +# z_hop_speed: 5 + + +[bed_screws] +screw1: 5,5 +screw2: 165,5 +screw3: 325,5 +screw4: 5,325 +screw5: 165,325 +screw6: 325,325 + + +[scanner] +# canbus_uuid: 0ca8d67388c2 +#adjust to suit your scanner +mcu: scanner +# serial: /dev/serial/by-id/usb-Cartographer_614e_20000A000443303459323220-if00 +x_offset: 0 +#adjust for your offset +y_offset: 32 +#adjust for your offset +backlash_comp: 0.13564 +# Backlash compensation distance for removing Z backlash before measuring +# the sensor response. +calibration_method: touch +sensor: cartographer +sensor_alt: carto +#alternate name to call commands. CARTO_TOUCH etc +#scanner_touch_z_offset: 0.05 +#this is the default and will be overwritten and added to the DO NOT SAVE area by using UI to save z offset +mesh_runs: 2 +# Number of passes to make during mesh scan. + +[bed_mesh] +speed: 300 +zero_reference_position: 165, 165 +mesh_min: 30, 30 +mesh_max: 300, 250 +horizontal_move_z: 5 +# height of scanner during bed mesh scan +probe_count: 20, 20 +algorithm: bicubic +# set this to themiddle of your bed + +[temperature_sensor Cartographer_MCU] +sensor_type: temperature_mcu +sensor_mcu: scanner +min_temp: 0 +max_temp: 105 + + +[adxl345] +cs_pin: scanner:PA3 +spi_bus: spi1 + +[resonance_tester] +accel_chip: adxl345 +probe_points: + 165, 165, 20 + + +[gcode_macro G29] +gcode: + BED_MESH_CALIBRATE ADAPTIVE=1 + BED_MESH_PROFILE SAVE=p1 + G1 X0 Y0 Z5 F4000 + +[virtual_sdcard] +path: ~/printer_data/gcodes +[exclude_object] +[display_status] + +[z_tilt] +z_positions: + 422, 165 + -95, 165 + +points: + + 32, 165 + 300, 165 +speed: 400 +horizontal_move_z: 10 +speed: 400 +retries: 5 +retry_tolerance: 0.0075 + + +[board_pins] +aliases: + # EXP1 header + EXP1_1=PE8, EXP1_2=PE7, + EXP1_3=PE9, EXP1_4=PE10, + EXP1_5=PE12, EXP1_6=PE13, # Slot in the socket on this side + EXP1_7=PE14, EXP1_8=PE15, + EXP1_9=, EXP1_10=<5V>, + + # EXP2 header + EXP2_1=PA6, EXP2_2=PA5, + EXP2_3=PB1, EXP2_4=PA4, + EXP2_5=PB2, EXP2_6=PA7, # Slot in the socket on this side + EXP2_7=PC15, EXP2_8=, + EXP2_9=, EXP2_10=PC5 + +#*# <---------------------- SAVE_CONFIG ----------------------> +#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated. +#*# +#*# [scanner] +#*# mode = touch +#*# scanner_touch_z_offset = 0.000 +#*# scanner_touch_threshold = 2000 +#*# scanner_touch_speed = 3 +#*# +#*# [scanner model default] +#*# model_coef = 1.4311262832401048, +#*# 1.7523359610190938, +#*# 0.7454799434155527, +#*# 0.30678509525346565, +#*# 0.4734808608754628, +#*# 0.7017361963522527, +#*# -0.34258530041831486, +#*# -0.7479257536837154, +#*# 0.34175667521191655, +#*# 0.437774104540267 +#*# model_domain = 3.120899309401426e-07,3.292733300451313e-07 +#*# model_range = 0.200000,5.100000 +#*# model_temp = 25.496799 +#*# model_offset = 0.00000 +#*# model_mode = touch +#*# model_fw_version = CARTOGRAPHER 5.0.0 +#*# +#*# [extruder] +#*# control = pid +#*# pid_kp = 23.508 +#*# pid_ki = 1.616 +#*# pid_kd = 85.510 +#*# +#*# [bed_mesh default] +#*# version = 1 +#*# points = +#*# 0.345810, 0.296366, 0.280429, 0.359747, 0.418760, 0.428365, 0.440183, 0.445966, 0.435581, 0.416147, 0.377431, 0.355078, 0.360746, 0.364059, 0.393573, 0.431857, 0.504036, 0.550941, 0.619015, 0.700373 +#*# 0.394088, 0.397639, 0.394112, 0.395603, 0.387365, 0.386946, 0.389032, 0.398332, 0.388213, 0.351619, 0.322332, 0.303877, 0.307599, 0.325808, 0.349595, 0.397959, 0.454807, 0.515506, 0.580783, 0.634931 +#*# 0.355559, 0.366767, 0.368726, 0.346528, 0.350314, 0.342167, 0.339540, 0.363006, 0.351790, 0.298384, 0.269829, 0.267293, 0.266301, 0.288767, 0.317110, 0.356628, 0.418577, 0.462984, 0.520730, 0.580604 +#*# 0.318915, 0.328673, 0.320808, 0.311936, 0.300724, 0.289474, 0.287473, 0.299565, 0.283553, 0.250282, 0.206369, 0.214429, 0.223401, 0.256202, 0.264613, 0.323327, 0.376984, 0.402973, 0.466525, 0.533152 +#*# 0.301993, 0.317036, 0.279639, 0.276389, 0.267650, 0.244139, 0.233333, 0.241282, 0.212323, 0.178598, 0.173532, 0.188747, 0.175736, 0.208312, 0.251160, 0.269097, 0.327719, 0.378871, 0.413258, 0.478928 +#*# 0.269539, 0.278142, 0.275734, 0.234203, 0.214552, 0.220538, 0.184791, 0.158933, 0.158132, 0.157919, 0.125783, 0.128525, 0.167391, 0.177576, 0.193720, 0.266817, 0.303017, 0.323516, 0.388031, 0.446970 +#*# 0.286408, 0.278891, 0.225673, 0.202093, 0.219459, 0.175134, 0.138659, 0.151697, 0.121184, 0.095378, 0.121990, 0.111482, 0.110215, 0.158577, 0.189854, 0.198274, 0.261679, 0.312385, 0.343314, 0.390209 +#*# 0.253330, 0.238493, 0.217600, 0.194671, 0.169552, 0.144228, 0.136917, 0.101081, 0.070004, 0.092723, 0.074355, 0.061882, 0.110693, 0.113573, 0.123322, 0.195698, 0.218413, 0.248657, 0.312578, 0.374245 +#*# 0.231304, 0.213410, 0.192086, 0.163955, 0.161544, 0.111687, 0.069851, 0.078988, 0.047522, 0.026321, 0.052954, 0.045893, 0.045653, 0.091322, 0.110064, 0.122374, 0.177883, 0.228171, 0.254873, 0.308981 +#*# 0.229843, 0.192984, 0.182566, 0.152078, 0.110547, 0.108596, 0.066074, 0.029596, 0.043859, 0.018897, 0.005928, 0.044343, 0.055464, 0.041221, 0.076919, 0.129985, 0.136765, 0.194039, 0.252950, 0.261897 +#*# 0.204667, 0.219508, 0.176636, 0.127510, 0.134506, 0.081383, 0.038417, 0.044658, 0.014989, -0.008225, 0.007996, 0.016116, 0.028992, 0.041969, 0.066326, 0.097645, 0.138560, 0.177058, 0.215858, 0.256976 +#*# 0.222155, 0.183474, 0.180101, 0.122880, 0.101718, 0.080880, 0.025707, 0.017143, 0.012002, -0.008776, -0.006326, 0.002451, 0.013953, 0.027993, 0.050438, 0.084557, 0.121450, 0.145584, 0.211142, 0.236928 +#*# 0.219699, 0.191585, 0.147784, 0.127326, 0.107809, 0.043794, 0.027335, 0.017508, -0.021406, -0.017796, -0.007824, -0.012577, -0.001186, 0.014978, 0.040575, 0.064431, 0.114472, 0.157473, 0.195495, 0.222935 +#*# 0.219827, 0.207591, 0.163880, 0.118280, 0.098958, 0.055559, 0.013850, -0.001068, -0.016713, -0.024445, -0.026063, -0.011650, -0.010916, -0.007977, 0.046556, 0.070015, 0.101674, 0.151872, 0.194414, 0.236126 +#*# 0.251704, 0.227033, 0.167862, 0.140003, 0.102339, 0.063486, 0.030635, 0.001066, -0.005900, -0.023192, -0.024682, -0.013211, -0.012235, 0.013197, 0.044476, 0.075165, 0.119944, 0.164142, 0.205385, 0.247979 +#*# 0.271280, 0.239862, 0.191309, 0.147161, 0.109584, 0.067661, 0.031660, 0.006903, -0.012769, -0.016029, -0.028440, -0.014900, 0.004254, 0.014679, 0.040971, 0.087644, 0.130927, 0.172691, 0.216768, 0.263949 +#*# 0.311520, 0.268117, 0.217776, 0.174111, 0.134875, 0.084171, 0.048048, 0.025056, 0.006761, -0.009902, -0.006826, 0.000415, 0.015372, 0.037148, 0.062163, 0.099381, 0.144600, 0.192360, 0.234689, 0.282198 +#*# 0.351201, 0.303618, 0.251250, 0.202210, 0.158798, 0.115262, 0.075656, 0.046355, 0.023149, 0.013019, 0.008487, 0.021314, 0.035320, 0.056638, 0.086770, 0.126618, 0.172074, 0.221458, 0.273013, 0.321456 +#*# 0.389482, 0.340271, 0.286465, 0.235236, 0.186322, 0.138818, 0.095606, 0.069766, 0.046120, 0.033030, 0.029413, 0.039235, 0.054836, 0.075540, 0.105609, 0.148057, 0.199576, 0.252981, 0.300262, 0.351765 +#*# 0.444881, 0.391868, 0.333472, 0.276222, 0.219577, 0.169273, 0.128926, 0.095676, 0.072649, 0.058001, 0.057571, 0.066414, 0.083236, 0.105185, 0.140422, 0.184576, 0.238860, 0.296649, 0.347763, 0.407280 +#*# x_count = 20 +#*# y_count = 20 +#*# mesh_x_pps = 2 +#*# mesh_y_pps = 2 +#*# algo = bicubic +#*# tension = 0.2 +#*# min_x = 30.0 +#*# max_x = 300.0 +#*# min_y = 30.0 +#*# max_y = 250.0 +#*# +#*# [bed_mesh p1] +#*# version = 1 +#*# points = +#*# 0.364701, 0.399888, 0.441448, 0.431092, 0.430147, 0.434288, 0.431158, 0.439421, 0.419346, 0.385664, 0.350691, 0.344102, 0.376482, 0.383519, 0.435754, 0.497677, 0.550115, 0.634251 +#*# 0.399015, 0.401833, 0.392548, 0.392849, 0.384688, 0.382555, 0.395466, 0.389840, 0.373608, 0.333253, 0.296902, 0.303758, 0.327964, 0.359136, 0.395734, 0.462753, 0.505252, 0.574791 +#*# 0.353703, 0.357298, 0.349160, 0.340832, 0.337943, 0.331504, 0.350552, 0.343069, 0.297073, 0.268625, 0.248651, 0.250210, 0.280728, 0.299781, 0.348736, 0.405031, 0.447621, 0.525580 +#*# 0.335987, 0.328809, 0.322590, 0.303198, 0.291335, 0.284148, 0.311288, 0.288397, 0.246502, 0.220607, 0.210073, 0.213224, 0.242642, 0.272951, 0.307609, 0.366594, 0.407861, 0.452198 +#*# 0.304129, 0.302562, 0.289350, 0.283280, 0.275542, 0.251240, 0.256381, 0.230216, 0.194123, 0.180530, 0.180859, 0.198182, 0.218243, 0.242606, 0.289920, 0.328719, 0.370927, 0.421668 +#*# 0.285010, 0.278842, 0.260024, 0.248929, 0.229641, 0.219939, 0.204283, 0.180013, 0.164755, 0.155261, 0.158084, 0.175331, 0.199212, 0.224646, 0.252467, 0.291951, 0.337449, 0.376608 +#*# 0.258394, 0.258516, 0.239968, 0.224718, 0.208640, 0.174119, 0.149687, 0.138880, 0.118843, 0.125227, 0.127233, 0.131376, 0.155701, 0.180547, 0.218232, 0.256163, 0.295218, 0.341966 +#*# 0.226557, 0.218893, 0.202048, 0.182443, 0.159431, 0.131391, 0.119659, 0.100283, 0.094446, 0.094740, 0.101915, 0.106602, 0.120303, 0.147256, 0.169068, 0.204731, 0.247980, 0.306065 +#*# 0.219162, 0.206621, 0.187110, 0.164293, 0.143381, 0.126391, 0.114482, 0.103075, 0.090413, 0.091350, 0.088665, 0.096071, 0.112046, 0.133689, 0.162142, 0.192952, 0.229370, 0.276603 +#*# 0.203042, 0.183819, 0.164060, 0.147520, 0.122497, 0.100205, 0.086021, 0.072764, 0.060203, 0.055956, 0.063814, 0.074978, 0.096088, 0.115870, 0.134066, 0.167984, 0.200740, 0.241358 +#*# 0.183480, 0.169932, 0.148360, 0.127134, 0.100671, 0.072711, 0.055700, 0.036220, 0.025419, 0.023035, 0.029276, 0.039084, 0.059025, 0.076202, 0.105225, 0.138245, 0.172985, 0.211751 +#*# 0.186437, 0.163060, 0.137549, 0.117834, 0.090665, 0.061256, 0.038606, 0.021344, 0.010838, 0.005547, 0.013315, 0.028111, 0.037630, 0.059063, 0.084036, 0.116643, 0.154821, 0.195169 +#*# 0.195313, 0.166126, 0.139905, 0.114992, 0.083902, 0.050797, 0.030594, 0.012198, 0.006856, 0.007404, 0.015772, 0.027016, 0.042759, 0.061399, 0.090740, 0.123712, 0.158668, 0.197111 +#*# 0.203852, 0.177205, 0.147353, 0.118533, 0.084086, 0.050987, 0.026051, 0.012992, 0.008926, 0.008027, 0.013613, 0.026100, 0.035456, 0.058599, 0.085831, 0.120923, 0.156844, 0.193550 +#*# 0.211551, 0.178101, 0.147587, 0.114848, 0.078508, 0.047465, 0.024671, 0.006833, -0.001917, -0.000485, 0.008205, 0.020121, 0.035531, 0.055415, 0.083975, 0.118060, 0.155826, 0.191147 +#*# 0.235339, 0.200806, 0.164026, 0.129265, 0.092892, 0.063583, 0.039668, 0.020204, 0.007204, 0.008413, 0.021571, 0.033037, 0.050258, 0.073286, 0.101823, 0.135325, 0.172727, 0.209934 +#*# 0.266468, 0.228325, 0.190145, 0.154790, 0.114175, 0.080918, 0.055738, 0.032610, 0.020071, 0.022048, 0.034425, 0.046930, 0.064629, 0.089061, 0.120818, 0.154175, 0.194306, 0.232443 +#*# x_count = 18 +#*# y_count = 17 +#*# mesh_x_pps = 2 +#*# mesh_y_pps = 2 +#*# algo = bicubic +#*# tension = 0.2 +#*# min_x = 47.5 +#*# max_x = 282.5 +#*# min_y = 30.0 +#*# max_y = 208.336 +#*# +#*# [heater_bed] +#*# control = pid +#*# pid_kp = 73.797 +#*# pid_ki = 1.060 +#*# pid_kd = 1284.072 + 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 %}