0
0
Fork 0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2025-01-19 08:08:25 +00:00

PROBING_TOOL (#24411)

This commit is contained in:
John Lagonikas 2023-03-22 02:15:51 +02:00 committed by GitHub
parent d450f67caa
commit 06cfd9c54a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 62 deletions

View file

@ -1552,6 +1552,12 @@
*/
#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
// Enable and set to use a specific tool for probing. Disable to allow any tool.
#define PROBING_TOOL 0
#ifdef PROBING_TOOL
//#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change
#endif
// Most probes should stay away from the edges of the bed, but
// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
#define PROBING_MARGIN 10

View file

@ -306,16 +306,13 @@ void unified_bed_leveling::G29() {
const uint8_t p_val = parser.byteval('P');
const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J');
#if HAS_MULTI_HOTEND
const uint8_t old_tool_index = active_extruder;
#endif
// Check for commands that require the printer to be homed
if (may_move) {
planner.synchronize();
// Send 'N' to force homing before G29 (internal only)
if (axes_should_home() || parser.seen_test('N')) gcode.home_all_axes();
TERN_(HAS_MULTI_HOTEND, if (active_extruder != 0) tool_change(0, true));
probe.use_probing_tool();
// Position bed horizontally and Z probe vertically.
#if HAS_SAFE_BED_LEVELING
@ -696,7 +693,7 @@ void unified_bed_leveling::G29() {
UNUSED(probe_deployed);
#endif
TERN_(HAS_MULTI_HOTEND, if (old_tool_index != 0) tool_change(old_tool_index));
probe.use_probing_tool(false);
return;
}

View file

@ -86,11 +86,7 @@ void GcodeSuite::G35() {
workspace_plane = PLANE_XY;
#endif
// Always home with tool 0 active
#if HAS_MULTI_HOTEND
const uint8_t old_tool_index = active_extruder;
tool_change(0, true);
#endif
probe.use_probing_tool();
// Disable duplication mode on homing
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
@ -153,9 +149,7 @@ void GcodeSuite::G35() {
SERIAL_ECHOLNPGM("G35 aborted.");
// Restore the active tool after homing
#if HAS_MULTI_HOTEND
if (old_tool_index != 0) tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER)); // Fetch previous toolhead if not PARKING_EXTRUDER
#endif
probe.use_probing_tool(false);
#if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G35)
set_bed_leveling_enabled(leveling_was_active);

View file

@ -97,10 +97,6 @@ public:
bool dryrun,
reenable;
#if HAS_MULTI_HOTEND
uint8_t tool_index;
#endif
#if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR)
int abl_probe_index;
#endif
@ -281,10 +277,7 @@ G29_TYPE GcodeSuite::G29() {
*/
if (!g29_in_progress) {
#if HAS_MULTI_HOTEND
abl.tool_index = active_extruder;
if (active_extruder != 0) tool_change(0, true);
#endif
probe.use_probing_tool();
#if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR)
abl.abl_probe_index = -1;
@ -947,7 +940,7 @@ G29_TYPE GcodeSuite::G29() {
process_subcommands_now(F(Z_PROBE_END_SCRIPT));
#endif
TERN_(HAS_MULTI_HOTEND, if (abl.tool_index != 0) tool_change(abl.tool_index));
probe.use_probing_tool(false);
report_current_position();

View file

@ -103,9 +103,8 @@ void GcodeSuite::G29() {
bedlevel.reset();
mbl_probe_index = 0;
if (!ui.wait_for_move) {
queue.inject(parser.seen_test('N') ? F("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : F("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart());
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
if (parser.seen_test('N'))
queue.inject(F("G28" TERN_(CAN_SET_LEVELING_AFTER_G28, "L0")));
// Position bed horizontally and Z probe vertically.
#if HAS_SAFE_BED_LEVELING
@ -141,6 +140,11 @@ void GcodeSuite::G29() {
do_blocking_move_to(safe_position);
#endif // HAS_SAFE_BED_LEVELING
queue.inject(F("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart());
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
return;
}
state = MeshNext;

View file

@ -63,10 +63,6 @@ enum CalEnum : char { // the 7 main calibration points -
#define LOOP_CAL_RAD(VAR) LOOP_CAL_PT(VAR, __A, _7P_STEP)
#define LOOP_CAL_ACT(VAR, _4P, _OP) LOOP_CAL_PT(VAR, _OP ? _AB : __A, _4P ? _4P_STEP : _7P_STEP)
#if HAS_MULTI_HOTEND
const uint8_t old_tool_index = active_extruder;
#endif
float lcd_probe_pt(const xy_pos_t &xy);
void ac_home() {
@ -78,7 +74,7 @@ void ac_home() {
}
void ac_setup(const bool reset_bed) {
TERN_(HAS_MULTI_HOTEND, tool_change(0, true));
TERN_(HAS_BED_PROBE, probe.use_probing_tool());
planner.synchronize();
remember_feedrate_scaling_off();
@ -92,7 +88,7 @@ void ac_cleanup(TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index)) {
TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height));
TERN_(HAS_BED_PROBE, probe.stow());
restore_feedrate_and_scaling();
TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, true));
TERN_(HAS_BED_PROBE, probe.use_probing_tool(false));
}
void print_signed_float(FSTR_P const prefix, const_float_t f) {

View file

@ -108,6 +108,7 @@ void GcodeSuite::G34() {
}
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
do { // break out on error
const int8_t z_auto_align_iterations = parser.intval('I', Z_STEPPER_ALIGN_ITERATIONS);
@ -142,11 +143,7 @@ void GcodeSuite::G34() {
TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
// Always home with tool 0 active
#if HAS_MULTI_HOTEND
const uint8_t old_tool_index = active_extruder;
tool_change(0, true);
#endif
probe.use_probing_tool();
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
@ -448,14 +445,16 @@ void GcodeSuite::G34() {
sync_plan_position();
#endif
// Restore the active tool after homing
TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER))); // Fetch previous tool for parking extruder
probe.use_probing_tool(false);
#if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34)
set_bed_leveling_enabled(leveling_was_active);
#endif
}while(0);
probe.use_probing_tool(false);
#endif // Z_STEPPER_AUTO_ALIGN
}

View file

@ -53,10 +53,7 @@
*/
void GcodeSuite::G30() {
#if HAS_MULTI_HOTEND
const uint8_t old_tool_index = active_extruder;
tool_change(0);
#endif
probe.use_probing_tool();
// Convert the given logical position to native position
const xy_pos_t pos = {
@ -106,8 +103,7 @@ void GcodeSuite::G30() {
#endif
}
// Restore the active tool
TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index));
probe.use_probing_tool(false);
}
#endif // HAS_BED_PROBE

View file

@ -1110,6 +1110,14 @@
#define HAS_BED_PROBE 1
#endif
// Probing tool change
#if !HAS_MULTI_EXTRUDER
#undef PROBING_TOOL
#endif
#if HAS_BED_PROBE && defined(PROBING_TOOL)
#define DO_TOOLCHANGE_FOR_PROBING 1
#endif
/**
* Fill in undefined Filament Sensor options
*/

View file

@ -2664,6 +2664,10 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS
#endif // HOTENDS > 2
#endif // HAS_MULTI_HOTEND
#if DO_TOOLCHANGE_FOR_PROBING && PROBING_TOOL >= EXTRUDERS
#error "PROBING_TOOL must be a valid tool index."
#endif
/**
* Pins must be set for temp sensors, with some other feature requirements.
*/

View file

@ -196,35 +196,35 @@ xyz_pos_t Probe::offset; // Initialized by settings.load()
inline void run_deploy_moves() {
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_1
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_1 = Z_PROBE_ALLEN_KEY_DEPLOY_1;
do_blocking_move_to(deploy_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_2
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_2 = Z_PROBE_ALLEN_KEY_DEPLOY_2;
do_blocking_move_to(deploy_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_3
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_3 = Z_PROBE_ALLEN_KEY_DEPLOY_3;
do_blocking_move_to(deploy_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_4
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_4 = Z_PROBE_ALLEN_KEY_DEPLOY_4;
do_blocking_move_to(deploy_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_DEPLOY_5
#ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE
#define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t deploy_5 = Z_PROBE_ALLEN_KEY_DEPLOY_5;
do_blocking_move_to(deploy_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE));
@ -234,35 +234,35 @@ xyz_pos_t Probe::offset; // Initialized by settings.load()
inline void run_stow_moves() {
#ifdef Z_PROBE_ALLEN_KEY_STOW_1
#ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_1 = Z_PROBE_ALLEN_KEY_STOW_1;
do_blocking_move_to(stow_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_2
#ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_2 = Z_PROBE_ALLEN_KEY_STOW_2;
do_blocking_move_to(stow_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_3
#ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_3 = Z_PROBE_ALLEN_KEY_STOW_3;
do_blocking_move_to(stow_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_4
#ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_4 = Z_PROBE_ALLEN_KEY_STOW_4;
do_blocking_move_to(stow_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE));
#endif
#ifdef Z_PROBE_ALLEN_KEY_STOW_5
#ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE
#define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0
#define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0f
#endif
constexpr xyz_pos_t stow_5 = Z_PROBE_ALLEN_KEY_STOW_5;
do_blocking_move_to(stow_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE));
@ -355,7 +355,8 @@ xyz_pos_t Probe::offset; // Initialized by settings.load()
void Probe::do_z_raise(const float z_raise) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe::do_z_raise(", z_raise, ")");
float z_dest = z_raise;
if (offset.z < 0) z_dest -= offset.z;
const float zoffs = DIFF_TERN(HAS_HOTEND_OFFSET, offset.z, hotend_offset[active_extruder].z);
if (zoffs < 0) z_dest -= zoffs;
do_z_clearance(z_dest);
}
@ -714,13 +715,15 @@ bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) {
float Probe::run_z_probe(const bool sanity_check/*=true*/) {
DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING));
const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z);
auto try_to_probe = [&](PGM_P const plbl, const_float_t z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck, const float clearance) -> bool {
// Tare the probe, if supported
if (TERN0(PROBE_TARE, tare())) return true;
// Do a first probe at the fast speed
const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger?
early_fail = (scheck && current_position.z > -offset.z + clearance); // Probe triggered too high?
early_fail = (scheck && current_position.z > zoffs + clearance); // Probe triggered too high?
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) {
DEBUG_ECHOPGM_P(plbl);
@ -737,7 +740,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
// Stop the probe before it goes too low to prevent damage.
// If Z isn't known then probe to -10mm.
const float z_probe_low_point = axis_is_trusted(Z_AXIS) ? -offset.z + Z_PROBE_LOW_POINT : -10.0;
const float z_probe_low_point = axis_is_trusted(Z_AXIS) ? zoffs + Z_PROBE_LOW_POINT : -10.0f;
// Double-probing does a fast probe followed by a slow probe
#if TOTAL_PROBING == 2
@ -759,7 +762,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
// If the nozzle is well over the travel height then
// move down quickly before doing the slow probe
const float z = Z_CLEARANCE_DEPLOY_PROBE + 5.0 + (offset.z < 0 ? -offset.z : 0);
const float z = Z_CLEARANCE_DEPLOY_PROBE + 5.0f + (zoffs > 0 ? zoffs : 0);
if (current_position.z > z) {
// Probe down fast. If the probe never triggered, raise for probe clearance
if (!probe_down_to_z(z, z_probe_fast_mm_s))
@ -847,7 +850,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", first_probe_z - z2);
// Return a weighted average of the fast and slow probes
const float measured_z = (z2 * 3.0 + first_probe_z * 2.0) * 0.2;
const float measured_z = (z2 * 3.0f + first_probe_z * 2.0f) * 0.2f;
#else
@ -856,10 +859,33 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
#endif
return measured_z;
return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z);
}
#if DO_TOOLCHANGE_FOR_PROBING
#include "tool_change.h"
/**
* Switches to the appropriate tool (PROBING_TOOL) for probing (probing = true), and switches
* back to the old tool when probing = false. Uses statics to avoid unnecessary checks and to
* cache the previous tool, so always call with false after calling with true.
*/
void Probe::use_probing_tool(const bool probing/*=true*/) {
static uint8_t old_tool;
static bool old_state = false;
if (probing == old_state) return;
old_state = probing;
if (probing) old_tool = active_extruder;
const uint8_t tool = probing ? PROBING_TOOL : old_tool;
if (tool != active_extruder)
tool_change(tool, ENABLED(PROBE_TOOLCHANGE_NO_MOVE));
}
#endif
/**
* - Switch to PROBING_TOOL if necessary
* - Move to the given XY
* - Deploy the probe, if not already deployed
* - Probe the bed, get the Z position
@ -867,6 +893,12 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
* - Stow the probe, or
* - Raise to the BETWEEN height
* - Return the probed Z position
* - Revert to previous tool
*
* A batch of multiple probing operations should always be preceded by use_probing_tool() invocation
* and succeeded by use_probing_tool(false), in order to avoid multiple tool changes and to end up
* with the previously active tool.
*
*/
float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRaise raise_after/*=PROBE_PT_NONE*/, const uint8_t verbose_level/*=0*/, const bool probe_relative/*=true*/, const bool sanity_check/*=true*/) {
DEBUG_SECTION(log_probe, "Probe::probe_at_point", DEBUGGING(LEVELING));
@ -899,7 +931,9 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Position Not Reachable");
return NAN;
}
if (probe_relative) npos -= offset_xy; // Get the nozzle position
if (probe_relative) // Get the nozzle position, adjust for active hotend if not 0
npos -= DIFF_TERN(HAS_HOTEND_OFFSET, offset_xy, xy_pos_t(hotend_offset[active_extruder]));
// Move the probe to the starting XYZ
do_blocking_move_to(npos, feedRate_t(XY_PROBE_FEEDRATE_MM_S));
@ -938,6 +972,7 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
#endif
}
DEBUG_ECHOLNPGM("measured_z: ", measured_z);
return measured_z;
}

View file

@ -188,6 +188,8 @@ public:
#endif // !HAS_BED_PROBE
static void use_probing_tool(const bool=true) IF_DISABLED(DO_TOOLCHANGE_FOR_PROBING, {});
static void move_z_after_homing() {
#if ALL(DWIN_LCD_PROUI, INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING) || defined(Z_AFTER_HOMING)
do_z_clearance(Z_POST_CLEARANCE, true);