diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index b6d81f4ef..f8edb8730 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -61,6 +61,7 @@ * G30 - Single Z probe, probes bed at X Y location (defaults to current XY location) * G31 - Dock sled (Z_PROBE_SLED only) * G32 - Undock sled (Z_PROBE_SLED only) + * G33 - Delta '4-point' auto calibration iteration * G38 - Probe target - similar to G28 except it uses the Z_MIN_PROBE for all three axes * G90 - Use Absolute Coordinates * G91 - Use Relative Coordinates @@ -1443,7 +1444,7 @@ bool get_target_extruder_from_command(int code) { #endif // NO_WORKSPACE_OFFSETS -#if DISABLED(NO_WORKSPACE_OFFSETS) +#if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) /** * Change the home offset for an axis, update the current * position and the software endstops to retain the same @@ -1457,7 +1458,7 @@ bool get_target_extruder_from_command(int code) { home_offset[axis] = v; update_software_endstops(axis); } -#endif // NO_WORKSPACE_OFFSETS +#endif // !NO_WORKSPACE_OFFSETS && !DELTA /** * Set an axis' current position to its home position (after homing). @@ -2299,7 +2300,7 @@ static void clean_up_after_endstop_or_probe_move() { SERIAL_PROTOCOLPGM(" Y: "); SERIAL_PROTOCOL_F(y, 3); SERIAL_PROTOCOLPGM(" Z: "); - SERIAL_PROTOCOL_F(FIXFLOAT(measured_z), 3); + SERIAL_PROTOCOL_F(measured_z, 3); SERIAL_EOL; } @@ -4901,8 +4902,366 @@ inline void gcode_G28() { #endif // Z_PROBE_SLED + #if ENABLED(DELTA_AUTO_CALIBRATION) + /** + * G33: Delta '4-point' auto calibration iteration + * + * Usage: G33 + * + * C (default) = Calibrate endstops, height and delta radius + * + * -2, 1-4: n x n probe points, default 3 x 3 + * + * 1: probe center + * set height only - useful when z_offset is changed + * 2: probe center and towers + * solve one '4 point' calibration + * -2: probe center and opposite the towers + * solve one '4 point' calibration + * 3: probe 3 center points, towers and opposite-towers + * averages between 2 '4 point' calibrations + * 4: probe 4 center points, towers, opposite-towers and itermediate points + * averages between 4 '4 point' calibrations + * + * V Verbose level (0-3, default 1) + * + * 0: Dry-run mode: no calibration + * 1: Settings + * 2: Setting + probe results + * 3: Expert mode: setting + iteration factors (see Configuration_adv.h) + * This prematurely stops the iteration process when factors are found + */ + inline void gcode_G33() { + + stepper.synchronize(); + + #if PLANNER_LEVELING + set_bed_leveling_enabled(false); + #endif + + const int8_t pp = code_seen('C') ? code_value_int() : DELTA_CALIBRATION_DEFAULT_POINTS, + probe_points = (WITHIN(pp, 1, 4) || pp == -2) ? pp : DELTA_CALIBRATION_DEFAULT_POINTS; + + int8_t verbose_level = code_seen('V') ? code_value_byte() : 1; + + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + #define _MAX_M33_V 3 + if (verbose_level == 3 && probe_points == 1) verbose_level--; // needs at least 4 points + #else + #define _MAX_M33_V 2 + if (verbose_level > 2) + SERIAL_PROTOCOLLNPGM("Enable DELTA_CALIBRATE_EXPERT_MODE in Configuration_adv.h"); + #endif + + if (!WITHIN(verbose_level, 0, _MAX_M33_V)) verbose_level = 1; + + float zero_std_dev = verbose_level ? 999.0 : 0.0; // 0.0 in dry-run mode : forced end + + gcode_G28(); + + float e_old[XYZ], + dr_old = delta_radius, + zh_old = home_offset[Z_AXIS]; + COPY(e_old,endstop_adj); + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + // expert variables + float h_f_old = 1.00, r_f_old = 0.00, + h_diff_min = 1.00, r_diff_max = 0.10; + #endif + + // print settings + + SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate"); + SERIAL_PROTOCOLPGM("Checking... AC"); + if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)"); + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + if (verbose_level == 3) SERIAL_PROTOCOLPGM(" (EXPERT)"); + #endif + SERIAL_EOL; + LCD_MESSAGEPGM("Checking... AC"); + + SERIAL_PROTOCOLPAIR("Height:", DELTA_HEIGHT + home_offset[Z_AXIS]); + if (abs(probe_points) > 1) { + SERIAL_PROTOCOLPGM(" Ex:"); + if (endstop_adj[A_AXIS] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(endstop_adj[A_AXIS], 2); + SERIAL_PROTOCOLPGM(" Ey:"); + if (endstop_adj[B_AXIS] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(endstop_adj[B_AXIS], 2); + SERIAL_PROTOCOLPGM(" Ez:"); + if (endstop_adj[C_AXIS] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(endstop_adj[C_AXIS], 2); + SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); + } + SERIAL_EOL; + + #if ENABLED(Z_PROBE_SLED) + DEPLOY_PROBE(); + #endif + + float test_precision; + int8_t iterations = 0; + + do { // start iterations + + setup_for_endstop_or_probe_move(); + + test_precision = + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + // Expert mode : forced end at std_dev < 0.1 + (verbose_level == 3 && zero_std_dev < 0.1) ? 0.0 : + #endif + zero_std_dev + ; + + float z_at_pt[13] = { 0 }; + + iterations++; + + // probe the points + + int16_t center_points = 0; + + if (probe_points != 3) { + z_at_pt[0] += probe_pt(0.0, 0.0 , true, 1); + center_points = 1; + } + + int16_t step_axis = 4; + if (probe_points >= 3) { + for (int8_t axis = 9; axis > 0; axis -= step_axis) { // uint8_t starts endless loop + z_at_pt[0] += probe_pt( + 0.1 * cos(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS), + 0.1 * sin(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS), true, 1); + } + center_points += 3; + z_at_pt[0] /= center_points; + } + + float S1 = z_at_pt[0], S2 = sq(S1); + + int16_t N = 1, start = (probe_points == -2) ? 3 : 1; + step_axis = (abs(probe_points) == 2) ? 4 : (probe_points == 3) ? 2 : 1; + + if (probe_points != 1) { + for (uint8_t axis = start; axis < 13; axis += step_axis) + z_at_pt[axis] += probe_pt( + cos(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS), + sin(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS), true, 1 + ); + + if (probe_points == 4) step_axis = 2; + } + + for (uint8_t axis = start; axis < 13; axis += step_axis) { + if (probe_points == 4) + z_at_pt[axis] = (z_at_pt[axis] + (z_at_pt[axis + 1] + z_at_pt[(axis + 10) % 12 + 1]) / 2.0) / 2.0; + + S1 += z_at_pt[axis]; + S2 += sq(z_at_pt[axis]); + N++; + } + zero_std_dev = round(sqrt(S2 / N) * 1000.0) / 1000.0 + 0.00001; // deviation from zero plane + + // Solve matrices + + if (zero_std_dev < test_precision) { + COPY(e_old, endstop_adj); + dr_old = delta_radius; + zh_old = home_offset[Z_AXIS]; + + float e_delta[XYZ] = { 0.0 }, r_delta = 0.0; + + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + float h_f_new = 0.0, r_f_new = 0.0 , t_f_new = 0.0, + h_diff = 0.00, r_diff = 0.00; + #endif + + #define ZP(N,I) ((N) * z_at_pt[I]) + #define Z1000(I) ZP(1.00, I) + #define Z1050(I) ZP(H_FACTOR, I) + #define Z0700(I) ZP((H_FACTOR) * 2.0 / 3.00, I) + #define Z0350(I) ZP((H_FACTOR) / 3.00, I) + #define Z0175(I) ZP((H_FACTOR) / 6.00, I) + #define Z2250(I) ZP(R_FACTOR, I) + #define Z0750(I) ZP((R_FACTOR) / 3.00, I) + #define Z0375(I) ZP((R_FACTOR) / 6.00, I) + + switch (probe_points) { + case 1: + LOOP_XYZ(i) e_delta[i] = Z1000(0); + r_delta = 0.00; + break; + + case 2: + e_delta[X_AXIS] = Z1050(0) + Z0700(1) - Z0350(5) - Z0350(9); + e_delta[Y_AXIS] = Z1050(0) - Z0350(1) + Z0700(5) - Z0350(9); + e_delta[Z_AXIS] = Z1050(0) - Z0350(1) - Z0350(5) + Z0700(9); + r_delta = Z2250(0) - Z0750(1) - Z0750(5) - Z0750(9); + break; + + case -2: + e_delta[X_AXIS] = Z1050(0) - Z0700(7) + Z0350(11) + Z0350(3); + e_delta[Y_AXIS] = Z1050(0) + Z0350(7) - Z0700(11) + Z0350(3); + e_delta[Z_AXIS] = Z1050(0) + Z0350(7) + Z0350(11) - Z0700(3); + r_delta = Z2250(0) - Z0750(7) - Z0750(11) - Z0750(3); + break; + + default: + e_delta[X_AXIS] = Z1050(0) + Z0350(1) - Z0175(5) - Z0175(9) - Z0350(7) + Z0175(11) + Z0175(3); + e_delta[Y_AXIS] = Z1050(0) - Z0175(1) + Z0350(5) - Z0175(9) + Z0175(7) - Z0350(11) + Z0175(3); + e_delta[Z_AXIS] = Z1050(0) - Z0175(1) - Z0175(5) + Z0350(9) + Z0175(7) + Z0175(11) - Z0350(3); + r_delta = Z2250(0) - Z0375(1) - Z0375(5) - Z0375(9) - Z0375(7) - Z0375(11) - Z0375(3); + break; + } + + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + // Calculate h & r factors + if (verbose_level == 3) { + LOOP_XYZ(axis) h_f_new += e_delta[axis] / 3; + r_f_new = r_delta; + h_diff = (1.0 / H_FACTOR) * (h_f_old - h_f_new) / h_f_old; + if (h_diff < h_diff_min && h_diff > 0.9) h_diff_min = h_diff; + if (r_f_old != 0) + r_diff = ( 0.0301 * sq(R_FACTOR) * R_FACTOR + + 0.311 * sq(R_FACTOR) + + 1.1493 * R_FACTOR + + 1.7952 + ) * (r_f_old - r_f_new) / r_f_old; + if (r_diff > r_diff_max && r_diff < 0.4444) r_diff_max = r_diff; + SERIAL_EOL; + + h_f_old = h_f_new; + r_f_old = r_f_new; + } + #endif // DELTA_CALIBRATE_EXPERT_MODE + + // Adjust delta_height and endstops by the max amount + LOOP_XYZ(axis) endstop_adj[axis] += e_delta[axis]; + delta_radius += r_delta; + + const float z_temp = MAX3(endstop_adj[0], endstop_adj[1], endstop_adj[2]); + home_offset[Z_AXIS] -= z_temp; + LOOP_XYZ(i) endstop_adj[i] -= z_temp; + + recalc_delta_settings(delta_radius, delta_diagonal_rod); + } + else { // !iterate + // step one back + COPY(endstop_adj, e_old); + delta_radius = dr_old; + home_offset[Z_AXIS] = zh_old; + + recalc_delta_settings(delta_radius, delta_diagonal_rod); + } + + // print report + + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + if (verbose_level == 3) { + const float r_factor = 22.902 * sq(r_diff_max) * r_diff_max + - 44.988 * sq(r_diff_max) + + 31.697 * r_diff_max + - 9.4439; + SERIAL_PROTOCOLPAIR("h_factor:", 1.0 / h_diff_min); + SERIAL_PROTOCOLPAIR(" r_factor:", r_factor); + SERIAL_EOL; + } + #endif + if (verbose_level == 2) { + SERIAL_PROTOCOLPGM(". c:"); + if (z_at_pt[0] > 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[0], 2); + if (probe_points > 1) { + SERIAL_PROTOCOLPGM(" x:"); + if (z_at_pt[1] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[1], 2); + SERIAL_PROTOCOLPGM(" y:"); + if (z_at_pt[5] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[5], 2); + SERIAL_PROTOCOLPGM(" z:"); + if (z_at_pt[9] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[9], 2); + } + if (probe_points > 0) SERIAL_EOL; + if (probe_points > 2 || probe_points == -2) { + if (probe_points > 2) SERIAL_PROTOCOLPGM(". "); + SERIAL_PROTOCOLPGM(" yz:"); + if (z_at_pt[7] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[7], 2); + SERIAL_PROTOCOLPGM(" zx:"); + if (z_at_pt[11] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[11], 2); + SERIAL_PROTOCOLPGM(" xy:"); + if (z_at_pt[3] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(z_at_pt[3], 2); + SERIAL_EOL; + } + } + if (test_precision != 0.0) { // !forced end + if (zero_std_dev >= test_precision) { + SERIAL_PROTOCOLPGM("Calibration OK"); + SERIAL_PROTOCOLLNPGM(" rolling back 1"); + LCD_MESSAGEPGM("Calibration OK"); + SERIAL_EOL; + } + else { // !end iterations + char mess[15] = "No convergence"; + if (iterations < 31) + sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations); + SERIAL_PROTOCOL(mess); + SERIAL_PROTOCOLPGM(" std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev, 3); + SERIAL_EOL; + lcd_setstatus(mess); + } + SERIAL_PROTOCOLPAIR("Height:", DELTA_HEIGHT + home_offset[Z_AXIS]); + if (abs(probe_points) > 1) { + SERIAL_PROTOCOLPGM(" Ex:"); + if (endstop_adj[A_AXIS] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(endstop_adj[A_AXIS], 2); + SERIAL_PROTOCOLPGM(" Ey:"); + if (endstop_adj[B_AXIS] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(endstop_adj[B_AXIS], 2); + SERIAL_PROTOCOLPGM(" Ez:"); + if (endstop_adj[C_AXIS] >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(endstop_adj[C_AXIS], 2); + SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); + } + SERIAL_EOL; + if (zero_std_dev >= test_precision) + SERIAL_PROTOCOLLNPGM("Save with M500"); + } + else { // forced end + #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE) + if (verbose_level == 3) + SERIAL_PROTOCOLLNPGM("Copy to Configuration_adv.h"); + else + #endif + { + SERIAL_PROTOCOLPGM("End DRY-RUN std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev, 3); + SERIAL_EOL; + } + } + + clean_up_after_endstop_or_probe_move(); + stepper.synchronize(); + + gcode_G28(); + + } while (zero_std_dev < test_precision && iterations < 31); + + #if ENABLED(Z_PROBE_SLED) + RETRACT_PROBE(); + #endif + } + + #endif // DELTA_AUTO_CALIBRATION + #endif // HAS_BED_PROBE + #if ENABLED(G38_PROBE_TARGET) static bool G38_run_probe() { @@ -5631,7 +5990,7 @@ inline void gcode_M42() { if (axis_unhomed_error(true, true, true)) return; - int8_t verbose_level = code_seen('V') ? code_value_byte() : 1; + const int8_t verbose_level = code_seen('V') ? code_value_byte() : 1; if (!WITHIN(verbose_level, 0, 4)) { SERIAL_PROTOCOLLNPGM("?Verbose Level not plausible (0-4)."); return; @@ -7023,7 +7382,7 @@ inline void gcode_M205() { if (code_seen('E')) planner.max_jerk[E_AXIS] = code_value_axis_units(E_AXIS); } -#if DISABLED(NO_WORKSPACE_OFFSETS) +#if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) /** * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y @@ -7048,6 +7407,7 @@ inline void gcode_M205() { /** * M665: Set delta configurations * + * H = diagonal rod // AC-version * L = diagonal rod * R = delta radius * S = segments per second @@ -7056,6 +7416,12 @@ inline void gcode_M205() { * C = Gamma (Tower 3) diagonal rod trim */ inline void gcode_M665() { + if (code_seen('H')) { + home_offset[Z_AXIS] = code_value_linear_units() - DELTA_HEIGHT; + current_position[Z_AXIS] += code_value_linear_units() - DELTA_HEIGHT - home_offset[Z_AXIS]; + home_offset[Z_AXIS] = code_value_linear_units() - DELTA_HEIGHT; + update_software_endstops(Z_AXIS); + } if (code_seen('L')) delta_diagonal_rod = code_value_linear_units(); if (code_seen('R')) delta_radius = code_value_linear_units(); if (code_seen('S')) delta_segments_per_second = code_value_float(); @@ -7914,7 +8280,7 @@ void quickstop_stepper() { #endif -#if DISABLED(NO_WORKSPACE_OFFSETS) +#if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) /** * M428: Set home_offset based on the distance between the @@ -9203,6 +9569,15 @@ void process_next_command() { break; #endif // Z_PROBE_SLED + + #if ENABLED(DELTA_AUTO_CALIBRATION) + + case 33: // G33: Delta Auto Calibrate + gcode_G33(); + break; + + #endif // DELTA_AUTO_CALIBRATION + #endif // HAS_BED_PROBE #if ENABLED(G38_PROBE_TARGET) @@ -9520,7 +9895,7 @@ void process_next_command() { gcode_M205(); break; - #if DISABLED(NO_WORKSPACE_OFFSETS) + #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) case 206: // M206: Set home offsets gcode_M206(); break; @@ -9688,7 +10063,7 @@ void process_next_command() { break; #endif - #if DISABLED(NO_WORKSPACE_OFFSETS) + #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) case 428: // M428: Apply current_position to home_offset gcode_M428(); break; @@ -11054,6 +11429,9 @@ void disable_all_steppers() { #if ENABLED(E3_IS_TMC2130) automatic_current_control(stepperE3); #endif + #if ENABLED(E4_IS_TMC2130) + automatic_current_control(stepperE4); + #endif } } diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h index 35d0b5f44..362681b33 100644 --- a/Marlin/SanityCheck.h +++ b/Marlin/SanityCheck.h @@ -395,7 +395,7 @@ * Delta Auto calibration */ #if ENABLED(DELTA_AUTO_CALIBRATION) && ENABLED(NO_WORKSPACE_OFFSETS) - #error "To use DELTA_AUTO_CALIBRATION you must disable NO_WORKSPACE_OFFSETS." + #error "DELTA_AUTO_CALIBRATION is incompatible with NO_WORKSPACE_OFFSETS." #endif /** diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 72cf680a0..b85d7e152 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -47,7 +47,7 @@ * 100 Version (char x4) * 104 EEPROM Checksum (uint16_t) * - * 106 E_STEPPERS (uint8_t) + * 106 E_STEPPERS (uint8_t) * 107 M92 XYZE planner.axis_steps_per_mm (float x4 ... x8) * 123 M203 XYZE planner.max_feedrate_mm_s (float x4 ... x8) * 139 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x8) @@ -300,9 +300,17 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(planner.min_segment_time); EEPROM_WRITE(planner.max_jerk); #if ENABLED(NO_WORKSPACE_OFFSETS) - float home_offset[XYZ] = { 0 }; + const float home_offset[XYZ] = { 0 }; + #endif + #if ENABLED(DELTA) + dummy = 0.0; + EEPROM_WRITE(dummy); + EEPROM_WRITE(dummy); + dummy = DELTA_HEIGHT + home_offset[Z_AXIS]; + EEPROM_WRITE(dummy); + #else + EEPROM_WRITE(home_offset); #endif - EEPROM_WRITE(home_offset); #if HOTENDS > 1 // Skip hotend 0 which must be 0 @@ -488,7 +496,7 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(dummy); } - // Save TCM2130 Configuration, and placeholder values + // Save TMC2130 Configuration, and placeholder values uint16_t val; #if ENABLED(HAVE_TMC2130) #if ENABLED(X_IS_TMC2130) @@ -551,6 +559,12 @@ void MarlinSettings::postprocess() { val = 0; #endif EEPROM_WRITE(val); + #if ENABLED(E4_IS_TMC2130) + val = stepperE4.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); #else val = 0; for (uint8_t q = 0; q < 11; ++q) EEPROM_WRITE(val); @@ -644,6 +658,12 @@ void MarlinSettings::postprocess() { #endif EEPROM_READ(home_offset); + #if ENABLED(DELTA) + home_offset[X_AXIS] = 0.0; + home_offset[Y_AXIS] = 0.0; + home_offset[Z_AXIS] -= DELTA_HEIGHT; + #endif + #if HOTENDS > 1 // Skip hotend 0 which must be 0 for (uint8_t e = 1; e < HOTENDS; e++) @@ -1019,6 +1039,9 @@ void MarlinSettings::reset() { delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; COPY(delta_diagonal_rod_trim, drt); COPY(delta_tower_angle_trim, dta); + #if ENABLED(DELTA) + home_offset[Z_AXIS] = 0; + #endif #elif ENABLED(Z_DUAL_ENDSTOPS) float z_endstop_adj = #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT @@ -1143,7 +1166,7 @@ void MarlinSettings::reset() { /** * M503 - Report current settings in RAM - * + * * Unless specifically disabled, M503 is available even without EEPROM */ void MarlinSettings::report(bool forReplay) { @@ -1231,7 +1254,7 @@ void MarlinSettings::reset() { SERIAL_ECHOPAIR(" E", planner.max_jerk[E_AXIS]); SERIAL_EOL; - #if DISABLED(NO_WORKSPACE_OFFSETS) + #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) CONFIG_ECHO_START; if (!forReplay) { SERIAL_ECHOLNPGM("Home offset (mm)"); @@ -1346,11 +1369,12 @@ void MarlinSettings::reset() { SERIAL_EOL; CONFIG_ECHO_START; if (!forReplay) { - SERIAL_ECHOLNPGM("Delta settings: L=diagonal rod, R=radius, S=segments-per-second, ABC=diagonal rod trim, IJK=tower angle trim"); + SERIAL_ECHOLNPGM("Delta settings: L=diagonal_rod, R=radius, H=height, S=segments_per_second, ABC=diagonal_rod_trim_tower_[123]"); CONFIG_ECHO_START; } SERIAL_ECHOPAIR(" M665 L", delta_diagonal_rod); SERIAL_ECHOPAIR(" R", delta_radius); + SERIAL_ECHOPAIR(" H", DELTA_HEIGHT + home_offset[Z_AXIS]); SERIAL_ECHOPAIR(" S", delta_segments_per_second); SERIAL_ECHOPAIR(" A", delta_diagonal_rod_trim[A_AXIS]); SERIAL_ECHOPAIR(" B", delta_diagonal_rod_trim[B_AXIS]); diff --git a/Marlin/language_en.h b/Marlin/language_en.h index e6c285a1a..ffa0d6694 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -498,6 +498,12 @@ #ifndef MSG_DELTA_CALIBRATE_CENTER #define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrate Center") #endif +#ifndef MSG_DELTA_AUTO_CALIBRATE + #define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto Calibration") +#endif +#ifndef MSG_DELTA_HEIGHT_CALIBRATE + #define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Set Delta Height") +#endif #ifndef MSG_INFO_MENU #define MSG_INFO_MENU _UxGT("About Printer") #endif diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index dfd9fd4ea..29f462247 100755 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -817,7 +817,7 @@ void kill_screen(const char* lcd_msg) { * */ - #if DISABLED(NO_WORKSPACE_OFFSETS) + #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) /** * Set the home offset based on the current_position */ @@ -1672,7 +1672,7 @@ void kill_screen(const char* lcd_msg) { #endif - #if DISABLED(NO_WORKSPACE_OFFSETS) + #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA) // // Set Home Offsets // @@ -1770,14 +1770,20 @@ void kill_screen(const char* lcd_msg) { lcd_goto_screen(_lcd_calibrate_homing); } + #if ENABLED(DELTA_AUTO_CALIBRATION) + #define _DELTA_TOWER_MOVE_RADIUS DELTA_CALIBRATION_RADIUS + #else + #define _DELTA_TOWER_MOVE_RADIUS DELTA_PRINTABLE_RADIUS + #endif + // Move directly to the tower position with uninterpolated moves // If we used interpolated moves it would cause this to become re-entrant void _goto_tower_pos(const float &a) { current_position[Z_AXIS] = max(Z_HOMING_HEIGHT, Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5; line_to_current(Z_AXIS); - current_position[X_AXIS] = a < 0 ? X_HOME_POS : sin(a) * -(DELTA_PRINTABLE_RADIUS); - current_position[Y_AXIS] = a < 0 ? Y_HOME_POS : cos(a) * (DELTA_PRINTABLE_RADIUS); + current_position[X_AXIS] = a < 0 ? LOGICAL_X_POSITION(X_HOME_POS) : sin(a) * -(_DELTA_TOWER_MOVE_RADIUS); + current_position[Y_AXIS] = a < 0 ? LOGICAL_Y_POSITION(Y_HOME_POS) : cos(a) * (_DELTA_TOWER_MOVE_RADIUS); line_to_current(Z_AXIS); current_position[Z_AXIS] = 4.0; @@ -1797,6 +1803,10 @@ void kill_screen(const char* lcd_msg) { void lcd_delta_calibrate_menu() { START_MENU(); MENU_BACK(MSG_MAIN); + #if ENABLED(DELTA_AUTO_CALIBRATION) + MENU_ITEM(gcode, MSG_DELTA_AUTO_CALIBRATE, PSTR("G33 C")); + MENU_ITEM(gcode, MSG_DELTA_HEIGHT_CALIBRATE, PSTR("G33 C1")); + #endif MENU_ITEM(submenu, MSG_AUTO_HOME, _lcd_delta_calibrate_home); if (axis_homed[Z_AXIS]) { MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_X, _goto_tower_x);