##################################################################### # Preperation ##################################################################### # copy this file in the same directory as your printer.cfg # add # [include flexplate.cfg] # to your printer.cfg # # add # _SET_PLATE_OFFSET # to your print start gcode to apply the offset before you print the first line of filament # # A [save_variables] block is needed since a printer save variable needs to be used to have it available after power up. # You can skip this if you already have an [save_variables] config block # e.g: # [save_variables] # filename: /home/pi/klipper_config/.variables.stb # I like to hide that file as there is nothing in that should be modified by the user. # Do a klipper restart after adding the stuff above # # After klipper is back you need define your first plate e.g. # ADD_NEW_PLATE NAME=Texture OFFSET=-0.010 # ##################################################################### # Macro for the print_start gcode section of your slicer # or your print start macro ##################################################################### # _SET_PLATE_OFFSET [MOVE=0|1] : Set the z offset # Set the offset of the active flexplate as an Z_ADJUST offset. MOVE=0 (default) # will add the offset with the next z move, MOVE=1 imitate change the z offset. # # !!! Caution: Insure that SET_GCODE_OFFSET Z=0 is set once at every # print start. Please read also the desribtion of the gcode SET_GCODE_OFFSET # at https://www.klipper3d.org/G-Codes.html#extended-g-code-commands !!! # ##################################################################### # Console ussage ##################################################################### # LIST_PLATES: List all plates # Use the index shown there for all other macros # # SET_PLATE INDEX=: Set the active flexplate # The flexplate stored at index will be activated. # # ADD_PLATE [NAME=] [OFFSET=]: Add a new flexplate to the list # If NAME or OFFSET is not defined than the defaults 'New' and 0.000 will be used. # !!! Caution do not use special characters like äüö or anything else in the name !!! # # REMOVE_PLATE INDEX=: Remove a flexplate of the list # Remove plate with INDEX from the list. Note the last or active plate can not be removed. # # CHANGE_PLATE_VALUE [INDEX=] [NAME=] [OFFSET=]: Change name or/and offset of an flexplate # If INDEX is not defined the name and/or offset value of the active plate will be changed. # !!! Caution do not use special characters like äüö or anything else in the name !!! # ##################################################################### # LCD menu usage ##################################################################### # Change the active flexplate and the offset of that flexplate. # ##################################################################### # Get offset_z and name for own usage ##################################################################### # {% set offset = printer.save_variables.variables.plates.array[printer.save_variables.variables.plates.index].offset %} # {% set name = printer.save_variables.variables.plates.array[printer.save_variables.variables.plates.index].name %} # ##################################################################### [gcode_macro _SET_PLATE_OFFSET] description: Helper: Apply the z-offset of the active flexplate gcode: {% if not printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: No Plate Array defined. ABORDED")} {% else %} {% set plates = printer.save_variables.variables.plates %} SET_GCODE_OFFSET Z_ADJUST={plates.array[plates.index].offset} MOVE={params.MOVE|default(0)} {% endif %} [gcode_macro LIST_PLATES] description: List all flexplates gcode: {% if not printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: No Plate Array defined. ABORDED")} {% else %} {% set plates = printer.save_variables.variables.plates %} {% set out = ["FLEXPLATE: Defined Plates"] %} {% for elem in range(plates.array|length) %} {% set _dummy = out.append("INDEX: %d -> %s -> offset: %.3fmm" % (elem, plates.array[elem].name, plates.array[elem].offset)) %} {% endfor %} {% set _dummy = out.append("\n Active Plate: %s" % plates.array[plates.index].name) %} {action_respond_info(out|join("\n"))} {% endif %} [gcode_macro SET_PLATE] description: Set an flexplate gcode: {% if not printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: No Plate Array defined. ABORDED")} {% else %} {% set plates = printer.save_variables.variables.plates %} {% if 'INDEX' not in params|upper %} {action_respond_info("FLEXPLATE: No INDEX defined, use SET_PLATE INDEX=index. ABORDED")} {% elif params.INDEX|int < 0 or params.INDEX|int >= plates.array|length %} {action_respond_info("FLEXPLATE: Index out of range [0..%d]. ABORDED" % (plates.array|length-1))} {% else %} {% set _dummy = plates.update({'index' : params.INDEX|int}) %} SAVE_VARIABLE VARIABLE=plates VALUE="{plates}" M117 Plate: {plates.array[plates.index].name} {action_respond_info("FLEXPLATE: Set plate: %s with offset: %.3fmm" % ( plates.array[plates.index].name,plates.array[plates.index].offset))} {% endif %} {% endif %} [gcode_macro ADD_PLATE] description: Add a flexplate to the list gcode: {% set name = params.NAME|default('New')|string %} {% set offset = params.OFFSET|default(0.0)|float|round(3) %} {% if not printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: Initialize Plate Array Add plate: %s with offset: %.3fmm at INDEX: 0" % (name,offset))} {% set plates = {'array': [{'name': name, 'offset': offset}], 'index' : 0} %} {% else %} {% set plates = printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: Add plate: %s with offset: %.3fmm at INDEX: %d" % (name,offset,plates.array|length))} {% set _dummy = plates.array.append({'name': name, 'offset': offset}) %} {% endif %} SAVE_VARIABLE VARIABLE=plates VALUE="{plates}" [gcode_macro REMOVE_PLATE] description: Remove a flexplate from the list gcode: {% if not printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: No Plate Array defined. ABORDED")} {% else %} {% set plates = printer.save_variables.variables.plates %} {% if 'INDEX' not in params|upper %} {action_respond_info("FLEXPLATE: No INDEX defined, use REMOVE_PLATE INDEX=index. ABORDED")} {% elif plates.array|length == 1 or params.INDEX|int == plates.index %} {action_respond_info("FLEXPLATE: Last or active plate can not be removed. ABORDED")} {% elif params.INDEX|int < 0 or params.INDEX|int >= plates.array|length %} {action_respond_info("FLEXPLATE: Index out of range [0..%d]. ABORDED" % (plates.array|length-1))} {% else %} {action_respond_info("FLEXPLATE: Remove plate with INDEX %d from list " % params.INDEX|int)} {% set _dummy = plates.array.pop(params.INDEX|int) %} SAVE_VARIABLE VARIABLE=plates VALUE="{plates}" {% endif %} {% endif %} [gcode_macro CHANGE_PLATE_VALUE] description: Change name or offset of an flexplate in the list gcode: {% if not printer.save_variables.variables.plates %} {action_respond_info("FLEXPLATE: No Plate Array defined. ABORDED")} {% else %} {% set plates = printer.save_variables.variables.plates %} {% set index = params.INDEX|default(plates.index)|int %} {% if index < 0 or index >= plates.array|length %} {action_respond_info("FLEXPLATE: Index out of range [0..%d]. ABORDED" % (plates.array|length-1))} {% else %} {% set change_txt = [] %} {% if 'NAME' in params|upper %} {% set _dummy = change_txt.append("name to %s" % params.NAME|string) %} {% set _dummy = plates.array[index].update({'name': params.NAME|string}) %} {% endif %} {% if 'OFFSET' in params|upper %} {% set _dummy = change_txt.append("offset to %.3fmm" % params.OFFSET|float|round(3)) %} {% set _dummy = plates.array[index].update({'offset': params.OFFSET|float|round(3)}) %} {% endif %} {% if change_txt|length > 0 %} {action_respond_info("FLEXPLATE: Changed %s at plate with INDEX %d" % (change_txt|join(" and "),index))} SAVE_VARIABLE VARIABLE=plates VALUE="{plates}" {% else %} {action_respond_info("FLEXPLATE: Nothing changed at plate with INDEX %d" % index)} {% endif %} {% endif %} {% endif %} # Display Menu # !!! Caution: I use my own menu root __voron_main !!! # If you use a stock menu un comment this here #[menu __main __flexplate] #type: list #name: Flexplate: {printer.save_variables.variables.plates.array[printer.save_variables.variables.plates.index].name} #enable: {'plates' in printer.save_variables.variables} #index: 1 #[menu __main __flexplate __set] #type: input #name: Set: {printer.save_variables.variables.plates.array[menu.input|int].name} #enable: {printer.print_stats.state != "printing" and printer.print_stats.state != "paused"} #input: {printer.save_variables.variables.plates.index} #input_min: 0 #input_max: {printer.save_variables.variables.plates.array|length - 1} #gcode: # {%- if menu.event == 'long_click' -%} # SET_PLATE INDEX={menu.input|int} # {%- endif -%} #[menu __main __flexplate __offset] #type: input #name: Offset:{'%01.3f' % menu.input} #enable: {printer.print_stats.state != "printing" and printer.print_stats.state != "paused"} #input: {printer.save_variables.variables.plates.array[printer.save_variables.variables.plates.index].offset} #input_min: -1.0 #input_max: 1.0 #input_step: 0.001 #gcode: # {%- if menu.event == 'long_click' -%} # CHANGE_PLATE_VALUE OFFSET={menu.input|float} # {%- endif -%}