Skip to content

Commit f5d5b0a

Browse files
authored
✨ EDITABLE_HOMING_FEEDRATE / M210 (#27456)
1 parent 30f5dd3 commit f5d5b0a

File tree

14 files changed

+248
-36
lines changed

14 files changed

+248
-36
lines changed

Marlin/Configuration.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -1610,7 +1610,8 @@
16101610
// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
16111611
#define PROBING_MARGIN 10
16121612

1613-
// X and Y axis travel speed (mm/min) between probes
1613+
// X and Y axis travel speed (mm/min) between probes.
1614+
// Leave undefined to use the average of the current XY homing feedrate.
16141615
#define XY_PROBE_FEEDRATE (133*60)
16151616

16161617
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
@@ -2304,6 +2305,9 @@
23042305
// Homing speeds (linear=mm/min, rotational=°/min)
23052306
#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) }
23062307

2308+
// Edit homing feedrates with M210 and MarlinUI menu items
2309+
//#define EDITABLE_HOMING_FEEDRATE
2310+
23072311
// Validate that endstops are triggered on homing moves
23082312
#define VALIDATE_HOMING_ENDSTOPS
23092313

Marlin/src/core/language.h

+32-21
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
#define STR_MAX_ACCELERATION "Max Acceleration (units/s2)"
291291
#define STR_MAX_FEEDRATES "Max feedrates (units/s)"
292292
#define STR_ACCELERATION_P_R_T "Acceleration (units/s2) (P<print-accel> R<retract-accel> T<travel-accel>)"
293+
#define STR_HOMING_FEEDRATE "Homing Feedrate"
293294
#define STR_TOOL_CHANGING "Tool-changing"
294295
#define STR_HOTEND_OFFSETS "Hotend offsets"
295296
#define STR_SERVO_ANGLES "Servo Angles"
@@ -323,6 +324,37 @@
323324
#define STR_USER_THERMISTORS "User thermistors"
324325
#define STR_DELAYED_POWEROFF "Delayed poweroff"
325326

327+
//
328+
// General axis names
329+
//
330+
#if HAS_X_AXIS
331+
#define AXIS1_NAME 'X'
332+
#endif
333+
#if HAS_Y_AXIS
334+
#define AXIS2_NAME 'Y'
335+
#endif
336+
#if HAS_Z_AXIS
337+
#define AXIS3_NAME 'Z'
338+
#endif
339+
#define STR_X "X"
340+
#define STR_Y "Y"
341+
#define STR_Z "Z"
342+
#define STR_E "E"
343+
#if IS_KINEMATIC
344+
#define STR_A "A"
345+
#define STR_B "B"
346+
#define STR_C "C"
347+
#else
348+
#define STR_A STR_X
349+
#define STR_B STR_Y
350+
#define STR_C STR_Z
351+
#endif
352+
#define STR_X2 STR_A "2"
353+
#define STR_Y2 STR_B "2"
354+
#define STR_Z2 STR_C "2"
355+
#define STR_Z3 STR_C "3"
356+
#define STR_Z4 STR_C "4"
357+
326358
//
327359
// Endstop Names used by Endstops::report_states
328360
//
@@ -354,29 +386,8 @@
354386
#define STR_Z_PROBE "z_probe"
355387
#define STR_PROBE_EN "probe_en"
356388
#define STR_FILAMENT "filament"
357-
358389
#define STR_CALIBRATION "calibration"
359390

360-
// General axis names
361-
#define STR_X "X"
362-
#define STR_Y "Y"
363-
#define STR_Z "Z"
364-
#define STR_E "E"
365-
#if IS_KINEMATIC
366-
#define STR_A "A"
367-
#define STR_B "B"
368-
#define STR_C "C"
369-
#else
370-
#define STR_A "X"
371-
#define STR_B "Y"
372-
#define STR_C "Z"
373-
#endif
374-
#define STR_X2 "X2"
375-
#define STR_Y2 "Y2"
376-
#define STR_Z2 "Z2"
377-
#define STR_Z3 "Z3"
378-
#define STR_Z4 "Z4"
379-
380391
// Extra Axis and Endstop Names
381392
#if HAS_I_AXIS
382393
#if AXIS4_NAME == 'A'

Marlin/src/gcode/calibrate/G28.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,9 @@ void GcodeSuite::G28() {
322322

323323
#else // !DELTA && !AXEL_TPARA
324324

325-
#define _UNSAFE(A) TERN0(Z_SAFE_HOMING, homeZ && axis_should_home(_AXIS(A)))
325+
#define _UNSAFE(A) TERN0(Z_SAFE_HOMING, homeZZ && axis_should_home(_AXIS(A)))
326326

327-
const bool homeZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')),
327+
const bool homeZZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')),
328328
NUM_AXIS_LIST_( // Other axes should be homed before Z safe-homing
329329
needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false, // UNUSED
330330
needI = _UNSAFE(I), needJ = _UNSAFE(J), needK = _UNSAFE(K),
@@ -333,7 +333,7 @@ void GcodeSuite::G28() {
333333
NUM_AXIS_LIST_( // Home each axis if needed or flagged
334334
homeX = needX || parser.seen_test('X'),
335335
homeY = needY || parser.seen_test('Y'),
336-
homeZZ = homeZ,
336+
homeZ = homeZZ,
337337
homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME),
338338
homeK = needK || parser.seen_test(AXIS6_NAME), homeU = needU || parser.seen_test(AXIS7_NAME),
339339
homeV = needV || parser.seen_test(AXIS8_NAME), homeW = needW || parser.seen_test(AXIS9_NAME)
@@ -355,7 +355,7 @@ void GcodeSuite::G28() {
355355

356356
#if HAS_Z_AXIS
357357

358-
UNUSED(needZ); UNUSED(homeZZ);
358+
UNUSED(needZ);
359359

360360
// Z may home first, e.g., when homing away from the bed.
361361
// This is also permitted when homing with a Z endstop.
@@ -439,8 +439,7 @@ void GcodeSuite::G28() {
439439

440440
#if HAS_Y_AXIS
441441
// Home Y (after X)
442-
if (DISABLED(HOME_Y_BEFORE_X) && doY)
443-
homeaxis(Y_AXIS);
442+
if (DISABLED(HOME_Y_BEFORE_X) && doY) homeaxis(Y_AXIS);
444443
#endif
445444

446445
#if ALL(FOAMCUTTER_XYUV, HAS_J_AXIS)

Marlin/src/gcode/config/M210.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
23+
#include "../../inc/MarlinConfigPre.h"
24+
25+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
26+
27+
#include "../gcode.h"
28+
#include "../../module/motion.h"
29+
30+
/**
31+
* M210 - Set homing feedrate for one or more axes
32+
* in current units (in/mm) per minute
33+
*
34+
* X[feedrate] Set X axis homing feedrate
35+
* Y[feedrate] Set Y axis homing feedrate
36+
* Z[feedrate] Set Z axis homing feedrate
37+
* A[feedrate] Set I axis homing feedrate (configured axis name applies)
38+
* B[feedrate] Set J axis homing feedrate (configured axis name applies)
39+
* C[feedrate] Set K axis homing feedrate (configured axis name applies)
40+
* U[feedrate] Set U axis homing feedrate (configured axis name applies)
41+
* V[feedrate] Set V axis homing feedrate (configured axis name applies)
42+
* W[feedrate] Set W axis homing feedrate (configured axis name applies)
43+
*
44+
* With no arguments, report the current offsets.
45+
*/
46+
void GcodeSuite::M210() {
47+
if (!parser.seen_any())
48+
return M210_report();
49+
50+
#if HAS_X_AXIS
51+
if (parser.floatval('X') > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS);
52+
#endif
53+
#if HAS_Y_AXIS
54+
if (parser.floatval('Y') > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS);
55+
#endif
56+
#if HAS_Z_AXIS
57+
if (parser.floatval('Z') > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS);
58+
#endif
59+
#if HAS_I_AXIS
60+
if (parser.floatval(AXIS4_NAME) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS);
61+
#endif
62+
#if HAS_J_AXIS
63+
if (parser.floatval(AXIS5_NAME) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS);
64+
#endif
65+
#if HAS_K_AXIS
66+
if (parser.floatval(AXIS6_NAME) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS);
67+
#endif
68+
#if HAS_U_AXIS
69+
if (parser.floatval(AXIS7_NAME) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS);
70+
#endif
71+
#if HAS_V_AXIS
72+
if (parser.floatval(AXIS8_NAME) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS);
73+
#endif
74+
#if HAS_W_AXIS
75+
if (parser.floatval(AXIS9_NAME) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS);
76+
#endif
77+
}
78+
79+
void GcodeSuite::M210_report(const bool forReplay/*=true*/) {
80+
TERN_(MARLIN_SMALL_BUILD, return);
81+
82+
report_heading_etc(forReplay, F(STR_HOMING_FEEDRATE));
83+
84+
SERIAL_ECHOPGM(" M210");
85+
SERIAL_ECHOLNPGM_P(
86+
LIST_N(DOUBLE(NUM_AXES)
87+
, SP_X_STR, X_AXIS_UNIT(homing_feedrate_mm_m.x)
88+
, SP_Y_STR, Y_AXIS_UNIT(homing_feedrate_mm_m.y)
89+
, SP_Z_STR, Z_AXIS_UNIT(homing_feedrate_mm_m.z)
90+
, SP_I_STR, I_AXIS_UNIT(homing_feedrate_mm_m.i)
91+
, SP_J_STR, J_AXIS_UNIT(homing_feedrate_mm_m.j)
92+
, SP_K_STR, K_AXIS_UNIT(homing_feedrate_mm_m.k)
93+
, SP_U_STR, U_AXIS_UNIT(homing_feedrate_mm_m.u)
94+
, SP_V_STR, V_AXIS_UNIT(homing_feedrate_mm_m.v)
95+
, SP_W_STR, W_AXIS_UNIT(homing_feedrate_mm_m.w)
96+
)
97+
);
98+
}
99+
100+
#endif // EDITABLE_HOMING_FEEDRATE

Marlin/src/gcode/gcode.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,10 @@ void GcodeSuite::get_destination_from_command() {
200200
#endif
201201

202202
if (parser.floatval('F') > 0) {
203-
feedrate_mm_s = parser.value_feedrate();
203+
const float fr_mm_min = parser.value_linear_units();
204+
feedrate_mm_s = MMM_TO_MMS(fr_mm_min);
204205
// Update the cutter feed rate for use by M4 I set inline moves.
205-
TERN_(LASER_FEATURE, cutter.feedrate_mm_m = MMS_TO_MMM(feedrate_mm_s));
206+
TERN_(LASER_FEATURE, cutter.feedrate_mm_m = fr_mm_min);
206207
}
207208

208209
#if ALL(PRINTCOUNTER, HAS_EXTRUDERS)
@@ -742,6 +743,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
742743
#endif
743744
#endif
744745

746+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
747+
case 210: M210(); break; // M210: Set the homing feedrate
748+
#endif
749+
745750
#if HAS_SOFTWARE_ENDSTOPS
746751
case 211: M211(); break; // M211: Enable, Disable, and/or Report software endstops
747752
#endif

Marlin/src/gcode/gcode.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
* M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>. (Requires FWRETRACT)
196196
* M209 - Turn Automatic Retract Detection on/off: S<0|1> (For slicers that don't support G10/11). (Requires FWRETRACT_AUTORETRACT)
197197
Every normal extrude-only move will be classified as retract depending on the direction.
198+
* M210 - Set or Report the homing feedrate (Requires EDITABLE_HOMING_FEEDRATE)
198199
* M211 - Enable, Disable, and/or Report software endstops: S<0|1> (Requires MIN_SOFTWARE_ENDSTOPS or MAX_SOFTWARE_ENDSTOPS)
199200
* M217 - Set filament swap parameters: "M217 S<length> P<feedrate> R<feedrate>". (Requires SINGLENOZZLE)
200201
* M218 - Set/get a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders)
@@ -897,8 +898,15 @@ class GcodeSuite {
897898
#endif
898899
#endif
899900

900-
static void M211();
901-
static void M211_report(const bool forReplay=true);
901+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
902+
static void M210();
903+
static void M210_report(const bool forReplay=true);
904+
#endif
905+
906+
#if HAS_SOFTWARE_ENDSTOPS
907+
static void M211();
908+
static void M211_report(const bool forReplay=true);
909+
#endif
902910

903911
#if HAS_MULTI_EXTRUDER
904912
static void M217();

Marlin/src/gcode/parser.h

+3
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ class GCodeParser {
347347
#define LINEAR_UNIT(V) parser.mm_to_linear_unit(V)
348348
#define VOLUMETRIC_UNIT(V) parser.mm_to_volumetric_unit(V)
349349

350+
#define X_AXIS_UNIT LINEAR_UNIT
351+
#define Y_AXIS_UNIT LINEAR_UNIT
352+
#define Z_AXIS_UNIT LINEAR_UNIT
350353
#define I_AXIS_UNIT(V) TERN(AXIS4_ROTATES, (V), LINEAR_UNIT(V))
351354
#define J_AXIS_UNIT(V) TERN(AXIS5_ROTATES, (V), LINEAR_UNIT(V))
352355
#define K_AXIS_UNIT(V) TERN(AXIS6_ROTATES, (V), LINEAR_UNIT(V))

Marlin/src/lcd/language/language_en.h

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ namespace LanguageNarrow_en {
9999
LSTR MSG_ENDSTOP_TEST = _UxGT("Endstop Test");
100100
LSTR MSG_Z_PROBE = _UxGT("Z Probe");
101101
LSTR MSG_HOMING = _UxGT("Homing");
102+
LSTR MSG_HOMING_FEEDRATE = _UxGT("Homing Feedrate");
103+
LSTR MSG_HOMING_FEEDRATE_N = _UxGT("@ Homing FR");
102104
LSTR MSG_AUTO_HOME = _UxGT("Auto Home");
103105
LSTR MSG_HOME_ALL = _UxGT("Home All");
104106
LSTR MSG_AUTO_HOME_N = _UxGT("Home @");
@@ -1094,6 +1096,7 @@ namespace LanguageWide_en {
10941096
LSTR MSG_INFO_PRINT_TIME = _UxGT("Print Time");
10951097
LSTR MSG_INFO_PRINT_LONGEST = _UxGT("Longest Job Time");
10961098
LSTR MSG_INFO_PRINT_FILAMENT = _UxGT("Extruded Total");
1099+
LSTR MSG_HOMING_FEEDRATE_N = _UxGT("@ Homing Feedrate");
10971100
#endif
10981101
}
10991102

Marlin/src/lcd/menu/menu_configuration.cpp

+39-2
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,40 @@ void menu_advanced_settings();
395395
END_MENU();
396396
}
397397

398-
#endif
398+
#endif // FWRETRACT
399+
400+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
401+
402+
#include "../../module/motion.h"
403+
#include "../../module/planner.h"
404+
#include "../../gcode/parser.h"
405+
406+
// Edit homing feedrates in inches- or degrees- or mm-per-minute
407+
void menu_homing_feedrate() {
408+
START_MENU();
409+
BACK_ITEM(MSG_HOMING_FEEDRATE);
410+
411+
#if ENABLED(MENUS_ALLOW_INCH_UNITS)
412+
#define _EDIT_HOMING_FR(A) do{ \
413+
const float maxfr = MMS_TO_MMM(planner.settings.max_feedrate_mm_s[_AXIS(A)]); \
414+
editable.decimal = A##_AXIS_UNIT(homing_feedrate_mm_m.A); \
415+
EDIT_ITEM(float5, MSG_HOMING_FEEDRATE_N, &editable.decimal, \
416+
A##_AXIS_UNIT(10), A##_AXIS_UNIT(maxfr), []{ \
417+
homing_feedrate_mm_m.A = parser.axis_value_to_mm(_AXIS(A), editable.decimal); \
418+
}); \
419+
}while(0);
420+
#else
421+
#define _EDIT_HOMING_FR(A) do{ \
422+
EDIT_ITEM(float5, MSG_HOMING_FEEDRATE_N, &homing_feedrate_mm_m.A, 10, MMS_TO_MMM(planner.settings.max_feedrate_mm_s[_AXIS(A)])); \
423+
}while(0);
424+
#endif
425+
426+
MAIN_AXIS_MAP(_EDIT_HOMING_FR);
427+
428+
END_MENU();
429+
}
430+
431+
#endif // EDITABLE_HOMING_FEEDRATE
399432

400433
#if HAS_PREHEAT && DISABLED(SLIM_LCD_MENUS)
401434

@@ -424,7 +457,7 @@ void menu_advanced_settings();
424457
END_MENU();
425458
}
426459

427-
#endif
460+
#endif // HAS_PREHEAT && !SLIM_LCD_MENUS
428461

429462
#if ENABLED(CUSTOM_MENU_CONFIG)
430463

@@ -623,6 +656,10 @@ void menu_configuration() {
623656
#endif
624657
#endif
625658

659+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
660+
SUBMENU(MSG_HOMING_FEEDRATE, menu_homing_feedrate);
661+
#endif
662+
626663
#if ENABLED(FWRETRACT)
627664
SUBMENU(MSG_RETRACT, menu_config_retract);
628665
#endif

Marlin/src/module/motion.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ xyze_pos_t destination; // {0}
146146
#endif
147147
feedRate_t feedrate_mm_s = MMM_TO_MMS(DEFAULT_FEEDRATE_MM_M);
148148
int16_t feedrate_percentage = 100;
149+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
150+
xyz_feedrate_t homing_feedrate_mm_m = HOMING_FEEDRATE_MM_M;
151+
#endif
149152

150153
// Cartesian conversion result goes here:
151154
xyz_pos_t cartes;

Marlin/src/module/motion.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ extern xyz_pos_t cartes;
7979
* Feed rates are often configured with mm/m
8080
* but the planner and stepper like mm/s units.
8181
*/
82-
constexpr xyz_feedrate_t homing_feedrate_mm_m = HOMING_FEEDRATE_MM_M;
82+
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
83+
extern xyz_feedrate_t homing_feedrate_mm_m;
84+
#else
85+
constexpr xyz_feedrate_t homing_feedrate_mm_m = HOMING_FEEDRATE_MM_M;
86+
#endif
87+
8388
FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a) {
8489
float v = TERN0(HAS_Z_AXIS, homing_feedrate_mm_m.z);
8590
#if DISABLED(DELTA)

0 commit comments

Comments
 (0)