Newer
Older
jeltz-klipper-config / config / filament_sensors.cfg
@Cory Tucker Cory Tucker 4 days ago 11 KB fix #1, fix #8, add in a QUERY_FILAMENT macro
# 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) }