Skip to content

Commit

Permalink
handle multiple rmmu initial filaments
Browse files Browse the repository at this point in the history
  • Loading branch information
HelgeKeck committed Apr 27, 2024
1 parent e2d0494 commit 6f5628c
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 134 deletions.
47 changes: 3 additions & 44 deletions klippy/rmmu.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def __init__(self, config):
# rmmu default status
self.is_homed = False
self.runout_detected = False
self.initial_filament = -1
self.needs_initial_purging = False
self.spool_joins = []
self.spool_mapping = []
Expand Down Expand Up @@ -212,6 +213,7 @@ def get_status(self, eventtime):
return {'name': self.name,
'tool_count': self.tool_count,
'is_homed': self.is_homed,
'initial_filament': self.initial_filament,
'needs_initial_purging': self.needs_initial_purging,
'loaded_filament': self.get_setting(self.name.lower() + self.VARS_LOADED_FILAMENT),
'loaded_filament_temp': self.get_setting(self.name.lower() + self.VARS_LOADED_FILAMENT_TEMP)}
Expand All @@ -221,6 +223,7 @@ def reset(self):
self.is_homed = False
self.runout_detected = False
self.start_print_param = None
self.initial_filament = -1
self.needs_initial_purging = False

# # update frontend
Expand Down Expand Up @@ -832,57 +835,13 @@ def unload_filament_from_toolhead_sensor_to_reverse_bowden(self, tool):
#####
# Filament presence check
#####
def test_filaments(self, param):
# echo
self.ratos_echo("Testing needed filaments...")

# home if needed
if not self.is_homed and len(self.parking_t_sensor_endstop) != self.tool_count:
self.home()

# test filaments
for i in range(0, self.tool_count):
toolhead_used = param.get('T' + str(i), "true")
if toolhead_used == "true":
toolhead = self.get_remapped_toolhead(i)
if not self.test_filament(toolhead):
self.select_filament(-1)
raise self.printer.command_error("Can not start print because Filament T" + str(toolhead) + " is not available!")

# release idler
if len(self.parking_t_sensor_endstop) != self.tool_count:
self.select_filament(-1)

# echo
self.ratos_echo("All needed filaments available!")

# testing spool join
if len(self.spool_joins) > 0:
self.ratos_echo("Validating spool join...")
for spool_join in self.spool_joins:
counter = 0
for spool in spool_join:
for i in range(0, self.tool_count):
if param.get('T' + str(i), "true") == "true":
if spool == i:
counter += 1
if counter > 1:
raise self.printer.command_error("Can not start print because joined spools are part of the print!")
self.ratos_echo("Spool join validated!")

def test_filament(self, filament):
# echo
self.ratos_echo("Testing filament T" + str(filament) + "...")

# test filament
if len(self.parking_t_sensor_endstop) == self.tool_count or len(self.feeder_filament_sensors) == self.tool_count:
if len(self.parking_t_sensor_endstop) == self.tool_count:
if not self.is_endstop_triggered(self.parking_t_sensor_endstop[filament]):
self.ratos_echo("Filament T" + str(filament) + " not detected!")
return False
if len(self.feeder_filament_sensors) == self.tool_count:
if not self.is_sensor_triggered(self.feeder_filament_sensors[filament]):
self.ratos_echo("Filament T" + str(filament) + " runout detected!")
return False
return True
else:
Expand Down
179 changes: 112 additions & 67 deletions klippy/rmmu_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def __init__(self, config):
self.mapping = {}
self.mode = "multi"
self.total_tool_count = 0
self.initial_filament = 0

self.register_commands()
self.register_handler()
Expand Down Expand Up @@ -165,7 +164,6 @@ def cmd_RMMU_END_PRINT(self, param):
def get_status(self, eventtime):
return {'name': self.name,
'mode': self.mode,
'initial_filament': self.initial_filament,
'total_tool_count': self.total_tool_count,
'mapping': self.mapping}

Expand All @@ -174,83 +172,130 @@ def get_status(self, eventtime):
#####
def start_print(self, param):
# parameter
self.initial_filament = param.get_int('INITIAL_TOOL', None, minval=0, maxval=self.total_tool_count)
self.wipe_accel = param.get_int('WIPE_ACCEL', None, minval=0, maxval=100000)
self.start_print_param = param

