From a69dd9b0f12e3423ee3aaf4cb969c1c6922575b4 Mon Sep 17 00:00:00 2001
From: Switchleg1 <89221799+Switchleg1@users.noreply.github.com>
Date: Sat, 20 Dec 2025 07:18:48 -0700
Subject: [PATCH] drill cycles
---
Marlin/Configuration_adv.h | 30 ++++++
Marlin/src/gcode/gcode.cpp | 14 +++
Marlin/src/gcode/gcode.h | 11 ++
Marlin/src/gcode/motion/G81.cpp | 174 ++++++++++++++++++++++++++++++++
platformio.ini | 1 +
5 files changed, 230 insertions(+)
create mode 100644 Marlin/src/gcode/motion/G81.cpp
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 8a1adb3e4c..6c19a7545b 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -4302,6 +4302,36 @@
#define FREEZE_STATE LOW // State of pin indicating freeze
#endif
+/**
+ * Canned drill cycle functionality
+ * Adds the following Gcode:
+ * 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 - retract to initial
+ * G99: Start - retract to specified
+ * or if DRILL_USE_81_ONLY is specified (or GCODE_MOTION_MODES):
+ * 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.4: Shallow peck drill cycle
+ * G81.18: Start - retract to initial
+ * G81.19: Start - retract to specified
+ * @section drill cycles
+ */
+#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 9fed4dcada..8c7bf5dc79 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -457,6 +457,20 @@ void GcodeSuite::process_parsed_command(const 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: set_relative_mode(false); break; // G90: Absolute Mode
case 91: set_relative_mode(true); break; // G91: Relative Mode
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 589cd2bc48..3001d9bf66 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -66,8 +66,15 @@
* 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 (Basic with dwell)
+ * G83 - Deep drill cycle (Normal with peck)
+ * G98 - Start drill - retract to initial
+ * G99 - Start drill - retract to specified
* G90 - Use Absolute Coordinates
* G91 - Use Relative Coordinates
* G92 - Set current position to coordinates given
@@ -629,6 +636,10 @@ private:
static void G80();
#endif
+#if ENABLED(DRILL_CYCLES)
+ static void G81(uint8_t mode);
+#endif
+
static void G92();
#if ENABLED(CALIBRATION_GCODE)
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/platformio.ini b/platformio.ini
index ed1670dc6d..b5e5687dff 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -114,6 +114,7 @@ default_src_filter = + - -
+
+
+
+ +
+
+
+