IDEX Improvements (#11848)
This commit is contained in:
parent
39732838b4
commit
0780913848
24 changed files with 285 additions and 115 deletions
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
//#define TREX3 // Turn this on for T-Rex 3 features like dual filament run out sensors
|
//#define TREX3 // Turn this on for T-Rex 3 features like dual filament run out sensors
|
||||||
|
|
||||||
#define ROXYs_TRex // Turn this on to get customizations only available on Roxy's T-Rex 2+
|
//#define ROXYs_TRex // Turn this on to get customizations only available on Roxy's T-Rex 2+
|
||||||
// Marlin controlled heat bed, Max7219 debug LED's, less bright LED light level
|
// Marlin controlled heat bed, Max7219 debug LED's, less bright LED light level
|
||||||
// More aggressive PID numbers for hotends (due to double fans)
|
// More aggressive PID numbers for hotends (due to double fans)
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -385,9 +385,7 @@
|
||||||
// Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all
|
// Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all
|
||||||
// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at
|
// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at
|
||||||
// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm])
|
// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm])
|
||||||
// Mode 3 (DXC_SYMMETRIC_DUPLICATION_MODE) : Symmetric Duplication mode. The firmware will perform similarly to DXC_DUPLICATION_MODE except in a mirror
|
// Mode 3 (DXC_SCALED_DUPLICATION_MODE) : Not working yet, but support routines in place
|
||||||
// image of the first x-carriage. ie. If you are printing a right hand shoe on the 1st extruder, you will
|
|
||||||
// get a left hand shoe on the 2nd extruder.
|
|
||||||
|
|
||||||
// This is the default power-up mode which can be later using M605.
|
// This is the default power-up mode which can be later using M605.
|
||||||
#define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE
|
#define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE
|
||||||
|
|
|
@ -56,6 +56,8 @@ uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
|
||||||
#if _ROT == 0 || _ROT == 270
|
#if _ROT == 0 || _ROT == 270
|
||||||
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
|
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
|
||||||
#define _LED_UNIT(Q) ((Q) & ~0x7)
|
#define _LED_UNIT(Q) ((Q) & ~0x7)
|
||||||
|
//#define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3) // some Max7219 boards have rotated the matrix
|
||||||
|
// this line can be substituted to correct orientation
|
||||||
#else
|
#else
|
||||||
#define _LED_BIT(Q) ((Q) & 0x7)
|
#define _LED_BIT(Q) ((Q) & 0x7)
|
||||||
#define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3)
|
#define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3)
|
||||||
|
|
|
@ -140,6 +140,7 @@ static void do_pause_e_move(const float &length, const float &fr) {
|
||||||
bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=0*/, const int8_t max_beep_count/*=0*/,
|
bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=0*/, const int8_t max_beep_count/*=0*/,
|
||||||
const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/,
|
const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/,
|
||||||
const AdvancedPauseMode mode/*=ADVANCED_PAUSE_MODE_PAUSE_PRINT*/
|
const AdvancedPauseMode mode/*=ADVANCED_PAUSE_MODE_PAUSE_PRINT*/
|
||||||
|
DXC_ARGS
|
||||||
) {
|
) {
|
||||||
#if DISABLED(ULTIPANEL)
|
#if DISABLED(ULTIPANEL)
|
||||||
UNUSED(show_lcd);
|
UNUSED(show_lcd);
|
||||||
|
@ -184,6 +185,13 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||||
lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_LOAD, mode);
|
lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_LOAD, mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
const int8_t saved_ext = active_extruder;
|
||||||
|
const bool saved_ext_dup_mode = extruder_duplication_enabled;
|
||||||
|
active_extruder = DXC_ext;
|
||||||
|
extruder_duplication_enabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Slow Load filament
|
// Slow Load filament
|
||||||
if (slow_load_length) do_pause_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE);
|
if (slow_load_length) do_pause_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE);
|
||||||
|
|
||||||
|
@ -201,6 +209,12 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE) // Tie the two extruders movement back together.
|
||||||
|
active_extruder = saved_ext;
|
||||||
|
extruder_duplication_enabled = saved_ext_dup_mode;
|
||||||
|
stepper.set_directions();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE)
|
#if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE)
|
||||||
|
|
||||||
#if ENABLED(ULTIPANEL)
|
#if ENABLED(ULTIPANEL)
|
||||||
|
@ -328,7 +342,8 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
|
||||||
*/
|
*/
|
||||||
uint8_t did_pause_print = 0;
|
uint8_t did_pause_print = 0;
|
||||||
|
|
||||||
bool pause_print(const float &retract, const point_t &park_point, const float &unload_length/*=0*/, const bool show_lcd/*=false*/) {
|
bool pause_print(const float &retract, const point_t &park_point, const float &unload_length/*=0*/, const bool show_lcd/*=false*/ DXC_ARGS) {
|
||||||
|
|
||||||
if (did_pause_print) return false; // already paused
|
if (did_pause_print) return false; // already paused
|
||||||
|
|
||||||
#ifdef ACTION_ON_PAUSE
|
#ifdef ACTION_ON_PAUSE
|
||||||
|
@ -380,10 +395,22 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u
|
||||||
if (!axis_unhomed_error())
|
if (!axis_unhomed_error())
|
||||||
Nozzle::park(2, park_point);
|
Nozzle::park(2, park_point);
|
||||||
|
|
||||||
// Unload the filament
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
if (unload_length)
|
const int8_t saved_ext = active_extruder;
|
||||||
|
const bool saved_ext_dup_mode = extruder_duplication_enabled;
|
||||||
|
active_extruder = DXC_ext;
|
||||||
|
extruder_duplication_enabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (unload_length) // Unload the filament
|
||||||
unload_filament(unload_length, show_lcd);
|
unload_filament(unload_length, show_lcd);
|
||||||
|
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
active_extruder = saved_ext;
|
||||||
|
extruder_duplication_enabled = saved_ext_dup_mode;
|
||||||
|
stepper.set_directions();
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +421,7 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u
|
||||||
*
|
*
|
||||||
* Used by M125 and M600
|
* Used by M125 and M600
|
||||||
*/
|
*/
|
||||||
void wait_for_filament_reload(const int8_t max_beep_count/*=0*/) {
|
void wait_for_filament_reload(const int8_t max_beep_count/*=0*/ DXC_ARGS) {
|
||||||
bool nozzle_timed_out = false;
|
bool nozzle_timed_out = false;
|
||||||
|
|
||||||
#if ENABLED(ULTIPANEL)
|
#if ENABLED(ULTIPANEL)
|
||||||
|
@ -413,6 +440,13 @@ void wait_for_filament_reload(const int8_t max_beep_count/*=0*/) {
|
||||||
HOTEND_LOOP()
|
HOTEND_LOOP()
|
||||||
thermalManager.start_heater_idle_timer(e, nozzle_timeout);
|
thermalManager.start_heater_idle_timer(e, nozzle_timeout);
|
||||||
|
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
const int8_t saved_ext = active_extruder;
|
||||||
|
const bool saved_ext_dup_mode = extruder_duplication_enabled;
|
||||||
|
active_extruder = DXC_ext;
|
||||||
|
extruder_duplication_enabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Wait for filament insert by user and press button
|
// Wait for filament insert by user and press button
|
||||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||||
wait_for_user = true; // LCD click or M108 will clear this
|
wait_for_user = true; // LCD click or M108 will clear this
|
||||||
|
@ -477,6 +511,11 @@ void wait_for_filament_reload(const int8_t max_beep_count/*=0*/) {
|
||||||
|
|
||||||
idle(true);
|
idle(true);
|
||||||
}
|
}
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
active_extruder = saved_ext;
|
||||||
|
extruder_duplication_enabled = saved_ext_dup_mode;
|
||||||
|
stepper.set_directions();
|
||||||
|
#endif
|
||||||
KEEPALIVE_STATE(IN_HANDLER);
|
KEEPALIVE_STATE(IN_HANDLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +537,15 @@ void wait_for_filament_reload(const int8_t max_beep_count/*=0*/) {
|
||||||
* - Send host action for resume, if configured
|
* - Send host action for resume, if configured
|
||||||
* - Resume the current SD print job, if any
|
* - Resume the current SD print job, if any
|
||||||
*/
|
*/
|
||||||
void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/) {
|
void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) {
|
||||||
|
/*
|
||||||
|
SERIAL_ECHOPGM("start of resume_print()\n");
|
||||||
|
SERIAL_ECHOPAIR("\ndual_x_carriage_mode:", dual_x_carriage_mode);
|
||||||
|
SERIAL_ECHOPAIR("\nextruder_duplication_enabled:", extruder_duplication_enabled);
|
||||||
|
SERIAL_ECHOPAIR("\nactive_extruder:", active_extruder);
|
||||||
|
SERIAL_ECHOPGM("\n\n");
|
||||||
|
*/
|
||||||
|
|
||||||
if (!did_pause_print) return;
|
if (!did_pause_print) return;
|
||||||
|
|
||||||
// Re-enable the heaters if they timed out
|
// Re-enable the heaters if they timed out
|
||||||
|
@ -508,14 +555,11 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
|
||||||
thermalManager.reset_heater_idle_timer(e);
|
thermalManager.reset_heater_idle_timer(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) {
|
if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament
|
||||||
// Load the new filament
|
load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, ADVANCED_PAUSE_MODE_PAUSE_PRINT DXC_PASS);
|
||||||
load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLED(ULTIPANEL)
|
#if ENABLED(ULTIPANEL)
|
||||||
// "Wait for print to resume"
|
lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_RESUME); // "Wait for print to resume"
|
||||||
lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_RESUME);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Intelligent resuming
|
// Intelligent resuming
|
||||||
|
|
|
@ -67,14 +67,24 @@ extern float filament_change_unload_length[EXTRUDERS],
|
||||||
|
|
||||||
extern uint8_t did_pause_print;
|
extern uint8_t did_pause_print;
|
||||||
|
|
||||||
bool pause_print(const float &retract, const point_t &park_point, const float &unload_length=0, const bool show_lcd=false);
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
#define DXC_PARAMS , const int8_t DXC_ext=-1
|
||||||
|
#define DXC_ARGS , const int8_t DXC_ext
|
||||||
|
#define DXC_PASS , DXC_ext
|
||||||
|
#else
|
||||||
|
#define DXC_PARAMS
|
||||||
|
#define DXC_ARGS
|
||||||
|
#define DXC_PASS
|
||||||
|
#endif
|
||||||
|
|
||||||
void wait_for_filament_reload(const int8_t max_beep_count=0);
|
bool pause_print(const float &retract, const point_t &park_point, const float &unload_length=0, const bool show_lcd=false DXC_PARAMS);
|
||||||
|
|
||||||
void resume_print(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, const int8_t max_beep_count=0);
|
void wait_for_filament_reload(const int8_t max_beep_count=0 DXC_PARAMS);
|
||||||
|
|
||||||
|
void resume_print(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, const int8_t max_beep_count=0 DXC_PARAMS);
|
||||||
|
|
||||||
bool load_filament(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=0, const int8_t max_beep_count=0, const bool show_lcd=false,
|
bool load_filament(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=0, const int8_t max_beep_count=0, const bool show_lcd=false,
|
||||||
const bool pause_for_user=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT);
|
const bool pause_for_user=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
|
||||||
|
|
||||||
bool unload_filament(const float &unload_length, const bool show_lcd=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT);
|
bool unload_filament(const float &unload_length, const bool show_lcd=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT);
|
||||||
|
|
||||||
|
|
|
@ -62,22 +62,31 @@ class FilamentRunoutSensor {
|
||||||
#else
|
#else
|
||||||
// Read the sensor for the active extruder
|
// Read the sensor for the active extruder
|
||||||
bool is_out;
|
bool is_out;
|
||||||
switch (active_extruder) {
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
case 0: is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; break;
|
const bool out1 = READ(FIL_RUNOUT_PIN ) == FIL_RUNOUT_INVERTING,
|
||||||
case 1: is_out = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; break;
|
out2 = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING;
|
||||||
#if NUM_RUNOUT_SENSORS > 2
|
if (extruder_duplication_enabled)
|
||||||
case 2: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break;
|
is_out = out1 || out2;
|
||||||
#if NUM_RUNOUT_SENSORS > 3
|
else
|
||||||
case 3: is_out = READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING; break;
|
is_out = active_extruder ? out2 : out1;
|
||||||
#if NUM_RUNOUT_SENSORS > 4
|
#else
|
||||||
case 4: is_out = READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING; break;
|
switch (active_extruder) {
|
||||||
#if NUM_RUNOUT_SENSORS > 5
|
case 0: is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||||
case 5: is_out = READ(FIL_RUNOUT6_PIN) == FIL_RUNOUT_INVERTING; break;
|
case 1: is_out = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||||
#endif
|
#if NUM_RUNOUT_SENSORS > 2
|
||||||
#endif
|
case 2: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||||
#endif
|
#if NUM_RUNOUT_SENSORS > 3
|
||||||
#endif
|
case 3: is_out = READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||||
|
#if NUM_RUNOUT_SENSORS > 4
|
||||||
|
case 4: is_out = READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||||
|
#if NUM_RUNOUT_SENSORS > 5
|
||||||
|
case 5: is_out = READ(FIL_RUNOUT6_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||||
|
#endif // > 5
|
||||||
|
#endif // > 4
|
||||||
|
#endif // > 3
|
||||||
|
#endif // > 2
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return (is_out ? ++runout_count : (runout_count = 0)) > FIL_RUNOUT_THRESHOLD;
|
return (is_out ? ++runout_count : (runout_count = 0)) > FIL_RUNOUT_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ void GcodeSuite::G28(const bool always_home_all) {
|
||||||
*/
|
*/
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
|
||||||
if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
|
if (dxc_is_duplicating()) {
|
||||||
|
|
||||||
// Always home the 2nd (right) extruder first
|
// Always home the 2nd (right) extruder first
|
||||||
active_extruder = 1;
|
active_extruder = 1;
|
||||||
|
@ -387,7 +387,10 @@ void GcodeSuite::G28(const bool always_home_all) {
|
||||||
delayed_move_time = 0;
|
delayed_move_time = 0;
|
||||||
active_extruder_parked = true;
|
active_extruder_parked = true;
|
||||||
extruder_duplication_enabled = IDEX_saved_duplication_state;
|
extruder_duplication_enabled = IDEX_saved_duplication_state;
|
||||||
|
extruder_duplication_enabled = false;
|
||||||
|
|
||||||
dual_x_carriage_mode = IDEX_saved_mode;
|
dual_x_carriage_mode = IDEX_saved_mode;
|
||||||
|
stepper.set_directions();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DUAL_X_CARRIAGE
|
#endif // DUAL_X_CARRIAGE
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
* units x-offset and an optional differential hotend temperature of
|
* units x-offset and an optional differential hotend temperature of
|
||||||
* mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate
|
* mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate
|
||||||
* the first with a spacing of 100mm in the x direction and 2 degrees hotter.
|
* the first with a spacing of 100mm in the x direction and 2 degrees hotter.
|
||||||
* M605 S3 : Enable Symmetric Duplication mode. The second extruder will duplicate the first extruder's
|
* M605 S3 : Enable Scaled Duplication mode. The second extruder will duplicate the first extruder's
|
||||||
* movement similar to the M605 S2 mode. However, the second extruder will be producing
|
* movement similar to the M605 S2 mode. However, the second extruder will be producing
|
||||||
* a mirror image of the first extruder. The initial x-offset and temperature differential are
|
* a scaled image of the first extruder. The initial x-offset and temperature differential are
|
||||||
* set with M605 S2 [Xnnn] [Rmmm] and then followed with a M605 S3 to start the mirrored movement.
|
* set with M605 S2 [Xnnn] [Rmmm] and then followed with a M605 S3 to start the mirrored movement.
|
||||||
* M605 W : IDEX What? command.
|
* M605 W : IDEX What? command.
|
||||||
*
|
*
|
||||||
|
@ -56,7 +56,27 @@
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
if (parser.seen('S')) {
|
if (parser.seen('S')) {
|
||||||
|
const DualXMode previous_mode = dual_x_carriage_mode;
|
||||||
|
|
||||||
dual_x_carriage_mode = (DualXMode)parser.value_byte();
|
dual_x_carriage_mode = (DualXMode)parser.value_byte();
|
||||||
|
scaled_duplication_mode = false;
|
||||||
|
|
||||||
|
if (dual_x_carriage_mode == DXC_SCALED_DUPLICATION_MODE) {
|
||||||
|
if (previous_mode != DXC_DUPLICATION_MODE) {
|
||||||
|
SERIAL_ECHOPGM("Printer must be in DXC_DUPLICATION_MODE prior to \n");
|
||||||
|
SERIAL_ECHOPGM("specifying DXC_SCALED_DUPLICATION_MODE.\n");
|
||||||
|
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scaled_duplication_mode = true;
|
||||||
|
stepper.set_directions();
|
||||||
|
float x_jog = current_position[X_AXIS] - .1;
|
||||||
|
for (uint8_t i = 2; --i;) {
|
||||||
|
planner.buffer_line(x_jog, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate_mm_s, 0);
|
||||||
|
x_jog += .1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (dual_x_carriage_mode) {
|
switch (dual_x_carriage_mode) {
|
||||||
case DXC_FULL_CONTROL_MODE:
|
case DXC_FULL_CONTROL_MODE:
|
||||||
|
@ -73,6 +93,7 @@
|
||||||
}
|
}
|
||||||
active_extruder_parked = false;
|
active_extruder_parked = false;
|
||||||
extruder_duplication_enabled = false;
|
extruder_duplication_enabled = false;
|
||||||
|
stepper.set_directions();
|
||||||
delayed_move_time = 0;
|
delayed_move_time = 0;
|
||||||
}
|
}
|
||||||
else if (!parser.seen('W')) // if no S or W parameter, the DXC mode gets reset to the user's default
|
else if (!parser.seen('W')) // if no S or W parameter, the DXC mode gets reset to the user's default
|
||||||
|
@ -82,21 +103,45 @@
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOPGM("IDEX mode: ");
|
SERIAL_ECHOPGM("IDEX mode: ");
|
||||||
switch (dual_x_carriage_mode) {
|
switch (dual_x_carriage_mode) {
|
||||||
case DXC_FULL_CONTROL_MODE: SERIAL_ECHOPGM("DXC_FULL_CONTROL_MODE"); break;
|
case DXC_FULL_CONTROL_MODE: SERIAL_ECHOPGM("DXC_FULL_CONTROL_MODE"); break;
|
||||||
case DXC_AUTO_PARK_MODE: SERIAL_ECHOPGM("DXC_AUTO_PARK_MODE"); break;
|
case DXC_AUTO_PARK_MODE: SERIAL_ECHOPGM("DXC_AUTO_PARK_MODE"); break;
|
||||||
case DXC_DUPLICATION_MODE: SERIAL_ECHOPGM("DXC_DUPLICATION_MODE"); break;
|
case DXC_DUPLICATION_MODE: SERIAL_ECHOPGM("DXC_DUPLICATION_MODE"); break;
|
||||||
|
case DXC_SCALED_DUPLICATION_MODE: SERIAL_ECHOPGM("DXC_SCALED_DUPLICATION_MODE"); break;
|
||||||
}
|
}
|
||||||
SERIAL_ECHOPAIR("\nActive Ext: ", int(active_extruder));
|
SERIAL_ECHOPAIR("\nActive Ext: ", int(active_extruder));
|
||||||
if (!active_extruder_parked) SERIAL_ECHOPGM(" NOT ");
|
if (!active_extruder_parked) SERIAL_ECHOPGM(" NOT ");
|
||||||
SERIAL_ECHOLNPGM(" parked.");
|
SERIAL_ECHOPGM(" parked.");
|
||||||
SERIAL_ECHOPAIR("active_extruder_x_pos: ", current_position[X_AXIS]);
|
SERIAL_ECHOPAIR("\nactive_extruder_x_pos: ", current_position[X_AXIS]);
|
||||||
SERIAL_ECHOPAIR(" inactive_extruder_x_pos: ", inactive_extruder_x_pos);
|
SERIAL_ECHOPAIR("\ninactive_extruder_x_pos: ", inactive_extruder_x_pos);
|
||||||
SERIAL_ECHOPAIR("\nT0 Home X: ", x_home_pos(0));
|
|
||||||
SERIAL_ECHOPAIR("\nT1 Home X: ", x_home_pos(1));
|
|
||||||
SERIAL_ECHOPAIR("\nextruder_duplication_enabled: ", int(extruder_duplication_enabled));
|
SERIAL_ECHOPAIR("\nextruder_duplication_enabled: ", int(extruder_duplication_enabled));
|
||||||
SERIAL_ECHOPAIR("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
|
SERIAL_ECHOPAIR("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
|
||||||
SERIAL_ECHOPAIR("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
|
SERIAL_ECHOPAIR("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
|
||||||
SERIAL_ECHOPAIR("\ndelayed_move_time: ", delayed_move_time);
|
SERIAL_ECHOPAIR("\ndelayed_move_time: ", delayed_move_time);
|
||||||
|
SERIAL_ECHOPAIR("\nX1 Home X: ", x_home_pos(0));
|
||||||
|
SERIAL_ECHOPAIR("\nX1_MIN_POS=", int(X1_MIN_POS));
|
||||||
|
SERIAL_ECHOPAIR("\nX1_MAX_POS=", int(X1_MAX_POS));
|
||||||
|
SERIAL_ECHOPAIR("\nX2 Home X: ", x_home_pos(1));
|
||||||
|
SERIAL_ECHOPAIR("\nX2_MIN_POS=", int(X2_MIN_POS));
|
||||||
|
SERIAL_ECHOPAIR("\nX2_MAX_POS=", int(X2_MAX_POS));
|
||||||
|
SERIAL_ECHOPAIR("\nX2_HOME_DIR=", int(X2_HOME_DIR));
|
||||||
|
SERIAL_ECHOPAIR("\nX2_HOME_POS=", int(X2_HOME_POS));
|
||||||
|
SERIAL_ECHOPAIR("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE));
|
||||||
|
SERIAL_ECHOPAIR("\nTOOLCHANGE_PARK_ZLIFT=", float(TOOLCHANGE_PARK_ZLIFT));
|
||||||
|
SERIAL_ECHOPAIR("\nTOOLCHANGE_UNPARK_ZLIFT=", float(TOOLCHANGE_UNPARK_ZLIFT));
|
||||||
|
SERIAL_ECHOPAIR("\nDEFAULT_DUPLICATION_X_OFFSET=", int(DEFAULT_DUPLICATION_X_OFFSET));
|
||||||
|
|
||||||
|
SERIAL_EOL();
|
||||||
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
|
SERIAL_ECHOPAIR(" nozzle:", int(i));
|
||||||
|
LOOP_XYZ(j) {
|
||||||
|
SERIAL_ECHOPGM(" hotend_offset[");
|
||||||
|
SERIAL_CHAR(axis_codes[j]);
|
||||||
|
SERIAL_ECHOPAIR("_AXIS][", int(i));
|
||||||
|
SERIAL_ECHOPAIR("]=", hotend_offset[j][i]);
|
||||||
|
}
|
||||||
|
SERIAL_EOL();
|
||||||
|
}
|
||||||
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ void GcodeSuite::M7219() {
|
||||||
SERIAL_ECHOPGM("led_line[");
|
SERIAL_ECHOPGM("led_line[");
|
||||||
if (r < 10) SERIAL_CHAR(' ');
|
if (r < 10) SERIAL_CHAR(' ');
|
||||||
SERIAL_ECHO(int(r));
|
SERIAL_ECHO(int(r));
|
||||||
SERIAL_ECHO("]=");
|
SERIAL_ECHOPGM("]=");
|
||||||
for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b));
|
for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b));
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,19 @@ void GcodeSuite::M600() {
|
||||||
|
|
||||||
if (get_target_extruder_from_command()) return;
|
if (get_target_extruder_from_command()) return;
|
||||||
|
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
int8_t DXC_ext = target_extruder;
|
||||||
|
if (!parser.seen('T')) { // If no tool index is specified, M600 was (probably) sent in response to filament runout.
|
||||||
|
// In this case, for duplicating modes set DXC_ext to the extruder that ran out.
|
||||||
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
||||||
|
if (dxc_is_duplicating())
|
||||||
|
DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING) ? 1 : 0;
|
||||||
|
#else
|
||||||
|
DXC_ext = active_extruder;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Show initial "wait for start" message
|
// Show initial "wait for start" message
|
||||||
#if ENABLED(ULTIPANEL)
|
#if ENABLED(ULTIPANEL)
|
||||||
lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INIT, ADVANCED_PAUSE_MODE_PAUSE_PRINT, target_extruder);
|
lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INIT, ADVANCED_PAUSE_MODE_PAUSE_PRINT, target_extruder);
|
||||||
|
@ -63,14 +76,18 @@ void GcodeSuite::M600() {
|
||||||
|
|
||||||
#if ENABLED(HOME_BEFORE_FILAMENT_CHANGE)
|
#if ENABLED(HOME_BEFORE_FILAMENT_CHANGE)
|
||||||
// Don't allow filament change without homing first
|
// Don't allow filament change without homing first
|
||||||
if (axis_unhomed_error()) home_all_axes();
|
if (axis_unhomed_error()) gcode.home_all_axes();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EXTRUDERS > 1
|
#if EXTRUDERS > 1
|
||||||
// Change toolhead if specified
|
// Change toolhead if specified
|
||||||
uint8_t active_extruder_before_filament_change = active_extruder;
|
const uint8_t active_extruder_before_filament_change = active_extruder;
|
||||||
if (active_extruder != target_extruder)
|
if (
|
||||||
tool_change(target_extruder, 0, true);
|
active_extruder != target_extruder
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
&& dual_x_carriage_mode != DXC_DUPLICATION_MODE && dual_x_carriage_mode != DXC_SCALED_DUPLICATION_MODE
|
||||||
|
#endif
|
||||||
|
) tool_change(target_extruder, 0, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initial retract before move to filament change position
|
// Initial retract before move to filament change position
|
||||||
|
@ -113,9 +130,9 @@ void GcodeSuite::M600() {
|
||||||
|
|
||||||
const bool job_running = print_job_timer.isRunning();
|
const bool job_running = print_job_timer.isRunning();
|
||||||
|
|
||||||
if (pause_print(retract, park_point, unload_length, true)) {
|
if (pause_print(retract, park_point, unload_length, true DXC_PASS)) {
|
||||||
wait_for_filament_reload(beep_count);
|
wait_for_filament_reload(beep_count DXC_PASS);
|
||||||
resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, beep_count);
|
resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, beep_count DXC_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EXTRUDERS > 1
|
#if EXTRUDERS > 1
|
||||||
|
|
|
@ -81,7 +81,11 @@ void GcodeSuite::M701() {
|
||||||
const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS)
|
const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS)
|
||||||
: filament_change_load_length[active_extruder]);
|
: filament_change_load_length[active_extruder]);
|
||||||
load_filament(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, FILAMENT_CHANGE_ALERT_BEEPS,
|
load_filament(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, FILAMENT_CHANGE_ALERT_BEEPS,
|
||||||
true, thermalManager.wait_for_heating(target_extruder), ADVANCED_PAUSE_MODE_LOAD_FILAMENT);
|
true, thermalManager.wait_for_heating(target_extruder), ADVANCED_PAUSE_MODE_LOAD_FILAMENT
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
, target_extruder
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
// Restore Z axis
|
// Restore Z axis
|
||||||
if (park_point.z > 0)
|
if (park_point.z > 0)
|
||||||
|
|
|
@ -139,12 +139,12 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok=false
|
||||||
*/
|
*/
|
||||||
bool enqueue_and_echo_command(const char* cmd) {
|
bool enqueue_and_echo_command(const char* cmd) {
|
||||||
|
|
||||||
//SERIAL_ECHO("enqueue_and_echo_command(\"");
|
//SERIAL_ECHOPGM("enqueue_and_echo_command(\"");
|
||||||
//SERIAL_ECHO(cmd);
|
//SERIAL_ECHO(cmd);
|
||||||
//SERIAL_ECHO("\") \n");
|
//SERIAL_ECHOPGM("\") \n");
|
||||||
|
|
||||||
if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') {
|
if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') {
|
||||||
//SERIAL_ECHO("Null command found... Did not queue!\n");
|
//SERIAL_ECHOPGM("Null command found... Did not queue!\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ void GcodeSuite::M104() {
|
||||||
thermalManager.setTargetHotend(temp, e);
|
thermalManager.setTargetHotend(temp, e);
|
||||||
|
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && e == 0)
|
if (dxc_is_duplicating() && e == 0)
|
||||||
thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
|
thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ void GcodeSuite::M109() {
|
||||||
thermalManager.setTargetHotend(temp, target_extruder);
|
thermalManager.setTargetHotend(temp, target_extruder);
|
||||||
|
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0)
|
if (dxc_is_duplicating() && target_extruder == 0)
|
||||||
thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
|
thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -214,9 +214,24 @@
|
||||||
#ifndef MSG_IDEX_MODE_DUPLICATE
|
#ifndef MSG_IDEX_MODE_DUPLICATE
|
||||||
#define MSG_IDEX_MODE_DUPLICATE _UxGT("Duplication")
|
#define MSG_IDEX_MODE_DUPLICATE _UxGT("Duplication")
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MSG_IDEX_MODE_SCALED_COPY
|
||||||
|
#define MSG_IDEX_MODE_SCALED_COPY _UxGT("Scaled copy")
|
||||||
|
#endif
|
||||||
#ifndef MSG_IDEX_MODE_FULL_CTRL
|
#ifndef MSG_IDEX_MODE_FULL_CTRL
|
||||||
#define MSG_IDEX_MODE_FULL_CTRL _UxGT("Full control")
|
#define MSG_IDEX_MODE_FULL_CTRL _UxGT("Full control")
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MSG_IDEX_X_OFFSET
|
||||||
|
#define MSG_IDEX_X_OFFSET _UxGT("2nd nozzle X")
|
||||||
|
#endif
|
||||||
|
#ifndef MSG_IDEX_Y_OFFSET
|
||||||
|
#define MSG_IDEX_Y_OFFSET _UxGT("2nd nozzle Y")
|
||||||
|
#endif
|
||||||
|
#ifndef MSG_IDEX_Z_OFFSET
|
||||||
|
#define MSG_IDEX_Z_OFFSET _UxGT("2nd nozzle Z")
|
||||||
|
#endif
|
||||||
|
#ifndef MSG_IDEX_SAVE_OFFSETS
|
||||||
|
#define MSG_IDEX_SAVE_OFFSETS _UxGT("Save Offsets")
|
||||||
|
#endif
|
||||||
#ifndef MSG_UBL_MANUAL_MESH
|
#ifndef MSG_UBL_MANUAL_MESH
|
||||||
#define MSG_UBL_MANUAL_MESH _UxGT("Manually Build Mesh")
|
#define MSG_UBL_MANUAL_MESH _UxGT("Manually Build Mesh")
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
#include "../gcode/gcode.h"
|
#include "../gcode/gcode.h"
|
||||||
#include "../gcode/queue.h"
|
#include "../gcode/queue.h"
|
||||||
#include "../module/configuration_store.h"
|
#include "../module/configuration_store.h"
|
||||||
|
#include "../module/tool_change.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../Marlin.h"
|
#include "../Marlin.h"
|
||||||
|
|
||||||
|
@ -521,7 +523,7 @@ uint16_t max_display_update_time = 0;
|
||||||
if (currentScreen == lcd_status_screen)
|
if (currentScreen == lcd_status_screen)
|
||||||
doubleclick_expire_ms = millis() + DOUBLECLICK_MAX_INTERVAL;
|
doubleclick_expire_ms = millis() + DOUBLECLICK_MAX_INTERVAL;
|
||||||
}
|
}
|
||||||
else if (screen == lcd_status_screen && currentScreen == lcd_main_menu && PENDING(millis(), doubleclick_expire_ms) && (planner.movesplanned() || IS_SD_PRINTING))
|
else if (screen == lcd_status_screen && currentScreen == lcd_main_menu && PENDING(millis(), doubleclick_expire_ms)/* && (planner.movesplanned() || IS_SD_PRINTING)*/)
|
||||||
screen =
|
screen =
|
||||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||||
lcd_babystep_zoffset
|
lcd_babystep_zoffset
|
||||||
|
@ -1038,15 +1040,31 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
* IDEX submenu
|
* IDEX submenu
|
||||||
*/
|
*/
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
static void _recalc_IDEX_settings() {
|
||||||
|
if (active_extruder) { // For the 2nd extruder re-home so the next tool-change gets the new offsets.
|
||||||
|
enqueue_and_echo_commands_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
|
||||||
|
active_extruder = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void IDEX_menu() {
|
static void IDEX_menu() {
|
||||||
START_MENU();
|
START_MENU();
|
||||||
MENU_BACK(MSG_MAIN);
|
MENU_BACK(MSG_MAIN);
|
||||||
MENU_ITEM(gcode, MSG_IDEX_MODE_AUTOPARK, PSTR("M605 S1\nG28 X\nG1 X100"));
|
MENU_ITEM(gcode, MSG_IDEX_MODE_AUTOPARK, PSTR("M605 S1\nG28 X\nG1 X100"));
|
||||||
if (!TEST(axis_known_position, Y_AXIS) || !TEST(axis_known_position, Z_AXIS))
|
const bool need_g28 = !(TEST(axis_known_position, Y_AXIS) && TEST(axis_known_position, Z_AXIS));
|
||||||
MENU_ITEM(gcode, MSG_IDEX_MODE_DUPLICATE, PSTR("T0\nG28\nM605 S2 X200\nG28 X\nG1 X100")); // If Y or Z is not homed, a full G28 is done first.
|
MENU_ITEM(gcode, MSG_IDEX_MODE_DUPLICATE, need_g28
|
||||||
else
|
? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100") // If Y or Z is not homed, do a full G28 first
|
||||||
MENU_ITEM(gcode, MSG_IDEX_MODE_DUPLICATE, PSTR("T0\nM605 S2 X200\nG28 X\nG1 X100")); // If Y and Z is homed, a full G28 is not needed first.
|
: PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100")
|
||||||
|
);
|
||||||
|
MENU_ITEM(gcode, MSG_IDEX_MODE_SCALED_COPY, need_g28
|
||||||
|
? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100\nM605 S3 X200") // If Y or Z is not homed, do a full G28 first
|
||||||
|
: PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100\nM605 S3 X200")
|
||||||
|
);
|
||||||
MENU_ITEM(gcode, MSG_IDEX_MODE_FULL_CTRL, PSTR("M605 S0\nG28 X"));
|
MENU_ITEM(gcode, MSG_IDEX_MODE_FULL_CTRL, PSTR("M605 S0\nG28 X"));
|
||||||
|
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52, MSG_IDEX_X_OFFSET , &hotend_offset[X_AXIS][1], MIN(X2_HOME_POS, X2_MAX_POS) - 25.0, MAX(X2_HOME_POS, X2_MAX_POS) + 25.0, _recalc_IDEX_settings);
|
||||||
|
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52, MSG_IDEX_Y_OFFSET , &hotend_offset[Y_AXIS][1], -10.0, 10.0, _recalc_IDEX_settings);
|
||||||
|
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52, MSG_IDEX_Z_OFFSET , &hotend_offset[Z_AXIS][1], -10.0, 10.0, _recalc_IDEX_settings);
|
||||||
|
MENU_ITEM(gcode, MSG_IDEX_SAVE_OFFSETS, PSTR("M500"));
|
||||||
END_MENU();
|
END_MENU();
|
||||||
}
|
}
|
||||||
#endif // DUAL_X_CARRIAGE
|
#endif // DUAL_X_CARRIAGE
|
||||||
|
|
|
@ -1886,6 +1886,9 @@ void MarlinSettings::reset(PORTARG_SOLO) {
|
||||||
"Offsets for the first hotend must be 0.0."
|
"Offsets for the first hotend must be 0.0."
|
||||||
);
|
);
|
||||||
LOOP_XYZ(i) HOTEND_LOOP() hotend_offset[i][e] = tmp4[i][e];
|
LOOP_XYZ(i) HOTEND_LOOP() hotend_offset[i][e] = tmp4[i][e];
|
||||||
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
hotend_offset[X_AXIS][1] = MAX(X2_HOME_POS, X2_MAX_POS);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -760,7 +760,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
|
|
||||||
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
|
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
|
||||||
bool extruder_duplication_enabled = false, // Used in Dual X mode 2 & 3
|
bool extruder_duplication_enabled = false, // Used in Dual X mode 2 & 3
|
||||||
symmetric_duplication_mode = false; // Used in Dual X mode 2 & 3
|
scaled_duplication_mode = false; // Used in Dual X mode 2 & 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
@ -818,8 +818,6 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
#define RAISED_Y raised_parked_position[Y_AXIS]
|
#define RAISED_Y raised_parked_position[Y_AXIS]
|
||||||
#define RAISED_Z raised_parked_position[Z_AXIS]
|
#define RAISED_Z raised_parked_position[Z_AXIS]
|
||||||
|
|
||||||
//SERIAL_ECHOLNPGM("dual_x_carriage_unpark()\n");
|
|
||||||
|
|
||||||
if ( planner.buffer_line(RAISED_X, RAISED_Y, RAISED_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder))
|
if ( planner.buffer_line(RAISED_X, RAISED_Y, RAISED_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder))
|
||||||
if (planner.buffer_line( CUR_X, CUR_Y, RAISED_Z, CUR_E, PLANNER_XY_FEEDRATE(), active_extruder))
|
if (planner.buffer_line( CUR_X, CUR_Y, RAISED_Z, CUR_E, PLANNER_XY_FEEDRATE(), active_extruder))
|
||||||
planner.buffer_line( CUR_X, CUR_Y, CUR_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
planner.buffer_line( CUR_X, CUR_Y, CUR_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
||||||
|
@ -829,6 +827,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Clear active_extruder_parked");
|
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Clear active_extruder_parked");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case DXC_SCALED_DUPLICATION_MODE:
|
||||||
case DXC_DUPLICATION_MODE:
|
case DXC_DUPLICATION_MODE:
|
||||||
if (active_extruder == 0) {
|
if (active_extruder == 0) {
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
|
@ -839,10 +838,12 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
#endif
|
#endif
|
||||||
// move duplicate extruder into correct duplication position.
|
// move duplicate extruder into correct duplication position.
|
||||||
planner.set_position_mm(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
planner.set_position_mm(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||||
|
|
||||||
if (!planner.buffer_line(
|
if (!planner.buffer_line(
|
||||||
current_position[X_AXIS] + duplicate_extruder_x_offset,
|
dual_x_carriage_mode == DXC_DUPLICATION_MODE ? duplicate_extruder_x_offset + current_position[X_AXIS] : inactive_extruder_x_pos,
|
||||||
current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS],
|
current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS],
|
||||||
planner.max_feedrate_mm_s[X_AXIS], 1)
|
planner.max_feedrate_mm_s[X_AXIS], 1
|
||||||
|
)
|
||||||
) break;
|
) break;
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
sync_plan_position();
|
sync_plan_position();
|
||||||
|
@ -860,6 +861,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stepper.set_directions();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,9 +908,9 @@ void prepare_move_to_destination() {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
#if UBL_SEGMENTED
|
#if UBL_SEGMENTED
|
||||||
// ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) // This does not seem to work correctly on UBL.
|
//ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) // This doesn't seem to work correctly on UBL.
|
||||||
#if ENABLED(DELTA) // A Delta case and a Cartesian case can work
|
#if IS_KINEMATIC // Use Kinematic / Cartesian cases as a workaround for now.
|
||||||
ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) // around the problem until it is fixed.
|
ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s))
|
||||||
#else
|
#else
|
||||||
prepare_move_to_destination_cartesian()
|
prepare_move_to_destination_cartesian()
|
||||||
#endif
|
#endif
|
||||||
|
@ -1499,7 +1501,7 @@ void homeaxis(const AxisEnum axis) {
|
||||||
soft_endstop_min[X_AXIS] = X2_MIN_POS;
|
soft_endstop_min[X_AXIS] = X2_MIN_POS;
|
||||||
soft_endstop_max[X_AXIS] = dual_max_x;
|
soft_endstop_max[X_AXIS] = dual_max_x;
|
||||||
}
|
}
|
||||||
else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
|
else if (dxc_is_duplicating()) {
|
||||||
// In Duplication Mode, T0 can move as far left as X_MIN_POS
|
// In Duplication Mode, T0 can move as far left as X_MIN_POS
|
||||||
// but not so far to the right that T1 would move past the end
|
// but not so far to the right that T1 would move past the end
|
||||||
soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS);
|
soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS);
|
||||||
|
|
|
@ -305,7 +305,7 @@ void homeaxis(const AxisEnum axis);
|
||||||
*/
|
*/
|
||||||
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
|
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
|
||||||
extern bool extruder_duplication_enabled, // Used in Dual X mode 2
|
extern bool extruder_duplication_enabled, // Used in Dual X mode 2
|
||||||
symmetric_duplication_mode; // Used in Dual X mode 2
|
scaled_duplication_mode; // Used in Dual X mode 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,9 +314,10 @@ void homeaxis(const AxisEnum axis);
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE)
|
||||||
|
|
||||||
enum DualXMode : char {
|
enum DualXMode : char {
|
||||||
DXC_FULL_CONTROL_MODE, // DUAL_X_CARRIAGE only
|
DXC_FULL_CONTROL_MODE,
|
||||||
DXC_AUTO_PARK_MODE, // DUAL_X_CARRIAGE only
|
DXC_AUTO_PARK_MODE,
|
||||||
DXC_DUPLICATION_MODE
|
DXC_DUPLICATION_MODE,
|
||||||
|
DXC_SCALED_DUPLICATION_MODE
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DualXMode dual_x_carriage_mode;
|
extern DualXMode dual_x_carriage_mode;
|
||||||
|
@ -327,6 +328,8 @@ void homeaxis(const AxisEnum axis);
|
||||||
extern millis_t delayed_move_time; // used in mode 1
|
extern millis_t delayed_move_time; // used in mode 1
|
||||||
extern int16_t duplicate_extruder_temp_offset; // used in mode 2 & 3
|
extern int16_t duplicate_extruder_temp_offset; // used in mode 2 & 3
|
||||||
|
|
||||||
|
FORCE_INLINE bool dxc_is_duplicating() { return dual_x_carriage_mode >= DXC_DUPLICATION_MODE; }
|
||||||
|
|
||||||
float x_home_pos(const int extruder);
|
float x_home_pos(const int extruder);
|
||||||
|
|
||||||
FORCE_INLINE int x_home_dir(const uint8_t extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; }
|
FORCE_INLINE int x_home_dir(const uint8_t extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; }
|
||||||
|
|
|
@ -251,7 +251,7 @@ int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
|
||||||
#define X_APPLY_DIR(v,ALWAYS) \
|
#define X_APPLY_DIR(v,ALWAYS) \
|
||||||
if (extruder_duplication_enabled || ALWAYS) { \
|
if (extruder_duplication_enabled || ALWAYS) { \
|
||||||
X_DIR_WRITE(v); \
|
X_DIR_WRITE(v); \
|
||||||
X2_DIR_WRITE(bool(v)); \
|
X2_DIR_WRITE(v); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
if (movement_extruder()) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
|
if (movement_extruder()) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
|
||||||
|
|
|
@ -472,13 +472,10 @@ class Stepper {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Set direction bits for all steppers
|
// Set direction bits for all steppers
|
||||||
static void set_directions();
|
static void set_directions();
|
||||||
|
|
||||||
// Allow reset_stepper_drivers to access private set_directions
|
private:
|
||||||
friend void reset_stepper_drivers();
|
|
||||||
|
|
||||||
// Set the current position in steps
|
// Set the current position in steps
|
||||||
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
|
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
|
||||||
|
|
|
@ -562,9 +562,18 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||||
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
|
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
|
||||||
#elif E_STEPPERS > 1
|
#elif E_STEPPERS > 1
|
||||||
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
|
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
|
||||||
#define E_STEP_WRITE(E,V) do{ if (extruder_duplication_enabled) { E0_STEP_WRITE(V); E1_STEP_WRITE(V); } else if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
|
|
||||||
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
|
#define E_STEP_WRITE(E,V) do{ if (extruder_duplication_enabled) { E0_STEP_WRITE(V); E1_STEP_WRITE(V); } \
|
||||||
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } else if (E == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
|
else if ((E) == 0) { E0_STEP_WRITE(V); } \
|
||||||
|
else { E1_STEP_WRITE(V); } }while(0)
|
||||||
|
|
||||||
|
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } \
|
||||||
|
else if ((E) == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } \
|
||||||
|
else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
|
||||||
|
|
||||||
|
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } \
|
||||||
|
else if ((E) == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } \
|
||||||
|
else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
|
||||||
#else
|
#else
|
||||||
#define E_STEP_WRITE(E,V) do{ if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
|
#define E_STEP_WRITE(E,V) do{ if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
|
||||||
#define NORM_E_DIR(E) do{ if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
|
#define NORM_E_DIR(E) do{ if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
|
||||||
|
|
|
@ -366,6 +366,8 @@ inline void invalid_extruder_error(const uint8_t e) {
|
||||||
switch (dual_x_carriage_mode) {
|
switch (dual_x_carriage_mode) {
|
||||||
case DXC_FULL_CONTROL_MODE: SERIAL_ECHOLNPGM("DXC_FULL_CONTROL_MODE"); break;
|
case DXC_FULL_CONTROL_MODE: SERIAL_ECHOLNPGM("DXC_FULL_CONTROL_MODE"); break;
|
||||||
case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break;
|
case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break;
|
||||||
|
case DXC_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break;
|
||||||
|
case DXC_SCALED_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_SCALED_DUPLICATION_MODE"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -455,9 +457,8 @@ inline void invalid_extruder_error(const uint8_t e) {
|
||||||
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) {
|
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) {
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
#if ENABLED(DUAL_X_CARRIAGE)
|
#if ENABLED(DUAL_X_CARRIAGE) // Only T0 allowed if the Printer is in DXC_DUPLICATION_MODE or DXC_SCALED_DUPLICATION_MODE
|
||||||
// Only T0 allowed in DXC_DUPLICATION_MODE
|
if (tmp_extruder != 0 && dxc_is_duplicating())
|
||||||
if (tmp_extruder != 0 && dual_x_carriage_mode == DXC_DUPLICATION_MODE)
|
|
||||||
return invalid_extruder_error(tmp_extruder);
|
return invalid_extruder_error(tmp_extruder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
#error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
|
#error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if E_STEPPERS > 3 || HOTENDS > 3
|
#if E_STEPPERS > 2 || HOTENDS > 2
|
||||||
#error "Formbot supports up to 3 hotends / E-steppers. Comment this line to keep going."
|
#error "Formbot supports up to 2 hotends / E-steppers. Comment this line to keep going."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_MACHINE_NAME "Formbot"
|
#define DEFAULT_MACHINE_NAME "Formbot"
|
||||||
|
@ -143,17 +143,15 @@
|
||||||
#define HEATER_BED_PIN 58
|
#define HEATER_BED_PIN 58
|
||||||
|
|
||||||
#define FAN_PIN 9
|
#define FAN_PIN 9
|
||||||
#define FAN1_PIN 4
|
//#define FAN1_PIN 4
|
||||||
|
|
||||||
|
|
||||||
#if DISABLED(ICSP_PORT_SWITCHES)
|
#if DISABLED(ICSP_PORT_SWITCHES)
|
||||||
#define FIL_RUNOUT_PIN 22
|
//#define FIL_RUNOUT_PIN 22
|
||||||
#define FIL_RUNOUT2_PIN 21
|
//#define FIL_RUNOUT2_PIN 21
|
||||||
#else
|
#elif ENABLED(FILAMENT_RUNOUT_SENSOR)
|
||||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
#define FIL_RUNOUT_PIN 52
|
||||||
#define FIL_RUNOUT_PIN 52
|
#define FIL_RUNOUT2_PIN 50
|
||||||
#define FIL_RUNOUT2_PIN 50
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -162,8 +160,8 @@
|
||||||
#define CASE_LIGHT_PIN 8
|
#define CASE_LIGHT_PIN 8
|
||||||
#define SDSS 53
|
#define SDSS 53
|
||||||
#ifndef ROXYs_TRex
|
#ifndef ROXYs_TRex
|
||||||
#define LED_PIN 13
|
#define LED_PIN 13 // The Formbot v 1 board has almost no unassigned pins on it. The Board's LED
|
||||||
#endif
|
#endif // is a good place to get a signal to control the Max7219 LED Matrix.
|
||||||
|
|
||||||
// Use the RAMPS 1.4 Analog input 5 on the AUX2 connector
|
// Use the RAMPS 1.4 Analog input 5 on the AUX2 connector
|
||||||
#define FILWIDTH_PIN 5 // Analog Input
|
#define FILWIDTH_PIN 5 // Analog Input
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
#error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
|
#error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if E_STEPPERS > 3 || HOTENDS > 3
|
#if E_STEPPERS > 2 || HOTENDS > 2
|
||||||
#error "Formbot supports up to 3 hotends / E-steppers. Comment this line to keep going."
|
#error "Formbot supports up to 2 hotends / E-steppers. Comment this line to keep going."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_MACHINE_NAME "Formbot"
|
#define DEFAULT_MACHINE_NAME "Formbot"
|
||||||
|
@ -143,18 +143,10 @@
|
||||||
#define HEATER_BED_PIN 8
|
#define HEATER_BED_PIN 8
|
||||||
|
|
||||||
#define FAN_PIN 9
|
#define FAN_PIN 9
|
||||||
#define FAN1_PIN 4
|
//#define FAN1_PIN 4
|
||||||
|
|
||||||
|
#define FIL_RUNOUT_PIN 23
|
||||||
#if DISABLED(ICSP_PORT_SWITCHES)
|
#define FIL_RUNOUT2_PIN 21
|
||||||
#define FIL_RUNOUT_PIN 22
|
|
||||||
#define FIL_RUNOUT2_PIN 21
|
|
||||||
#else
|
|
||||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
|
||||||
#define FIL_RUNOUT_PIN 52
|
|
||||||
#define FIL_RUNOUT2_PIN 50
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Misc. Functions
|
// Misc. Functions
|
||||||
|
|
Reference in a new issue