From 3805a3115c6131b83e8d3e425a9c41d33d8333d3 Mon Sep 17 00:00:00 2001 From: DJGummikuh Date: Sun, 25 May 2025 17:28:28 +0200 Subject: [PATCH] Initial commit with actual code. --- mmu/generate.g | 232 +++++++++++++++++++++++++++++++ mmu/lib/assert-empty.g | 6 + mmu/lib/assert-endstop.g | 33 +++++ mmu/lib/assert-selector-loaded.g | 25 ++++ mmu/lib/check-endstop.g | 17 +++ mmu/lib/disengage.g | 7 + mmu/lib/engage.g | 10 ++ mmu/lib/filament-runout.g | 10 ++ mmu/lib/globals.g | 65 +++++++++ mmu/lib/load-tool.g | 21 +++ mmu/lib/save-selector-state.g | 3 + mmu/lib/selector-state.g | 3 + mmu/lib/unload.g | 29 ++++ mmu/settings.g | 33 +++++ 14 files changed, 494 insertions(+) create mode 100644 mmu/generate.g create mode 100644 mmu/lib/assert-empty.g create mode 100644 mmu/lib/assert-endstop.g create mode 100644 mmu/lib/assert-selector-loaded.g create mode 100644 mmu/lib/check-endstop.g create mode 100644 mmu/lib/disengage.g create mode 100644 mmu/lib/engage.g create mode 100644 mmu/lib/filament-runout.g create mode 100644 mmu/lib/globals.g create mode 100644 mmu/lib/load-tool.g create mode 100644 mmu/lib/save-selector-state.g create mode 100644 mmu/lib/selector-state.g create mode 100644 mmu/lib/unload.g create mode 100644 mmu/settings.g diff --git a/mmu/generate.g b/mmu/generate.g new file mode 100644 index 0000000..29a098c --- /dev/null +++ b/mmu/generate.g @@ -0,0 +1,232 @@ +;M98 P"mmu/lib/globals.g" +;M98 P"mmu/settings.g" +; generated/free-endstop.g +var output = "mmu/lib/generated/free-endstop.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "; disassociate the pin first" +echo >>{var.output} "M950 J" ^ global.mmu_selector_trigger ^ "C""nil"" ; unassign the selector triger pin definition." +echo >>{var.output} "M581 T" ^ global.mmu_selector_trigger ^ "P-1 ; delete the trigger for the mmu selector" +echo >>{var.output} "M574 " ^ global.mmu_selector_axis ^ 0 ^ "; declare that the selector axis has no endstop." +echo >>{var.output} "M574 " ^ global.mmu_extruder_axis ^ 0 ^ "; declare that the mmu extruder axis has no endstop." +echo >>{var.output} "if fileexists(""/sys/trigger" ^ global.mmu_encoder_trigger ^ ".g"") ; if we have a sys/triggerX.g file" +echo >>{var.output} " M30 {""/sys/trigger" ^ global.mmu_selector_trigger ^ ".g""} ; delete it." + +; generated/buzz.g +set var.output = "mmu/lib/generated/buzz.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "G91 ; switch to relative movement." +echo >>{var.output} "G92 " ^ global.mmu_extruder_axis ^ "0 ; Null the MMU extruder axis." +echo >>{var.output} "G1 F" ^ global.mmu_extruder_slow_speed ^ " " ^ global.mmu_extruder_axis ^ "5 ; slowly go forward 5 millimeters." +echo >>{var.output} "M400 ; wait for the command to end." +echo >>{var.output} "G1 F" ^ global.mmu_extruder_slow_speed ^ " " ^ global.mmu_extruder_axis ^ "-5 ; slowly go backwards 5 millimeters again." +echo >>{var.output} "M400 ; wait again." +echo >>{var.output} "M84 " ^ global.mmu_extruder_axis ^ " ; turn off the extruder axis." +echo >>{var.output} "G90 ; return to absolute movement." + +; generated/home.g +set var.output = "mmu/lib/generated/home.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "M98 P""mmu/lib/assert-empty.g""" +echo >>{var.output} "M98 P""mmu/lib/generated/free-endstop.g""" +echo >>{var.output} "M98 P""mmu/lib/disengage.g""" +echo >>{var.output} "M584 P{#move.axes} ; allow operating on MMU axes" +echo >>{var.output} "set global.mmu_extruder_loaded = false" +echo >>{var.output} "G91" +echo >>{var.output} "M574 S1 " ^ global.mmu_selector_axis ^ "1" ^ " P""" ^ global.mmu_selector_endstop_pin ^ """" +echo >>{var.output} "G1 H1 F6000 " ^ global.mmu_selector_axis ^ -global.mmu_selector_axis_max - 5 +echo >>{var.output} "M98 P""mmu/lib/assert-endstop.g""" +echo >>{var.output} "G1 F6000 " ^ global.mmu_selector_axis ^ "5" +echo >>{var.output} "G1 H1 F300 " ^ global.mmu_selector_axis ^ -10 +echo >>{var.output} "M98 P""mmu/lib/assert-endstop.g""" +echo >>{var.output} "M574 " ^ global.mmu_selector_axis ^ 0 +echo >>{var.output} "G90" +echo >>{var.output} "M98 P""mmu/lib/generated/select.g"" S0 H1" +echo >>{var.output} "M584 P{#move.axes - 2} ; hide MMU axes" + +; generated/init.g +set var.output = "mmu/lib/generated/init.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "M98 P""mmu/lib/globals.g"" ; initialize all global variables." +echo >>{var.output} "M98 P""mmu/settings.g"" ; overwrite gobal default values with printer-specifics." +echo >>{var.output} "M98 P""" ^ global.mmu_selector_file ^ """ ; restore selector state." +echo >>{var.output} "M950 S" ^ global.mmu_servo_num ^ " C""" ^ global.mmu_servo_pin ^ """" +echo >>{var.output} "M906 " ^ global.mmu_extruder_axis ^ global.mmu_extruder_current ^ " " ^ global.mmu_selector_axis ^ global.mmu_selector_current +echo >>{var.output} "M350 " ^ global.mmu_extruder_axis ^ global.mmu_extruder_microsteps ^ " " ^ global.mmu_selector_axis ^ global.mmu_selector_microsteps +echo >>{var.output} "M92 " ^ global.mmu_extruder_axis ^ global.mmu_extruder_steps ^ " " ^ global.mmu_selector_axis ^ global.mmu_selector_steps +echo >>{var.output} "M201 " ^ global.mmu_extruder_axis ^ global.mmu_extruder_accel ^ " " ^ global.mmu_selector_axis ^ global.mmu_selector_accel +echo >>{var.output} "M203 " ^ global.mmu_extruder_axis ^ 24000 ^ " " ^ global.mmu_selector_axis ^ 24000 +echo >>{var.output} "M208 S1 " ^ global.mmu_selector_axis ^ global.mmu_selector_axis_min ^ " " ^ global.mmu_extruder_axis ^ "-9999" +echo >>{var.output} "M208 S0 " ^ global.mmu_selector_axis ^ global.mmu_selector_axis_max ^ " " ^ global.mmu_extruder_axis ^ "9999" +echo >>{var.output} "M591 D0 S0 P0" +echo >>{var.output} "M98 P""mmu/lib/filament-runout.g""" + +; generated/load.g +set var.output = "mmu/lib/generated/load.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "M98 R1" +echo >>{var.output} "if state.macroRestarted" +echo >>{var.output} " if !global.mmu_extruder_loaded" +echo >>{var.output} " var err = ""Filament not yet loaded: T"" ^ global.mmu_selector_pos" +echo >>{var.output} " if state.status == ""processing""" +echo >>{var.output} " echo var.err" +echo >>{var.output} " M291 P{var.err} R""Load Filament"" S1 T0" +echo >>{var.output} " M98 R1" +echo >>{var.output} " M226" +echo >>{var.output} " M99" +echo >>{var.output} "if global.mmu_extruder_loaded" +echo >>{var.output} " echo ""Extruder already loaded, skipping; restarted="" ^ state.macroRestarted" +echo >>{var.output} " M99" +echo >>{var.output} "if global.mmu_selector_pos == -1" +echo >>{var.output} " abort ""Home selector first""" +echo >>{var.output} "M98 P""mmu/lib/assert-empty.g""" +echo >>{var.output} "M98 P""mmu/lib/engage.g""" +echo >>{var.output} "G91" +echo >>{var.output} "M584 P{#move.axes} ; enable axes, we need them" +echo >>{var.output} "M98 P""mmu/lib/generated/free-endstop.g""" +echo >>{var.output} "M574 A0" +echo >>{var.output} "M574 S1 " ^ global.mmu_extruder_axis ^ "2" ^ " P""" ^ global.mmu_filament_sensor_pin ^ """ ; Endstop Configuration. Microswitch (S1), High End (2)" +echo >>{var.output} "M208 S1 " ^ global.mmu_extruder_axis ^ "-9999 ; max travel to minimum -10m" +echo >>{var.output} "M208 S0 " ^ global.mmu_extruder_axis ^ "9999 ; max travel to maximum +10m" +echo >>{var.output} "G91 ; set to relative moves" +echo >>{var.output} "G1 H1 F" ^ global.mmu_extruder_fast_speed ^ " " ^ global.mmu_extruder_axis ^ 50 ^ " ; run for up to 50mm waiting for the endstop to trigger." +echo >>{var.output} "M98 P""mmu/lib/assert-selector-loaded.g""" +echo >>{var.output} "G92 " ^ global.mmu_extruder_axis ^ "0" +echo >>{var.output} "M98 P""mmu/lib/generated/free-endstop.g""" +echo >>{var.output} "M574 A0" +echo >>{var.output} "M574 S1 " ^ global.mmu_extruder_axis ^ "2" ^ " P""" ^ global.mmu_extruder_runout_pin ^ """ ; Endstop Configuration. Microswitch (S1), High End (2)" +echo >>{var.output} "M208 S1 " ^ global.mmu_extruder_axis ^ "-9999" +echo >>{var.output} "M208 S0 " ^ global.mmu_extruder_axis ^ "9999" +echo >>{var.output} "G1 H1 F" ^ global.mmu_extruder_fast_speed ^ " " ^ global.mmu_extruder_axis ^ global.mmu_bowden_length ^ " ; fast load the filament to the extruder runout sensor." +echo >>{var.output} "G1 F" ^ global.mmu_extruder_load_speed ^ " " ^ global.mmu_extruder_axis ^ -10 ^ " ; back off slightly." +echo >>{var.output} "G1 H1 " ^global.mmu_extruder_axis ^ 20 ^ " ; slowly feed again for more precision." +echo >>{var.output} "M574 " ^ global.mmu_extruder_axis ^ 0 ^ " ; Disconnect endstop" +echo >>{var.output} "M98 P""mmu/lib/generated/load-extruder.g""" +echo >>{var.output} "if !global.mmu_extruder_loaded" +echo >>{var.output} " var errmsg = ""Load into extruder not detected: T"" ^ global.mmu_selector_pos" +echo >>{var.output} " if state.status == ""processing""" +echo >>{var.output} " echo var.errmsg" +echo >>{var.output} " M291 P{var.errmsg} R""Load Filament"" S1 T0" +echo >>{var.output} " M98 R1" +echo >>{var.output} " M226" +echo >>{var.output} " else" +echo >>{var.output} " abort var.errmsg" +echo >>{var.output} "M98 P""mmu/lib/disengage.g""" +echo >>{var.output} "G90" + +; generated/load-extruder.g +set var.output = "mmu/lib/generated/load-extruder.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "if global.mmu_extruder_loaded && (!exists(param.F) || param.F != 1)" +echo >>{var.output} " echo ""Cannot load extruder while already loaded; restarted="" ^ state.macroRestarted" +echo >>{var.output} " M99" +echo >>{var.output} "G91" +echo >>{var.output} "G92 " ^ global.mmu_extruder_axis ^ "0" ^ " ; Null the mmu extruder." +echo >>{var.output} "G1 " ^ global.mmu_extruder_axis ^ global.mmu_sensor_extruder_gears_length ^ " E" ^ global.mmu_sensor_extruder_gears_length ^ " ; filament: runout sensor -> extruder. Spin extruder as well to prevent the filament from going elsewhere" +echo >>{var.output} "G1 F" ^ global.mmu_extruder_load_speed ^ " E" ^ {global.mmu_extruder_gear_diameter + 10} ^ " " ^ global.mmu_extruder_axis ^ {global.mmu_extruder_gear_diameter + 10} +echo >>{var.output} "M400" +echo >>{var.output} "M98 P""mmu/lib/disengage.g""" +echo >>{var.output} "G1 F" ^ global.mmu_extruder_load_speed ^ " E" ^ {global.mmu_extruder_to_park_length - (global.mmu_extruder_gear_diameter + 10)} ^ " ; bring filament to park position." +echo >>{var.output} "M400" +echo >>{var.output} "M584 P{#move.axes - 2} ; hide MMU axes" +echo >>{var.output} "set global.mmu_extruder_loaded = true" +echo >>{var.output} "T{global.mmu_tool_number}" +echo >>{var.output} "G90" +echo >>{var.output} "M98 P""mmu/lib/save-selector-state.g""" +echo >>{var.output} "M98 P""mmu/lib/filament-runout.g""" + +; generated/load-lane.g +set var.output = "mmu/lib/generated/load-lane.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "; this macro initially loads a lane. That means it starts spinning the MMU extruder until the filament sensor trips," +echo >>{var.output} "; then moves the filament back so it sits flush with the selector lane, allowing the selector to move." +echo >>{var.output} "M98 P""mmu/lib/assert-empty.g""" +echo >>{var.output} "M98 P""mmu/lib/generated/free-endstop.g""" +echo >>{var.output} "M98 P""mmu/lib/engage.g""" +echo >>{var.output} "M584 P{#move.axes} ; allow operating on MMU axes" +echo >>{var.output} "set global.mmu_extruder_loaded = false ; we asserted before that we are empty, so we are currently obviously not loaded." +echo >>{var.output} "M574 S1 " ^ global.mmu_extruder_axis ^ "2" ^ " P""" ^ global.mmu_filament_sensor_pin ^ """ ; Endstop Configuration. Microswitch (S1), High End (2)" +echo >>{var.output} "M208 S1 " ^ global.mmu_extruder_axis ^ "-9999 ; max travel to minimum -10m" +echo >>{var.output} "M208 S0 " ^ global.mmu_extruder_axis ^ "9999 ; max travel to maximum +10m" +echo >>{var.output} "G91 ; set to relative moves" +echo >>{var.output} "G1 H1 F600 " ^ global.mmu_extruder_axis ^ 600 ^ " ; run for up to 60cm waiting for the endstop to trigger." +echo >>{var.output} "M98 P""mmu/lib/assert-endstop.g""" +echo >>{var.output} "G1 F6000 " ^ global.mmu_extruder_axis ^ -15 +echo >>{var.output} "M400" ; Wait +echo >>{var.output} "G92 " ^ global.mmu_extruder_axis ^ 0 ^ " ; Null Selector-Extruder again" +echo >>{var.output} "M574 " ^ global.mmu_extruder_axis ^ 0 ^ " ; Disconnect endstop" +echo >>{var.output} "M18 " ^ global.mmu_extruder_axis ^ " ; turn off extruder power - we don't need it afterwards." +echo >>{var.output} "M98 P""mmu/lib/disengage.g""" +echo >>{var.output} "M584 P{#move.axes - 2} ; hide MMU axes" + +; generated/select.g +set var.output = "mmu/lib/generated/select.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "if global.mmu_selector_pos == -1 && (!exists(param.H) || param.H != 1)" +echo >>{var.output} " abort ""Home selector first""" +echo >>{var.output} "if !exists(param.S)" +echo >>{var.output} " abort ""No Slot selected""" +echo >>{var.output} "if !exists(param.H) || param.H != 1" +echo >>{var.output} " M98 P""mmu/lib/assert-empty.g""" +echo >>{var.output} "if global.mmu_servo_engaged" +echo >>{var.output} " M98 P""mmu/lib/disengage.g""" +echo >>{var.output} "M584 P{#move.axes} ; allow operating on MMU axes" +echo >>{var.output} "var axis = -1" +echo >>{var.output} "while var.axis == -1" +echo >>{var.output} " if iterations >= #move.axes" +echo >>{var.output} " break" +echo >>{var.output} " if move.axes[iterations].letter == global.mmu_selector_axis" +echo >>{var.output} " set var.axis = iterations" +echo >>{var.output} "if var.axis == -1" +echo >>{var.output} " abort ""Cannot find selector axis""" +echo >>{var.output} "G90" +echo >>{var.output} "var slot_position = (param.S * global.mmu_slot_spacing) " +echo >>{var.output} "if var.slot_position > global.mmu_selector_axis_max" +echo >>{var.output} " abort ""Selected Slot "" ^ param.S ^ "" would move selector beyond its length of "" ^ global.mmu_selector_axis_max ^ ""!""" +echo >>{var.output} "set global.mmu_selector_pos = param.S" +echo >>{var.output} "G92 " ^ global.mmu_selector_axis ^ "{move.axes[var.axis].userPosition}" +echo >>{var.output} "G1 F18000 " ^ global.mmu_selector_axis ^ "{var.slot_position}" +echo >>{var.output} "M84 " ^ global.mmu_selector_axis +echo >>{var.output} "M98 P""mmu/lib/save-selector-state.g""" +echo >>{var.output} "M98 P""mmu/lib/filament-runout.g""" +echo >>{var.output} "M584 P{#move.axes - 2} ; hide MMU axes" + +; generated/unload-selector.g +set var.output = "mmu/lib/generated/unload-selector.g" + +echo >{var.output} "; THIS FILE IS AUTO-GENERATED!!! Do not edit, your changes WILL be overwritten next time you run mmu/generate.g again!" +echo >>{var.output} "M98 R1" +echo >>{var.output} "if state.macroRestarted" +echo >>{var.output} " if !global.mmu_extruder_loaded" +echo >>{var.output} " if state.status == ""processing""" +echo >>{var.output} " M291 P{""Filament not yet loaded: T"" ^ global.mmu_selector_pos} R""Load Filament"" S1 T0" +echo >>{var.output} " M98 R1" +echo >>{var.output} " M226" +echo >>{var.output} " M99" +echo >>{var.output} "M98 P""mmu/lib/engage.g""" +echo >>{var.output} "M98 P""mmu/lib/generated/free-endstop.g""" +echo >>{var.output} "M584 P{#move.axes} ; allow operating on MMU axes" +echo >>{var.output} "G91" +echo >>{var.output} "M574 S1 " ^ global.mmu_extruder_axis ^ "2" ^ " P""!" ^ global.mmu_filament_sensor_pin ^ """" +echo >>{var.output} "M208 S1 " ^ global.mmu_extruder_axis ^ "-9999" +echo >>{var.output} "M208 S0 " ^ global.mmu_extruder_axis ^ "9999" +;echo >>{var.output} "G1 F" ^ global.mmu_extruder_fast_speed ^ " " ^ global.mmu_extruder_axis ^ "-10" +;echo >>{var.output} "G1 F" ^ global.mmu_extruder_fast_speed ^ " " ^ global.mmu_extruder_axis ^ "-30 E30" +echo >>{var.output} "G1 H1 F" ^ global.mmu_extruder_fast_speed ^ " " ^ global.mmu_extruder_axis ^ -7000 +echo >>{var.output} "G1 F6000 " ^ global.mmu_extruder_axis ^ -15 +echo >>{var.output} "M98 P""mmu/lib/assert-endstop.g""" +echo >>{var.output} "M574 S1 " ^ global.mmu_extruder_axis ^ 0 +echo >>{var.output} "M400" +echo >>{var.output} "G92 " ^ global.mmu_extruder_axis ^ 0 +echo >>{var.output} "M84 " ^ global.mmu_extruder_axis +echo >>{var.output} "M98 P""mmu/lib/disengage.g""" +echo >>{var.output} "set global.mmu_extruder_loaded = false" +echo >>{var.output} "M98 P""mmu/lib/save-selector-state.g""" +echo >>{var.output} "M584 P{#move.axes - 2}" \ No newline at end of file diff --git a/mmu/lib/assert-empty.g b/mmu/lib/assert-empty.g new file mode 100644 index 0000000..901846e --- /dev/null +++ b/mmu/lib/assert-empty.g @@ -0,0 +1,6 @@ +; checks if the selector is empty and not currently resting on its endstop. +M98 P"mmu/lib/check-endstop.g" A{global.mmu_selector_axis} +M98 P"mmu/lib/check-endstop.g" A{global.mmu_extruder_axis} + +if #sensors.gpIn > global.mmu_selector_trigger && sensors.gpIn[global.mmu_selector_trigger] != null && sensors.gpIn[global.mmu_selector_trigger].value == 0 + abort "Filament is loaded into selector" \ No newline at end of file diff --git a/mmu/lib/assert-endstop.g b/mmu/lib/assert-endstop.g new file mode 100644 index 0000000..ca16099 --- /dev/null +++ b/mmu/lib/assert-endstop.g @@ -0,0 +1,33 @@ +M98 R1 + +if state.macroRestarted + if !global.mmu_extruder_loaded + if state.status == "processing" + M291 P{"Restarted: Filament not yet loaded: T" ^ global.mmu_selector_pos} R"Load Filament" S1 T0 + M98 R1 + M226 + M99 +var eAxis = -1 + +while var.eAxis == -1 && iterations < #move.axes + if iterations >= #move.axes + break + if move.axes[iterations].letter == global.mmu_extruder_axis + set var.eAxis = iterations + +if var.eAxis == -1 + abort "Cannot find endstop axis: " ^ var.eAxis + +var gpTriggered = #sensors.gpIn > global.mmu_selector_trigger && sensors.gpIn[global.mmu_selector_trigger] != null && sensors.gpIn[global.mmu_selector_trigger].value != 0 +;var sAxisTriggered = sensors.endstops[var.sAxis] != null && !sensors.endstops[var.sAxis].triggered +var eAxisTriggered = sensors.endstops[var.eAxis] != null && !sensors.endstops[var.eAxis].triggered +;echo "gpTriggered: " ^ var.gpTriggered ^ ", sAxisTriggered: " ^ var.sAxisTriggered ^ ", eAxisTriggered: " ^ var.eAxisTriggered ^ "." +if var.gpTriggered || var.eAxisTriggered + var errmsg = "Filament not yet unloaded: T" ^ global.mmu_selector_pos + echo var.errmsg + if state.status == "processing" + M291 P{var.errmsg} R"Load Filament" S1 T0 + M98 R1 + M226 + else + abort "Selector/Filament endstop is is not triggered" diff --git a/mmu/lib/assert-selector-loaded.g b/mmu/lib/assert-selector-loaded.g new file mode 100644 index 0000000..6f3b068 --- /dev/null +++ b/mmu/lib/assert-selector-loaded.g @@ -0,0 +1,25 @@ +M98 R1 + +var eAxis = -1 + +while var.eAxis == -1 && iterations < #move.axes + if iterations >= #move.axes + break + if move.axes[iterations].letter == global.mmu_extruder_axis + set var.eAxis = iterations + +if var.eAxis == -1 + abort "Cannot find endstop axis: " ^ var.eAxis + +var eAxisTriggered = sensors.endstops[var.eAxis] != null && sensors.endstops[var.eAxis].triggered +if !var.eAxisTriggered + M98 P"mmu/lib/disengage.g" ; disengage the selector so that filament can be pushed in. + var errmsg = "Expected selector to be loaded but it's not!" + echo var.errmsg + if state.status == "processing" + M291 P{var.errmsg} R"Check Selector and click continue to try again." S2 + M98 R1 + M226 + else + abort "Selector/Filament endstop is is not triggered" +M98 P"mmu/lib/engage.g" diff --git a/mmu/lib/check-endstop.g b/mmu/lib/check-endstop.g new file mode 100644 index 0000000..ad87c5d --- /dev/null +++ b/mmu/lib/check-endstop.g @@ -0,0 +1,17 @@ +var axis = -1 + +if !exists(param.A) + abort "(A)xis not specified for check-endstop.g" + + +while var.axis == -1 && iterations < #move.axes + if iterations >= #move.axes + break + if move.axes[iterations].letter == param.A + set var.axis = iterations + +if var.axis == -1 + abort "Cannot find endstop axis: " ^ param.A + +if sensors.endstops[var.axis] != null && sensors.endstops[var.axis].triggered + abort "Selector/Filament endstop is already triggered" \ No newline at end of file diff --git a/mmu/lib/disengage.g b/mmu/lib/disengage.g new file mode 100644 index 0000000..86a9a44 --- /dev/null +++ b/mmu/lib/disengage.g @@ -0,0 +1,7 @@ +M280 P{global.mmu_servo_num} S{global.mmu_servo_disengage} +G4 P200 +M400 +; servo off disabled due to truncated final pulse issue +; https://forum.duet3d.com/topic/32172/turning-off-servos-and-m42-interrupting-the-last-pulse +;M42 P{global.mmu_servo_num} S0 +set global.mmu_servo_engaged = false diff --git a/mmu/lib/engage.g b/mmu/lib/engage.g new file mode 100644 index 0000000..ab19546 --- /dev/null +++ b/mmu/lib/engage.g @@ -0,0 +1,10 @@ +if !global.mmu_servo_engaged + M280 P{global.mmu_servo_num} S{global.mmu_servo_engage} + G4 P200 + ;M98 P"mmu/lib/generated/buzz.g" + M400 + ; servo off disabled due to truncated final pulse issue + ; https://forum.duet3d.com/topic/32172/turning-off-servos-and-m42-interrupting-the-last-pulse + ;M42 P{global.mmu_servo_num} S0 + +set global.mmu_servo_engaged = true diff --git a/mmu/lib/filament-runout.g b/mmu/lib/filament-runout.g new file mode 100644 index 0000000..c47bccf --- /dev/null +++ b/mmu/lib/filament-runout.g @@ -0,0 +1,10 @@ +M98 P"mmu/lib/generated/free-endstop.g" + +M950 J{global.mmu_selector_trigger} C{global.mmu_filament_sensor_pin} +M581 T{global.mmu_selector_trigger} P{global.mmu_selector_trigger} + +;echo >{"trigger" ^ global.mmu_selector_trigger ^ ".g"} "if state.status == ""processing""" +;echo >>{"trigger" ^ global.mmu_selector_trigger ^ ".g"} " M291 P""Selector sensor triggered"" R""Pause"" T5 S1" +;echo >>{"trigger" ^ global.mmu_selector_trigger ^ ".g"} " M25" +;echo >>{"trigger" ^ global.mmu_selector_trigger ^ ".g"} "else" +;echo >>{"trigger" ^ global.mmu_selector_trigger ^ ".g"} " echo ""Selector sensor triggered""" diff --git a/mmu/lib/globals.g b/mmu/lib/globals.g new file mode 100644 index 0000000..1cef742 --- /dev/null +++ b/mmu/lib/globals.g @@ -0,0 +1,65 @@ +; global declarations, some relatively sane defaults included +; value overrides should go in mmu/settings.g +if !exists(global.mmu_settings_loaded) + ; + ; general settings + ; + global mmu_bowden_length = 525 + global mmu_sensor_extruder_gears_length = 43 + global mmu_extruder_to_park_length = 56 + global mmu_tool_number = 0 + ; + ; selector axis settings + ; + global mmu_selector_axis = "U" + global mmu_selector_endstop_pin = "ystop" + global mmu_filament_sensor_pin = "xstop" + global mmu_selector_current = 750 + global mmu_selector_steps = 80 + global mmu_selector_microsteps = 16 + global mmu_selector_accel = 2000 + global mmu_selector_axis_min = 0 + global mmu_selector_axis_max = 200 + ; + ; filament drive settings + ; + global mmu_extruder_axis = "V" + global mmu_extruder_current = 565 + global mmu_extruder_steps = 415 + global mmu_extruder_microsteps = 16 + global mmu_extruder_accel = 600 + global mmu_extruder_gear_diameter = 7.35 + ; calculated as gear bottom to stopping location + ; this should be where the filament can be moved while cold + global mmu_extruder_park = 40 + global mmu_extruder_retract_park = 35 + global mmu_extruder_load_speed = 300 + global mmu_extruder_slow_speed = 1200 + global mmu_extruder_fast_speed = 2400 + ; + ; selector servo settings + ; + global mmu_servo_pin = "exp.heater3" + global mmu_servo_num = 0 + global mmu_servo_disengage = 100 + global mmu_servo_engage = 0 + + global mmu_slot_spacing = 17.4 + ; + ; filament sensor settings + ; + global mmu_encoder_pin = "e0stop" + global mmu_encoder_trigger = 2 + global mmu_selector_trigger = 3 + global mmu_pulse_distance = 1.415 + ; + ; DO NOT EDIT + ; non-configurable system state variables + ; + global mmu_pulse_count = 0 + global mmu_extruder_loaded = false + global mmu_tmp_file = "mmu/lib/tmp.g" + global mmu_selector_file = "mmu/lib/selector-state.g" + global mmu_selector_pos = -1 + global mmu_servo_engaged = false + global mmu_settings_loaded = true diff --git a/mmu/lib/load-tool.g b/mmu/lib/load-tool.g new file mode 100644 index 0000000..47101ff --- /dev/null +++ b/mmu/lib/load-tool.g @@ -0,0 +1,21 @@ +; this loads the provided tool. Syntax: M98 P"mmu/lib/load-tool.g" T +M98 R1 ; allow this macro to be paused. +if global.mmu_selector_pos == -1 && (!exists(param.H) || param.H != 1) + abort "Home selector first" + +if !exists(param.T) + abort "No Tool selected" + +if global.mmu_selector_pos == param.T && global.mmu_extruder_loaded ; if we are already on the selected Tool AND the filament is already marked as loaded + echo {"Filament already loaded into tool " ^ param.T} + M99 ; End Macro here, equivalent to "return" in Java + +echo "Switching to T" ^ param.T + +if global.mmu_extruder_loaded ; if we still have filament loaded, unload first. + M98 P"mmu/lib/unload.g" + +if !global.mmu_extruder_loaded ; check if we are unloaded now. Then: + M98 P"mmu/lib/generated/home.g" ; rehome to prevent compounding drift. + M98 P"mmu/lib/generated/select.g" S{param.T} ; Move to new position... + M98 P"mmu/lib/generated/load.g" ; and load filament from the new position. \ No newline at end of file diff --git a/mmu/lib/save-selector-state.g b/mmu/lib/save-selector-state.g new file mode 100644 index 0000000..34a0abf --- /dev/null +++ b/mmu/lib/save-selector-state.g @@ -0,0 +1,3 @@ +echo >{global.mmu_selector_file} "; AUTOGENERATED FILE DO NOT EDIT" +echo >>{global.mmu_selector_file} "set global.mmu_selector_pos = " ^ global.mmu_selector_pos +echo >>{global.mmu_selector_file} "set global.mmu_extruder_loaded = " ^ global.mmu_extruder_loaded diff --git a/mmu/lib/selector-state.g b/mmu/lib/selector-state.g new file mode 100644 index 0000000..eebf56e --- /dev/null +++ b/mmu/lib/selector-state.g @@ -0,0 +1,3 @@ +; AUTOGENERATED FILE DO NOT EDIT +set global.mmu_selector_pos = 0 +set global.mmu_extruder_loaded = true diff --git a/mmu/lib/unload.g b/mmu/lib/unload.g new file mode 100644 index 0000000..f3e0492 --- /dev/null +++ b/mmu/lib/unload.g @@ -0,0 +1,29 @@ +M98 R1 ; allow pausing of this macro + +if state.macroRestarted + if global.mmu_extruder_loaded + if state.status == "processing" + var errmsg = "Restarted Filament not yet unloaded: T" ^ global.mmu_selector_pos + echo var.errmsg + M291 P{var.errmsg} "Unload Filament" S1 T0 + M98 R1 + M226 + else + M99 + +if !exists(param.F) && !global.mmu_extruder_loaded && global.mmu_selector_pos != -1 + echo "Filament is not loaded" + M99 + + +T{global.mmu_tool_number} ; Select the currently active tool. +M302 P1 ; allow cold extrusion -- Questionable! +G1 E{-(10 + global.mmu_extruder_gear_diameter + global.mmu_extruder_park)} F{global.mmu_extruder_slow_speed} +M302 P0 + +M98 P"mmu/lib/generated/unload-selector.g" +set global.mmu_extruder_loaded = false +M98 P"mmu/lib/save-selector-state.g" +M98 P"mmu/lib/disengage.g" +G90 +M98 P"mmu/lib/filament-runout.g" diff --git a/mmu/settings.g b/mmu/settings.g new file mode 100644 index 0000000..0cc99b6 --- /dev/null +++ b/mmu/settings.g @@ -0,0 +1,33 @@ +; configure drivers and toolboard +M569 P124.0 S0 ; +M569 P124.1 S1 +M584 B124.1 ; run the selector on axis B +M584 A124.0 R0 S0 P3 ; run the extruder on axis A. These axis assignments are arbitrary and only are required to not be used by anything else. + +set global.mmu_selector_axis = "B" +set global.mmu_extruder_axis = "A" + +set global.mmu_bowden_length = 1580 ; overall distance between the selector catchpoint and the extruder gear catchpoint. +global mmu_extruder_nozzle_length = 50 ; distance between the extruder gear catchpoint and the nozzle. +global mmu_extruder_sensor_length = 55 ; distance between the extruder's filament sensor and the extruder gears. +global mmu_selector_sensor_length = 50 ; distance between the selector's filament sensor and the catchpoint for unloaded filaments. +set global.mmu_extruder_gear_diameter = 7.3 ; bmg filament gear diameter +set global.mmu_extruder_steps = 205 +set global.mmu_extruder_microsteps = 8 +set global.mmu_extruder_accel = 100 +set global.mmu_selector_accel = 100 +set global.mmu_extruder_slow_speed = 2400 +set global.mmu_extruder_fast_speed = 7000 +set global.mmu_extruder_load_speed = 1200 +set global.mmu_extruder_current = 1000 +set global.mmu_selector_current = 565 +set global.mmu_extruder_park = 70 +set global.mmu_selector_endstop_pin = "^124.io1.in" +set global.mmu_filament_sensor_pin = "^124.io0.in" +global mmu_extruder_runout_pin = "^io5.in" +set global.mmu_servo_num = 1 +set global.mmu_servo_pin = "124.rgbled" + + +set global.mmu_selector_axis_max = 270 ; measured, dependant on the number of lanes you have. I have 16 +set global.mmu_servo_disengage = 145 ; measured with the down angle tool. engage is at 0° \ No newline at end of file