diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 0c166d5dd..5fe746a77 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -1006,6 +1006,33 @@ // Feedrate (mm/min) for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) +/** + * Probe Activation Switch + * A switch indicating proper deployment, or an optical + * switch triggered when the carriage is near the bed. + */ +//#define PROBE_ACTIVATION_SWITCH +#if ENABLED(PROBE_ACTIVATION_SWITCH) + #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active + //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin +#endif + +/** + * Tare Probe (determine zero-point) prior to each probe. + * Useful for a strain gauge or piezo sensor that needs to factor out + * elements such as cables pulling on the carriage. + */ +//#define PROBE_TARE +#if ENABLED(PROBE_TARE) + #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin + #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before + #define PROBE_TARE_STATE HIGH // State to write pin for tare + //#define PROBE_TARE_PIN PA5 // Override default pin + #if ENABLED(PROBE_ACTIVATION_SWITCH) + //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active + #endif +#endif + /** * Multiple Probing * diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index f1e477933..98d155e1d 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -154,6 +154,7 @@ #define STR_Z4_MIN "z4_min" #define STR_Z4_MAX "z4_max" #define STR_Z_PROBE "z_probe" +#define STR_PROBE_EN "probe_en" #define STR_FILAMENT_RUNOUT_SENSOR "filament" #define STR_PROBE_OFFSET "Probe Offset" #define STR_SKEW_MIN "min_skew_factor: " diff --git a/Marlin/src/gcode/probe/M401_M402.cpp b/Marlin/src/gcode/probe/M401_M402.cpp index 8e9bd11b8..bd9bb44c4 100644 --- a/Marlin/src/gcode/probe/M401_M402.cpp +++ b/Marlin/src/gcode/probe/M401_M402.cpp @@ -33,6 +33,7 @@ */ void GcodeSuite::M401() { probe.deploy(); + TERN_(PROBE_TARE, probe.tare()); report_current_position(); } diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 904ef0d38..0ff80dc96 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1409,6 +1409,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "Z_SAFE_HOMING is recommended when homing with a probe. Enable it or comment out this line to continue." #endif + #if ENABLED(PROBE_ACTIVATION_SWITCH) + #ifndef PROBE_ACTIVATION_SWITCH_STATE + #error "PROBE_ACTIVATION_SWITCH_STATE is required for PROBE_ACTIVATION_SWITCH." + #elif !PIN_EXISTS(PROBE_ACTIVATION_SWITCH) + #error "A PROBE_ACTIVATION_SWITCH_PIN is required for PROBE_ACTIVATION_SWITCH." + #endif + #endif + #else /** diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index ef0b92a7e..1467e1b70 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -280,6 +280,12 @@ void Endstops::init() { #endif #endif + #if ENABLED(PROBE_ACTIVATION_SWITCH) + SET_INPUT(PROBE_ACTIVATION_SWITCH_PIN); + #endif + + TERN_(PROBE_TARE, probe.tare()); + TERN_(ENDSTOP_INTERRUPTS_FEATURE, setup_endstop_interrupts()); // Enable endstops @@ -458,6 +464,9 @@ void _O2 Endstops::report_states() { #if HAS_Z4_MAX ES_REPORT(Z4_MAX); #endif + #if BOTH(MARLIN_DEV_MODE, PROBE_ACTIVATION_SWITCH) + print_es_state(READ(PROBE_ACTIVATION_SWITCH_PIN) == PROBE_ACTIVATION_SWITCH_STATE, PSTR(STR_PROBE_EN)); + #endif #if HAS_CUSTOM_PROBE_PIN print_es_state(PROBE_TRIGGERED(), PSTR(STR_Z_PROBE)); #endif @@ -582,7 +591,7 @@ void Endstops::update() { #endif #endif - #if HAS_Z_MIN && !Z_SPI_SENSORLESS + #if HAS_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) UPDATE_ENDSTOP_BIT(Z, MIN); #if ENABLED(Z_MULTI_ENDSTOPS) #if HAS_Z2_MIN @@ -607,9 +616,13 @@ void Endstops::update() { #endif #endif - // When closing the gap check the enabled probe - #if HAS_CUSTOM_PROBE_PIN - UPDATE_ENDSTOP_BIT(Z, MIN_PROBE); + #if HAS_BED_PROBE + // When closing the gap check the enabled probe + if (true + #if ENABLED(PROBE_ACTIVATION_SWITCH) + || READ(PROBE_ACTIVATION_SWITCH_PIN) == PROBE_ACTIVATION_SWITCH_STATE + #endif + ) UPDATE_ENDSTOP_BIT(Z, TERN(HAS_CUSTOM_PROBE_PIN, MIN_PROBE, MIN)); #endif #if HAS_Z_MAX && !Z_SPI_SENSORLESS diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 45ec51314..3800bc6b0 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -1589,8 +1589,11 @@ void homeaxis(const AxisEnum axis) { // Fast move towards endstop until triggered if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 1 Fast:"); - #if BOTH(HOMING_Z_WITH_PROBE, BLTOUCH) - if (axis == Z_AXIS && bltouch.deploy()) return; // The initial DEPLOY + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS) { + if (TERN0(BLTOUCH, bltouch.deploy())) return; + if (TERN0(PROBE_TARE, probe.tare())) return; + } #endif #if DISABLED(DELTA) && defined(SENSORLESS_BACKOFF_MM) diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 63b1928c7..261fde491 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -512,6 +512,33 @@ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) { return !probe_triggered; } +#if ENABLED(PROBE_TARE) + /** + * @brief Tare the Z probe + * + * @details Signal to the probe to tare itself + * + * @return TRUE if the tare cold not be completed + */ + bool Probe::tare() { + #if BOTH(PROBE_ACTIVATION_SWITCH, PROBE_TARE_ONLY_WHILE_INACTIVE) + if (READ(PROBE_ACTIVATION_SWITCH_PIN) == PROBE_ACTIVATION_SWITCH_STATE) { + SERIAL_ECHOLNPGM("Cannot tare an active probe"); + return true; + } + #endif + + SERIAL_ECHOLNPGM("Taring probe"); + OUT_WRITE(PROBE_TARE_PIN, PROBE_TARE_STATE); + delay(PROBE_TARE_TIME); + OUT_WRITE(PROBE_TARE_PIN, !PROBE_TARE_STATE); + delay(PROBE_TARE_DELAY); + + endstops.hit_on_purpose(); + return false; + } +#endif + /** * @brief Probe at the current XY (possibly more than once) to find the bed Z. * @@ -523,8 +550,11 @@ bool Probe::probe_down_to_z(const float 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)); - auto try_to_probe = [&](PGM_P const plbl, const float &z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck, const float clearance) { + auto try_to_probe = [&](PGM_P const plbl, const float &z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck, const float clearance) -> bool { // Do a first probe at the fast speed + + if (TERN0(PROBE_TARE, tare())) return true; + 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? #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -549,6 +579,8 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { #if TOTAL_PROBING == 2 // Do a first probe at the fast speed + if (TERN0(PROBE_TARE, tare())) return NAN; + if (try_to_probe(PSTR("FAST"), z_probe_low_point, z_probe_fast_mm_s, sanity_check, Z_CLEARANCE_BETWEEN_PROBES) ) return NAN; @@ -586,6 +618,9 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) { ) #endif { + // If the probe won't tare, return + if (TERN0(PROBE_TARE, tare())) return true; + // Probe downward slowly to find the bed if (try_to_probe(PSTR("SLOW"), z_probe_low_point, MMM_TO_MMS(Z_PROBE_SPEED_SLOW), sanity_check, Z_CLEARANCE_MULTI_PROBE) ) return NAN; diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h index 3ee699b4d..49520eb33 100644 --- a/Marlin/src/module/probe.h +++ b/Marlin/src/module/probe.h @@ -210,6 +210,10 @@ public: static void set_probing_paused(const bool p); #endif + #if ENABLED(PROBE_TARE) + static bool tare(); + #endif + private: static bool probe_down_to_z(const float z, const feedRate_t fr_mm_s); static void do_z_raise(const float z_raise); diff --git a/buildroot/tests/STM32F103RET6_creality-tests b/buildroot/tests/STM32F103RET6_creality-tests index 4e6c4f988..cc3275741 100755 --- a/buildroot/tests/STM32F103RET6_creality-tests +++ b/buildroot/tests/STM32F103RET6_creality-tests @@ -19,3 +19,12 @@ opt_add SDCARD_EEPROM_EMULATION exec_test $1 $2 "Ender 3 v2, SD EEPROM, w/o CLASSIC_JERK" "$3" restore_configs +opt_set SERIAL_PORT 1 +opt_set MOTHERBOARD BOARD_CREALITY_V452 +opt_disable NOZZLE_TO_PROBE_OFFSET +opt_enable NOZZLE_AS_PROBE Z_SAFE_HOMING Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN +opt_enable PROBE_ACTIVATION_SWITCH PROBE_ACTIVATION_SWITCH_PIN PROBE_TARE PROBE_TARE_ONLY_WHILE_INACTIVE +exec_test $1 $2 "Creality V4.5.2 PROBE_ACTIVATION_SWITCH, Probe Tare" "$3" + +# clean up +restore_configs