|
@ -49,10 +49,14 @@ |
|
|
bool toolchange_extruder_ready[EXTRUDERS]; |
|
|
bool toolchange_extruder_ready[EXTRUDERS]; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if ENABLED(MAGNETIC_PARKING_EXTRUDER) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0) |
|
|
#if EITHER(MAGNETIC_PARKING_EXTRUDER, TOOL_SENSOR) || defined(EVENT_GCODE_AFTER_TOOLCHANGE) || (ENABLED(PARKING_EXTRUDER) && PARKING_EXTRUDER_SOLENOIDS_DELAY > 0) |
|
|
#include "../gcode/gcode.h" |
|
|
#include "../gcode/gcode.h" |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(TOOL_SENSOR) |
|
|
|
|
|
#include "../lcd/marlinui.h" |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
#if ENABLED(DUAL_X_CARRIAGE) |
|
|
#if ENABLED(DUAL_X_CARRIAGE) |
|
|
#include "stepper.h" |
|
|
#include "stepper.h" |
|
|
#endif |
|
|
#endif |
|
@ -147,11 +151,11 @@ |
|
|
|
|
|
|
|
|
#endif // SWITCHING_NOZZLE
|
|
|
#endif // SWITCHING_NOZZLE
|
|
|
|
|
|
|
|
|
inline void _line_to_current(const AxisEnum fr_axis, const float fscale=1) { |
|
|
void _line_to_current(const AxisEnum fr_axis, const float fscale=1) { |
|
|
line_to_current_position(planner.settings.max_feedrate_mm_s[fr_axis] * fscale); |
|
|
line_to_current_position(planner.settings.max_feedrate_mm_s[fr_axis] * fscale); |
|
|
} |
|
|
} |
|
|
inline void slow_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.5f); } |
|
|
void slow_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.2f); } |
|
|
inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis); } |
|
|
void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.5f); } |
|
|
|
|
|
|
|
|
#if ENABLED(MAGNETIC_PARKING_EXTRUDER) |
|
|
#if ENABLED(MAGNETIC_PARKING_EXTRUDER) |
|
|
|
|
|
|
|
@ -370,7 +374,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
DEBUG_POS("PE Tool-Change done.", current_position); |
|
|
DEBUG_POS("PE Tool-Change done.", current_position); |
|
|
parking_extruder_set_parked(false); |
|
|
parking_extruder_set_parked(false); |
|
|
} |
|
|
} |
|
|
else if (do_solenoid_activation) { // && nomove == true
|
|
|
else if (do_solenoid_activation) { |
|
|
// Deactivate current extruder solenoid
|
|
|
// Deactivate current extruder solenoid
|
|
|
pe_solenoid_set_pin_state(active_extruder, !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE); |
|
|
pe_solenoid_set_pin_state(active_extruder, !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE); |
|
|
// Engage new extruder magnetic field
|
|
|
// Engage new extruder magnetic field
|
|
@ -384,12 +388,117 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
|
|
|
|
|
|
#if ENABLED(SWITCHING_TOOLHEAD) |
|
|
#if ENABLED(SWITCHING_TOOLHEAD) |
|
|
|
|
|
|
|
|
inline void swt_lock(const bool locked=true) { |
|
|
// Return a bitmask of tool sensor states
|
|
|
|
|
|
inline uint8_t poll_tool_sensor_pins() { |
|
|
|
|
|
return (0 |
|
|
|
|
|
#if ENABLED(TOOL_SENSOR) |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR1) |
|
|
|
|
|
| (READ(TOOL_SENSOR1_PIN) << 0) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR2) |
|
|
|
|
|
| (READ(TOOL_SENSOR2_PIN) << 1) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR3) |
|
|
|
|
|
| (READ(TOOL_SENSOR3_PIN) << 2) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR4) |
|
|
|
|
|
| (READ(TOOL_SENSOR4_PIN) << 3) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR5) |
|
|
|
|
|
| (READ(TOOL_SENSOR5_PIN) << 4) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR6) |
|
|
|
|
|
| (READ(TOOL_SENSOR6_PIN) << 5) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR7) |
|
|
|
|
|
| (READ(TOOL_SENSOR7_PIN) << 6) |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR8) |
|
|
|
|
|
| (READ(TOOL_SENSOR8_PIN) << 7) |
|
|
|
|
|
#endif |
|
|
|
|
|
#endif |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(TOOL_SENSOR) |
|
|
|
|
|
|
|
|
|
|
|
bool tool_sensor_disabled; // = false
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t check_tool_sensor_stats(const uint8_t tool_index, const bool kill_on_error/*=false*/, const bool disable/*=false*/) { |
|
|
|
|
|
static uint8_t sensor_tries; // = 0
|
|
|
|
|
|
for (;;) { |
|
|
|
|
|
if (poll_tool_sensor_pins() == _BV(tool_index)) { |
|
|
|
|
|
sensor_tries = 0; |
|
|
|
|
|
return tool_index; |
|
|
|
|
|
} |
|
|
|
|
|
else if (kill_on_error && (!tool_sensor_disabled || disable)) { |
|
|
|
|
|
sensor_tries++; |
|
|
|
|
|
if (sensor_tries > 10) kill(PSTR("Tool Sensor error")); |
|
|
|
|
|
safe_delay(5); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
sensor_tries++; |
|
|
|
|
|
if (sensor_tries > 10) return -1; |
|
|
|
|
|
safe_delay(5); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
inline void switching_toolhead_lock(const bool locked) { |
|
|
|
|
|
#ifdef SWITCHING_TOOLHEAD_SERVO_ANGLES |
|
|
const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES; |
|
|
const uint16_t swt_angles[2] = SWITCHING_TOOLHEAD_SERVO_ANGLES; |
|
|
MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]); |
|
|
MOVE_SERVO(SWITCHING_TOOLHEAD_SERVO_NR, swt_angles[locked ? 0 : 1]); |
|
|
|
|
|
#elif PIN_EXISTS(SWT_SOLENOID) |
|
|
|
|
|
OUT_WRITE(SWT_SOLENOID_PIN, locked); |
|
|
|
|
|
gcode.dwell(10); |
|
|
|
|
|
#else |
|
|
|
|
|
#error "No toolhead locking mechanism configured." |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void swt_init() { swt_lock(); } |
|
|
#include <bitset> |
|
|
|
|
|
|
|
|
|
|
|
void swt_init() { |
|
|
|
|
|
switching_toolhead_lock(true); |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(TOOL_SENSOR) |
|
|
|
|
|
// Init tool sensors
|
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR1) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR1_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR2) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR2_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR3) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR3_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR4) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR4_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR5) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR5_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR6) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR6_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR7) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR7_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
#if PIN_EXISTS(TOOL_SENSOR8) |
|
|
|
|
|
SET_INPUT_PULLUP(TOOL_SENSOR8_PIN); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
if (check_tool_sensor_stats(0)) { |
|
|
|
|
|
ui.set_status_P("TC error"); |
|
|
|
|
|
switching_toolhead_lock(false); |
|
|
|
|
|
while (check_tool_sensor_stats(0)) { /* nada */ } |
|
|
|
|
|
switching_toolhead_lock(true); |
|
|
|
|
|
} |
|
|
|
|
|
ui.set_status_P("TC Success"); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
inline void switching_toolhead_tool_change(const uint8_t new_tool, bool no_move/*=false*/) { |
|
|
inline void switching_toolhead_tool_change(const uint8_t new_tool, bool no_move/*=false*/) { |
|
|
if (no_move) return; |
|
|
if (no_move) return; |
|
@ -398,6 +507,8 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
const float placexpos = toolheadposx[active_extruder], |
|
|
const float placexpos = toolheadposx[active_extruder], |
|
|
grabxpos = toolheadposx[new_tool]; |
|
|
grabxpos = toolheadposx[new_tool]; |
|
|
|
|
|
|
|
|
|
|
|
(void)check_tool_sensor_stats(active_extruder, true); |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* 1. Move to switch position of current toolhead |
|
|
* 1. Move to switch position of current toolhead |
|
|
* 2. Unlock tool and drop it in the dock |
|
|
* 2. Unlock tool and drop it in the dock |
|
@ -421,13 +532,14 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
DEBUG_SYNCHRONIZE(); |
|
|
DEBUG_SYNCHRONIZE(); |
|
|
DEBUG_POS("Move Y SwitchPos + Security", current_position); |
|
|
DEBUG_POS("Move Y SwitchPos + Security", current_position); |
|
|
|
|
|
|
|
|
fast_line_to_current(Y_AXIS); |
|
|
slow_line_to_current(Y_AXIS); |
|
|
|
|
|
|
|
|
// 2. Unlock tool and drop it in the dock
|
|
|
// 2. Unlock tool and drop it in the dock
|
|
|
|
|
|
TERN_(TOOL_SENSOR, tool_sensor_disabled = true); |
|
|
|
|
|
|
|
|
planner.synchronize(); |
|
|
planner.synchronize(); |
|
|
DEBUG_ECHOLNPGM("(2) Unlock and Place Toolhead"); |
|
|
DEBUG_ECHOLNPGM("(2) Unlock and Place Toolhead"); |
|
|
swt_lock(false); |
|
|
switching_toolhead_lock(false); |
|
|
safe_delay(500); |
|
|
safe_delay(500); |
|
|
|
|
|
|
|
|
current_position.y = SWITCHING_TOOLHEAD_Y_POS; |
|
|
current_position.y = SWITCHING_TOOLHEAD_Y_POS; |
|
@ -440,7 +552,9 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
|
|
|
|
|
|
current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; |
|
|
current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; |
|
|
DEBUG_POS("Move back Y clear", current_position); |
|
|
DEBUG_POS("Move back Y clear", current_position); |
|
|
fast_line_to_current(Y_AXIS); // move away from docked toolhead
|
|
|
slow_line_to_current(Y_AXIS); // move away from docked toolhead
|
|
|
|
|
|
|
|
|
|
|
|
(void)check_tool_sensor_stats(active_extruder); |
|
|
|
|
|
|
|
|
// 3. Move to the new toolhead
|
|
|
// 3. Move to the new toolhead
|
|
|
|
|
|
|
|
@ -457,7 +571,7 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
DEBUG_SYNCHRONIZE(); |
|
|
DEBUG_SYNCHRONIZE(); |
|
|
DEBUG_POS("Move Y SwitchPos + Security", current_position); |
|
|
DEBUG_POS("Move Y SwitchPos + Security", current_position); |
|
|
|
|
|
|
|
|
fast_line_to_current(Y_AXIS); |
|
|
slow_line_to_current(Y_AXIS); |
|
|
|
|
|
|
|
|
// 4. Grab and lock the new toolhead
|
|
|
// 4. Grab and lock the new toolhead
|
|
|
|
|
|
|
|
@ -472,14 +586,19 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a |
|
|
// Wait for move to finish, pause 0.2s, move servo, pause 0.5s
|
|
|
// Wait for move to finish, pause 0.2s, move servo, pause 0.5s
|
|
|
planner.synchronize(); |
|
|
planner.synchronize(); |
|
|
safe_delay(200); |
|
|
safe_delay(200); |
|
|
swt_lock(); |
|
|
|
|
|
|
|
|
(void)check_tool_sensor_stats(new_tool, true, true); |
|
|
|
|
|
|
|
|
|
|
|
switching_toolhead_lock(true); |
|
|
safe_delay(500); |
|
|
safe_delay(500); |
|
|
|
|
|
|
|
|
current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; |
|
|
current_position.y -= SWITCHING_TOOLHEAD_Y_CLEAR; |
|
|
DEBUG_POS("Move back Y clear", current_position); |
|
|
DEBUG_POS("Move back Y clear", current_position); |
|
|
fast_line_to_current(Y_AXIS); // Move away from docked toolhead
|
|
|
slow_line_to_current(Y_AXIS); // Move away from docked toolhead
|
|
|
planner.synchronize(); // Always sync the final move
|
|
|
planner.synchronize(); // Always sync the final move
|
|
|
|
|
|
|
|
|
|
|
|
(void)check_tool_sensor_stats(new_tool, true, true); |
|
|
|
|
|
|
|
|
DEBUG_POS("ST Tool-Change done.", current_position); |
|
|
DEBUG_POS("ST Tool-Change done.", current_position); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1053,8 +1172,11 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { |
|
|
move_nozzle_servo(new_tool); |
|
|
move_nozzle_servo(new_tool); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
// Set the new active extruder
|
|
|
IF_DISABLED(DUAL_X_CARRIAGE, active_extruder = new_tool); // Set the new active extruder
|
|
|
if (DISABLED(DUAL_X_CARRIAGE)) active_extruder = new_tool; |
|
|
|
|
|
|
|
|
TERN_(TOOL_SENSOR, tool_sensor_disabled = false); |
|
|
|
|
|
|
|
|
|
|
|
(void)check_tool_sensor_stats(active_extruder, true); |
|
|
|
|
|
|
|
|
// The newly-selected extruder XYZ is actually at...
|
|
|
// The newly-selected extruder XYZ is actually at...
|
|
|
DEBUG_ECHOLNPAIR("Offset Tool XYZ by { ", diff.x, ", ", diff.y, ", ", diff.z, " }"); |
|
|
DEBUG_ECHOLNPAIR("Offset Tool XYZ by { ", diff.x, ", ", diff.y, ", ", diff.z, " }"); |
|
|