Mit KI Ähnliches finden
Druckprofil(0)
Modelldatei(0)
Veröffentlicht:2026-02-27 01:54:08
0
0
Modification of blobifier for Sovol SV08
Build of Materials:
Instead of the aluminum plate as in the original project, I used a piece of PCB 1.6mm
The holder of the entire structure is attached to the plastic base of the bed with two M3 screws into the installed heat set inserts.
The module is easy to remove for maintenance (dovetail). An M3 screw can be used for fixing
When installing the pusher into the guides, press the wide part of the part and, twisting it along the axis, push it forward.
An additional MCU Pi Pico was used for connection. Instructions on how to install it are here.
If necessary, the tray can be extended by ~50mm
Below is an example of a macro for autonomous work, without HappyHare, MMU.
#######################################################################
# Конфигурация аппаратной части
#######################################################################
[servo blobifier_servo]
# Настройки сервопривода лотка Blobifier
pin: pico:gpio18 # GPIO пин подключения
minimum_pulse_width: 0.0005 # Минимальная ширина импульса (0.5мс)
maximum_pulse_width: 0.0025 # Максимальная ширина импульса (2.5мс)
maximum_servo_angle: 180 # Максимальный угол поворота (180°)
[gcode_button bucket]
# Конфигурация концевика ведра для блобов
pin: ^!pico:gpio19 # Пин с подтяжкой и инверсией
press_gcode:
M117 Bucket installed # Сообщение при установке
M118 "Bucket installed" # Дублируем в консоль
release_gcode:
M117 Bucket removed # Сообщение при извлечении
M118 "Bucket removed" # Дублируем в консоль
_BLOBIFIER_COUNT_RESET # Автосброс счетчика
#######################################################################
# Основные макросы
#######################################################################
[gcode_macro _BLOBIFIER_SAFE_DESCEND]
# Проверка безопасных зон для перемещений
description: Проверка свободных зон для работы Blobifier
variable_tray: True # Флаг безопасности лотка
variable_brush: True # Флаг безопасности щетки
variable_print_height: 0 # Текущая высота печати
variable_print_previous_height: 0 # Высота предыдущего слоя
variable_print_layer_height: 0.3 # Высота слоя по умолчанию
variable_first_layer: True # Флаг первого слоя
gcode:
# Инициализация переменных
{% set bl = printer['gcode_macro BLOBIFIER'] %}
{% set pos_max = printer.toolhead.axis_maximum %}
{% set position_y = pos_max.y - bl.skew_correction %}
# Сброс флагов безопасности
SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=tray VALUE=True
SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=brush VALUE=True
# Проверка коллизий с объектами печати
{% if printer.exclude_object.objects %}
M118 "Checking for objects in blob area..."
{% set tray_area = [bl.purge_x + bl.toolhead_x, position_y - bl.toolhead_y] %}
{% for obj in printer.exclude_object.objects %}
{% for point in obj.polygon %}
# Если объект в зоне лотка - помечаем как опасную
{% if point.x < tray_area[0] and point.y > tray_area[1] %}
SET_GCODE_VARIABLE MACRO=_BLOBIFIER_SAFE_DESCEND VARIABLE=tray VALUE=False
M118 WARNING: "Object detected in purge area!"
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
[gcode_macro BLOBIFIER]
# Главный макрос управления Blobifier
description: Основная процедура продувки и очистки сопла
variable_purge_spd: 300 # Скорость экструзии (мм/мин)
variable_purge_temp_min: 240 # Минимальная температура (°C)
variable_toolhead_x: 72 # Габариты инструмента по X (мм)
variable_toolhead_y: 50 # Габариты инструмента по Y (мм)
variable_brush_top: 4 # Рабочая высота щетки (мм)
variable_clearance_z: 10 # Безопасный зазор по Z (мм)
variable_wipe_qty: 2 # Количество проходов очистки
variable_travel_spd_xy: 10000 # Скорость перемещения XY (мм/мин)
variable_travel_spd_z: 1000 # Скорость перемещения Z (мм/мин)
variable_wipe_spd_xy: 6000 # Скорость очистки (мм/мин)
variable_brush_accel: 3000 # Ускорение при очистке (мм/с²)
variable_skew_correction: 0.1 # Коррекция перекоса (мм)
variable_brush_start: 153 # Позиция щетки по X (мм)
variable_brush_width: 35 # Ширина щетки (мм)
variable_purge_x: 22 # Позиция продувки по X (мм)
variable_tray_top: 2.8 # Высота лотка (мм)
variable_tray_angle_out: 0 # Угол сервы (лоток выдвинут)
variable_tray_angle_in: 180 # Угол сервы (лоток задвинут)
variable_purge_start: 0.2 # Стартовая высота продувки (мм)
variable_z_raise: 10 # Подъем при продувке (мм)
variable_eject_hop: 10 # Подъем после выброса (мм)
variable_pressure_release_time: 1000 # Время сброса давления (мс)
variable_part_cooling_fan: 1 # Скорость охлаждения (0-1)
variable_purge_length_minimum: 20# Минимальная продувка (мм)
variable_purge_length: 100 # Стандартная продувка (мм)
variable_max_blobs: 400 # Лимит блобов в ведре
variable_delay_ms: 200 # Задержка сервы (мс)
variable_z_raise_exp: 0.85 # Экспонента уменьшения подъема
variable_purge_length_maximum: 150 # Максимум на один блоб
variable_purge_length_modifier: 0.6 # Модификатор длины продувки
variable_purge_length_addition: 0 # Дополнительная длина продувки
#variable_part_cooling_fan: 0.3 # Для PLA/PETG (30% скорости)
variable_part_cooling_fan: 0.1 # Для ABS/ASA (10% скорости)
# variable_part_cooling_fan: -1 # Не управлять вентилятором
gcode:
# Сохраняем текущее состояние принтера
SAVE_GCODE_STATE NAME=BLOBIFIER_state
# Определяем перменную длины экструзии
{% set purge_len = params.PURGE_LENGTH|default(purge_length)|float %}
{% set purge_len = [purge_len, purge_length_minimum]|max %}
{% if purge_len > 0 %}
# Сохраняем состояние вентилятора
{% if part_cooling_fan >= 0 %}
{% set backup_fan = printer.fan.speed %}
M118 Saved fan speed: {(backup_fan * 100)|round(1)}%
{% endif %}
M117 Blobifier started
M118 Blobifier process started
# Автоматический HOME при необходимости
{% if "xyz" not in printer.toolhead.homed_axes %}
M118 Auto-homing axes...
M117 Homing axes...
G28
M118 "Homing complete"
{% endif %}
# Получаем статус безопасных зон
{% set safe = printer['gcode_macro _BLOBIFIER_SAFE_DESCEND'] %}
{% set ignore_safe = safe.print_height|float < clearance_z|float %}
# Проверка безопасности лотка
{% if safe.tray or ignore_safe %}
M118 Extending purge tray...
M117 Extending tray
BLOBIFIER_SERVO POS=out
G1 Z{tray_top + purge_start} F{travel_spd_z}
M118 Ready to purge
M117 Ready to purge
{% else %}
M118 ERROR: Purge area not safe! Aborting
M117 Purge area blocked!
RESTORE_GCODE_STATE NAME=BLOBIFIER_state
RETURN
{% endif %}
# 1. Определение температуры продувки
# Пытаемся получить температуру напрямую из переменной слайсера
{% set target_temp = params.EXTRUDER_TEMP|default(purge_temp_min)|float %}
# Принудительная проверка минимальной температуры
{% if target_temp < purge_temp_min %}
{% set target_temp = purge_temp_min %}
M118 WARNING: Temperature too low! Using minimum {purge_temp_min}°C
{% endif %}
# 2. Прогрев экструдера (исправленная логика)
{% if printer.extruder.temperature < target_temp %}
M118 Heating to {target_temp}°C...
M117 Heating to {target_temp}°C
M109 S{target_temp} # Ждем достижения температуры
{% else %}
M118 Temperature OK: {printer.extruder.temperature}°C
{% endif %}
# Перемещение в позицию продувки
LCD_WHITE #MOD LCD cleaning color
M118 Moving to purge position...
M117 Moving to position
G90
G1 Z10
G1 X{purge_x} Y{printer.toolhead.axis_maximum.y - skew_correction} F{travel_spd_xy}
#включение вентилятора перед экструзией (только если есть продувка)
{% if purge_len > 0 and part_cooling_fan >= 0 %}
M118 Enabling cooling at {(part_cooling_fan * 100)|int}%
M106 S{part_cooling_fan * 255}
G4 P500 # Пауза для раскрутки вентилятора
{% endif %}
# Выдвижение лотка с проверкой безопасности
{% if safe.tray or ignore_safe %}
M118 Extending purge tray...
M117 Extending tray
BLOBIFIER_SERVO POS=out
G1 Z{tray_top + purge_start} F{travel_spd_z}
M118 Ready to purge
M117 Ready to purge
{% else %}
M118 ERROR: "Purge area not safe! Aborting"
M117 Purge area blocked!
RESTORE_GCODE_STATE NAME=BLOBIFIER_state
RETURN
{% endif %}
# Расчет параметров пульсации
{% set purge_per_blob = purge_len|float %}
{% set retracts_per_blob = (purge_per_blob / 40)|round(0, 'ceil')|int %}
{% set purge_per_retract = (purge_per_blob / retracts_per_blob)|int %}
{% set pulses_per_blob = (purge_per_blob / retracts_per_blob / 5)|round(0, 'ceil')|int %}
{% set purge_per_pulse = purge_per_blob / pulses_per_blob %}
{% set pulse_time_constant = purge_per_pulse * 0.95 / purge_spd / (purge_per_pulse * 0.95 / purge_spd + purge_per_pulse * 0.05 / 50) %}
{% set pulse_duration = purge_per_pulse / purge_spd %}
# Переход в относительные координаты
G91
M83
# Пульсирующая экструзия с динамическим Z
{% for pulse in range(pulses_per_blob) %}
{% set purged_this_blob = pulse * purge_per_pulse %}
{% set z_last_pos = purge_start + ((purged_this_blob)/purge_per_blob)**z_raise_exp * z_raise %}
{% set z_pos = purge_start + ((purged_this_blob + purge_per_pulse)/purge_per_blob)**z_raise_exp * z_raise %}
{% set z_up = z_pos - z_last_pos %}
{% set speed = z_up / pulse_duration %}
# Быстрая фаза (95% подачи)
G1 Z{z_up * pulse_time_constant} E{purge_per_pulse * 0.95} F{speed}
# Медленная фаза (5% подачи)
G1 Z{z_up * (1 - pulse_time_constant)} E{purge_per_pulse * 0.05} F{speed}
# Периодическая ретракция
{% if pulse % retracts_per_blob == 0 and pulse > 0 %}
G1 E-2 F1800
G1 E2 F800
{% endif %}
{% endfor %}
# Плавное выключение вентилятора после продувки
{% if part_cooling_fan >= 0 %}
{% for i in range(100, 0, -5) %}
M106 S{(i/100 * part_cooling_fan * 255)|int}
G4 P50
{% endfor %}
M106 S0
{% endif %}
# Возврат в абсолютные координаты
G90
M82
# Формирование и сброс блоба
M118 Forming blob...
M117 Forming blob
BLOBIFIER_SERVO POS=in
G1 Z{tray_top} F{travel_spd_z}
BLOBIFIER_SERVO POS=out
BLOBIFIER_SERVO POS=in
BLOBIFIER_SERVO POS=out
# Восстановление исходного состояния вентилятора
{% if part_cooling_fan >= 0 %}
M118 Restoring original fan speed
M106 S{(backup_fan * 255)|int}
{% endif %}
# Учет блобов и проверка заполненности
_BLOBIFIER_COUNT
{% endif %}
# Завершающие операции
M118 Finishing operations...
M117 Finishing...
G1 Z{tray_top + eject_hop} F{travel_spd_z}
G4 P{pressure_release_time}
# Очистка сопла если безопасно
{% if safe.brush or ignore_safe %}
BLOBIFIER_CLEAN
{% else %}
M118 Moving to safe position
M117 Moving to safe XY
G1 X{brush_start} F{travel_spd_xy}
{% endif %}
# Восстановление состояния
M118 Blobifier process complete
M117 Blobifier done
RESTORE_GCODE_STATE NAME=BLOBIFIER_state
[gcode_macro BLOBIFIER_CLEAN]
description: Процедура очистки сопла о щетку
gcode:
# Получаем конфигурацию
{% set cfg = printer["gcode_macro BLOBIFIER"] %}
{% set position_y = printer.configfile.config["stepper_y"]["position_max"]|float %}
M118 Starting nozzle cleaning...
M117 Nozzle cleaning
SAVE_GCODE_STATE NAME=BLOBIFIER_CLEAN_state
# Установка ускорения для очистки
{% if cfg.brush_accel > 0 %}
{% set original_accel = printer.toolhead.max_accel %}
SET_VELOCITY_LIMIT ACCEL={cfg.brush_accel}
{% endif %}
# Подготовка к очистке
G90
M118 Positioning for cleaning...
M117 Positioning...
G1 Z{cfg.brush_top + cfg.clearance_z} F{cfg.travel_spd_z}
G1 X{cfg.brush_start} F{cfg.travel_spd_xy}
G1 Y{position_y} F{cfg.travel_spd_xy}
# Процесс очистки
M118 Cleaning nozzle...
M117 Cleaning passes...
G1 Z{cfg.brush_top} F{cfg.travel_spd_z}
{% for wipe in range(1, cfg.wipe_qty + 1) %}
G1 X{cfg.brush_start + cfg.brush_width} F{cfg.wipe_spd_xy}
G1 X{cfg.brush_start} F{cfg.wipe_spd_xy}
{% endfor %}
# Завершение
M118 Raising nozzle...
M117 Raising nozzle
G1 X140 Z10 F{cfg.travel_spd_z} # Подъем на 10мм
# Восстановление ускорения
{% if cfg.brush_accel > 0 %}
SET_VELOCITY_LIMIT ACCEL={original_accel}
{% endif %}
M118 Nozzle cleaning complete
M117 Cleaning done
RESTORE_GCODE_STATE NAME=BLOBIFIER_CLEAN_state
[gcode_macro BLOBIFIER_SERVO]
description: Управление сервоприводом лотка
variable_delay_ms: 200 # Задержка после движения (мс)
gcode:
# Получаем настройки
{% set BL = printer["gcode_macro BLOBIFIER"] %}
{% set delay = BL.delay_ms if 'delay_ms' in BL else 200 %}
# Обработка команд
{% if params.POS|lower == "in" %}
M118 Retracting purge tray...
M117 Tray IN
SET_SERVO SERVO=blobifier_servo ANGLE={BL.tray_angle_in}
G4 P{delay|int}
{% elif params.POS|lower == "out" %}
M118 Extending purge tray...
M117 Tray OUT
SET_SERVO SERVO=blobifier_servo ANGLE={BL.tray_angle_out}
G4 P{delay|int}
{% else %}
M118 ERROR: "Invalid POS parameter! Use 'in' or 'out'"
M117 Invalid POS command!
{% endif %}
# Отключение сервопривода
SET_SERVO SERVO=blobifier_servo WIDTH=0
[gcode_macro _BLOBIFIER_COUNT]
description: Счетчик блобов в ведре
variable_current_blobs: 0 # Текущее количество
gcode:
M118 DEBUG: Current blobs before: {current_blobs}
{% set new_count = current_blobs + 1 %}
# Проверка заполненности
{% if new_count >= printer['gcode_macro BLOBIFIER'].max_blobs %}
M118 WARNING: Bucket is full! Pausing print.
M117 Bucket FULL! Pausing
PAUSE
{% else %}
SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE={new_count}
M118 "Blob count: {new_count}/{printer['gcode_macro BLOBIFIER'].max_blobs}"
M117 Blobs: {new_count}/{printer['gcode_macro BLOBIFIER'].max_blobs}
{% endif %}
M118 DEBUG: New count: {new_count}
[gcode_macro _BLOBIFIER_COUNT_RESET]
description: Сброс счетчика блобов
gcode:
SET_GCODE_VARIABLE MACRO=_BLOBIFIER_COUNT VARIABLE=current_blobs VALUE=0
M118 "Blob counter reset"
M117 Blob counter reset
[exclude_object]
[delayed_gcode BLOBIFIER_INIT]
# Инициализация при запуске
initial_duration: 10 # Задержка 10 сек после старта
gcode:
# Устанавливаем сервопривод в среднее положение
SET_SERVO SERVO=blobifier_servo ANGLE=90
# Отключаем сервопривод
SET_SERVO SERVO=blobifier_servo WIDTH=0
