Cancel Objects - As seen at ERRF2019 (#15590)
This commit is contained in:
		| @@ -2056,7 +2056,7 @@ | ||||
|    * | ||||
|    * IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when | ||||
|    * homing and adds a guard period for endstop triggering. | ||||
|    *  | ||||
|    * | ||||
|    * TMC2209 requires STEALTHCHOP enabled for SENSORLESS_HOMING | ||||
|    */ | ||||
|   //#define SENSORLESS_HOMING // StallGuard capable drivers only | ||||
| @@ -2556,6 +2556,13 @@ | ||||
|   //#define HOST_PROMPT_SUPPORT | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Cancel Objects | ||||
|  * | ||||
|  * Implement M486 to allow Marlin to skip objects | ||||
|  */ | ||||
| //#define CANCEL_OBJECTS | ||||
|  | ||||
| /** | ||||
|  * I2C position encoders for closed loop control. | ||||
|  * Developed by Chris Barr at Aus3D. | ||||
|   | ||||
| @@ -342,18 +342,31 @@ void disable_all_steppers() { | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(ADVANCED_PAUSE_FEATURE) | ||||
|   #include "feature/pause.h" | ||||
| #else | ||||
|   constexpr bool did_pause_print = false; | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Printing is active when the print job timer is running | ||||
|  */ | ||||
| bool printingIsActive() { | ||||
|   return print_job_timer.isRunning() || IS_SD_PRINTING(); | ||||
|   return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING()); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Printing is paused according to SD or host indicators | ||||
|  */ | ||||
| bool printingIsPaused() { | ||||
|   return print_job_timer.isPaused() || IS_SD_PAUSED(); | ||||
|   return did_pause_print || print_job_timer.isPaused() || IS_SD_PAUSED(); | ||||
| } | ||||
|  | ||||
| void startOrResumeJob() { | ||||
|   #if ENABLED(CANCEL_OBJECTS) | ||||
|     if (!printingIsPaused()) cancelable.reset(); | ||||
|   #endif | ||||
|   print_job_timer.start(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -333,6 +333,7 @@ inline bool IsStopped() { return !Running; } | ||||
|  | ||||
| bool printingIsActive(); | ||||
| bool printingIsPaused(); | ||||
| void startOrResumeJob(); | ||||
|  | ||||
| extern bool wait_for_heatup; | ||||
|  | ||||
|   | ||||
							
								
								
									
										76
									
								
								Marlin/src/feature/cancel_object.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								Marlin/src/feature/cancel_object.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #include "../inc/MarlinConfig.h" | ||||
|  | ||||
| #if ENABLED(CANCEL_OBJECTS) | ||||
|  | ||||
| #include "cancel_object.h" | ||||
| #include "../gcode/gcode.h" | ||||
| #include "../lcd/ultralcd.h" | ||||
|  | ||||
| CancelObject cancelable; | ||||
|  | ||||
| int8_t CancelObject::object_count, // = 0 | ||||
|        CancelObject::active_object = -1; | ||||
| uint32_t CancelObject::canceled; // = 0x0000 | ||||
| bool CancelObject::skipping; // = false | ||||
|  | ||||
| void CancelObject::set_active_object(const int8_t obj) { | ||||
|   active_object = obj; | ||||
|   if (WITHIN(obj, 0, 31)) { | ||||
|     if (obj >= object_count) object_count = obj + 1; | ||||
|     skipping = TEST(canceled, obj); | ||||
|   } | ||||
|   else | ||||
|     skipping = false; | ||||
| } | ||||
|  | ||||
| void CancelObject::cancel_object(const int8_t obj) { | ||||
|   if (WITHIN(obj, 0, 31)) { | ||||
|     SBI(canceled, obj); | ||||
|     if (obj == active_object) skipping = true; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void CancelObject::uncancel_object(const int8_t obj) { | ||||
|   if (WITHIN(obj, 0, 31)) { | ||||
|     CBI(canceled, obj); | ||||
|     if (obj == active_object) skipping = false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void CancelObject::report() { | ||||
|   if (active_object >= 0) { | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOLNPAIR("Active Object: ", int(active_object)); | ||||
|   } | ||||
|  | ||||
|   if (canceled) { | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOPGM("Canceled:"); | ||||
|     for (int i = 0; i < object_count; i++) | ||||
|       if (TEST(canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); } | ||||
|     SERIAL_EOL(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // CANCEL_OBJECTS | ||||
							
								
								
									
										40
									
								
								Marlin/src/feature/cancel_object.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Marlin/src/feature/cancel_object.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| class CancelObject { | ||||
| public: | ||||
|   static bool skipping; | ||||
|   static int8_t object_count, active_object; | ||||
|   static uint32_t canceled; | ||||
|   static void set_active_object(const int8_t obj); | ||||
|   static void cancel_object(const int8_t obj); | ||||
|   static void uncancel_object(const int8_t obj); | ||||
|   static void report(); | ||||
|   static inline void clear_active_object() { set_active_object(-1); } | ||||
|   static inline void cancel_active_object() { cancel_object(active_object); } | ||||
|   static inline void reset() { canceled = 0x0000; object_count = 0; clear_active_object(); } | ||||
| }; | ||||
|  | ||||
| extern CancelObject cancelable; | ||||
							
								
								
									
										57
									
								
								Marlin/src/gcode/feature/cancel/M486.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								Marlin/src/gcode/feature/cancel/M486.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfig.h" | ||||
|  | ||||
| #if ENABLED(CANCEL_OBJECTS) | ||||
|  | ||||
| #include "../../gcode.h" | ||||
| #include "../../../feature/cancel_object.h" | ||||
|  | ||||
| /** | ||||
|  * M486: A simple interface to cancel objects | ||||
|  * | ||||
|  *   T[count] : Reset objects and/or set the count | ||||
|  *   S<index> : Start an object with the given index | ||||
|  *   P<index> : Cancel the object with the given index | ||||
|  *   U<index> : Un-cancel object with the given index | ||||
|  *   C        : Cancel the current object (the last index given by S<index>) | ||||
|  *   S-1      : Start a non-object like a brim or purge tower that should always print | ||||
|  */ | ||||
| void GcodeSuite::M486() { | ||||
|  | ||||
|   if (parser.seen('T')) { | ||||
|     cancelable.reset(); | ||||
|     cancelable.object_count = parser.intval('T', 1); | ||||
|   } | ||||
|  | ||||
|   if (parser.seen('S')) | ||||
|     cancelable.set_active_object(parser.value_integer()); | ||||
|  | ||||
|   if (parser.seen('C')) cancelable.cancel_active_object(); | ||||
|  | ||||
|   if (parser.seen('P')) cancelable.cancel_object(parser.value_integer()); | ||||
|  | ||||
|   if (parser.seen('U')) cancelable.uncancel_object(parser.value_integer()); | ||||
| } | ||||
|  | ||||
| #endif // CANCEL_OBJECTS | ||||
| @@ -114,15 +114,34 @@ int8_t GcodeSuite::get_target_e_stepper_from_command() { | ||||
|  */ | ||||
| void GcodeSuite::get_destination_from_command() { | ||||
|   xyze_bool_t seen = { false, false, false, false }; | ||||
|   LOOP_XYZE(i) { | ||||
|  | ||||
|   #if ENABLED(CANCEL_OBJECTS) | ||||
|     const bool &skip_move = cancelable.skipping; | ||||
|   #else | ||||
|     constexpr bool skip_move = false; | ||||
|   #endif | ||||
|  | ||||
|   // Get new XYZ position, whether absolute or relative | ||||
|   LOOP_XYZ(i) { | ||||
|     if ( (seen[i] = parser.seenval(axis_codes[i])) ) { | ||||
|       const float v = parser.value_axis_units((AxisEnum)i); | ||||
|       destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : (i == E_AXIS) ? v : LOGICAL_TO_NATIVE(v, i); | ||||
|       if (skip_move) | ||||
|         destination[i] = current_position[i]; | ||||
|       else | ||||
|         destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i); | ||||
|     } | ||||
|     else | ||||
|       destination[i] = current_position[i]; | ||||
|   } | ||||
|  | ||||
|   // Get new E position, whether absolute or relative | ||||
|   if ( (seen.e = parser.seenval('E')) ) { | ||||
|     const float v = parser.value_axis_units(E_AXIS); | ||||
|     destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v; | ||||
|   } | ||||
|   else | ||||
|     destination.e = current_position.e; | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) && !PIN_EXISTS(POWER_LOSS) | ||||
|     // Only update power loss recovery on moves with E | ||||
|     if (recovery.enabled && IS_SD_PRINTING() && seen.e && (seen.x || seen.y)) | ||||
| @@ -133,7 +152,7 @@ void GcodeSuite::get_destination_from_command() { | ||||
|     feedrate_mm_s = parser.value_feedrate(); | ||||
|  | ||||
|   #if ENABLED(PRINTCOUNTER) | ||||
|     if (!DEBUGGING(DRYRUN)) | ||||
|     if (!DEBUGGING(DRYRUN) && !skip_move) | ||||
|       print_job_timer.incFilamentUsed(destination.e - current_position.e); | ||||
|   #endif | ||||
|  | ||||
| @@ -322,6 +341,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { | ||||
|     break; | ||||
|  | ||||
|     case 'M': switch (parser.codenum) { | ||||
|  | ||||
|       #if HAS_RESUME_CONTINUE | ||||
|         case 0:                                                   // M0: Unconditional stop - Wait for user button press on LCD | ||||
|         case 1: M0_M1(); break;                                   // M1: Conditional stop - Wait for user button press on LCD | ||||
| @@ -667,6 +687,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { | ||||
|         case 428: M428(); break;                                  // M428: Apply current_position to home_offset | ||||
|       #endif | ||||
|  | ||||
|       #if ENABLED(CANCEL_OBJECTS) | ||||
|         case 486: M486(); break;                                  // M486: Identify and cancel objects | ||||
|       #endif | ||||
|  | ||||
|       case 500: M500(); break;                                    // M500: Store settings in EEPROM | ||||
|       case 501: M501(); break;                                    // M501: Read settings from EEPROM | ||||
|       case 502: M502(); break;                                    // M502: Revert to default settings | ||||
|   | ||||
| @@ -213,6 +213,7 @@ | ||||
|  * M422 - Set Z Stepper automatic alignment position using probe. X<units> Y<units> A<axis> (Requires Z_STEPPER_AUTO_ALIGN) | ||||
|  * M425 - Enable/Disable and tune backlash correction. (Requires BACKLASH_COMPENSATION and BACKLASH_GCODE) | ||||
|  * M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA) | ||||
|  * M486 - Identify and cancel objects. (Requires CANCEL_OBJECTS) | ||||
|  * M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS) | ||||
|  * M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS) | ||||
|  * M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! ** | ||||
| @@ -796,6 +797,10 @@ private: | ||||
|     static void M428(); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(CANCEL_OBJECTS) | ||||
|     static void M486(); | ||||
|   #endif | ||||
|  | ||||
|   static void M500(); | ||||
|   static void M501(); | ||||
|   static void M502(); | ||||
|   | ||||
| @@ -138,7 +138,9 @@ void GCodeParser::parse(char *p) { | ||||
|   switch (letter) { | ||||
|  | ||||
|     case 'G': case 'M': case 'T': | ||||
|  | ||||
|     #if ENABLED(CANCEL_OBJECTS) | ||||
|       case 'O': | ||||
|     #endif | ||||
|       // Skip spaces to get the numeric part | ||||
|       while (*p == ' ') p++; | ||||
|  | ||||
| @@ -230,7 +232,14 @@ void GCodeParser::parse(char *p) { | ||||
|     case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return; | ||||
|     default: break; | ||||
|   } | ||||
|  | ||||
| /* | ||||
|   #if ENABLED(CANCEL_OBJECTS) | ||||
|   if (letter == 'O') switch (codenum) { | ||||
|     case 1:  string_arg = p; return; | ||||
|     default: break; | ||||
|   } | ||||
|   #endif | ||||
| */ | ||||
|   #if ENABLED(DEBUG_GCODE_PARSER) | ||||
|     const bool debug = codenum == 800; | ||||
|   #endif | ||||
|   | ||||
| @@ -42,6 +42,8 @@ | ||||
|   #include "../../feature/power_loss_recovery.h" | ||||
| #endif | ||||
|  | ||||
| #include "../../Marlin.h" // for startOrResumeJob | ||||
|  | ||||
| /** | ||||
|  * M24: Start or Resume SD Print | ||||
|  */ | ||||
| @@ -54,14 +56,14 @@ void GcodeSuite::M24() { | ||||
|  | ||||
|   #if ENABLED(PARK_HEAD_ON_PAUSE) | ||||
|     if (did_pause_print) { | ||||
|       resume_print(); | ||||
|       resume_print(); // will call print_job_timer.start() | ||||
|       return; | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   if (card.isFileOpen()) { | ||||
|     card.startFileprint(); | ||||
|     print_job_timer.start(); | ||||
|     card.startFileprint();            // SD card will now be read for commands | ||||
|     startOrResumeJob();               // Start (or resume) the print job timer | ||||
|     #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|       recovery.prepare(); | ||||
|     #endif | ||||
|   | ||||
| @@ -29,6 +29,8 @@ | ||||
| #include "../../module/printcounter.h" | ||||
| #include "../../module/planner.h" | ||||
|  | ||||
| #include "../../Marlin.h" // for startOrResumeJob | ||||
|  | ||||
| /** | ||||
|  * M32: Select file and start SD Print | ||||
|  * | ||||
| @@ -52,7 +54,7 @@ void GcodeSuite::M32() { | ||||
|     card.startFileprint(); | ||||
|  | ||||
|     // Procedure calls count as normal print time. | ||||
|     if (!call_procedure) print_job_timer.start(); | ||||
|     if (!call_procedure) startOrResumeJob(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -24,11 +24,13 @@ | ||||
| #include "../../module/printcounter.h" | ||||
| #include "../../lcd/ultralcd.h" | ||||
|  | ||||
| #include "../../Marlin.h" // for startOrResumeJob | ||||
|  | ||||
| /** | ||||
|  * M75: Start print timer | ||||
|  */ | ||||
| void GcodeSuite::M75() { | ||||
|   print_job_timer.start(); | ||||
|   startOrResumeJob(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -29,10 +29,14 @@ | ||||
| #include "../../module/motion.h" | ||||
| #include "../../module/planner.h" | ||||
| #include "../../lcd/ultralcd.h" | ||||
| #include "../../Marlin.h" | ||||
|  | ||||
| #include "../../Marlin.h" // for startOrResumeJob, etc. | ||||
|  | ||||
| #if ENABLED(PRINTJOB_TIMER_AUTOSTART) | ||||
|   #include "../../module/printcounter.h" | ||||
|   #if ENABLED(CANCEL_OBJECTS) | ||||
|     #include "../../feature/cancel_object.h" | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(SINGLENOZZLE) | ||||
| @@ -126,7 +130,7 @@ void GcodeSuite::M109() { | ||||
|         ui.reset_status(); | ||||
|       } | ||||
|       else | ||||
|         print_job_timer.start(); | ||||
|         startOrResumeJob(); | ||||
|     #endif | ||||
|  | ||||
|     #if HAS_DISPLAY | ||||
|   | ||||
| @@ -37,7 +37,7 @@ | ||||
|   #include "../../feature/leds/leds.h" | ||||
| #endif | ||||
|  | ||||
| #include "../../Marlin.h" // for wait_for_heatup and idle() | ||||
| #include "../../Marlin.h" // for wait_for_heatup, idle, startOrResumeJob | ||||
|  | ||||
| /** | ||||
|  * M140: Set bed temperature | ||||
| @@ -59,7 +59,7 @@ void GcodeSuite::M190() { | ||||
|     thermalManager.setTargetBed(parser.value_celsius()); | ||||
|     #if ENABLED(PRINTJOB_TIMER_AUTOSTART) | ||||
|       if (parser.value_celsius() > BED_MINTEMP) | ||||
|         print_job_timer.start(); | ||||
|         startOrResumeJob(); | ||||
|     #endif | ||||
|   } | ||||
|   else return; | ||||
|   | ||||
| @@ -38,7 +38,7 @@ | ||||
|   #include "../../feature/leds/leds.h" | ||||
| #endif | ||||
|  | ||||
| #include "../../Marlin.h" // for wait_for_heatup and idle() | ||||
| #include "../../Marlin.h" // for wait_for_heatup, idle, startOrResumeJob | ||||
|  | ||||
| /** | ||||
|  * M141: Set chamber temperature | ||||
| @@ -60,7 +60,7 @@ void GcodeSuite::M191() { | ||||
|     thermalManager.setTargetChamber(parser.value_celsius()); | ||||
|     #if ENABLED(PRINTJOB_TIMER_AUTOSTART) | ||||
|       if (parser.value_celsius() > BED_MINTEMP) | ||||
|         print_job_timer.start(); | ||||
|         startOrResumeJob(); | ||||
|     #endif | ||||
|   } | ||||
|   else return; | ||||
|   | ||||
| @@ -427,6 +427,7 @@ namespace Language_en { | ||||
|   PROGMEM Language_Str MSG_PAUSE_PRINT                     = _UxGT("Pause Print"); | ||||
|   PROGMEM Language_Str MSG_RESUME_PRINT                    = _UxGT("Resume Print"); | ||||
|   PROGMEM Language_Str MSG_STOP_PRINT                      = _UxGT("Stop Print"); | ||||
|   PROGMEM Language_Str MSG_OBJECT_CANCEL                   = _UxGT("Cancel Object"); | ||||
|   PROGMEM Language_Str MSG_OUTAGE_RECOVERY                 = _UxGT("Outage Recovery"); | ||||
|   PROGMEM Language_Str MSG_MEDIA_MENU                      = _UxGT("Print from Media"); | ||||
|   PROGMEM Language_Str MSG_NO_MEDIA                        = _UxGT("No Media"); | ||||
|   | ||||
| @@ -50,6 +50,7 @@ | ||||
|  | ||||
| void menu_tmc(); | ||||
| void menu_backlash(); | ||||
| void menu_cancelobject(); | ||||
|  | ||||
| #if ENABLED(DAC_STEPPER_CURRENT) | ||||
|  | ||||
| @@ -652,6 +653,10 @@ void menu_advanced_settings() { | ||||
|     SUBMENU(MSG_BACKLASH, menu_backlash); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(CANCEL_OBJECTS) | ||||
|     SUBMENU(MSG_CANCELOBJECTS, [](){ editable.int8 = -1; goto_screen(menu_cancelobject); }); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(DAC_STEPPER_CURRENT) | ||||
|     SUBMENU(MSG_DRIVE_STRENGTH, menu_dac); | ||||
|   #endif | ||||
|   | ||||
							
								
								
									
										73
									
								
								Marlin/src/lcd/menu/menu_cancelobject.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								Marlin/src/lcd/menu/menu_cancelobject.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| // | ||||
| // Cancel Object Menu | ||||
| // | ||||
|  | ||||
| #include "../../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if HAS_LCD_MENU && ENABLED(CANCEL_OBJECTS) | ||||
|  | ||||
| #include "menu.h" | ||||
|  | ||||
| #include "../../feature/cancel_object.h" | ||||
|  | ||||
| // | ||||
| // TODO: Select the active object | ||||
| // upon entry to the menu and present | ||||
| // a confirmation screen. | ||||
| // | ||||
| void menu_cancelobject() { | ||||
|   START_MENU(); | ||||
|   MENU_BACK(MSG_MAIN); | ||||
|  | ||||
|   GCODES_ITEM(MSG_OBJECT_CANCEL, PSTR("M486 C")); | ||||
|  | ||||
|   // Draw cancelable items in a loop | ||||
|   for (int8_t i = 0; i < cancelable.object_count; i++) { | ||||
|     if (!TEST(cancelable.canceled, i)) { | ||||
|       editable.int8 = i; | ||||
|       ACTION_ITEM(MSG_OBJECT_CANCEL, [](){ | ||||
|         cancelable.cancel_object(editable.int8); | ||||
|         ui.quick_feedback(); | ||||
|       }); | ||||
|       MENU_ITEM_ADDON_START(LCD_WIDTH - 2 - (i >= 10)); | ||||
|         lcd_put_int(i); | ||||
|       MENU_ITEM_ADDON_END(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* | ||||
|   MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_OBJECT_CANCEL, &editable.int8, -1, 32, [](){ | ||||
|     if (editable.int8 > -1) { | ||||
|       cancelable.cancel_object(editable.int8); | ||||
|       ui.quick_feedback(); | ||||
|       editable.int8 = -1; | ||||
|     } | ||||
|   }); | ||||
|   */ | ||||
|  | ||||
|   END_MENU(); | ||||
| } | ||||
|  | ||||
| #endif // HAS_LCD_MENU && CANCEL_OBJECTS | ||||
| @@ -96,6 +96,10 @@ | ||||
|   #include "../feature/backlash.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(CANCEL_OBJECTS) | ||||
|   #include "../feature/cancel_object.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "../feature/power_loss_recovery.h" | ||||
| #endif | ||||
| @@ -2597,7 +2601,11 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con | ||||
|   #endif | ||||
|  | ||||
|   // DRYRUN prevents E moves from taking place | ||||
|   if (DEBUGGING(DRYRUN)) { | ||||
|   if (DEBUGGING(DRYRUN) | ||||
|     #if ENABLED(CANCEL_OBJECTS) | ||||
|       || cancelable.skipping | ||||
|     #endif | ||||
|   ) { | ||||
|     position.e = target.e; | ||||
|     #if HAS_POSITION_FLOAT | ||||
|       position_float.e = e; | ||||
|   | ||||
| @@ -2229,7 +2229,7 @@ int32_t Stepper::position(const AxisEnum axis) { | ||||
| // be very careful here. If the interrupt being preempted was the | ||||
| // Stepper ISR (this CAN happen with the endstop limits ISR) then | ||||
| // when the stepper ISR resumes, we must be very sure that the movement | ||||
| // is properly cancelled | ||||
| // is properly canceled | ||||
| void Stepper::endstop_triggered(const AxisEnum axis) { | ||||
|  | ||||
|   const bool was_enabled = STEPPER_ISR_ENABLED(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user