Skip to content

Commit 95d9199

Browse files
committed
integrate G38 into probes.cpp, introduce probe_safely()
1 parent 7a4c138 commit 95d9199

File tree

4 files changed

+303
-179
lines changed

4 files changed

+303
-179
lines changed

Marlin/src/gcode/calibrate/G34_M422.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
* I<int> Number of test iterations. If omitted, Z_STEPPER_ALIGN_ITERATIONS. (1-30)
6969
* T<float> Target Accuracy factor. If omitted, Z_STEPPER_ALIGN_ACC. (0.01-1.0)
7070
* A<float> Provide an Amplification value. If omitted, Z_STEPPER_ALIGN_AMP. (0.5-2.0)
71+
* E<bool> Stow or raise the probe after probing. 0=raise (default), 1=stow.
7172
* R Recalculate points based on current probe offsets
7273
*
7374
* Example:

Marlin/src/gcode/probe/G38.cpp

Lines changed: 48 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -30,46 +30,11 @@
3030
#include "../../module/motion.h"
3131
#include "../../module/planner.h"
3232
#include "../../module/probe.h"
33+
#include "../../feature/bedlevel/bedlevel.h"
34+
#include "../../lcd/marlinui.h"
3335

34-
inline void G38_single_probe(const uint8_t move_value) {
35-
endstops.enable(true);
36-
G38_move = move_value;
37-
prepare_line_to_destination();
38-
planner.synchronize();
39-
G38_move = 0;
40-
endstops.hit_on_purpose();
41-
set_current_from_steppers_for_axis(ALL_AXES_ENUM);
42-
sync_plan_position();
43-
}
44-
45-
inline bool G38_run_probe() {
46-
47-
bool G38_pass_fail = false;
48-
const xyze_pos_t start_pos = current_position;
49-
const xyze_pos_t old_destination = destination;
50-
probe.use_probing_tool();
51-
if (probe.deploy()) {
52-
SERIAL_ERROR_MSG("Failed to deploy probe");
53-
endstops.not_homing();
54-
probe.use_probing_tool(false);
55-
return false;
56-
}
57-
const xyze_pos_t npos_start = start_pos - DIFF_TERN(HAS_HOTEND_OFFSET, probe.offset, hotend_offset[active_extruder]);
58-
const xyze_pos_t npos_destination = old_destination - DIFF_TERN(HAS_HOTEND_OFFSET, probe.offset, hotend_offset[active_extruder]);
59-
do_blocking_move_to(npos_start);
60-
destination = npos_destination;
61-
62-
63-
#if MULTIPLE_PROBING > 1
64-
// Get direction of move and retract
65-
xyz_float_t retract_mm;
66-
LOOP_NUM_AXES(i) {
67-
const float dist = npos_destination[i] - npos_start[i];
68-
retract_mm[i] = ABS(dist) < G38_MINIMUM_MOVE ? 0 : home_bump_mm((AxisEnum)i) * (dist > 0 ? -1 : 1);
69-
}
70-
#endif
7136

72-
planner.synchronize(); // Wait until the machine is idle
37+
inline bool G38_run_probe(const ProbePtRaise raise_after) {
7338

7439
// Move flag value
7540
#if ENABLED(G38_PROBE_AWAY)
@@ -78,47 +43,34 @@ inline bool G38_run_probe() {
7843
constexpr uint8_t move_value = 1;
7944
#endif
8045

81-
G38_did_trigger = false;
82-
83-
// Move until destination reached or target hit
84-
G38_single_probe(move_value);
85-
86-
if (G38_did_trigger) {
87-
88-
G38_pass_fail = true;
89-
90-
#if MULTIPLE_PROBING > 1
91-
// Move away by the retract distance
92-
destination = current_position + retract_mm;
93-
endstops.enable(false);
94-
prepare_line_to_destination();
95-
planner.synchronize();
96-
#if ENABLED(SOLENOID_PROBE)
97-
probe.stow();
98-
safe_delay(1000);
99-
if (probe.deploy()) {
100-
endstops.not_homing();
101-
probe.use_probing_tool(false);
102-
return false;
103-
}
104-
#endif
105-
REMEMBER(fr, feedrate_mm_s, feedrate_mm_s * 0.25);
46+
const xyz_pos_t measured = probe.probe_safely(destination, raise_after, move_value, 0, true, true, Z_TWEEN_SAFE_CLEARANCE, true, true);
10647

107-
// Bump the target more slowly
108-
destination -= retract_mm * 2;
48+
LOOP_NUM_AXES(a) {
49+
if (isnan(measured[a])) return true;
50+
}
10951

110-
G38_single_probe(move_value);
111-
#endif
52+
// Report a good probe result in machine coordinate system to the host and LCD
53+
SString<30> msg(
54+
F("Machine X:"), p_float_t(measured.x, 2),
55+
F(" Y:"), p_float_t(measured.y, 2),
56+
F(" Z:"), p_float_t(measured.z, 3)
57+
);
58+
msg.echoln();
59+
TERN_(VERBOSE_SINGLE_PROBE, ui.set_status(msg));
60+
61+
// If the probe is stowed, move the nozzle to the position of the probe
62+
const xyz_pos_t offs = DIFF_TERN(HAS_HOTEND_OFFSET, probe.offset, hotend_offset[active_extruder]);
63+
if ((!endstops.z_probe_enabled) && (probe.offset.z >= TERN0(HAS_HOTEND_OFFSET, hotend_offset[active_extruder].z))) {
64+
if ((!NEAR_ZERO(offs.x)) || (!NEAR_ZERO(offs.y)) || offs.z > 0.0f) {
65+
do_z_clearance_by(Z_TWEEN_SAFE_CLEARANCE);
66+
}
67+
destination = measured;
68+
do_blocking_move_to(destination);
69+
planner.synchronize();
11270
}
11371

114-
endstops.enable(false);
115-
TERN_(SOLENOID_PROBE, probe.stow());
116-
const xyze_pos_t probed_pos = current_position + DIFF_TERN(HAS_HOTEND_OFFSET, probe.offset, hotend_offset[active_extruder]);
117-
probe.use_probing_tool(false);
118-
destination = probed_pos;
119-
do_blocking_move_to(destination);
120-
planner.synchronize();
121-
return G38_pass_fail;
72+
report_current_position();
73+
return false;
12274
}
12375

12476
/**
@@ -131,26 +83,44 @@ inline bool G38_run_probe() {
13183
*
13284
* G38.4 - Probe away from workpiece, stop on contact break, signal error if failure
13385
* G38.5 - Probe away from workpiece, stop on contact break
86+
*
87+
* Parameters:
88+
*
89+
* X Probe X position (default current X)
90+
* Y Probe Y position (default current Y)
91+
* Z Probe Z position (default current Z)
92+
* S Stow the probe after probing (default: 0)
13493
*/
13594
void GcodeSuite::G38(const int8_t subcode) {
13695

13796
// Get X Y Z E F
13897
get_destination_from_command();
98+
99+
probe.use_probing_tool();
100+
101+
// Disable leveling so the planner won't mess with us
102+
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
139103

140104
remember_feedrate_scaling_off();
141105

106+
// Raise after based on the 'S' parameter
107+
const ProbePtRaise raise_after = parser.boolval('S', false) ? PROBE_PT_STOW : PROBE_PT_NONE;
108+
142109
const bool error_on_fail = TERN(G38_PROBE_AWAY, !TEST(subcode, 0), subcode == 2);
143110

144111
// If any axis has enough movement, do the move
145-
LOOP_NUM_AXES(i)
112+
LOOP_NUM_AXES(i) {
146113
if (ABS(destination[i] - current_position[i]) >= G38_MINIMUM_MOVE) {
147114
if (!parser.seenval('F')) feedrate_mm_s = homing_feedrate((AxisEnum)i);
148115
// If G38.2 fails throw an error
149-
if (!G38_run_probe() && error_on_fail) SERIAL_ERROR_MSG("Failed to reach target");
116+
if (G38_run_probe(raise_after) && error_on_fail) {
117+
SERIAL_ERROR_MSG("Failed to reach target");
118+
}
150119
break;
151120
}
152-
121+
}
153122
restore_feedrate_and_scaling();
123+
probe.use_probing_tool(false);
154124
}
155125

156126
#endif // G38_PROBE_TARGET

0 commit comments

Comments
 (0)