diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 8867ec976..17d51f06f 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -6304,131 +6304,134 @@ inline void gcode_T(uint8_t tmp_extruder) { SERIAL_CHAR('T'); SERIAL_PROTOCOL_F(tmp_extruder, DEC); SERIAL_ECHOLN(MSG_INVALID_EXTRUDER); + return; } - else { - target_extruder = tmp_extruder; - #if EXTRUDERS > 1 - bool make_move = false; + float stored_feedrate = feedrate; + + if (code_seen('F')) { + float next_feedrate = code_value(); + if (next_feedrate > 0.0) stored_feedrate = feedrate = next_feedrate; + } + else { + #ifdef XY_TRAVEL_SPEED + feedrate = XY_TRAVEL_SPEED; + #else + feedrate = min(max_feedrate[X_AXIS], max_feedrate[Y_AXIS]); #endif + } - if (code_seen('F')) { + #if EXTRUDERS > 1 + if (tmp_extruder != active_extruder) { + // Save current position to return to after applying extruder offset + set_destination_to_current(); + #if ENABLED(DUAL_X_CARRIAGE) + if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && IsRunning() && + (delayed_move_time || current_position[X_AXIS] != x_home_pos(active_extruder))) { + // Park old head: 1) raise 2) move to park position 3) lower + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT, + current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder); + plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT, + current_position[E_AXIS], max_feedrate[X_AXIS], active_extruder); + plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS], + current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder); + st_synchronize(); + } - #if EXTRUDERS > 1 - make_move = true; - #endif + // apply Y & Z extruder offset (x offset is already used in determining home pos) + current_position[Y_AXIS] -= extruder_offset[Y_AXIS][active_extruder] - extruder_offset[Y_AXIS][tmp_extruder]; + current_position[Z_AXIS] -= extruder_offset[Z_AXIS][active_extruder] - extruder_offset[Z_AXIS][tmp_extruder]; + active_extruder = tmp_extruder; - float next_feedrate = code_value(); - if (next_feedrate > 0.0) feedrate = next_feedrate; - } - #if EXTRUDERS > 1 - if (tmp_extruder != active_extruder) { - // Save current position to return to after applying extruder offset - set_destination_to_current(); - #if ENABLED(DUAL_X_CARRIAGE) - if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && IsRunning() && - (delayed_move_time || current_position[X_AXIS] != x_home_pos(active_extruder))) { - // Park old head: 1) raise 2) move to park position 3) lower - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT, - current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder); - plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT, - current_position[E_AXIS], max_feedrate[X_AXIS], active_extruder); - plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS], - current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder); - st_synchronize(); - } + // This function resets the max/min values - the current position may be overwritten below. + set_axis_is_at_home(X_AXIS); - // apply Y & Z extruder offset (x offset is already used in determining home pos) - current_position[Y_AXIS] -= extruder_offset[Y_AXIS][active_extruder] - extruder_offset[Y_AXIS][tmp_extruder]; - current_position[Z_AXIS] -= extruder_offset[Z_AXIS][active_extruder] - extruder_offset[Z_AXIS][tmp_extruder]; - active_extruder = tmp_extruder; + if (dual_x_carriage_mode == DXC_FULL_CONTROL_MODE) { + current_position[X_AXIS] = inactive_extruder_x_pos; + inactive_extruder_x_pos = destination[X_AXIS]; + } + else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { + active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position + if (active_extruder_parked) + current_position[X_AXIS] = inactive_extruder_x_pos; + else + current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; + inactive_extruder_x_pos = destination[X_AXIS]; + extruder_duplication_enabled = false; + } + else { + // record raised toolhead position for use by unpark + memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); + raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT; + active_extruder_parked = true; + delayed_move_time = 0; + } + // No extra case for AUTO_BED_LEVELING_FEATURE in DUAL_X_CARRIAGE. Does that mean they don't work together? + #else // !DUAL_X_CARRIAGE + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + // Offset extruder, make sure to apply the bed level rotation matrix + vector_3 tmp_offset_vec = vector_3(extruder_offset[X_AXIS][tmp_extruder], + extruder_offset[Y_AXIS][tmp_extruder], + 0), + act_offset_vec = vector_3(extruder_offset[X_AXIS][active_extruder], + extruder_offset[Y_AXIS][active_extruder], + 0), + offset_vec = tmp_offset_vec - act_offset_vec; - // This function resets the max/min values - the current position may be overwritten below. - set_axis_is_at_home(X_AXIS); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM(">>> gcode_T"); + tmp_offset_vec.debug("tmp_offset_vec"); + act_offset_vec.debug("act_offset_vec"); + offset_vec.debug("offset_vec (BEFORE)"); + DEBUG_POS("BEFORE rotation", current_position); + } + #endif - if (dual_x_carriage_mode == DXC_FULL_CONTROL_MODE) { - current_position[X_AXIS] = inactive_extruder_x_pos; - inactive_extruder_x_pos = destination[X_AXIS]; - } - else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { - active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position - if (active_extruder == 0 || active_extruder_parked) - current_position[X_AXIS] = inactive_extruder_x_pos; - else - current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; - inactive_extruder_x_pos = destination[X_AXIS]; - extruder_duplication_enabled = false; - } - else { - // record raised toolhead position for use by unpark - memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); - raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT; - active_extruder_parked = true; - delayed_move_time = 0; - } - #else // !DUAL_X_CARRIAGE - #if ENABLED(AUTO_BED_LEVELING_FEATURE) - // Offset extruder, make sure to apply the bed level rotation matrix - vector_3 tmp_offset_vec = vector_3(extruder_offset[X_AXIS][tmp_extruder], - extruder_offset[Y_AXIS][tmp_extruder], - 0), - act_offset_vec = vector_3(extruder_offset[X_AXIS][active_extruder], - extruder_offset[Y_AXIS][active_extruder], - 0), - offset_vec = tmp_offset_vec - act_offset_vec; + offset_vec.apply_rotation(plan_bed_level_matrix.transpose(plan_bed_level_matrix)); - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) { - SERIAL_ECHOLNPGM(">>> gcode_T"); - tmp_offset_vec.debug("tmp_offset_vec"); - act_offset_vec.debug("act_offset_vec"); - offset_vec.debug("offset_vec (BEFORE)"); - DEBUG_POS("BEFORE rotation", current_position); - } - #endif + current_position[X_AXIS] += offset_vec.x; + current_position[Y_AXIS] += offset_vec.y; + current_position[Z_AXIS] += offset_vec.z; - offset_vec.apply_rotation(plan_bed_level_matrix.transpose(plan_bed_level_matrix)); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + offset_vec.debug("offset_vec (AFTER)"); + DEBUG_POS("AFTER rotation", current_position); + SERIAL_ECHOLNPGM("<<< gcode_T"); + } + #endif - current_position[X_AXIS] += offset_vec.x; - current_position[Y_AXIS] += offset_vec.y; - current_position[Z_AXIS] += offset_vec.z; + #else // !AUTO_BED_LEVELING_FEATURE + // Offset extruder (only by XY) + for (int i=X_AXIS; i<=Y_AXIS; i++) + current_position[i] += extruder_offset[i][tmp_extruder] - extruder_offset[i][active_extruder]; + #endif // !AUTO_BED_LEVELING_FEATURE + // Set the new active extruder and position + active_extruder = tmp_extruder; + #endif // !DUAL_X_CARRIAGE + #if ENABLED(DELTA) + sync_plan_position_delta(); + #else + sync_plan_position(); + #endif + // Move to the old position + if (IsRunning()) prepare_move(); + } // (tmp_extruder != active_extruder) - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) { - offset_vec.debug("offset_vec (AFTER)"); - DEBUG_POS("AFTER rotation", current_position); - SERIAL_ECHOLNPGM("<<< gcode_T"); - } - #endif + #if ENABLED(EXT_SOLENOID) + st_synchronize(); + disable_all_solenoids(); + enable_solenoid_on_active_extruder(); + #endif // EXT_SOLENOID - #else // !AUTO_BED_LEVELING_FEATURE - // Offset extruder (only by XY) - for (int i=X_AXIS; i<=Y_AXIS; i++) - current_position[i] += extruder_offset[i][tmp_extruder] - extruder_offset[i][active_extruder]; - #endif // !AUTO_BED_LEVELING_FEATURE - // Set the new active extruder and position - active_extruder = tmp_extruder; - #endif // !DUAL_X_CARRIAGE - #if ENABLED(DELTA) - sync_plan_position_delta(); - #else - sync_plan_position(); - #endif - // Move to the old position if 'F' was in the parameters - if (make_move && IsRunning()) prepare_move(); - } + #endif // EXTRUDERS > 1 - #if ENABLED(EXT_SOLENOID) - st_synchronize(); - disable_all_solenoids(); - enable_solenoid_on_active_extruder(); - #endif // EXT_SOLENOID + feedrate = stored_feedrate; - #endif // EXTRUDERS > 1 - SERIAL_ECHO_START; - SERIAL_ECHO(MSG_ACTIVE_EXTRUDER); - SERIAL_PROTOCOLLN((int)active_extruder); - } + SERIAL_ECHO_START; + SERIAL_ECHO(MSG_ACTIVE_EXTRUDER); + SERIAL_PROTOCOLLN((int)active_extruder); } /**