# handle toolhead mapping
# self.initial_filament = self.get_remapped_toolhead(self.initial_filament)

# home RMMUs
for rmmu in self.rmmu:
rmmu.home()

# # get used physical toolheads
# used_toolheads = []
# for t in range(0, self.total_tool_count):
# if param.get('T' + str(t), "true") == "true":
# if not t in used_toolheads:
# used_toolheads.append(t)
# self.ratos_echo("used_toolheads: " + str(used_toolheads))

# get initial RMMU and tool
rmmu = self.rmmu[0]
rmmu_tool = self.initial_filament
if rmmu_tool >= self.rmmu[0].tool_count:
rmmu = self.rmmu[1]
rmmu_tool = rmmu_tool - self.rmmu[0].tool_count
self.wipe_accel = param.get_int('WIPE_ACCEL', None, minval=0, maxval=100000)
used_tools = []
try:
used_tools = [int(v.strip()) for v in str(param.get('USED_TOOLS', None)).split(',')]
except:
raise self.printer.command_error("Unable to parse START_PRINT parameter USED_TOOLS.")
if len(used_tools) == 0:
raise self.printer.command_error("Unable to parse START_PRINT parameter USED_TOOLS.")

# home needed RMMUs
for t in used_tools:
physical_toolhead = int(self.mapping[str(t)]["TOOLHEAD"])
if not self.rmmu[physical_toolhead].is_homed:
self.rmmu[physical_toolhead].home()

# get used physical toolheads
used_toolheads = []
for t in used_tools:
physical_toolhead = int(self.mapping[str(t)]["TOOLHEAD"])
if physical_toolhead not in used_toolheads:
used_toolheads.append(physical_toolhead)

# check for filament in hotend
rmmu.needs_initial_purging = True
if rmmu.is_sensor_triggered(rmmu.toolhead_filament_sensor):
loaded_filament = rmmu.get_status(self.toolhead.get_last_move_time())['loaded_filament']
loaded_filament_temp = rmmu.get_status(self.toolhead.get_last_move_time())['loaded_filament_temp']
if loaded_filament >=0 and loaded_filament <= self.total_tool_count:
if loaded_filament != rmmu_tool:
if loaded_filament_temp > rmmu.heater.min_extrude_temp and loaded_filament_temp < rmmu.heater.max_temp:
# unloaded the filament that is already loaded
self.ratos_echo("Wrong filament detected in hotend!")
self.ratos_echo("Unloading filament T" + str(loaded_filament) + "! Please wait...")

# start heating up extruder but dont wait for it so we can save some time
self.ratos_echo("Preheating extruder to " + str(loaded_filament_temp) + "°C.")
rmmu.extruder_set_temperature(loaded_filament_temp, False)

# home printer if needed and move toolhead to its parking position
self.gcode.run_script_from_command('MAYBE_HOME')
if rmmu_tool >= self.rmmu[0].tool_count:
self.gcode.run_script_from_command('_MOVE_TO_LOADING_POSITION TOOLHEAD=1')
else:
self.gcode.run_script_from_command('_MOVE_TO_LOADING_POSITION TOOLHEAD=0')

# wait for the extruder to heat up
self.ratos_echo("Heating up extruder to " + str(loaded_filament_temp) + "°C! Please wait...")
rmmu.extruder_set_temperature(loaded_filament_temp, True)

# unload filament
if not rmmu.unload_filament(loaded_filament):
for physical_toolhead in used_toolheads:
initial_tool = -1
for t in used_tools:
if physical_toolhead == int(self.mapping[str(t)]["TOOLHEAD"]):
initial_tool = int(self.mapping[str(t)]["FILAMENT"])
break
# handle toolhead mapping
# self.initial_filament = self.get_remapped_toolhead(self.initial_filament)
rmmu = self.rmmu[physical_toolhead]
rmmu.initial_filament = initial_tool
rmmu.needs_initial_purging = True
if rmmu.is_sensor_triggered(rmmu.toolhead_filament_sensor):
loaded_filament = rmmu.get_status(self.toolhead.get_last_move_time())['loaded_filament']
loaded_filament_temp = rmmu.get_status(self.toolhead.get_last_move_time())['loaded_filament_temp']
if loaded_filament >=0 and loaded_filament <= self.total_tool_count:
if loaded_filament != rmmu.initial_filament:
if loaded_filament_temp > rmmu.heater.min_extrude_temp and loaded_filament_temp < rmmu.heater.max_temp:
# unloaded the filament that is already loaded
self.ratos_echo("Wrong filament detected in hotend!")
self.ratos_echo("Unloading filament T" + str(loaded_filament) + "! Please wait...")

