diff --git a/Marlin/src/config/examples/Formbot/T-Rex_2+/Configuration.h b/Marlin/src/config/examples/Formbot/T-Rex_2+/Configuration.h index 408291c938..7079ea881f 100644 --- a/Marlin/src/config/examples/Formbot/T-Rex_2+/Configuration.h +++ b/Marlin/src/config/examples/Formbot/T-Rex_2+/Configuration.h @@ -22,7 +22,7 @@ //#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 // More aggressive PID numbers for hotends (due to double fans) /** diff --git a/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h b/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h index 72d1ce5c2f..522b335756 100644 --- a/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h +++ b/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h @@ -385,9 +385,7 @@ // 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 // 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 - // 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. + // Mode 3 (DXC_SCALED_DUPLICATION_MODE) : Not working yet, but support routines in place // This is the default power-up mode which can be later using M605. #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.cpp b/Marlin/src/feature/Max7219_Debug_LEDs.cpp index 0588c836b5..c8aaaaffeb 100644 --- a/Marlin/src/feature/Max7219_Debug_LEDs.cpp +++ b/Marlin/src/feature/Max7219_Debug_LEDs.cpp @@ -56,6 +56,8 @@ uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 }; #if _ROT == 0 || _ROT == 270 #define _LED_BIT(Q) (7 - ((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 #define _LED_BIT(Q) ((Q) & 0x7) #define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3) diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 0af61060d6..2b7f547dd6 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -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*/, const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/, const AdvancedPauseMode mode/*=ADVANCED_PAUSE_MODE_PAUSE_PRINT*/ + DXC_ARGS ) { #if DISABLED(ULTIPANEL) 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); #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 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 } + #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(ULTIPANEL) @@ -328,7 +342,8 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, */ 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 #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()) Nozzle::park(2, park_point); - // Unload the filament - if (unload_length) + #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 + + if (unload_length) // Unload the filament 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; } @@ -394,7 +421,7 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u * * 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; #if ENABLED(ULTIPANEL) @@ -413,6 +440,13 @@ void wait_for_filament_reload(const int8_t max_beep_count/*=0*/) { HOTEND_LOOP() 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 KEEPALIVE_STATE(PAUSED_FOR_USER); 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); } + #if ENABLED(DUAL_X_CARRIAGE) + active_extruder = saved_ext; + extruder_duplication_enabled = saved_ext_dup_mode; + stepper.set_directions(); + #endif 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 * - 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; // 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); } - if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) { - // Load the new filament - load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out); - } + if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // 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); #if ENABLED(ULTIPANEL) - // "Wait for print to resume" - lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_RESUME); + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_RESUME); // "Wait for print to resume" #endif // Intelligent resuming diff --git a/Marlin/src/feature/pause.h b/Marlin/src/feature/pause.h index c920fd599f..5eb39a5e1a 100644 --- a/Marlin/src/feature/pause.h +++ b/Marlin/src/feature/pause.h @@ -67,14 +67,24 @@ extern float filament_change_unload_length[EXTRUDERS], 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, - 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); diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index 85e9384fa6..aaabaad6e9 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -62,22 +62,31 @@ class FilamentRunoutSensor { #else // Read the sensor for the active extruder bool is_out; - switch (active_extruder) { - case 0: is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; break; - case 1: is_out = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; break; - #if NUM_RUNOUT_SENSORS > 2 - case 2: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break; - #if NUM_RUNOUT_SENSORS > 3 - 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 - #endif - #endif - #endif + #if ENABLED(DUAL_X_CARRIAGE) + const bool out1 = READ(FIL_RUNOUT_PIN ) == FIL_RUNOUT_INVERTING, + out2 = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; + if (extruder_duplication_enabled) + is_out = out1 || out2; + else + is_out = active_extruder ? out2 : out1; + #else + switch (active_extruder) { + case 0: is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; break; + case 1: is_out = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; break; + #if NUM_RUNOUT_SENSORS > 2 + case 2: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break; + #if NUM_RUNOUT_SENSORS > 3 + 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 return (is_out ? ++runout_count : (runout_count = 0)) > FIL_RUNOUT_THRESHOLD; } diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 66054d00e5..6553fc5cfc 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -369,7 +369,7 @@ void GcodeSuite::G28(const bool always_home_all) { */ #if ENABLED(DUAL_X_CARRIAGE) - if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { + if (dxc_is_duplicating()) { // Always home the 2nd (right) extruder first active_extruder = 1; @@ -387,7 +387,10 @@ void GcodeSuite::G28(const bool always_home_all) { delayed_move_time = 0; active_extruder_parked = true; extruder_duplication_enabled = IDEX_saved_duplication_state; + extruder_duplication_enabled = false; + dual_x_carriage_mode = IDEX_saved_mode; + stepper.set_directions(); } #endif // DUAL_X_CARRIAGE diff --git a/Marlin/src/gcode/control/M605.cpp b/Marlin/src/gcode/control/M605.cpp index 80b39ef301..780a7f57b5 100644 --- a/Marlin/src/gcode/control/M605.cpp +++ b/Marlin/src/gcode/control/M605.cpp @@ -44,9 +44,9 @@ * units x-offset and an optional differential hotend temperature of * 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. - * 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 - * 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. * M605 W : IDEX What? command. * @@ -56,7 +56,27 @@ planner.synchronize(); if (parser.seen('S')) { + const DualXMode previous_mode = dual_x_carriage_mode; + 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) { case DXC_FULL_CONTROL_MODE: @@ -73,6 +93,7 @@ } active_extruder_parked = false; extruder_duplication_enabled = false; + stepper.set_directions(); 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 @@ -82,21 +103,45 @@ SERIAL_ECHO_START(); SERIAL_ECHOPGM("IDEX mode: "); switch (dual_x_carriage_mode) { - 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_DUPLICATION_MODE: SERIAL_ECHOPGM("DXC_DUPLICATION_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_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)); if (!active_extruder_parked) SERIAL_ECHOPGM(" NOT "); - SERIAL_ECHOLNPGM(" parked."); - SERIAL_ECHOPAIR("active_extruder_x_pos: ", current_position[X_AXIS]); - SERIAL_ECHOPAIR(" inactive_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_ECHOPGM(" parked."); + SERIAL_ECHOPAIR("\nactive_extruder_x_pos: ", current_position[X_AXIS]); + SERIAL_ECHOPAIR("\ninactive_extruder_x_pos: ", inactive_extruder_x_pos); SERIAL_ECHOPAIR("\nextruder_duplication_enabled: ", int(extruder_duplication_enabled)); SERIAL_ECHOPAIR("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset); SERIAL_ECHOPAIR("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset); 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(); } } diff --git a/Marlin/src/gcode/feature/leds/M7219.cpp b/Marlin/src/gcode/feature/leds/M7219.cpp index 3621c4ac02..2a141185e0 100644 --- a/Marlin/src/gcode/feature/leds/M7219.cpp +++ b/Marlin/src/gcode/feature/leds/M7219.cpp @@ -79,7 +79,7 @@ void GcodeSuite::M7219() { SERIAL_ECHOPGM("led_line["); if (r < 10) SERIAL_CHAR(' '); SERIAL_ECHO(int(r)); - SERIAL_ECHO("]="); + SERIAL_ECHOPGM("]="); for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b)); SERIAL_EOL(); } diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index 42ed74dbe1..5bb54de65c 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -56,6 +56,19 @@ void GcodeSuite::M600() { 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 #if ENABLED(ULTIPANEL) 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) // Don't allow filament change without homing first - if (axis_unhomed_error()) home_all_axes(); + if (axis_unhomed_error()) gcode.home_all_axes(); #endif #if EXTRUDERS > 1 // Change toolhead if specified - uint8_t active_extruder_before_filament_change = active_extruder; - if (active_extruder != target_extruder) - tool_change(target_extruder, 0, true); + const uint8_t active_extruder_before_filament_change = active_extruder; + if ( + 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 // Initial retract before move to filament change position @@ -113,9 +130,9 @@ void GcodeSuite::M600() { const bool job_running = print_job_timer.isRunning(); - if (pause_print(retract, park_point, unload_length, true)) { - wait_for_filament_reload(beep_count); - resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, beep_count); + if (pause_print(retract, park_point, unload_length, true DXC_PASS)) { + wait_for_filament_reload(beep_count DXC_PASS); + resume_print(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, beep_count DXC_PASS); } #if EXTRUDERS > 1 diff --git a/Marlin/src/gcode/feature/pause/M701_M702.cpp b/Marlin/src/gcode/feature/pause/M701_M702.cpp index d9b4175cea..1203b6bd09 100644 --- a/Marlin/src/gcode/feature/pause/M701_M702.cpp +++ b/Marlin/src/gcode/feature/pause/M701_M702.cpp @@ -81,7 +81,11 @@ void GcodeSuite::M701() { const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) : filament_change_load_length[active_extruder]); 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 if (park_point.z > 0) diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 7951e5904f..7187f1fee0 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -139,12 +139,12 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok=false */ 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("\") \n"); + //SERIAL_ECHOPGM("\") \n"); 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; } diff --git a/Marlin/src/gcode/temperature/M104_M109.cpp b/Marlin/src/gcode/temperature/M104_M109.cpp index 61099aa208..07859ca21e 100644 --- a/Marlin/src/gcode/temperature/M104_M109.cpp +++ b/Marlin/src/gcode/temperature/M104_M109.cpp @@ -53,7 +53,7 @@ void GcodeSuite::M104() { thermalManager.setTargetHotend(temp, e); #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); #endif @@ -103,7 +103,7 @@ void GcodeSuite::M109() { thermalManager.setTargetHotend(temp, target_extruder); #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); #endif diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 78280b8977..d02927bf3f 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -214,9 +214,24 @@ #ifndef MSG_IDEX_MODE_DUPLICATE #define MSG_IDEX_MODE_DUPLICATE _UxGT("Duplication") #endif +#ifndef MSG_IDEX_MODE_SCALED_COPY + #define MSG_IDEX_MODE_SCALED_COPY _UxGT("Scaled copy") +#endif #ifndef MSG_IDEX_MODE_FULL_CTRL #define MSG_IDEX_MODE_FULL_CTRL _UxGT("Full control") #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 #define MSG_UBL_MANUAL_MESH _UxGT("Manually Build Mesh") #endif diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index 070d127850..1a0d5f9839 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -38,6 +38,8 @@ #include "../gcode/gcode.h" #include "../gcode/queue.h" #include "../module/configuration_store.h" +#include "../module/tool_change.h" + #include "../Marlin.h" @@ -521,7 +523,7 @@ uint16_t max_display_update_time = 0; if (currentScreen == lcd_status_screen) 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 = #if ENABLED(BABYSTEP_ZPROBE_OFFSET) lcd_babystep_zoffset @@ -1038,15 +1040,31 @@ void lcd_quick_feedback(const bool clear_buttons) { * IDEX submenu */ #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() { START_MENU(); MENU_BACK(MSG_MAIN); - 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)) - 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. - else - 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. + MENU_ITEM(gcode, MSG_IDEX_MODE_AUTOPARK, PSTR("M605 S1\nG28 X\nG1 X100")); + const bool need_g28 = !(TEST(axis_known_position, Y_AXIS) && TEST(axis_known_position, Z_AXIS)); + MENU_ITEM(gcode, MSG_IDEX_MODE_DUPLICATE, need_g28 + ? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100") // If Y or Z is not homed, do a full G28 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_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(); } #endif // DUAL_X_CARRIAGE diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index 031bb2830a..101175b229 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -1886,6 +1886,9 @@ void MarlinSettings::reset(PORTARG_SOLO) { "Offsets for the first hotend must be 0.0." ); 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 // diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 06db3caf04..5094a0952a 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -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) 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 #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_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( 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); @@ -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"); #endif break; + case DXC_SCALED_DUPLICATION_MODE: case DXC_DUPLICATION_MODE: if (active_extruder == 0) { #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -839,10 +838,12 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS }, #endif // 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]); + if (!planner.buffer_line( - current_position[X_AXIS] + duplicate_extruder_x_offset, - current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], - planner.max_feedrate_mm_s[X_AXIS], 1) + 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], + planner.max_feedrate_mm_s[X_AXIS], 1 + ) ) break; planner.synchronize(); sync_plan_position(); @@ -860,6 +861,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS }, break; } } + stepper.set_directions(); return false; } @@ -906,9 +908,9 @@ void prepare_move_to_destination() { if ( #if UBL_SEGMENTED -// ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) // This does not seem to work correctly on UBL. - #if ENABLED(DELTA) // A Delta case and a Cartesian case can work - 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)) // This doesn't seem to work correctly on UBL. + #if IS_KINEMATIC // Use Kinematic / Cartesian cases as a workaround for now. + ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) #else prepare_move_to_destination_cartesian() #endif @@ -1499,7 +1501,7 @@ void homeaxis(const AxisEnum axis) { soft_endstop_min[X_AXIS] = X2_MIN_POS; 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 // but not so far to the right that T1 would move past the end soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS); diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 7d05a0ebd4..1b4f727c8e 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -305,7 +305,7 @@ void homeaxis(const AxisEnum axis); */ #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) 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 /** @@ -314,9 +314,10 @@ void homeaxis(const AxisEnum axis); #if ENABLED(DUAL_X_CARRIAGE) enum DualXMode : char { - DXC_FULL_CONTROL_MODE, // DUAL_X_CARRIAGE only - DXC_AUTO_PARK_MODE, // DUAL_X_CARRIAGE only - DXC_DUPLICATION_MODE + DXC_FULL_CONTROL_MODE, + DXC_AUTO_PARK_MODE, + DXC_DUPLICATION_MODE, + DXC_SCALED_DUPLICATION_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 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); FORCE_INLINE int x_home_dir(const uint8_t extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; } diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index a83fbd85b0..76c068977f 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -251,7 +251,7 @@ int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 }; #define X_APPLY_DIR(v,ALWAYS) \ if (extruder_duplication_enabled || ALWAYS) { \ X_DIR_WRITE(v); \ - X2_DIR_WRITE(bool(v)); \ + X2_DIR_WRITE(v); \ } \ else { \ if (movement_extruder()) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 2585181973..0ebe1d6e20 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -472,13 +472,10 @@ class Stepper { #endif } - private: - // Set direction bits for all steppers static void set_directions(); - // Allow reset_stepper_drivers to access private set_directions - friend void reset_stepper_drivers(); + private: // 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); diff --git a/Marlin/src/module/stepper_indirection.h b/Marlin/src/module/stepper_indirection.h index 28a1e54069..1a615e395c 100644 --- a/Marlin/src/module/stepper_indirection.h +++ b/Marlin/src/module/stepper_indirection.h @@ -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) #elif E_STEPPERS > 1 #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 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) + + #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 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 #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) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index a1cb42aa23..a1e6f3c17c 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -366,6 +366,8 @@ inline void invalid_extruder_error(const uint8_t e) { switch (dual_x_carriage_mode) { 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_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break; + case DXC_SCALED_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_SCALED_DUPLICATION_MODE"); break; } } #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*/) { planner.synchronize(); - #if ENABLED(DUAL_X_CARRIAGE) - // Only T0 allowed in DXC_DUPLICATION_MODE - if (tmp_extruder != 0 && dual_x_carriage_mode == DXC_DUPLICATION_MODE) + #if ENABLED(DUAL_X_CARRIAGE) // Only T0 allowed if the Printer is in DXC_DUPLICATION_MODE or DXC_SCALED_DUPLICATION_MODE + if (tmp_extruder != 0 && dxc_is_duplicating()) return invalid_extruder_error(tmp_extruder); #endif diff --git a/Marlin/src/pins/pins_FORMBOT_TREX2.h b/Marlin/src/pins/pins_FORMBOT_TREX2.h index 9af13bdb38..f98bb37a13 100644 --- a/Marlin/src/pins/pins_FORMBOT_TREX2.h +++ b/Marlin/src/pins/pins_FORMBOT_TREX2.h @@ -28,8 +28,8 @@ #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." #endif -#if E_STEPPERS > 3 || HOTENDS > 3 - #error "Formbot supports up to 3 hotends / E-steppers. Comment this line to keep going." +#if E_STEPPERS > 2 || HOTENDS > 2 + #error "Formbot supports up to 2 hotends / E-steppers. Comment this line to keep going." #endif #define DEFAULT_MACHINE_NAME "Formbot" @@ -143,17 +143,15 @@ #define HEATER_BED_PIN 58 #define FAN_PIN 9 -#define FAN1_PIN 4 +//#define FAN1_PIN 4 #if DISABLED(ICSP_PORT_SWITCHES) - #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 + //#define FIL_RUNOUT_PIN 22 + //#define FIL_RUNOUT2_PIN 21 +#elif ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_PIN 52 + #define FIL_RUNOUT2_PIN 50 #endif // @@ -162,8 +160,8 @@ #define CASE_LIGHT_PIN 8 #define SDSS 53 #ifndef ROXYs_TRex - #define LED_PIN 13 -#endif + #define LED_PIN 13 // The Formbot v 1 board has almost no unassigned pins on it. The Board's LED +#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 #define FILWIDTH_PIN 5 // Analog Input diff --git a/Marlin/src/pins/pins_FORMBOT_TREX3.h b/Marlin/src/pins/pins_FORMBOT_TREX3.h index 322e0f2ea0..5591edcbfe 100644 --- a/Marlin/src/pins/pins_FORMBOT_TREX3.h +++ b/Marlin/src/pins/pins_FORMBOT_TREX3.h @@ -28,8 +28,8 @@ #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." #endif -#if E_STEPPERS > 3 || HOTENDS > 3 - #error "Formbot supports up to 3 hotends / E-steppers. Comment this line to keep going." +#if E_STEPPERS > 2 || HOTENDS > 2 + #error "Formbot supports up to 2 hotends / E-steppers. Comment this line to keep going." #endif #define DEFAULT_MACHINE_NAME "Formbot" @@ -143,18 +143,10 @@ #define HEATER_BED_PIN 8 #define FAN_PIN 9 -#define FAN1_PIN 4 +//#define FAN1_PIN 4 - -#if DISABLED(ICSP_PORT_SWITCHES) - #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 +#define FIL_RUNOUT_PIN 23 +#define FIL_RUNOUT2_PIN 21 // // Misc. Functions