|
@@ -1303,11 +1303,7 @@ bool get_target_extruder_from_command(int code) {
|
1303
|
1303
|
|
1304
|
1304
|
#if ENABLED(DUAL_X_CARRIAGE)
|
1305
|
1305
|
|
1306
|
|
- #define DXC_FULL_CONTROL_MODE 0
|
1307
|
|
- #define DXC_AUTO_PARK_MODE 1
|
1308
|
|
- #define DXC_DUPLICATION_MODE 2
|
1309
|
|
-
|
1310
|
|
- static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
|
|
1306
|
+ static DualXMode dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
|
1311
|
1307
|
|
1312
|
1308
|
static float x_home_pos(int extruder) {
|
1313
|
1309
|
if (extruder == 0)
|
|
@@ -6950,8 +6946,11 @@ inline void gcode_M503() {
|
6950
|
6946
|
*/
|
6951
|
6947
|
inline void gcode_M605() {
|
6952
|
6948
|
stepper.synchronize();
|
6953
|
|
- if (code_seen('S')) dual_x_carriage_mode = code_value_byte();
|
|
6949
|
+ if (code_seen('S')) dual_x_carriage_mode = (DualXMode)code_value_byte();
|
6954
|
6950
|
switch (dual_x_carriage_mode) {
|
|
6951
|
+ case DXC_FULL_CONTROL_MODE:
|
|
6952
|
+ case DXC_AUTO_PARK_MODE:
|
|
6953
|
+ break;
|
6955
|
6954
|
case DXC_DUPLICATION_MODE:
|
6956
|
6955
|
if (code_seen('X')) duplicate_extruder_x_offset = max(code_value_axis_units(X_AXIS), X2_MIN_POS - x_home_pos(0));
|
6957
|
6956
|
if (code_seen('R')) duplicate_extruder_temp_offset = code_value_temp_diff();
|
|
@@ -6966,9 +6965,6 @@ inline void gcode_M503() {
|
6966
|
6965
|
SERIAL_CHAR(',');
|
6967
|
6966
|
SERIAL_ECHOLN(hotend_offset[Y_AXIS][1]);
|
6968
|
6967
|
break;
|
6969
|
|
- case DXC_FULL_CONTROL_MODE:
|
6970
|
|
- case DXC_AUTO_PARK_MODE:
|
6971
|
|
- break;
|
6972
|
6968
|
default:
|
6973
|
6969
|
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
|
6974
|
6970
|
break;
|
|
@@ -7258,9 +7254,9 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
7258
|
7254
|
if (DEBUGGING(LEVELING)) {
|
7259
|
7255
|
SERIAL_ECHOPGM("Dual X Carriage Mode ");
|
7260
|
7256
|
switch (dual_x_carriage_mode) {
|
7261
|
|
- case DXC_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break;
|
7262
|
|
- case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break;
|
7263
|
7257
|
case DXC_FULL_CONTROL_MODE: SERIAL_ECHOLNPGM("DXC_FULL_CONTROL_MODE"); break;
|
|
7258
|
+ case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break;
|
|
7259
|
+ case DXC_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break;
|
7264
|
7260
|
}
|
7265
|
7261
|
}
|
7266
|
7262
|
#endif
|
|
@@ -7305,6 +7301,16 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
7305
|
7301
|
current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos);
|
7306
|
7302
|
inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]);
|
7307
|
7303
|
break;
|
|
7304
|
+ case DXC_AUTO_PARK_MODE:
|
|
7305
|
+ // record raised toolhead position for use by unpark
|
|
7306
|
+ memcpy(raised_parked_position, current_position, sizeof(raised_parked_position));
|
|
7307
|
+ raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT;
|
|
7308
|
+ #if ENABLED(max_software_endstops)
|
|
7309
|
+ NOMORE(raised_parked_position[Z_AXIS], soft_endstop_max[Z_AXIS]);
|
|
7310
|
+ #endif
|
|
7311
|
+ active_extruder_parked = true;
|
|
7312
|
+ delayed_move_time = 0;
|
|
7313
|
+ break;
|
7308
|
7314
|
case DXC_DUPLICATION_MODE:
|
7309
|
7315
|
active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position
|
7310
|
7316
|
if (active_extruder_parked)
|
|
@@ -7314,13 +7320,6 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
7314
|
7320
|
inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]);
|
7315
|
7321
|
extruder_duplication_enabled = false;
|
7316
|
7322
|
break;
|
7317
|
|
- default:
|
7318
|
|
- // record raised toolhead position for use by unpark
|
7319
|
|
- memcpy(raised_parked_position, current_position, sizeof(raised_parked_position));
|
7320
|
|
- raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT;
|
7321
|
|
- active_extruder_parked = true;
|
7322
|
|
- delayed_move_time = 0;
|
7323
|
|
- break;
|
7324
|
7323
|
}
|
7325
|
7324
|
|
7326
|
7325
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
@@ -8975,39 +8974,45 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
8975
|
8974
|
*/
|
8976
|
8975
|
inline bool prepare_move_to_destination_dualx() {
|
8977
|
8976
|
if (active_extruder_parked) {
|
8978
|
|
- if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) {
|
8979
|
|
- // move duplicate extruder into correct duplication position.
|
8980
|
|
- planner.set_position_mm(
|
8981
|
|
- LOGICAL_X_POSITION(inactive_extruder_x_pos),
|
8982
|
|
- current_position[Y_AXIS],
|
8983
|
|
- current_position[Z_AXIS],
|
8984
|
|
- current_position[E_AXIS]
|
8985
|
|
- );
|
8986
|
|
- planner.buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset,
|
8987
|
|
- current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[X_AXIS], 1);
|
8988
|
|
- SYNC_PLAN_POSITION_KINEMATIC();
|
8989
|
|
- stepper.synchronize();
|
8990
|
|
- extruder_duplication_enabled = true;
|
8991
|
|
- active_extruder_parked = false;
|
8992
|
|
- }
|
8993
|
|
- else if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE) { // handle unparking of head
|
8994
|
|
- if (current_position[E_AXIS] == destination[E_AXIS]) {
|
8995
|
|
- // This is a travel move (with no extrusion)
|
8996
|
|
- // Skip it, but keep track of the current position
|
8997
|
|
- // (so it can be used as the start of the next non-travel move)
|
8998
|
|
- if (delayed_move_time != 0xFFFFFFFFUL) {
|
8999
|
|
- set_current_to_destination();
|
9000
|
|
- NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]);
|
9001
|
|
- delayed_move_time = millis();
|
9002
|
|
- return false;
|
|
8977
|
+ switch (dual_x_carriage_mode) {
|
|
8978
|
+ case DXC_FULL_CONTROL_MODE:
|
|
8979
|
+ break;
|
|
8980
|
+ case DXC_DUPLICATION_MODE:
|
|
8981
|
+ if (active_extruder == 0) {
|
|
8982
|
+ // move duplicate extruder into correct duplication position.
|
|
8983
|
+ planner.set_position_mm(
|
|
8984
|
+ LOGICAL_X_POSITION(inactive_extruder_x_pos),
|
|
8985
|
+ current_position[Y_AXIS],
|
|
8986
|
+ current_position[Z_AXIS],
|
|
8987
|
+ current_position[E_AXIS]
|
|
8988
|
+ );
|
|
8989
|
+ planner.buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset,
|
|
8990
|
+ current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[X_AXIS], 1);
|
|
8991
|
+ SYNC_PLAN_POSITION_KINEMATIC();
|
|
8992
|
+ stepper.synchronize();
|
|
8993
|
+ extruder_duplication_enabled = true;
|
|
8994
|
+ active_extruder_parked = false;
|
9003
|
8995
|
}
|
9004
|
|
- }
|
9005
|
|
- delayed_move_time = 0;
|
9006
|
|
- // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
|
9007
|
|
- planner.buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
9008
|
|
- planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], PLANNER_XY_FEEDRATE(), active_extruder);
|
9009
|
|
- planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
9010
|
|
- active_extruder_parked = false;
|
|
8996
|
+ break;
|
|
8997
|
+ case DXC_AUTO_PARK_MODE:
|
|
8998
|
+ if (current_position[E_AXIS] == destination[E_AXIS]) {
|
|
8999
|
+ // This is a travel move (with no extrusion)
|
|
9000
|
+ // Skip it, but keep track of the current position
|
|
9001
|
+ // (so it can be used as the start of the next non-travel move)
|
|
9002
|
+ if (delayed_move_time != 0xFFFFFFFFUL) {
|
|
9003
|
+ set_current_to_destination();
|
|
9004
|
+ NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]);
|
|
9005
|
+ delayed_move_time = millis();
|
|
9006
|
+ return false;
|
|
9007
|
+ }
|
|
9008
|
+ }
|
|
9009
|
+ delayed_move_time = 0;
|
|
9010
|
+ // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
|
|
9011
|
+ planner.buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
|
9012
|
+ planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], PLANNER_XY_FEEDRATE(), active_extruder);
|
|
9013
|
+ planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
|
9014
|
+ active_extruder_parked = false;
|
|
9015
|
+ break;
|
9011
|
9016
|
}
|
9012
|
9017
|
}
|
9013
|
9018
|
return true;
|