From 6f92950a25ecd80a8f02fe9a86ec58d5db2aee92 Mon Sep 17 00:00:00 2001 From: Switchleg1 <89221799+Switchleg1@users.noreply.github.com> Date: Sat, 20 Dec 2025 08:20:42 -0700 Subject: [PATCH] drill cycles --- Marlin/Configuration_adv.h | 28 +++++ Marlin/src/gcode/gcode.cpp | 14 +++ Marlin/src/gcode/gcode.h | 11 ++ Marlin/src/gcode/host/M115.cpp | 3 + Marlin/src/gcode/motion/G81.cpp | 174 ++++++++++++++++++++++++++++++++ ini/features.ini | 1 + 6 files changed, 231 insertions(+) create mode 100644 Marlin/src/gcode/motion/G81.cpp diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index f1f6594228..955e79312d 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -4436,6 +4436,34 @@ #define FREEZE_STATE LOW // State of pin indicating freeze #endif +/** + * Adds canned drilling cycle G Codes: + * G73: Shallow peck drill cycle + * G80: Cancel drill cycle + * G81: Basic drill cycle + * G82: Normal drill cycle (Basic with dwell) + * G83: Deep drill cycle (Normal with peck) + * G98: Start drill - retract to initial + * G99: Start drill - retract to specified + * or when DRILL_USE_81_ONLY is specified: + * G81.4: Shallow peck drill cycle + * G81.0: Cancel drill cycle + * G81.1: Basic drill cycle + * G81.2: Normal drill cycle (Basic with dwell) + * G81.3: Deep drill cycle (Normal with peck) + * G81.18: Start drill - retract to initial + * G81.19: Start drill - retract to specified + */ +#define DRILL_CYCLES +#if ENABLED(DRILL_CYCLES) + //#define DRILL_USE_81_ONLY + #define DRILL_CYCLES_XY_FEEDRATE 1600 + #define DRILL_CYCLES_RETRACT_FEEDRATE 1200 + #define DRILL_CYCLES_DEFAULT_FEEDRATE 300 + #define DRILL_CYCLES_DEFAULT_PECK 2.0 + #define DRILL_CYCLES_DEFAULT_DWELL 0 +#endif + /** * MAX7219 Debug Matrix * diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 10a6f3d65b..f7765c72b6 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -463,6 +463,20 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) { case 80: G80(); break; // G80: Reset the current motion mode #endif + #if ENABLED(DRILL_CYCLES) + #if ENABLED(DRILL_USE_81_ONLY) || ENABLED(GCODE_MOTION_MODES) + case 81: G81(parser.subcode); break; // G81: Drill cycle G81: Cancel, G81.18 G81.19 Start, G81.1 G81.2 G81.3 G81.4 Cycles + #else + case 73: G81(4); break; // G73: Shallow peck drill cycle + case 80: G81(0); break; // G80: Cancel drill cycle + case 81: G81(1); break; // G81: Basic drill cycle + case 82: G81(2); break; // G82: Normal drill cycle (Basic with dwell) + case 83: G81(3); break; // G83: Deep drill cycle (Normal with peck) + case 98: G81(18); break; // G98: Retract to initial + case 99: G81(19); break; // G99: Retract to specified + #endif + #endif + case 90: G90(); break; // G90: Absolute Mode case 91: G91(); break; // G91: Relative Mode diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 378a1a73f4..5d4f377718 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -66,11 +66,18 @@ * G42 - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL) * G60 - Save current position. (Requires SAVED_POSITIONS) * G61 - Apply/Restore saved coordinates. (Requires SAVED_POSITIONS) + * G73 - Shallow peck drill cycle * G76 - Calibrate first layer temperature offsets. (Requires PTC_PROBE and PTC_BED) * G80 - Cancel current motion mode (Requires GCODE_MOTION_MODES) + * G80 - Cancel drill cancel + * G81 - Basic drill cycle + * G82 - Normal drill cycle + * G83 - Deep drill cycle * G90 - Use Absolute Coordinates * G91 - Use Relative Coordinates * G92 - Set current position to coordinates given + * G98 - Start drill - retract to initial + * G99 - Start drill - retract to specified * * "M" Codes * @@ -644,6 +651,10 @@ private: static void G80(); #endif + #if ENABLED(DRILL_CYCLES) + static void G81(uint8_t mode); + #endif + static void G90() { set_relative_mode(false); } static void G91() { set_relative_mode(true); } diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 19d0ae9b63..462542d65d 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -226,6 +226,9 @@ void GcodeSuite::M115() { // MOTION_MODES (M80-M89) cap_line(F("MOTION_MODES"), ENABLED(GCODE_MOTION_MODES)); + // DRILL CYCLES (G73-99) + cap_line(F("DRILL_CYCLES"), ENABLED(DRILL_CYCLES)); + // ARC_SUPPORT (G2-G3) cap_line(F("ARCS"), ENABLED(ARC_SUPPORT)); diff --git a/Marlin/src/gcode/motion/G81.cpp b/Marlin/src/gcode/motion/G81.cpp new file mode 100644 index 0000000000..54aceb0f9a --- /dev/null +++ b/Marlin/src/gcode/motion/G81.cpp @@ -0,0 +1,174 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 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 . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(DRILL_CYCLES) + +#include "../gcode.h" +#include "../../module/motion.h" + +/** + * G73: Shallow peck drill cycle + * G80: Cancel drill cycle + * G81: Basic drill cycle + * G82: Normal drill cycle (Basic with dwell) + * G83: Deep drill cycle (Normal with peck) + * G98: Start drill - retract to initial + * G99: Start drill - retract to specified + */ + + //#define DRILL_CYCLE_DEBUG + +bool retract_to_initial = true; +bool drill_cycle_started = false; + +void move_to_XYZF(float x, float y, float z, uint16_t f) { + char gcode_str[50], x_str[10], y_str[10], z_str[10]; + dtostrf(x, 1, 3, x_str); + dtostrf(y, 1, 3, y_str); + dtostrf(z, 1, 3, z_str); + + sprintf_P(gcode_str, PSTR("G1 X%s Y%s Z%s F%d"), x_str, y_str, z_str, f); +#if ENABLED(DRILL_CYCLE_DEBUG) + SERIAL_ECHOPGM("DEBUG: ", gcode_str); +#endif + gcode.process_subcommands_now(gcode_str); + } + + void drill_start(bool initial) { + if(!drill_cycle_started) { + drill_cycle_started = true; + retract_to_initial = initial; + } +} + +void drill_stop() { + drill_cycle_started = false; +} + +void drill_cycle(uint8_t mode) { + if(!drill_cycle_started) return; + + bool allow_peck = mode == 83 || mode == 73; + bool allow_dwell = mode == 82 || mode == 83 || mode == 73; + + float drill_x_position = parser.seenval(AXIS_CHAR(X_AXIS)) ? parser.value_float() : NATIVE_TO_LOGICAL(current_position.x, X_AXIS); + float drill_y_position = parser.seenval(AXIS_CHAR(Y_AXIS)) ? parser.value_float() : NATIVE_TO_LOGICAL(current_position.y, Y_AXIS); + float drill_initial_z = NATIVE_TO_LOGICAL(current_position.z, Z_AXIS); + + if(!parser.seenval(AXIS_CHAR(Z_AXIS))) return; + float drill_finish_depth = parser.value_float(); + + float drill_rapid_z = parser.seenval('R') ? parser.value_float() : drill_initial_z; + float drill_retract_z = retract_to_initial ? drill_initial_z : drill_rapid_z; + float drill_current_depth = drill_rapid_z; + + uint16_t drill_feedrate = parser.seenval('F') ? parser.value_int() : (drill_feedrate > 0 ? drill_feedrate : DRILL_CYCLES_DEFAULT_FEEDRATE); + float drill_peck_distance = allow_peck ? (parser.seenval('Q') ? parser.value_float() : (DRILL_CYCLES_DEFAULT_PECK > 0 ? DRILL_CYCLES_DEFAULT_PECK : 10000)) : 10000; + uint16_t drill_dwell_time = allow_dwell ? (parser.seenval('P') ? parser.value_int() : DRILL_CYCLES_DEFAULT_DWELL) : 0; + + //move to initial xy position + move_to_XYZF(drill_x_position, + drill_y_position, + drill_initial_z, + DRILL_CYCLES_XY_FEEDRATE); + + //move to rapid z position + move_to_XYZF(drill_x_position, + drill_y_position, + drill_rapid_z, + DRILL_CYCLES_RETRACT_FEEDRATE); + + //start drill cycle + float drill_last_z = drill_rapid_z; + while(drill_current_depth > drill_finish_depth) { + //calculate new drill depth + drill_current_depth -= drill_peck_distance; + if(drill_current_depth < drill_finish_depth) drill_current_depth = drill_finish_depth; + + //drill into material + move_to_XYZF(drill_x_position, + drill_y_position, + drill_current_depth, + drill_feedrate); + + //do dwell + if(drill_dwell_time > 0) { + char gcode_str[15]; + sprintf_P(gcode_str, PSTR("G4 P%d"), drill_dwell_time); + #if ENABLED(DRILL_CYCLE_DEBUG) + SERIAL_ECHOPGM("DEBUG: ", gcode_str); + #endif + gcode.process_subcommands_now(gcode_str); + } + + //move to rapid z position + move_to_XYZF(drill_x_position, + drill_y_position, + mode == 73 ? drill_last_z : drill_rapid_z, + DRILL_CYCLES_RETRACT_FEEDRATE); + + //store current depth + drill_last_z = drill_current_depth; + } + + //retract to final z + move_to_XYZF(drill_x_position, + drill_y_position, + drill_retract_z, + DRILL_CYCLES_RETRACT_FEEDRATE); +} + +void GcodeSuite::G81(uint8_t mode) { + switch(mode) { + case 0: + drill_stop(); + break; + + case 1: + drill_cycle(81); + break; + + case 2: + drill_cycle(82); + break; + + case 3: + drill_cycle(83); + break; + + case 4: + drill_cycle(73); + break; + + case 18: + drill_start(true); + break; + + case 19: + drill_start(false); + break; + } +} + +#endif // DRILL_CYCLES diff --git a/ini/features.ini b/ini/features.ini index 03a9bdbba8..4dda225f8a 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -349,6 +349,7 @@ HAS_MULTI_LANGUAGE = build_src_filter=+ ARC_SUPPORT = build_src_filter=+ GCODE_MOTION_MODES = build_src_filter=+ +DRILL_CYCLES = build_src_filter=+ BABYSTEPPING = build_src_filter=+ + OTA_FIRMWARE_UPDATE = build_src_filter=+ Z_PROBE_SLED = build_src_filter=+