# start heating up extruder but dont wait for it so we can save some time
self.ratos_echo("Preheating extruder to " + str(loaded_filament_temp) + "°C.")
rmmu.extruder_set_temperature(loaded_filament_temp, False)

# home printer if needed and move toolhead to its parking position
self.gcode.run_script_from_command('MAYBE_HOME')
if rmmu.initial_filament >= self.rmmu[0].tool_count:
self.gcode.run_script_from_command('_MOVE_TO_LOADING_POSITION TOOLHEAD=1')
else:
self.gcode.run_script_from_command('_MOVE_TO_LOADING_POSITION TOOLHEAD=0')

# wait for the extruder to heat up
self.ratos_echo("Heating up extruder to " + str(loaded_filament_temp) + "°C! Please wait...")
rmmu.extruder_set_temperature(loaded_filament_temp, True)

# unload filament
if not rmmu.unload_filament(loaded_filament):
rmmu.extruder_set_temperature(0, False)
raise self.printer.command_error("Could not unload filament! Please unload the filament and restart the print.")

# cool down extruder, dont wait for it
rmmu.extruder_set_temperature(0, False)
raise self.printer.command_error("Could not unload filament! Please unload the filament and restart the print.")

# cool down extruder, dont wait for it
rmmu.extruder_set_temperature(0, False)
else:
raise self.printer.command_error("Unknown filament detected in toolhead! Please unload the filament and restart the print.")
else:
raise self.printer.command_error("Unknown filament detected in toolhead! Please unload the filament and restart the print.")
# tell RatOS that initial purging is not needed
rmmu.needs_initial_purging = False
else:
# tell RatOS that initial purging is not needed
rmmu.needs_initial_purging = False
else:
raise self.printer.command_error("Unknown filament detected in toolhead! Please unload the filament and restart the print.")
raise self.printer.command_error("Unknown filament detected in toolhead! Please unload the filament and restart the print.")

# # test if all demanded filaments are available and raises an error if not
# rmmu.test_filaments(param)
# disable toolhead filament sensor
rmmu.toolhead_filament_sensor.runout_helper.sensor_enabled = False

# disable toolhead filament sensor
rmmu.toolhead_filament_sensor.runout_helper.sensor_enabled = False
# test if all demanded filaments are available and raises an error if not
self.test_filaments(used_tools)

# call RatOS start print gcode macro
self.gcode.run_script_from_command('START_PRINT ' + str(param.get_raw_command_parameters().strip()))

#####
# Filament presence check
#####
def test_filaments(self, used_tools):
# echo
self.ratos_echo("Testing needed filaments...")

# test filaments
for filament in used_tools:
rmmu_filament = int(self.mapping[str(filament)]["FILAMENT"])
# filament = self.get_remapped_toolhead(filament)
physical_toolhead = int(self.mapping[str(filament)]["TOOLHEAD"])
rmmu = self.rmmu[physical_toolhead]
self.ratos_echo("Testing filament T" + str(filament) + "...")
if not rmmu.test_filament(rmmu_filament):
self.ratos_echo("Filament T" + str(filament) + " not found!")
rmmu.select_filament(-1)
raise self.printer.command_error("Can not start print because Filament T" + str(filament) + " is not available!")

# release idler
if len(rmmu.parking_t_sensor_endstop) != rmmu.tool_count:
rmmu.select_filament(-1)

# echo
self.ratos_echo("All needed filaments available!")

# # testing spool join
# if len(self.spool_joins) > 0:
# self.ratos_echo("Validating spool join...")
# for spool_join in self.spool_joins:
# counter = 0
# for spool in spool_join:
# for i in range(0, self.tool_count):
# if param.get('T' + str(i), "true") == "true":
# if spool == i:
# counter += 1
# if counter > 1:
# raise self.printer.command_error("Can not start print because joined spools are part of the print!")
# self.ratos_echo("Spool join validated!")

