diff --git a/Marlin/src/feature/bedlevel/bdl/bdl.cpp b/Marlin/src/feature/bedlevel/bdl/bdl.cpp index 064a8ffbd211..14989a07d344 100644 --- a/Marlin/src/feature/bedlevel/bdl/bdl.cpp +++ b/Marlin/src/feature/bedlevel/bdl/bdl.cpp @@ -34,6 +34,7 @@ #include "../../../module/temperature.h" #include "../../../module/endstops.h" #include "../../babystep.h" +#include "../../../lcd/marlinui.h" // I2C software Master library for segment bed heating and bed distance sensor #include @@ -42,6 +43,8 @@ BDS_Leveling bdl; //#define DEBUG_OUT_BD +#define DEBUG_OUT ENABLED(DEBUG_OUT_BD) +#include "../../../core/debug_out.h" // M102 S-5 Read raw Calibrate data // M102 S-6 Start Calibrate @@ -49,144 +52,196 @@ BDS_Leveling bdl; // M102 S-1 Read sensor information #define MAX_BD_HEIGHT 4.0f +#define CMD_READ_VERSION 1016 #define CMD_START_READ_CALIBRATE_DATA 1017 #define CMD_END_READ_CALIBRATE_DATA 1018 #define CMD_START_CALIBRATE 1019 #define CMD_END_CALIBRATE 1021 -#define CMD_READ_VERSION 1016 - -I2C_SegmentBED BD_I2C_SENSOR; - #define BD_SENSOR_I2C_ADDR 0x3C +I2C_SegmentBED BD_I2C_SENSOR; +float BDS_Leveling::pos_zero_offset; int8_t BDS_Leveling::config_state; -uint8_t BDS_Leveling::homing; - -void BDS_Leveling::echo_name() { SERIAL_ECHOPGM("Bed Distance Leveling"); } void BDS_Leveling::init(uint8_t _sda, uint8_t _scl, uint16_t delay_s) { - int ret = BD_I2C_SENSOR.i2c_init(_sda, _scl, BD_SENSOR_I2C_ADDR, delay_s); - if (ret != 1) SERIAL_ECHOLNPGM("BD_I2C_SENSOR Init Fail return code:", ret); - config_state = 0; + config_state = BDS_IDLE; + const int ret = BD_I2C_SENSOR.i2c_init(_sda, _scl, BD_SENSOR_I2C_ADDR, delay_s); + if (ret != 1) SERIAL_ECHOLNPGM("BD Sensor Init Fail (", ret, ")"); + sync_plan_position(); + pos_zero_offset = planner.get_axis_position_mm(Z_AXIS) - current_position.z; + SERIAL_ECHOLNPGM("BD Sensor Zero Offset:", pos_zero_offset); +} + +bool BDS_Leveling::check(const uint16_t data, const bool raw_data/*=false*/, const bool hicheck/*=false*/) { + if (BD_I2C_SENSOR.BD_Check_OddEven(data) == 0) { + SERIAL_ECHOLNPGM("Read Error."); + return true; // error + } + if (raw_data == true) { + if (hicheck && (data & 0x3FF) > 550) + SERIAL_ECHOLNPGM("BD Sensor mounted too high!"); + else if (!good_data(data)) + SERIAL_ECHOLNPGM("Invalid data, please calibrate."); + else + return false; + } + else { + if ((data & 0x3FF) >= (MAX_BD_HEIGHT) * 100 - 10) + SERIAL_ECHOLNPGM("Out of Range."); + else + return false; + } + return true; // error +} + +float BDS_Leveling::interpret(const uint16_t data) { + return (data & 0x3FF) / 100.0f; } float BDS_Leveling::read() { - const uint16_t tmp = BD_I2C_SENSOR.BD_i2c_read(); - float BD_z = NAN; - if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) && (tmp & 0x3FF) < 1020) - BD_z = (tmp & 0x3FF) / 100.0f; - return BD_z; + const uint16_t data = BD_I2C_SENSOR.BD_i2c_read(); + return check(data) ? NAN : interpret(data); } void BDS_Leveling::process() { - //if (config_state == 0) return; - static millis_t next_check_ms = 0; // starting at T=0 - static float z_pose = 0.0f; - const millis_t ms = millis(); - if (ELAPSED(ms, next_check_ms)) { // timed out (or first run) - next_check_ms = ms + (config_state < 0 ? 1000 : 100); // check at 1Hz or 10Hz - - unsigned short tmp = 0; - const float cur_z = planner.get_axis_position_mm(Z_AXIS); //current_position.z - static float old_cur_z = cur_z, - old_buf_z = current_position.z; - + if (config_state == BDS_IDLE && printingIsActive()) return; + static millis_t next_check_ms = 0; // starting at T=0 + static float zpos = 0.0f; + const millis_t ms = millis(); + if (ELAPSED(ms, next_check_ms)) { // timed out (or first run) + next_check_ms = ms + (config_state < BDS_IDLE ? 200 : 50); // check at 5Hz or 20Hz + + uint16_t tmp = 0; + const float cur_z = planner.get_axis_position_mm(Z_AXIS) - pos_zero_offset; + static float old_cur_z = cur_z, old_buf_z = current_position.z; tmp = BD_I2C_SENSOR.BD_i2c_read(); - if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) && (tmp & 0x3FF) < 1020) { - const float z_sensor = (tmp & 0x3FF) / 100.0f; - if (cur_z < 0) config_state = 0; - //float abs_z = current_position.z > cur_z ? (current_position.z - cur_z) : (cur_z - current_position.z); + if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) && good_data(tmp)) { + const float z_sensor = interpret(tmp); #if ENABLED(BABYSTEPPING) - if (cur_z < config_state * 0.1f - && config_state > 0 - && old_cur_z == cur_z - && old_buf_z == current_position.z - && z_sensor < (MAX_BD_HEIGHT) - ) { - babystep.set_mm(Z_AXIS, cur_z - z_sensor); - #if ENABLED(DEBUG_OUT_BD) - SERIAL_ECHOLNPGM("BD:", z_sensor, ", Z:", cur_z, "|", current_position.z); - #endif - } - else { - babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(HIGH); - stepper.apply_directions(); + if (config_state > 0) { + if (cur_z < config_state * 0.1f + && old_cur_z == cur_z + && old_buf_z == current_position.z + && z_sensor < (MAX_BD_HEIGHT) - 0.1f + ) { + babystep.set_mm(Z_AXIS, cur_z - z_sensor); + DEBUG_ECHOLNPGM("BD:", z_sensor, ", Z:", cur_z, "|", current_position.z); + } + else { + babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(HIGH); + //stepper.apply_directions(); // TODO: Remove this line as probably not needed + } } #endif + old_cur_z = cur_z; old_buf_z = current_position.z; endstops.bdp_state_update(z_sensor <= 0.01f); - //endstops.update(); + + #if HAS_STATUS_MESSAGE + static float old_z_sensor = 0; + if (old_z_sensor != z_sensor) { + old_z_sensor = z_sensor; + char tmp_1[32]; + sprintf_P(tmp_1, PSTR("BD:%d.%02dmm"), int(z_sensor), int(z_sensor * 100) % 100); + //SERIAL_ECHOLNPGM("Bed Dis:", z_sensor, "mm"); + ui.set_status(tmp_1, true); + } + #endif } else stepper.apply_directions(); - #if ENABLED(DEBUG_OUT_BD) - SERIAL_ECHOLNPGM("BD:", tmp & 0x3FF, ", Z:", cur_z, "|", current_position.z); - if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) == 0) SERIAL_ECHOLNPGM("errorCRC"); - #endif + DEBUG_ECHOLNPGM("BD:", tmp & 0x3FF, " Z:", cur_z, "|", current_position.z); + if (TERN0(DEBUG_OUT_BD, BD_I2C_SENSOR.BD_Check_OddEven(tmp) == 0)) DEBUG_ECHOLNPGM("CRC error"); - if ((tmp & 0x3FF) > 1020) { + if (!good_data(tmp)) { BD_I2C_SENSOR.BD_i2c_stop(); safe_delay(10); } + // Read version. Usually used as a connection check + if (config_state == BDS_VERSION) { + config_state = BDS_IDLE; + BD_I2C_SENSOR.BD_i2c_write(CMD_READ_VERSION); + safe_delay(100); + char tmp_1[21]; + for (int i = 0; i < 19; i++) { + tmp_1[i] = BD_I2C_SENSOR.BD_i2c_read() & 0xFF; + safe_delay(50); + } + BD_I2C_SENSOR.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA); + SERIAL_ECHOLNPGM("BD Sensor version:", tmp_1); + if (tmp_1[0] != 'V') SERIAL_ECHOLNPGM("Read Error. Check connection and delay."); + safe_delay(50); + } // read raw calibrate data - if (config_state == -5) { + else if (config_state == BDS_READ_RAW) { BD_I2C_SENSOR.BD_i2c_write(CMD_START_READ_CALIBRATE_DATA); - safe_delay(1000); + safe_delay(100); for (int i = 0; i < MAX_BD_HEIGHT * 10; i++) { tmp = BD_I2C_SENSOR.BD_i2c_read(); - SERIAL_ECHOLNPGM("Calibrate data:", i, ",", tmp & 0x3FF, ", check:", BD_I2C_SENSOR.BD_Check_OddEven(tmp)); - safe_delay(500); + SERIAL_ECHOLNPGM("Calibrate data:", i, ",", tmp & 0x3FF); + (void)check(tmp, true, i == 0); + safe_delay(50); } - config_state = 0; BD_I2C_SENSOR.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA); - safe_delay(500); + safe_delay(50); + config_state = BDS_IDLE; } - else if (config_state <= -6) { // Start Calibrate - safe_delay(100); - if (config_state == -6) { - //BD_I2C_SENSOR.BD_i2c_write(1019); // begin calibrate - //delay(1000); - gcode.stepper_inactive_time = SEC_TO_MS(60 * 5); - gcode.process_subcommands_now(F("M17 Z")); - gcode.process_subcommands_now(F("G1 Z0.0")); - z_pose = 0; - safe_delay(1000); + else if (config_state <= BDS_CALIBRATE_START) { // Start Calibrate + safe_delay(10); + if (config_state == BDS_CALIBRATE_START) { + config_state = BDS_CALIBRATING; + REMEMBER(gsit, gcode.stepper_inactive_time, SEC_TO_MS(60 * 5)); + SERIAL_ECHOLNPGM("c_z0:", planner.get_axis_position_mm(Z_AXIS), "-", pos_zero_offset); + + // Move the z axis instead of enabling the Z axis with M17 + // TODO: Use do_blocking_move_to_z for synchronized move. + current_position.z = 0; + sync_plan_position(); + gcode.process_subcommands_now(F("G1Z0.05")); + safe_delay(300); + gcode.process_subcommands_now(F("G1Z0.00")); + safe_delay(300); + current_position.z = 0; + sync_plan_position(); + //safe_delay(1000); + + while ((planner.get_axis_position_mm(Z_AXIS) - pos_zero_offset) > 0.00001f) { + safe_delay(200); + SERIAL_ECHOLNPGM("waiting cur_z:", planner.get_axis_position_mm(Z_AXIS)); + } + zpos = 0.00001f; + safe_delay(100); BD_I2C_SENSOR.BD_i2c_write(CMD_START_CALIBRATE); // Begin calibrate - SERIAL_ECHOLNPGM("Begin calibrate"); - safe_delay(2000); - config_state = -7; + SERIAL_ECHOLNPGM("BD Sensor Calibrating..."); + safe_delay(200); } - else if (planner.get_axis_position_mm(Z_AXIS) < 10.0f) { - if (z_pose >= MAX_BD_HEIGHT) { + else if ((planner.get_axis_position_mm(Z_AXIS) - pos_zero_offset) < 10.0f) { + if (zpos >= MAX_BD_HEIGHT) { + config_state = BDS_IDLE; BD_I2C_SENSOR.BD_i2c_write(CMD_END_CALIBRATE); // End calibrate - SERIAL_ECHOLNPGM("End calibrate data"); - z_pose = 7; - config_state = 0; - safe_delay(1000); + SERIAL_ECHOLNPGM("BD Sensor calibrated."); + zpos = 7.0f; + safe_delay(500); } else { - float tmp_k = 0; - char tmp_1[30]; - sprintf_P(tmp_1, PSTR("G1 Z%d.%d"), int(z_pose), int(int(z_pose * 10) % 10)); + char tmp_1[32]; + // TODO: Use prepare_internal_move_to_destination to guarantee machine space + sprintf_P(tmp_1, PSTR("G1Z%d.%d"), int(zpos), int(zpos * 10) % 10); gcode.process_subcommands_now(tmp_1); - - SERIAL_ECHO(tmp_1); - SERIAL_ECHOLNPGM(" ,Z:", current_position.z); - - while (tmp_k < (z_pose - 0.1f)) { - tmp_k = planner.get_axis_position_mm(Z_AXIS); - safe_delay(1); + SERIAL_ECHO(tmp_1); SERIAL_ECHOLNPGM(", Z:", current_position.z); + for (float tmp_k = 0; abs(zpos - tmp_k) > 0.004f;) { + tmp_k = planner.get_axis_position_mm(Z_AXIS) - pos_zero_offset; + safe_delay(10); } - safe_delay(800); - tmp = (z_pose + 0.0001f) * 10; + safe_delay(zpos <= 0.4f ? 600 : 100); + tmp = uint16_t((zpos + 0.00001f) * 10); BD_I2C_SENSOR.BD_i2c_write(tmp); - SERIAL_ECHOLNPGM("w:", tmp, ",Zpose:", z_pose); - z_pose += 0.1001f; - //queue.enqueue_now_P(PSTR("G90")); + SERIAL_ECHOLNPGM("w:", tmp, ", Z:", zpos); + zpos += 0.1001f; } } } diff --git a/Marlin/src/feature/bedlevel/bdl/bdl.h b/Marlin/src/feature/bedlevel/bdl/bdl.h index 6307b1ab28f8..b3037bc1c277 100644 --- a/Marlin/src/feature/bedlevel/bdl/bdl.h +++ b/Marlin/src/feature/bedlevel/bdl/bdl.h @@ -23,14 +23,26 @@ #include +enum BDS_State : int8_t { + BDS_IDLE, + BDS_VERSION = -1, + BDS_READ_MM = -2, + BDS_HOMING_Z = -3, + BDS_READ_RAW = -5, + BDS_CALIBRATE_START = -6, + BDS_CALIBRATING = -7 +}; + class BDS_Leveling { public: static int8_t config_state; - static uint8_t homing; - static void echo_name(); + static float pos_zero_offset; static void init(uint8_t _sda, uint8_t _scl, uint16_t delay_s); static void process(); static float read(); + static float interpret(const uint16_t data); + static float good_data(const uint16_t data) { return (data & 0x3FF) < 1016; } + static bool check(const uint16_t data, const bool raw_data=false, const bool hicheck=false); }; extern BDS_Leveling bdl; diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index c2fa520a3c6d..b3758c3c9465 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -43,6 +43,9 @@ #if ABL_PLANAR #include "../../../libs/vector_3.h" #endif +#if ENABLED(BD_SENSOR_PROBE_NO_STOP) + #include "../../../feature/bedlevel/bdl/bdl.h" +#endif #include "../../../lcd/marlinui.h" #if ENABLED(EXTENSIBLE_UI) @@ -705,7 +708,66 @@ G29_TYPE GcodeSuite::G29() { if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", bedlevel_settings.bedlevel_points.x * bedlevel_settings.bedlevel_points.y, "."); TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(bedlevel_settings.bedlevel_points.x * bedlevel_settings.bedlevel_points.y))); - abl.measured_z = faux ? 0.001f * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level); + #if ENABLED(BD_SENSOR_PROBE_NO_STOP) + if (PR_INNER_VAR == inStart) { + char tmp_1[32]; + + // move to the start point of new line + abl.measured_z = faux ? 0.001f * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level); + // Go to the end of the row/column ... and back up by one + // TODO: Why not just use... PR_INNER_VAR = inStop - inInc + for (PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; PR_INNER_VAR += inInc); + PR_INNER_VAR -= inInc; + + // Get the coordinate of the resulting grid point + abl.probePos = abl.probe_position_lf + abl.gridSpacing * abl.meshCount.asFloat(); + + // Coordinate that puts the probe at the grid point + abl.probePos -= probe.offset_xy; + + // Put a G1 move into the buffer + // TODO: Instead of G1, we can just add the move directly to the planner... + // { + // destination = current_position; destination = abl.probePos; + // REMEMBER(fr, feedrate_mm_s, XY_PROBE_FEEDRATE_MM_S); + // prepare_line_to_destination(); + // } + sprintf_P(tmp_1, PSTR("G1X%d.%d Y%d.%d F%d"), + int(abl.probePos.x), int(abl.probePos.x * 10) % 10, + int(abl.probePos.y), int(abl.probePos.y * 10) % 10, + XY_PROBE_FEEDRATE + ); + gcode.process_subcommands_now(tmp_1); + + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("destX: ", abl.probePos.x, " Y:", abl.probePos.y); + + // Reset the inner counter back to the start + PR_INNER_VAR = inStart; + + // Get the coordinate of the start of the row/column + abl.probePos = abl.probe_position_lf + abl.gridSpacing * abl.meshCount.asFloat(); + } + + // Wait around until the real axis position reaches the comparison point + // TODO: Use NEAR() because float is imprecise + constexpr AxisEnum axis = TERN(PROBE_Y_FIRST, Y_AXIS, X_AXIS); + const float cmp = abl.probePos[axis] - probe.offset_xy[axis]; + float pos; + for (;;) { + pos = planner.get_axis_position_mm(axis); + if (inInc > 0 ? (pos >= cmp) : (pos <= cmp)) break; + idle_no_sleep(); + } + //if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM_P(axis == Y_AXIS ? PSTR("Y=") : PSTR("X=", pos); + + abl.measured_z = current_position.z - bdl.read(); + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("x_cur ", planner.get_axis_position_mm(X_AXIS), " z ", abl.measured_z); + + #else // !BD_SENSOR_PROBE_NO_STOP + + abl.measured_z = faux ? 0.001f * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level); + + #endif if (isnan(abl.measured_z)) { set_bed_leveling_enabled(abl.reenable); diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index cb4f80618de5..6fb062c17003 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -36,10 +36,6 @@ #include "../../feature/bedlevel/bedlevel.h" #endif -#if ENABLED(BD_SENSOR) - #include "../../feature/bedlevel/bdl/bdl.h" -#endif - #if ENABLED(SENSORLESS_HOMING) #include "../../feature/tmc_util.h" #endif @@ -229,8 +225,6 @@ void GcodeSuite::G28() { return; } - TERN_(BD_SENSOR, bdl.config_state = 0); - #if ENABLED(FULL_REPORT_TO_HOST_FEATURE) const M_StateEnum old_grblstate = M_State_grbl; set_and_report_grblstate(M_HOMING); diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index 7657aadc6d85..5ea89b713638 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -139,17 +139,15 @@ inline void servo_probe_test() { bool deploy_state = false, stow_state; #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - constexpr bool probe_hit_state = Z_MIN_ENDSTOP_HIT_STATE; #define PROBE_TEST_PIN Z_MIN_PIN #define _PROBE_PREF "Z_MIN" #else - constexpr bool probe_hit_state = Z_MIN_PROBE_ENDSTOP_HIT_STATE; #define PROBE_TEST_PIN Z_MIN_PROBE_PIN #define _PROBE_PREF "Z_MIN_PROBE" #endif SERIAL_ECHOLNPGM(". Probe " _PROBE_PREF "_PIN: ", PROBE_TEST_PIN); - serial_ternary(F(". " _PROBE_PREF "_ENDSTOP_HIT_STATE: "), probe_hit_state, F("HIGH"), F("LOW")); + serial_ternary(F(". " _PROBE_PREF "_ENDSTOP_HIT_STATE: "), PROBE_HIT_STATE, F("HIGH"), F("LOW")); SERIAL_EOL(); SET_INPUT_PULLUP(PROBE_TEST_PIN); @@ -166,11 +164,11 @@ inline void servo_probe_test() { SERIAL_ECHOLNPGM(". Check for BLTOUCH"); bltouch._reset(); bltouch._stow(); - if (READ(PROBE_TEST_PIN) != probe_hit_state) { + if (!PROBE_TRIGGERED()) { bltouch._set_SW_mode(); - if (READ(PROBE_TEST_PIN) == probe_hit_state) { + if (PROBE_TRIGGERED()) { bltouch._deploy(); - if (READ(PROBE_TEST_PIN) != probe_hit_state) { + if (!PROBE_TRIGGERED()) { bltouch._stow(); SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected."); // Check for a 3.1 by letting the user trigger it, later @@ -198,7 +196,7 @@ inline void servo_probe_test() { stow_state = READ(PROBE_TEST_PIN); } - if (probe_hit_state == deploy_state) SERIAL_ECHOLNPGM("WARNING: " _PROBE_PREF "_ENDSTOP_HIT_STATE is probably wrong."); + if (PROBE_HIT_STATE == deploy_state) SERIAL_ECHOLNPGM("WARNING: " _PROBE_PREF "_ENDSTOP_HIT_STATE is probably wrong."); if (deploy_state != stow_state) { SERIAL_ECHOLNPGM("= Mechanical Switch detected"); diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 49055d392f5a..cf4a82339562 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -725,7 +725,6 @@ class GcodeSuite { #if ENABLED(BD_SENSOR) static void M102(); - static void M102_report(const bool forReplay=true); #endif #if HAS_HOTEND diff --git a/Marlin/src/gcode/probe/M102.cpp b/Marlin/src/gcode/probe/M102.cpp index b70c9aed1836..f24a723ed791 100644 --- a/Marlin/src/gcode/probe/M102.cpp +++ b/Marlin/src/gcode/probe/M102.cpp @@ -30,6 +30,7 @@ #include "../gcode.h" #include "../../feature/bedlevel/bdl/bdl.h" +#include "../../MarlinCore.h" // for printingIsActive /** * M102: Configure the Bed Distance Sensor @@ -38,20 +39,25 @@ * M102 S0 : Disable adjustable Z height. * * Negative S values are commands: - * M102 S-1 : Read sensor information + * M102 S-1 : Read BDsensor version + * M102 S-2 : Read BDsensor distance value * M102 S-5 : Read raw Calibration data * M102 S-6 : Start Calibration */ void GcodeSuite::M102() { - if (parser.seenval('S')) - bdl.config_state = parser.value_int(); - else - M102_report(); -} - -void GcodeSuite::M102_report(const bool forReplay/*=true*/) { - report_heading(forReplay, F("Bed Distance Sensor")); - SERIAL_ECHOLNPGM(" M102 S", bdl.config_state); + if (bdl.config_state < BDS_IDLE) { + SERIAL_ECHOLNPGM("BDsensor is busy:", bdl.config_state); + return; + } + if (parser.seenval('S')) { + const int8_t command = parser.value_int(); + if (command == BDS_READ_MM) + SERIAL_ECHOLNPGM("Bed Distance:", bdl.read(), "mm"); + else if ((command < BDS_IDLE) && printingIsActive()) + return; + else + bdl.config_state = command; + } } #endif // BD_SENSOR diff --git a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp index 0327a2f137c8..87a6544e5ef5 100644 --- a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp +++ b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp @@ -451,7 +451,7 @@ void NextionTFT::panelInfo(uint8_t req) { SEND_VALasTXT("z2", READ(Z2_MAX_PIN) == Z2_MAX_ENDSTOP_HIT_STATE ? "triggered" : "open"); #endif #if HAS_BED_PROBE - //SEND_VALasTXT("bltouch", READ(Z_MIN_PROBE_PIN) == Z_MIN_PROBE_ENDSTOP_HIT_STATE ? "triggered" : "open"); + //SEND_VALasTXT("bltouch", PROBE_TRIGGERED() ? "triggered" : "open"); #else SEND_NA("bltouch"); #endif diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 9442f3b50382..98820b9e678d 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -67,7 +67,11 @@ Endstops::endstop_mask_t Endstops::live_state = 0; #if ENABLED(BD_SENSOR) bool Endstops::bdp_state; // = false - #define READ_ENDSTOP(P) ((P == Z_MIN_PIN) ? bdp_state : READ(P)) + #if HOMING_Z_WITH_PROBE + #define READ_ENDSTOP(P) ((P == TERN(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_MIN_PIN, Z_MIN_PROBE_PIN)) ? bdp_state : READ(P)) + #else + #define READ_ENDSTOP(P) READ(P) + #endif #else #define READ_ENDSTOP(P) READ(P) #endif diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index be7432821d36..d86ae27a1ccf 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -73,6 +73,11 @@ #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../core/debug_out.h" + +#if ENABLED(BD_SENSOR) + #include "../feature/bedlevel/bdl/bdl.h" +#endif + // Relative Mode. Enable with G91, disable with G90. bool relative_mode; // = false; @@ -2129,6 +2134,7 @@ void prepare_line_to_destination() { if (axis == Z_AXIS) { if (TERN0(BLTOUCH, bltouch.deploy())) return; // BLTouch was deployed above, but get the alarm state. if (TERN0(PROBE_TARE, probe.tare())) return; + TERN_(BD_SENSOR, bdl.config_state = BDS_HOMING_Z); } #endif @@ -2379,6 +2385,10 @@ void prepare_line_to_destination() { #endif + #if ALL(BD_SENSOR, HOMING_Z_WITH_PROBE) + if (axis == Z_AXIS) bdl.config_state = BDS_IDLE; + #endif + // Put away the Z probe if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.stow())) return; diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h index 9c191c5df4c8..8f5990b76cb8 100644 --- a/Marlin/src/module/probe.h +++ b/Marlin/src/module/probe.h @@ -42,12 +42,19 @@ PROBE_PT_RAISE // Raise to "between" clearance after run_z_probe }; +#if ENABLED(BD_SENSOR) + #define PROBE_READ() bdp_state +#elif USE_Z_MIN_PROBE + #define PROBE_READ() (READ(Z_MIN_PROBE_PIN) != endstop_settings.Z_MIN_PROBE_INVERTING) +#else + #define PROBE_READ() READ(Z_MIN_PIN) +#endif #if USE_Z_MIN_PROBE -// #define PROBE_TRIGGERED() (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING) - #define PROBE_TRIGGERED() (READ(Z_MIN_PROBE_PIN) != endstop_settings.Z_MIN_PROBE_INVERTING) + #define PROBE_HIT_STATE Z_MIN_PROBE_ENDSTOP_HIT_STATE #else - #define PROBE_TRIGGERED() (READ(Z_MIN_PIN) == Z_MIN_ENDSTOP_HIT_STATE) + #define PROBE_HIT_STATE Z_MIN_ENDSTOP_HIT_STATE #endif +#define PROBE_TRIGGERED() (PROBE_READ() == PROBE_HIT_STATE) // In BLTOUCH HS mode, the probe travels in a deployed state. #define Z_TWEEN_SAFE_CLEARANCE SUM_TERN(BLTOUCH, Z_CLEARANCE_BETWEEN_PROBES, bltouch.z_extra_clearance()) diff --git a/Marlin/src/module/stepper/indirection.h b/Marlin/src/module/stepper/indirection.h index 425c2dc1b357..6fde2571a5b6 100644 --- a/Marlin/src/module/stepper/indirection.h +++ b/Marlin/src/module/stepper/indirection.h @@ -1000,7 +1000,7 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset #if HAS_Z_AXIS #define ENABLE_AXIS_Z() if (SHOULD_ENABLE(z)) { ENABLE_STEPPER_Z(); ENABLE_STEPPER_Z2(); ENABLE_STEPPER_Z3(); ENABLE_STEPPER_Z4(); AFTER_CHANGE(z, true); } - #define DISABLE_AXIS_Z() if (SHOULD_DISABLE(z)) { DISABLE_STEPPER_Z(); DISABLE_STEPPER_Z2(); DISABLE_STEPPER_Z3(); DISABLE_STEPPER_Z4(); AFTER_CHANGE(z, false); set_axis_untrusted(Z_AXIS); Z_RESET(); TERN_(BD_SENSOR, bdl.config_state = 0); } + #define DISABLE_AXIS_Z() if (SHOULD_DISABLE(z)) { DISABLE_STEPPER_Z(); DISABLE_STEPPER_Z2(); DISABLE_STEPPER_Z3(); DISABLE_STEPPER_Z4(); AFTER_CHANGE(z, false); set_axis_untrusted(Z_AXIS); Z_RESET(); TERN_(BD_SENSOR, bdl.config_state = BDS_IDLE); } #else #define ENABLE_AXIS_Z() NOOP #define DISABLE_AXIS_Z() NOOP