# filament states: # is_ready_to_print - # load_state # hotend_filament - the filament currently in the hotend. Set to the current loaded filament # loaded_filament - the filament spool which is currently connected to the extruder. Modifiable when filament is # heater_state - cold, heating, heated # if the heater state is 'heated' on printer boot, # and the current hotend and bed temperature is within 15c of the set temperature, then turn the heaters back on. [filaments] on_set_filament_gcode: # A list of G-Code commands to execute after the SET_FILAMENT macro runs. See # docs/Command_Templates.md for G-Code format. These parameters are passed # to the gcode: # * 'EXTRUDER' - the name of the extruder. 'extruder', 'extruder1' etc. # * 'T' - the integer index of the extruder # * 'PRESET' - the filament preset that was just assigned to th extruder # * 'LAST_PRESET' - the filament preset that was previously assigned to the extruder, if any on_clear_filament_gcode: # A list of G-Code commands to execute after the CLEAR_FILAMENT macro runs. See # docs/Command_Templates.md for G-Code format. These parameters are pass to the gcode: # * 'EXTRUDER' - the name of the extruder. 'extruder', 'extruder1' etc. # * 'T' - the integer index of the extruder # * 'LAST_PRESET' - the filament preset that was previously assigned to the extruder, if any [gcode_macro QUERY_FILAMENT] description: Prompts the user to select a filament, and sets the value of filament_extruder to that filament gcode: {% set response = params.RESPONSE|default(False) %} {% set name = params.NAME|default(False) %} {% set return_macro = params.RETURN_MACRO|default(False) %} {% if not response %} RESPOND TYPE=command MSG="action:prompt_begin Select Filament" {% for filament_name in printer.filaments.presets|map(attribute='name',default='None') %} RESPOND TYPE=command MSG="action:prompt_button {filament_name}|QUERY_FILAMENT {rawparams} NAME={filament_name} RESPONSE=True|primary" {% endfor %} RESPOND TYPE=command MSG="action:prompt_show" {% else %} # close the dialog RESPOND TYPE=command MSG="action:prompt_end" SET_EXTRUDER_FILAMENT NAME={name} # if we've specified a return macro, run this next. {% if return_macro %} {return_macro} {% endif %} {% endif %} [gcode_macro UNPRIME_FILAMENT] description: Unprimes the filament, leaving it in a state where it can be unloaded without changing temperatures gcode: {% set svv = printer.save_variables.variables %} {% set unload = params.UNLOAD|default(False) %} {% if svv.filament_load_state == "primed" %} # check if there is a valid value for the currently loaded filament. if not, prompt the user for it. {% if not svv.filament_extruder in printer.filaments.presets|map(attribute='name',default='yeet') %} # if there isn't a set loaded filament, run QUERY_FILAMENT {% else %} QUERY_FILAMENT RETURN_MACRO=LOAD_FILAMENT SET_FILAMENT_LOAD_STATE STATE="processing" # tell the end macro wether to call the unload macro after this SET_GCODE_VARIABLE MACRO=END_UNPRIME_FILAMENT VARIABLE=unload VALUE={unload} # If the extruder was cold, keep it cold after finishing. SET_GCODE_VARIABLE MACRO=END_UNPRIME_FILAMENT VARIABLE=etemp VALUE={printer['extruder'].target} # set temperature of extruder # if in auto mode, set temperature and wait. Otherwise wait for the set temperature if it it's above 25c. {% if svv.heater_mode == "auto" %} SET_TEMPERATURE_AND_WAIT HEATER=extruder TARGET={printer['extruder'].filament.extruder} MODE=auto {% elif printer['extruder'].target > 25 %} TEMPERATURE_WAIT SENSOR=extruder MINIMUM={printer['extruder'].target|float - 1} MAXIMUM={printer['extruder'].target|float + 2} {% endif %} # run the loop to retract until the switch is no longer pressed M83 # relative extruder moves UPDATE_DELAYED_GCODE ID=LOOP_UNPRIME_FILAMENT DURATION=0.15 # retract filament until the button is no longer pressed {% endif %} {% else %} {action_respond_info("unable to unprime filament. Current filament state: %s " %(svv.filament_load_state))} {% endif %} [delayed_gcode LOOP_UNPRIME_FILAMENT] # Retracts filament until the extruder_exit button is no longer pressed gcode: {% if printer["gcode_button extruder_exit"].state == "PRESSED" %} G0 E-2 F{20*60} # retract by -2mm at 20mm/s (0.1s) UPDATE_DELAYED_GCODE ID=LOOP_UNPRIME_FILAMENT DURATION=0.15 # really long wait here. Otherwise klipper gets angry and queues up moves or something. {% else %} END_UNPRIME_FILAMENT {% endif %} [gcode_macro END_UNPRIME_FILAMENT] description: Called by LOOP_UNPRIME_FILAMENT, finishes up unpriming the filament. variable_etemp = 0 variable_unload = False gcode: # reload filament by an extra 10mm to press the button again G0 E10 F{40*60} M82 # absolute extruder moves # set temperature to what it was before SET_HEATER_TEMPERATURE HEATER='extruder' TARGET={etemp} MODE=auto # set filament state SET_FILAMENT_LOAD_STATE STATE="loaded" # if we want to unload after this, do so {% if unload %} UNLOAD_FILAMENT {% endif %} [gcode_macro UNLOAD_FILAMENT] description: Unloads the current filament gcode: {% set svv = printer.save_variables.variables %} # check against current filament state {% if svv.filament_load_state == "loaded" %} # retract filament by 30mm M83 # relative extruder moves G0 E-30 F{40*60} M82 # absolute extruder moves M84 E # disable extruder motor SET_FILAMENT_LOAD_STATE STATE="unloaded_waiting" SET_EXTRUDER_FILAMENT NAME="None" {% elif svv.filament_load_state == "primed" %} UNPRIME_FILAMENT UNLOAD=True {% else %} {action_respond_info("unable to unload filament. Current filament state: %s " %(svv.filament_load_state))} {% endif %} [gcode_macro LOAD_FILAMENT] # loads filament after it has been detected in the entry sensor or manually triggered gcode: {% set svv = printer.save_variables.variables %} {% set prompt = params.PROMPT|default(False) %}M84 E {% set prime = params.PRIME|default(False) %} # tell the end macro wether to call the prime macro after this SET_GCODE_VARIABLE MACRO=END_LOAD_FILAMENT VARIABLE=prime VALUE={prime} {% if not filament_state in ['unloaded'] %} # check if there is a valid value for the currently loaded filament. if not, prompt the user for it. {% if not svv.filament_extruder in printer.filaments.presets|map(attribute='name',default='yeet') %} # if there isn't a set loaded filament, run QUERY_FILAMENT QUERY_FILAMENT RETURN_MACRO=LOAD_FILAMENT {% else %} # forward the filament name to the next macro SET_GCODE_VARIABLE MACRO=END_LOAD_FILAMENT VARIABLE=name VALUE="'{params.NAME}'" # we could set it here, but it avoids weird states if the macro fails for some reason. SET_FILAMENT_LOAD_STATE STATE="processing" M83 # relative extruder moves # load filament into extruder gear UPDATE_DELAYED_GCODE ID=LOOP_LOAD_FILAMENT DURATION=0.15 {% endif %} {% else %} {action_respond_info("unable to load filament. Current filament state: %s " %(svv.filament_load_state))} {% endif %} [delayed_gcode LOOP_LOAD_FILAMENT] gcode: {% if printer["gcode_button extruder_exit"].state == "RELEASED" %} G0 E2 F{20*60} # Extrude by 2mm at 20mm/s (0.1s) UPDATE_DELAYED_GCODE ID=LOOP_LOAD_FILAMENT DURATION=0.15 # really long wait here. Otherwise klipper gets angry and queues up moves or something. {% else %} END_LOAD_FILAMENT {% endif %} [gcode_macro END_LOAD_FILAMENT] variable_prime = False variable_name = None gcode: M82 # absolute extruder moves # set loaded filament SET_FILAMENT_LOAD_STATE STATE="loaded" {% if prime %} PRIME_FILAMENT {% endif %} [gcode_macro PRIME_FILAMENT] gcode: {% set svv = printer.save_variables.variables %} {% if svv.filament_load_state in ['unloaded', 'loaded'] %} # check if there is a valid value for the currently loaded filament. if not, prompt the user for it. {% if not svv.filament_extruder in printer.filaments.presets|map(attribute='name',default='yeet') %} # if there isn't a set loaded filament, run QUERY_FILAMENT QUERY_FILAMENT RETURN_MACRO=PRIME_FILAMENT {% elif svv.filament_load_state in ['unloaded'] %} LOAD_FILAMENT PRIME=True {% elif svv.filament_load_state in ['loaded'] %} # perform filament priming.... {% endif %} {% else %} {action_respond_info("unable to prime filament. Current filament state: %s " %(svv.filament_load_state))} {% endif %} [gcode_macro PURGE_FILAMENT] gcode: {% set svv = printer.save_variables.variables %} {% if not svv.filament_extruder in printer.filaments.presets|map(attribute='name',default='yeet') %} # if there isn't a set loaded filament, run QUERY_FILAMENT QUERY_FILAMENT RETURN_MACRO=PURGE_FILAMENT {% elif svv.filament_load_state in ["loaded", "primed"] %} # if the filament is loaded or primed, then continue ##SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_hotend, ## svv.filament_extruder])|map(attribute="extruder",default='None')|max|string)} MODE=auto; set extruder temp #set extruder temp to max of the filament temperatures in the hotend or extruder to purge correctly # todo # move to / extend purge bucket ; TODO {% else %} {action_respond_info("unable to purge filament. Current filament state: %s " %(svv.filament_load_state))} {% endif %} [gcode_macro CLEAN_NOZZLE] gcode: [gcode_button bowden_sensor] pin: PF2 press_gcode: {% set svv = printer.save_variables.variables %} { action_respond_info("bowden_load") } #DEBUG SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=0 # TODO - USER LOAD FILAMENT. Setup some sort of response? Maybe wake printer from sleep mode and turn on lights? # can't switch back frgom near runout as the extruder can't grab further filament release_gcode: {% set svv = printer.save_variables.variables %} {% if svv.filament_load_state == 'loaded_ready'%} {action_raise_error("Warning: bowden sensor released, nearing filament runout")} # disable the encoder sensor SET_FILAMENT_SENSOR SENSOR=filament_sensor ENABLE=0 # TODO IMPLEMENT MORE WARNINGS. {% elif svv.filament_load_state != 'unloaded' %} {action_raise_error("Warning: bowden sensor released during nonsensical filament state.")} {% endif %} [filament_motion_sensor bowden_encoder_sensor] detection_length: 10 extruder: extruder switch_pin: ^PF3 pause_on_runout: True insert_gcode: runout_gcode: [gcode_button extruder_entry] pin: printHead:PB7 press_gcode: {% set svv = printer.save_variables.variables %} { action_respond_info("extruder_entry_insert") } {% if svv.filament_load_state == 'unloaded' %} LOAD_FILAMENT {% endif %} release_gcode: { action_respond_info("extruder_entry_release") } {% set svv = printer.save_variables.variables %} {% if svv.filament_load_state == 'loaded' %} {action_raise_error("Warning: extruder entry sensor released, filament runout")} SET_FILAMENT_LOAD_STATE STATE="runout" {% if svv.printer_state == 'printing'%} PAUSE {% endif %} # TODO IMPLEMENT MORE WARNINGS. {% elif svv.filament_load_state == 'unloaded_waiting' %} SET_FILAMENT_LOAD_STATE STATE="unloaded" {% elif svv.filament_load_state != 'unloaded' %} {action_raise_error("Warning: bowden sensor released during nonsensical filament state.")} {% endif %} [gcode_button extruder_exit] pin: printHead:PB5 press_gcode: {% set svv = printer.save_variables.variables %} # not much here, this is handled by repeatedly checking the state in the filamet unload macro { action_respond_info("extruder_exit_insert") } release_gcode: {% set svv = printer.save_variables.variables %} { action_respond_info("extruder_exit_runout") } { action_respond_info(svv.filament_load_state|string) }