Voron Trident Bambu-style nozzle wiper, modified with servo-driven baffle
Print Profile(1)

Description
A version of Big Horse's nozzle wiper has been modified to use a servo to drive the baffle up and down, which eliminates the need to print TPU parts. It is also no longer limited by printhead type (actually, the main point is no longer having to use the toolhead to hit the push rod; I've broken five push rods). For the complete nozzle wiper model, get it from Big Horse's Bilibili channel: https://www.bilibili.com/video/BV1nPWZzuE9g. You no longer need to print the push rod; you only need to print the waste bucket and the baffle.

Also, I'm providing a gcode for Rabbit Multi-color adapted from this nozzle wiper model. Note that you need to modify the parameters. It mainly has the following functions:
- Servo adaptation
- Supports Rabbit Multi-color to pass in extrusion length
- Pulse extrusion
Rabbit Multi-color modifies mmu/base/mmu_parameters.cfg
force_purge_standalone: 1 # 0 = Slicer wipetower in print else standalone, 1 = Always standalone purging (TURN WIPETOWER OFF!)
purge_macro: WIPE_NOZZLE # Name of macro to call to perform the standalone purging operation. E.g. BLOBIFIER, _MMU_PURGE
extruder_purge_current: 120 # % of extruder current (100%-150%) to use when purging (100 to disable)
wipe_nozzle.cfg
[servo nozzle]
pin: PA14
minimum_pulse_width: 0.0005
maximum_pulse_width: 0.0024
maximum_servo_angle: 180
initial_angle: 0[gcode_macro WIPE_CONFIG]
# This macro is only for storing parameters, not for executing any G-code
# Please configure the following parameters
variable_ptfe_x: 239 # X-coordinate for purging waste
variable_ptfe_y: 310 # Y-coordinate for purging waste
variable_wipe_x: 250 # Nozzle wipe X-coordinate
variable_wipe_y: 310 # Nozzle wipe Y-coordinatevariable_servo_angle_default: 0 # Servo default angle
variable_servo_angle_wipe: 90 # Servo angle for raising baffle# Extrusion length calculation parameters ported from Blobifier. The default is fine; if you think the extrusion is too much or too little, adjust variable_purge_length_modifier
variable_purge_length_minimum: 30 # Minimum purge length (mm), ensures purge_len is not less than this value
variable_purge_length: 150 # Default purge length (mm), used when there is no slicer mapping
variable_purge_length_modifier: 1 # Switching volume correction factor, scales the purge volume provided by the slicer
variable_purge_length_addition: 0 # Additional compensation length (mm), added to the calculated purge length
variable_purge_spd: 400 # Pulse fast segment feed rate (F, mm/min)
variable_purge_temp_min: 200 # Minimum nozzle temperature (°C) before purging
variable_purge_pulse_mm: 5 # Target length per pulse (mm), determines the number of pulses
gcode:
# Deliberately left blank
[gcode_macro WIPE_NOZZLE]
description: Wipe nozzle for filament changegcode:
# ======================================================================================
# ==================== RECORD STATE (INCL. FANS, SPEEDS, ETC...) =======================
# ======================================================================================
SAVE_GCODE_STATE NAME=WIPE_NOZZLE_state
{% set cfg = printer["gcode_macro WIPE_CONFIG"] %}
{% set sequence_vars = printer['gcode_macro _MMU_SEQUENCE_VARS'] %}
{% set park_vars = printer['gcode_macro _MMU_PARK'] %}
# Save feed rate to restore later
{% set backup_feedrate = printer.gcode_move.speed_factor %}
# Set feed rate to 100% to ensure correct extrusion speed
M220 S100
# Save part cooling fan speed to restore later
{% set backup_fan_speed = printer.fan.speed %}
# ======================================================================================
# ==================== EXTRUSION LENGTH CALCULATION LOGIC ================================
# ======================================================================================
# Extrusion length calculation logic ported from Blobifier
{% set filament_diameter = printer.configfile.config.extruder.filament_diameter|float %}
{% set filament_cross_section = (filament_diameter/2) ** 2 * 3.1415 %}
{% set from_tool = printer.mmu.last_tool %}
{% set to_tool = printer.mmu.tool %}
# Get purge volume (if correct slicer is set)
{% set pv = printer.mmu.slicer_tool_map.purge_volumes %}
# Determine extrusion length
{% if from_tool == to_tool and to_tool >= 0 %}
{action_respond_info("WIPE_NOZZLE: Tool not changed (T%s > T%s), %s" % (from_tool, to_tool, "priming" if cfg.purge_length_minimum else "skipping"))}
{% set purge_len = 0 %}
{% elif pv %}
{% if from_tool < 0 and to_tool >= 0%}
{action_respond_info("WIPE_NOZZLE: Source tool unknown. Seeking max for T? > T%d" % to_tool)}
{% set purge_vol = pv|map(attribute=to_tool)|max %}
{% elif to_tool < 0 %}
{action_respond_info("WIPE_NOZZLE: Tool unknown. Seeking max")}
{% set purge_vol = pv|map('max')|max %}
{% else %}
{% set purge_vol = pv[from_tool][to_tool]|float * cfg.purge_length_modifier %}
{action_respond_info("WIPE_NOZZLE: Switching T%s > T%s" % (from_tool, to_tool))}
{% endif %}
{% set purge_len = purge_vol / filament_cross_section %}
{% set purge_len = purge_len + printer.mmu.extruder_filament_remaining + park_vars.retracted_length + cfg.purge_length_addition %}
{% else %}
{action_respond_info("WIPE_NOZZLE: No tool mapping. Using default value")}
{% set purge_len = cfg.purge_length|float + printer.mmu.extruder_filament_remaining + park_vars.retracted_length %}
{% endif %}
# Apply minimum extrusion length
{% set purge_len = [purge_len, cfg.purge_length_minimum]|max|round(0, 'ceil')|int %}
{action_respond_info("WIPE_NOZZLE: Extruding %dmm of filament" % (purge_len))}
# Skip if no extrusion is needed
{% if purge_len <= 0 %}
{action_respond_info("WIPE_NOZZLE: No extrusion needed, skipping")}
RESTORE_GCODE_STATE NAME=WIPE_NOZZLE_state
M99
{% endif %}
# Calculate extrusion per pulse
{% set pulses_count = (purge_len / cfg.purge_pulse_mm)|round(0, 'ceil')|int %}
{% set purge_per_pulse = purge_len / pulses_count %}G90 # All axes use absolute positioning
M83 # Extruder uses relative positioning##------0. Servo raises baffle
SET_SERVO SERVO=nozzle ANGLE={cfg.servo_angle_wipe | int} # Switch angle according to the passed parameter
G4 P500
SET_SERVO SERVO=nozzle WIDTH=0
##------1. Move to purge waste coordinates
G1 X{cfg.ptfe_x} Y{cfg.ptfe_y-50} F6000
M400
G1 X{cfg.ptfe_x} Y{cfg.ptfe_y} F6000
##------2. Heat nozzle to ensure sufficient temperature
{% if printer.extruder.temperature < cfg.purge_temp_min %}
{% if printer.extruder.target < cfg.purge_temp_min %}
M109 S{cfg.purge_temp_min}
{% else %}
TEMPERATURE_WAIT SENSOR=extruder MINIMUM={cfg.purge_temp_min}
{% endif %}
{% endif %}
##------3. Extrude filament using pulse method (ported from Blobifier)
G92 E0 # Reset extruder
{action_respond_info("WIPE_NOZZLE: Extruding with pulses, total %d pulses" % pulses_count)}
# Extrude with pulses
{% for pulse in range(pulses_count) %}
# Fast extrusion
G1 E{purge_per_pulse * 0.95} F{cfg.purge_spd}
# Slow extrusion
G1 E{purge_per_pulse * 0.05} F50
# Retract every 5 pulses for thorough cleaning
{% if pulse % 5 == 0 and pulse > 0 %}
G1 E-2 F1800
G1 E2 F800
{% endif %}
{% endfor %}##------4. Lower servo
SET_SERVO SERVO=nozzle ANGLE={cfg.servo_angle_default | int} # Switch angle according to the passed parameter
G4 P500
SET_SERVO SERVO=nozzle WIDTH=0
M106 S255 # Fan full on
G4 P4000 # Dwell P<milliseconds>
G1 Y{cfg.wipe_y} F3000
M400
##------5. Shake nozzle
{% for wipes in range(1, 7) %}
G1 X{cfg.ptfe_x+10} F15000
G1 X{cfg.ptfe_x-10} F15000
{% endfor %}##------6. Wipe nozzle
{% for wipes in range(1, 7) %}
G1 X{cfg.wipe_x + 10} F5000
G1 X{cfg.wipe_x - 10} F15000
{% endfor %}# G92 E0
M400
# ======================================================================================
# ==================== RESTORE STATE ===================================================
# ======================================================================================
# Retract to match Happy Hare's expectations
{action_respond_info("WIPE_NOZZLE: Final retract length: %d mm" % (park_vars.retracted_length))}
G1 E-{park_vars.retracted_length*0.9} F{sequence_vars.retract_speed * 60}
# Restore part cooling fan speed
M106 S{(backup_fan_speed * 255)|int}
# Restore feed rate
M220 S{(backup_feedrate * 100)|int}
# Restore G-code state
RESTORE_GCODE_STATE NAME=WIPE_NOZZLE_state





Comment & Rating (0)