PARK_HEAD_ON_PAUSE implementation

This commit is contained in:
Scott Lahteine 2017-03-19 04:26:22 -05:00
parent 26473cab6d
commit ff0dd162b7
2 changed files with 179 additions and 20 deletions

View File

@ -122,6 +122,7 @@
* M119 - Report endstops status. * M119 - Report endstops status.
* M120 - Enable endstops detection. * M120 - Enable endstops detection.
* M121 - Disable endstops detection. * M121 - Disable endstops detection.
* M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE)
* M126 - Solenoid Air Valve Open. (Requires BARICUDA) * M126 - Solenoid Air Valve Open. (Requires BARICUDA)
* M127 - Solenoid Air Valve Closed. (Requires BARICUDA) * M127 - Solenoid Air Valve Closed. (Requires BARICUDA)
* M128 - EtoP Open. (Requires BARICUDA) * M128 - EtoP Open. (Requires BARICUDA)
@ -150,7 +151,7 @@
* M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>. (Requires FWRETRACT) * M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>. (Requires FWRETRACT)
* M209 - Turn Automatic Retract Detection on/off: S<0|1> (For slicers that don't support G10/11). (Requires FWRETRACT) * M209 - Turn Automatic Retract Detection on/off: S<0|1> (For slicers that don't support G10/11). (Requires FWRETRACT)
Every normal extrude-only move will be classified as retract depending on the direction. Every normal extrude-only move will be classified as retract depending on the direction.
* M211 - Enable, Disable, and/or Report software endstops: S<0|1> * M211 - Enable, Disable, and/or Report software endstops: S<0|1> (Requires MIN_SOFTWARE_ENDSTOPS or MAX_SOFTWARE_ENDSTOPS)
* M218 - Set a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders) * M218 - Set a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders)
* M220 - Set Feedrate Percentage: "M220 S<percent>" (i.e., "FR" on the LCD) * M220 - Set Feedrate Percentage: "M220 S<percent>" (i.e., "FR" on the LCD)
* M221 - Set Flow Percentage: "M221 S<percent>" * M221 - Set Flow Percentage: "M221 S<percent>"
@ -199,13 +200,11 @@
* M350 - Set microstepping mode. (Requires digital microstepping pins.) * M350 - Set microstepping mode. (Requires digital microstepping pins.)
* M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.) * M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.)
* *
* ************ SCARA Specific - This can change to suit future G-code regulations
* M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration) * M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
* M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree) * M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
* M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration) * M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
* M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree) * M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
* M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position) * M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
* ************* SCARA End ***************
* *
* ************ Custom codes - This can change to suit future G-code regulations * ************ Custom codes - This can change to suit future G-code regulations
* M100 - Watch Free Memory (For Debugging). (Requires M100_FREE_MEMORY_WATCHER) * M100 - Watch Free Memory (For Debugging). (Requires M100_FREE_MEMORY_WATCHER)
@ -4667,6 +4666,45 @@ inline void gcode_M17() {
enable_all_steppers(); enable_all_steppers();
} }
#if IS_KINEMATIC
#define RUNPLAN(RATE_MM_S) planner.buffer_line_kinematic(destination, RATE_MM_S, active_extruder)
#else
#define RUNPLAN(RATE_MM_S) line_to_destination(RATE_MM_S)
#endif
#if ENABLED(PARK_HEAD_ON_PAUSE)
float resume_position[XYZE];
bool move_away_flag = false;
inline void move_back_on_resume() {
if (!move_away_flag) return;
move_away_flag = false;
// Set extruder to saved position
destination[E_AXIS] = current_position[E_AXIS] = resume_position[E_AXIS];
planner.set_e_position_mm(current_position[E_AXIS]);
#if IS_KINEMATIC
// Move XYZ to starting position
planner.buffer_line_kinematic(lastpos, FILAMENT_CHANGE_XY_FEEDRATE, active_extruder);
#else
// Move XY to starting position, then Z
destination[X_AXIS] = resume_position[X_AXIS];
destination[Y_AXIS] = resume_position[Y_AXIS];
RUNPLAN(FILAMENT_CHANGE_XY_FEEDRATE);
destination[Z_AXIS] = resume_position[Z_AXIS];
RUNPLAN(FILAMENT_CHANGE_Z_FEEDRATE);
#endif
stepper.synchronize();
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
filament_ran_out = false;
#endif
set_current_to_destination();
}
#endif // PARK_HEAD_ON_PAUSE
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
/** /**
@ -4694,9 +4732,13 @@ inline void gcode_M17() {
inline void gcode_M23() { card.openFile(current_command_args, true); } inline void gcode_M23() { card.openFile(current_command_args, true); }
/** /**
* M24: Start SD Print * M24: Start or Resume SD Print
*/ */
inline void gcode_M24() { inline void gcode_M24() {
#if ENABLED(PARK_HEAD_ON_PAUSE)
move_back_on_resume();
#endif
card.startFileprint(); card.startFileprint();
print_job_timer.start(); print_job_timer.start();
} }
@ -4704,7 +4746,14 @@ inline void gcode_M17() {
/** /**
* M25: Pause SD Print * M25: Pause SD Print
*/ */
inline void gcode_M25() { card.pauseSDPrint(); } inline void gcode_M25() {
card.pauseSDPrint();
print_job_timer.pause();
#if ENABLED(PARK_HEAD_ON_PAUSE)
enqueue_and_echo_commands_P(PSTR("M125")); // Must be enqueued with pauseSDPrint set to be last in the buffer
#endif
}
/** /**
* M26: Set SD Card file index * M26: Set SD Card file index
@ -6084,6 +6133,111 @@ inline void gcode_M120() { endstops.enable_globally(true); }
*/ */
inline void gcode_M121() { endstops.enable_globally(false); } inline void gcode_M121() { endstops.enable_globally(false); }
#if ENABLED(PARK_HEAD_ON_PAUSE)
/**
* M125: Store current position and move to filament change position.
* Called on pause (by M25) to prevent material leaking onto the
* object. On resume (M24) the head will be moved back and the
* print will resume.
*
* If Marlin is compiled without SD Card support, M125 can be
* used directly to pause the print and move to park position,
* resuming with a button click or M108.
*
* L = override retract length
* X = override X
* Y = override Y
* Z = override Z raise
*/
inline void gcode_M125() {
if (move_away_flag) return; // already paused
const bool job_running = print_job_timer.isRunning();
// there are blocks after this one, or sd printing
move_away_flag = job_running || planner.blocks_queued()
#if ENABLED(SDSUPPORT)
|| card.sdprinting
#endif
;
if (!move_away_flag) return; // nothing to pause
// M125 can be used to pause a print too
#if ENABLED(SDSUPPORT)
card.pauseSDPrint();
#endif
print_job_timer.pause();
// Save current position
COPY(resume_position, current_position);
set_destination_to_current();
// Initial retract before move to filament change position
destination[E_AXIS] += code_seen('L') ? code_value_axis_units(E_AXIS) : 0
#if defined(FILAMENT_CHANGE_RETRACT_LENGTH) && FILAMENT_CHANGE_RETRACT_LENGTH > 0
- (FILAMENT_CHANGE_RETRACT_LENGTH)
#endif
;
RUNPLAN(FILAMENT_CHANGE_RETRACT_FEEDRATE);
// Lift Z axis
const float z_lift = code_seen('Z') ? code_value_axis_units(Z_AXIS) :
#if defined(FILAMENT_CHANGE_Z_ADD) && FILAMENT_CHANGE_Z_ADD > 0
FILAMENT_CHANGE_Z_ADD
#else
0
#endif
;
if (z_lift > 0) {
destination[Z_AXIS] += z_lift;
NOMORE(destination[Z_AXIS], Z_MAX_POS);
RUNPLAN(FILAMENT_CHANGE_Z_FEEDRATE);
}
// Move XY axes to filament change position or given position
destination[X_AXIS] = code_seen('X') ? code_value_axis_units(X_AXIS) : 0
#ifdef FILAMENT_CHANGE_X_POS
+ FILAMENT_CHANGE_X_POS
#endif
;
destination[Y_AXIS] = code_seen('Y') ? code_value_axis_units(Y_AXIS) : 0
#ifdef FILAMENT_CHANGE_Y_POS
+ FILAMENT_CHANGE_Y_POS
#endif
;
#if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE)
if (active_extruder > 0) {
if (!code_seen('X')) destination[X_AXIS] += hotend_offset[X_AXIS][active_extruder];
if (!code_seen('Y')) destination[Y_AXIS] += hotend_offset[Y_AXIS][active_extruder];
}
#endif
clamp_to_software_endstops(destination);
RUNPLAN(FILAMENT_CHANGE_XY_FEEDRATE);
set_current_to_destination();
stepper.synchronize();
disable_e_steppers();
#if DISABLED(SDSUPPORT)
// Wait for lcd click or M108
wait_for_user = true;
KEEPALIVE_STATE(PAUSED_FOR_USER);
while (wait_for_user) idle();
KEEPALIVE_STATE(IN_HANDLER);
// Return to print position and continue
move_back_on_resume();
if (job_running) print_job_timer.start();
move_away_flag = false;
#endif
}
#endif // PARK_HEAD_ON_PAUSE
#if ENABLED(BLINKM) || ENABLED(RGB_LED) #if ENABLED(BLINKM) || ENABLED(RGB_LED)
void set_led_color(const uint8_t r, const uint8_t g, const uint8_t b) { void set_led_color(const uint8_t r, const uint8_t g, const uint8_t b) {
@ -7253,25 +7407,18 @@ inline void gcode_M503() {
busy_doing_M600 = true; // Stepper Motors can't timeout when this is set busy_doing_M600 = true; // Stepper Motors can't timeout when this is set
// Pause the print job timer // Pause the print job timer
bool job_running = print_job_timer.isRunning(); const bool job_running = print_job_timer.isRunning();
print_job_timer.pause(); print_job_timer.pause();
// Show initial message and wait for synchronize steppers // Show initial message and wait for synchronize steppers
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_INIT); lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_INIT);
stepper.synchronize(); stepper.synchronize();
float lastpos[NUM_AXIS];
// Save current position of all axes // Save current position of all axes
LOOP_XYZE(i) float lastpos[XYZE];
lastpos[i] = destination[i] = current_position[i]; COPY(lastpos, current_position);
set_destination_to_current();
// Define runplan for move axes
#if IS_KINEMATIC
#define RUNPLAN(RATE_MM_S) planner.buffer_line_kinematic(destination, RATE_MM_S, active_extruder);
#else
#define RUNPLAN(RATE_MM_S) line_to_destination(RATE_MM_S);
#endif
// Initial retract before move to filament change position // Initial retract before move to filament change position
destination[E_AXIS] += code_seen('E') ? code_value_axis_units(E_AXIS) : 0 destination[E_AXIS] += code_seen('E') ? code_value_axis_units(E_AXIS) : 0
@ -8555,6 +8702,11 @@ void process_next_command() {
break; break;
#endif // FAN_COUNT > 0 #endif // FAN_COUNT > 0
#if ENABLED(PARK_HEAD_ON_PAUSE)
case 125: // M125: Store current position and move to filament change position
gcode_M125(); break;
#endif
#if ENABLED(BARICUDA) #if ENABLED(BARICUDA)
// PWM for HEATER_1_PIN // PWM for HEATER_1_PIN
#if HAS_HEATER_1 #if HAS_HEATER_1

View File

@ -615,11 +615,18 @@ void kill_screen(const char* lcd_msg) {
void lcd_sdcard_pause() { void lcd_sdcard_pause() {
card.pauseSDPrint(); card.pauseSDPrint();
print_job_timer.pause(); print_job_timer.pause();
#if ENABLED(PARK_HEAD_ON_PAUSE)
enqueue_and_echo_commands_P(PSTR("M125"))
#endif
} }
void lcd_sdcard_resume() { void lcd_sdcard_resume() {
#if ENABLED(PARK_HEAD_ON_PAUSE)
enqueue_and_echo_commands_P(PSTR("M24"))
#else
card.startFileprint(); card.startFileprint();
print_job_timer.start(); print_job_timer.start();
#endif
} }
void lcd_sdcard_stop() { void lcd_sdcard_stop() {
@ -634,7 +641,7 @@ void kill_screen(const char* lcd_msg) {
lcd_setstatus(MSG_PRINT_ABORTED, true); lcd_setstatus(MSG_PRINT_ABORTED, true);
} }
#endif //SDSUPPORT #endif // SDSUPPORT
#if ENABLED(MENU_ITEM_CASE_LIGHT) #if ENABLED(MENU_ITEM_CASE_LIGHT)