#####
# Change Filament
#####
Expand Down
44 changes: 28 additions & 16 deletions macros.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -313,16 +313,6 @@ gcode:
{% if printer["dual_carriage"] is defined %}
SET_GCODE_VARIABLE MACRO=T1 VARIABLE=active VALUE=True
{% endif %}
# {% if printer["rmmu"] is defined %}
# {% for i in range(printer["rmmu"].tool_count) %}
# SET_GCODE_VARIABLE MACRO=T{i} VARIABLE=active VALUE=False
# {% set color_key = "COLOR" if i==0 else "COLOR_%s" % i|string %}
# {% if params[color_key] is defined %}
# {% set color_parameter = params[color_key] %}
# SET_GCODE_VARIABLE MACRO=T{i} VARIABLE=color VALUE='"{color_parameter|string}"'
# {% endif %}
# {% endfor %}
# {% endif %}

# set both_toolheads variable based on toolshift count. we first assume both toolheads will be needed
{% set both_toolheads = true %}
Expand Down Expand Up @@ -629,11 +619,32 @@ gcode:
{% endif %}

# rmmu load initial tool
{% if printer["rmmu_hub"] is defined and printer["rmmu RMMU_T%s" % initial_tool].loaded_filament|int != printer["rmmu_hub"].initial_filament|int %}
_MOVE_TO_LOADING_POSITION TOOLHEAD={initial_tool}
RMMU_LOAD_FILAMENT FILAMENT={printer["rmmu_hub"].initial_filament|int}
{% if printer["dual_carriage"] is defined %}
PARK_TOOLHEAD
{% if printer["rmmu_hub"] is defined %}
{% if physical_t0_used and printer["rmmu RMMU_T0"] is defined and printer["rmmu RMMU_T0"].loaded_filament|int != printer["rmmu RMMU_T0"].initial_filament|int %}
{% if initial_tool == 1 %}
SET_DUAL_CARRIAGE CARRIAGE=0 MODE=PRIMARY
{% endif %}
_MOVE_TO_LOADING_POSITION TOOLHEAD=0
RMMU_LOAD_FILAMENT FILAMENT={printer["rmmu RMMU_T0"].initial_filament|int}
{% if printer["dual_carriage"] is defined %}
PARK_TOOLHEAD
{% endif %}
{% if initial_tool == 1 %}
SET_DUAL_CARRIAGE CARRIAGE=1 MODE=PRIMARY
{% endif %}
{% endif %}
{% if physical_t1_used and printer["rmmu RMMU_T1"] is defined and printer["rmmu RMMU_T1"].loaded_filament|int != printer["rmmu RMMU_T1"].initial_filament|int %}
{% if initial_tool == 0 %}
SET_DUAL_CARRIAGE CARRIAGE=1 MODE=PRIMARY
{% endif %}
_MOVE_TO_LOADING_POSITION TOOLHEAD=1
RMMU_LOAD_FILAMENT FILAMENT={printer["rmmu RMMU_T1"].initial_filament|int}
{% if printer["dual_carriage"] is defined %}
PARK_TOOLHEAD
{% endif %}
{% if initial_tool == 0 %}
SET_DUAL_CARRIAGE CARRIAGE=0 MODE=PRIMARY
{% endif %}
{% endif %}
{% endif %}

Expand Down Expand Up @@ -736,13 +747,14 @@ gcode:
# config
{% set min_temp = printer["gcode_macro RatOS"].preheat_extruder_temp|float %}
{% set max_temp = printer["gcode_macro RatOS"].preheat_extruder_temp|float + 5 %}
{% set default_toolhead = printer["gcode_macro RatOS"].default_toolhead|default(0)|int %}

# preheat extruder
{% if printer["gcode_macro RatOS"].preheat_extruder|lower == 'true' %}
RATOS_ECHO MSG="Pre-heating extruder..."
# Wait for extruder to reach a predefined preheat temp so an inductive probe (if present) is at a predictable temp.
# Also allows the bed heat to spread a little, and softens any plastic that might be stuck to the nozzle.
M104 S{min_temp}
M104 S{min_temp} T{default_toolhead}
TEMPERATURE_WAIT SENSOR=extruder MINIMUM={min_temp} MAXIMUM={max_temp}
{% endif %}

Expand Down
Loading

0 comments on commit 6f5628c

Please sign in to comment.