From 646aa20b433cbde61a849a2b79ddf1c0a13714ef Mon Sep 17 00:00:00 2001 From: Luc Van Daele Date: Thu, 12 Apr 2018 04:14:48 +0200 Subject: [PATCH] Overhaul of G33 Delta Calibration (#8822) --- .../examples/JGAurora/A5/Configuration.h | 2 +- .../examples/RepRapPro/Huxley/Configuration.h | 2 +- .../FLSUN/auto_calibrate/Configuration.h | 20 +- .../delta/FLSUN/kossel/Configuration.h | 20 +- .../delta/FLSUN/kossel_mini/Configuration.h | 20 +- .../delta/Hatchbox_Alpha/Configuration.h | 20 +- .../examples/delta/generic/Configuration.h | 20 +- .../delta/kossel_mini/Configuration.h | 20 +- .../examples/delta/kossel_pro/Configuration.h | 20 +- .../examples/delta/kossel_xl/Configuration.h | 29 +- Marlin/src/feature/Max7219_Debug_LEDs.cpp | 4 +- Marlin/src/gcode/calibrate/G33.cpp | 739 +++++++++--------- Marlin/src/gcode/calibrate/M665.cpp | 2 +- Marlin/src/gcode/gcode.h | 2 +- Marlin/src/lcd/language/language_en.h | 3 + Marlin/src/lcd/ultralcd.cpp | 53 +- Marlin/src/lcd/ultralcd.h | 4 - Marlin/src/module/motion.cpp | 6 +- Marlin/src/module/probe.cpp | 5 +- Marlin/src/module/probe.h | 3 +- 20 files changed, 516 insertions(+), 478 deletions(-) diff --git a/Marlin/src/config/examples/JGAurora/A5/Configuration.h b/Marlin/src/config/examples/JGAurora/A5/Configuration.h index fdba3bbea7..4d7fe97be4 100644 --- a/Marlin/src/config/examples/JGAurora/A5/Configuration.h +++ b/Marlin/src/config/examples/JGAurora/A5/Configuration.h @@ -320,7 +320,7 @@ #define TEMP_SENSOR_2 0 #define TEMP_SENSOR_3 0 #define TEMP_SENSOR_4 0 -#define TEMP_SENSOR_BED 1 // measured to be satisfactorily accurate on centre of bed within +/- 1 degC. +#define TEMP_SENSOR_BED 1 // measured to be satisfactorily accurate on center of bed within +/- 1 degC. #define TEMP_SENSOR_CHAMBER 0 // Dummy thermistor constant temperature readings, for use with 998 and 999 diff --git a/Marlin/src/config/examples/RepRapPro/Huxley/Configuration.h b/Marlin/src/config/examples/RepRapPro/Huxley/Configuration.h index 1f48ae435a..15667d8772 100644 --- a/Marlin/src/config/examples/RepRapPro/Huxley/Configuration.h +++ b/Marlin/src/config/examples/RepRapPro/Huxley/Configuration.h @@ -620,7 +620,7 @@ Black rubber belt(MXL), 18 - tooth aluminium pulley : 87.489 step per mm (Huxley * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ #define DEFAULT_MAX_Z_FEEDRATE 3.3 // older Huxley has problem with speeds > 3.3 mm/s on z axis -#define DEFAULT_MAX_FEEDRATE { 200, 200, DEFAULT_MAX_Z_FEEDRATE, 25 } +#define DEFAULT_MAX_FEEDRATE { 200, 200, DEFAULT_MAX_Z_FEEDRATE, 25 } /** * Default Max Acceleration (change/s) change = mm/s diff --git a/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration.h b/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration.h index 17e6d888f3..3261d31ed5 100644 --- a/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration.h +++ b/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration.h @@ -532,19 +532,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 73.5 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -653,7 +647,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 100 } // default steps per unit for Kossel (GT2, 20 tooth) +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 100 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration.h b/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration.h index b63d1c595e..250041188d 100644 --- a/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration.h +++ b/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration.h @@ -532,19 +532,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 7 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 63 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -653,7 +647,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 100 } // default steps per unit for Kossel (GT2, 20 tooth) +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 100 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration.h b/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration.h index f48ca4cfea..bfcc4c99f0 100644 --- a/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration.h +++ b/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration.h @@ -532,19 +532,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 73.5 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -653,7 +647,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 90 } // default steps per unit for Kossel (GT2, 20 tooth) +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 90 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/Hatchbox_Alpha/Configuration.h b/Marlin/src/config/examples/delta/Hatchbox_Alpha/Configuration.h index 37d5c4236f..2820f3bd4f 100644 --- a/Marlin/src/config/examples/delta/Hatchbox_Alpha/Configuration.h +++ b/Marlin/src/config/examples/delta/Hatchbox_Alpha/Configuration.h @@ -537,19 +537,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 121.5 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -658,7 +652,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 95 } // default steps per unit for Kossel (GT2, 20 tooth) +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 95 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/generic/Configuration.h b/Marlin/src/config/examples/delta/generic/Configuration.h index e76648db32..00bb3aa545 100644 --- a/Marlin/src/config/examples/delta/generic/Configuration.h +++ b/Marlin/src/config/examples/delta/generic/Configuration.h @@ -522,19 +522,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 121.5 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -643,7 +637,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 80, 760*1.1 } // default steps per unit for Kossel (GT2, 20 tooth) +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 20 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 760*1.1 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/kossel_mini/Configuration.h b/Marlin/src/config/examples/delta/kossel_mini/Configuration.h index 93cf1a8c58..fe91a8c272 100644 --- a/Marlin/src/config/examples/delta/kossel_mini/Configuration.h +++ b/Marlin/src/config/examples/delta/kossel_mini/Configuration.h @@ -522,19 +522,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 78.0 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -643,7 +637,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 80, 760*1.1 } // default steps per unit for Kossel (GT2, 20 tooth) +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 20 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 760*1.1 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/kossel_pro/Configuration.h b/Marlin/src/config/examples/delta/kossel_pro/Configuration.h index f6ffad1c56..47609fb030 100644 --- a/Marlin/src/config/examples/delta/kossel_pro/Configuration.h +++ b/Marlin/src/config/examples/delta/kossel_pro/Configuration.h @@ -508,19 +508,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 110.0 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -636,7 +630,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { XYZ_STEPS, XYZ_STEPS, XYZ_STEPS, 184.8 } +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 32 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 20 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 184.8 } // default steps per unit for Kossel (GT2, 20 tooth) /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/config/examples/delta/kossel_xl/Configuration.h b/Marlin/src/config/examples/delta/kossel_xl/Configuration.h index 4997a8aa14..a3c825ea19 100644 --- a/Marlin/src/config/examples/delta/kossel_xl/Configuration.h +++ b/Marlin/src/config/examples/delta/kossel_xl/Configuration.h @@ -526,19 +526,13 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 - - // Enable and set these values based on results of 'G33 A' - //#define H_FACTOR 1.01 - //#define R_FACTOR 2.61 - //#define A_FACTOR 0.87 - #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 121.5 // mm // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.025 + #define PROBE_MANUALLY_STEP (MIN_STEPS_PER_SEGMENT / DEFAULT_XYZ_STEPS_PER_UNIT) #endif // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). @@ -626,15 +620,6 @@ //============================================================================= // @section motion -// variables to calculate steps -#define XYZ_FULL_STEPS_PER_ROTATION 200 -#define XYZ_MICROSTEPS 16 -#define XYZ_BELT_PITCH 2 -#define XYZ_PULLEY_TEETH 16 - -// delta speeds must be the same on xyz -#define XYZ_STEPS (XYZ_FULL_STEPS_PER_ROTATION * XYZ_MICROSTEPS / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) - /** * Default Settings * @@ -655,7 +640,15 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { XYZ_STEPS, XYZ_STEPS, XYZ_STEPS, 158 } // default steps per unit for PowerWasp +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 + +// delta speeds must be the same on xyz +#define DEFAULT_XYZ_STEPS_PER_UNIT ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) +#define DEFAULT_AXIS_STEPS_PER_UNIT { DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, DEFAULT_XYZ_STEPS_PER_UNIT, 158 } // default steps per unit for PowerWasp /** * Default Max Feed Rate (mm/s) diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.cpp b/Marlin/src/feature/Max7219_Debug_LEDs.cpp index 62fa049c89..03752a3d1c 100644 --- a/Marlin/src/feature/Max7219_Debug_LEDs.cpp +++ b/Marlin/src/feature/Max7219_Debug_LEDs.cpp @@ -287,8 +287,8 @@ void Max7219_idle_tasks() { #endif CRITICAL_SECTION_END #endif - - static uint16_t refresh_cnt = 0; // The Max7219 circuit boards available for several dollars on eBay + + static uint16_t refresh_cnt = 0; // The Max7219 circuit boards available for several dollars on eBay if (refresh_cnt++ > 50000) { // are vulnerable to electrical noise, especially with long wires Max7219_register_setup(); // next to high current wires. If the display becomes corrupted due Max7219_LED_Toggle(7, 0); // to electrical noise, this will fix it within a couple of seconds. diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index 036b3425f3..7202d534e7 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -26,12 +26,15 @@ #include "../gcode.h" #include "../../module/delta.h" -#include "../../module/probe.h" #include "../../module/motion.h" #include "../../module/stepper.h" #include "../../module/endstops.h" #include "../../lcd/ultralcd.h" +#if HAS_BED_PROBE + #include "../../module/probe.h" +#endif + #if HOTENDS > 1 #include "../../module/tool_change.h" #endif @@ -43,7 +46,7 @@ constexpr uint8_t _7P_STEP = 1, // 7-point step - to change number of calibration points _4P_STEP = _7P_STEP * 2, // 4-point step NPP = _7P_STEP * 6; // number of calibration points on the radius -enum CalEnum : char { // the 7 main calibration points - add definitions if needed +enum CalEnum : char { // the 7 main calibration points - add definitions if needed CEN = 0, __A = 1, _AB = __A + _7P_STEP, @@ -60,7 +63,54 @@ enum CalEnum : char { // the 7 main calibration po #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) -static void print_signed_float(const char * const prefix, const float &f) { +#if HOTENDS > 1 + const uint8_t old_tool_index = active_extruder; + #define AC_CLEANUP() ac_cleanup(old_tool_index) +#else + #define AC_CLEANUP() ac_cleanup() +#endif + +float lcd_probe_pt(const float &rx, const float &ry); + +bool ac_home() { + endstops.enable(true); + if (!home_delta()) + return false; + endstops.not_homing(); + return true; +} + +void ac_setup(const bool reset_bed) { + #if HOTENDS > 1 + tool_change(0, 0, true); + #endif + + stepper.synchronize(); + setup_for_endstop_or_probe_move(); + + #if HAS_LEVELING + if (reset_bed) reset_bed_level(); // After full calibration bed-level data is no longer valid + #endif +} + +void ac_cleanup( + #if HOTENDS > 1 + const uint8_t old_tool_index + #endif +) { + #if ENABLED(DELTA_HOME_TO_SAFE_ZONE) + do_blocking_move_to_z(delta_clip_start_height); + #endif + #if HAS_BED_PROBE + STOW_PROBE(); + #endif + clean_up_after_endstop_or_probe_move(); + #if HOTENDS > 1 + tool_change(old_tool_index, 0, true); + #endif +} + +void print_signed_float(const char * const prefix, const float &f) { SERIAL_PROTOCOLPGM(" "); serialprintPGM(prefix); SERIAL_PROTOCOLCHAR(':'); @@ -68,7 +118,10 @@ static void print_signed_float(const char * const prefix, const float &f) { SERIAL_PROTOCOL_F(f, 2); } -static void print_G33_settings(const bool end_stops, const bool tower_angles) { +/** + * - Print the delta settings + */ +static void print_calibration_settings(const bool end_stops, const bool tower_angles) { SERIAL_PROTOCOLPAIR(".Height:", delta_height); if (end_stops) { print_signed_float(PSTR("Ex"), delta_endstop_adj[A_AXIS]); @@ -89,16 +142,25 @@ static void print_G33_settings(const bool end_stops, const bool tower_angles) { if ((!end_stops && tower_angles) || (end_stops && !tower_angles)) { // XOR SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); } + #if HAS_BED_PROBE + if (!end_stops && !tower_angles) { + SERIAL_PROTOCOL_SP(30); + print_signed_float(PSTR("Offset"), zprobe_zoffset); + } + #endif SERIAL_EOL(); } -static void print_G33_results(const float z_at_pt[NPP + 1], const bool tower_points, const bool opposite_points) { +/** + * - Print the probe results + */ +static void print_calibration_results(const float z_pt[NPP + 1], const bool tower_points, const bool opposite_points) { SERIAL_PROTOCOLPGM(". "); - print_signed_float(PSTR("c"), z_at_pt[CEN]); + print_signed_float(PSTR("c"), z_pt[CEN]); if (tower_points) { - print_signed_float(PSTR(" x"), z_at_pt[__A]); - print_signed_float(PSTR(" y"), z_at_pt[__B]); - print_signed_float(PSTR(" z"), z_at_pt[__C]); + print_signed_float(PSTR(" x"), z_pt[__A]); + print_signed_float(PSTR(" y"), z_pt[__B]); + print_signed_float(PSTR(" z"), z_pt[__C]); } if (tower_points && opposite_points) { SERIAL_EOL(); @@ -106,50 +168,63 @@ static void print_G33_results(const float z_at_pt[NPP + 1], const bool tower_poi SERIAL_PROTOCOL_SP(13); } if (opposite_points) { - print_signed_float(PSTR("yz"), z_at_pt[_BC]); - print_signed_float(PSTR("zx"), z_at_pt[_CA]); - print_signed_float(PSTR("xy"), z_at_pt[_AB]); + print_signed_float(PSTR("yz"), z_pt[_BC]); + print_signed_float(PSTR("zx"), z_pt[_CA]); + print_signed_float(PSTR("xy"), z_pt[_AB]); } SERIAL_EOL(); } /** - * After G33: - * - Move to the print ceiling (DELTA_HOME_TO_SAFE_ZONE only) - * - Stow the probe - * - Restore endstops state - * - Select the old tool, if needed + * - Calculate the standard deviation from the zero plane */ -static void G33_cleanup( - #if HOTENDS > 1 - const uint8_t old_tool_index - #endif -) { - #if ENABLED(DELTA_HOME_TO_SAFE_ZONE) - do_blocking_move_to_z(delta_clip_start_height); - #endif - STOW_PROBE(); - clean_up_after_endstop_or_probe_move(); - #if HOTENDS > 1 - tool_change(old_tool_index, 0, true); - #endif +static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool _1p_cal, const bool _4p_cal, const bool _4p_opp) { + if (!_0p_cal) { + float S2 = sq(z_pt[CEN]); + int16_t N = 1; + if (!_1p_cal) { // std dev from zero plane + LOOP_CAL_ACT(rad, _4p_cal, _4p_opp) { + S2 += sq(z_pt[rad]); + N++; + } + return round(SQRT(S2 / N) * 1000.0) / 1000.0 + 0.00001; + } + } + return 0.00001; } -inline float calibration_probe(const float nx, const float ny, const bool stow) { +/** + * - Probe a point + */ +static float calibration_probe(const float &nx, const float &ny, const bool stow, const bool set_up) { #if HAS_BED_PROBE - return probe_pt(nx, ny, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, false); + return probe_pt(nx, ny, set_up ? PROBE_PT_BIG_RAISE : stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, false); #else UNUSED(stow); + UNUSED(set_up); return lcd_probe_pt(nx, ny); #endif } -static float probe_G33_points(float z_at_pt[NPP + 1], const int8_t probe_points, const bool towers_set, const bool stow_after_each) { +#if HAS_BED_PROBE + static float probe_z_shift(const float center) { + STOW_PROBE(); + endstops.enable_z_probe(false); + float z_shift = lcd_probe_pt(0, 0) - center; + endstops.enable_z_probe(true); + return z_shift; + } +#endif + +/** + * - Probe a grid + */ +static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const bool towers_set, const bool stow_after_each, const bool set_up) { const bool _0p_calibration = probe_points == 0, - _1p_calibration = probe_points == 1, + _1p_calibration = probe_points == 1 || probe_points == -1, _4p_calibration = probe_points == 2, _4p_opposite_points = _4p_calibration && !towers_set, - _7p_calibration = probe_points >= 3 || probe_points == 0, + _7p_calibration = probe_points >= 3, _7p_no_intermediates = probe_points == 3, _7p_1_intermediates = probe_points == 4, _7p_2_intermediates = probe_points == 5, @@ -159,28 +234,28 @@ static float probe_G33_points(float z_at_pt[NPP + 1], const int8_t probe_points, _7p_11_intermediates = probe_points == 9, _7p_14_intermediates = probe_points == 10, _7p_intermed_points = probe_points >= 4, - _7p_6_centre = probe_points >= 5 && probe_points <= 7, - _7p_9_centre = probe_points >= 8; + _7p_6_center = probe_points >= 5 && probe_points <= 7, + _7p_9_center = probe_points >= 8; - LOOP_CAL_ALL(axis) z_at_pt[axis] = 0.0; + LOOP_CAL_ALL(rad) z_pt[rad] = 0.0; if (!_0p_calibration) { if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center - z_at_pt[CEN] += calibration_probe(0, 0, stow_after_each); - if (isnan(z_at_pt[CEN])) return NAN; + z_pt[CEN] += calibration_probe(0, 0, stow_after_each, set_up); + if (isnan(z_pt[CEN])) return false; } if (_7p_calibration) { // probe extra center points - const float start = _7p_9_centre ? _CA + _7P_STEP / 3.0 : _7p_6_centre ? _CA : __C, - steps = _7p_9_centre ? _4P_STEP / 3.0 : _7p_6_centre ? _7P_STEP : _4P_STEP; - I_LOOP_CAL_PT(axis, start, steps) { - const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), + const float start = _7p_9_center ? _CA + _7P_STEP / 3.0 : _7p_6_center ? _CA : __C, + steps = _7p_9_center ? _4P_STEP / 3.0 : _7p_6_center ? _7P_STEP : _4P_STEP; + I_LOOP_CAL_PT(rad, start, steps) { + const float a = RADIANS(210 + (360 / NPP) * (rad - 1)), r = delta_calibration_radius * 0.1; - z_at_pt[CEN] += calibration_probe(cos(a) * r, sin(a) * r, stow_after_each); - if (isnan(z_at_pt[CEN])) return NAN; + z_pt[CEN] += calibration_probe(cos(a) * r, sin(a) * r, stow_after_each, set_up); + if (isnan(z_pt[CEN])) return false; } - z_at_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points); + z_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points); } if (!_1p_calibration) { // probe the radius @@ -195,182 +270,150 @@ static float probe_G33_points(float z_at_pt[NPP + 1], const int8_t probe_points, _7p_no_intermediates ? _7P_STEP : // 1r * 6 + 3c = 9 _4P_STEP; // .5r * 6 + 1c = 4 bool zig_zag = true; - F_LOOP_CAL_PT(axis, start, _7p_9_centre ? steps * 3 : steps) { - const int8_t offset = _7p_9_centre ? 1 : 0; - for (int8_t circle = -offset; circle <= offset; circle++) { - const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), - r = delta_calibration_radius * (1 + 0.1 * (zig_zag ? circle : - circle)), - interpol = fmod(axis, 1); - const float z_temp = calibration_probe(cos(a) * r, sin(a) * r, stow_after_each); - if (isnan(z_temp)) return NAN; + F_LOOP_CAL_PT(rad, start, _7p_9_center ? steps * 3 : steps) { + const int8_t offset = _7p_9_center ? 2 : 0; + for (int8_t circle = 0; circle <= offset; circle++) { + const float a = RADIANS(210 + (360 / NPP) * (rad - 1)), + r = delta_calibration_radius * (1 - 0.1 * (zig_zag ? offset - circle : circle)), + interpol = fmod(rad, 1); + const float z_temp = calibration_probe(cos(a) * r, sin(a) * r, stow_after_each, set_up); + if (isnan(z_temp)) return false; // split probe point to neighbouring calibration points - z_at_pt[uint8_t(round(axis - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90))); - z_at_pt[uint8_t(round(axis - interpol)) % NPP + 1] += z_temp * sq(sin(RADIANS(interpol * 90))); + z_pt[uint8_t(round(rad - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90))); + z_pt[uint8_t(round(rad - interpol)) % NPP + 1] += z_temp * sq(sin(RADIANS(interpol * 90))); } zig_zag = !zig_zag; } if (_7p_intermed_points) - LOOP_CAL_RAD(axis) - z_at_pt[axis] /= _7P_STEP / steps; - } + LOOP_CAL_RAD(rad) + z_pt[rad] /= _7P_STEP / steps; - float S1 = z_at_pt[CEN], - S2 = sq(z_at_pt[CEN]); - int16_t N = 1; - if (!_1p_calibration) { // std dev from zero plane - LOOP_CAL_ACT(axis, _4p_calibration, _4p_opposite_points) { - S1 += z_at_pt[axis]; - S2 += sq(z_at_pt[axis]); - N++; - } - return round(SQRT(S2 / N) * 1000.0) / 1000.0 + 0.00001; + do_blocking_move_to_xy(0.0, 0.0); } } - - return 0.00001; + return true; } -#if HAS_BED_PROBE +/** + * kinematics routines and auto tune matrix scaling parameters: + * see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for + * - formulae for approximative forward kinematics in the end-stop displacement matrix + * - definition of the matrix scaling parameters + */ +static void reverse_kinematics_probe_points(float z_pt[NPP + 1], float mm_at_pt_axis[NPP + 1][ABC]) { + float pos[XYZ] = { 0.0 }; - static bool G33_auto_tune() { - float z_at_pt[NPP + 1] = { 0.0 }, - z_at_pt_base[NPP + 1] = { 0.0 }, - z_temp, h_fac = 0.0, r_fac = 0.0, a_fac = 0.0, norm = 0.8; - - #define ZP(N,I) ((N) * z_at_pt[I]) - #define Z06(I) ZP(6, I) - #define Z03(I) ZP(3, I) - #define Z02(I) ZP(2, I) - #define Z01(I) ZP(1, I) - #define Z32(I) ZP(3/2, I) - - SERIAL_PROTOCOLPGM("AUTO TUNE baseline"); - SERIAL_EOL(); - if (isnan(probe_G33_points(z_at_pt_base, 3, true, false))) return false; - print_G33_results(z_at_pt_base, true, true); - - LOOP_XYZ(axis) { - delta_endstop_adj[axis] -= 1.0; - recalc_delta_settings(); - - endstops.enable(true); - if (!home_delta()) return false; - endstops.not_homing(); - - SERIAL_PROTOCOLPGM("Tuning E"); - SERIAL_CHAR(tolower(axis_codes[axis])); - SERIAL_EOL(); - - if (isnan(probe_G33_points(z_at_pt, 3, true, false))) return false; - LOOP_CAL_ALL(axis) z_at_pt[axis] -= z_at_pt_base[axis]; - print_G33_results(z_at_pt, true, true); - delta_endstop_adj[axis] += 1.0; - recalc_delta_settings(); - switch (axis) { - case A_AXIS : - h_fac += 4.0 / (Z03(CEN) +Z01(__A) +Z32(_CA) +Z32(_AB)); // Offset by X-tower end-stop - break; - case B_AXIS : - h_fac += 4.0 / (Z03(CEN) +Z01(__B) +Z32(_BC) +Z32(_AB)); // Offset by Y-tower end-stop - break; - case C_AXIS : - h_fac += 4.0 / (Z03(CEN) +Z01(__C) +Z32(_BC) +Z32(_CA) ); // Offset by Z-tower end-stop - break; - } - } - h_fac /= 3.0; - h_fac *= norm; // Normalize to 1.02 for Kossel mini - - for (int8_t zig_zag = -1; zig_zag < 2; zig_zag += 2) { - delta_radius += 1.0 * zig_zag; - recalc_delta_settings(); - - endstops.enable(true); - if (!home_delta()) return false; - endstops.not_homing(); - - SERIAL_PROTOCOLPGM("Tuning R"); - SERIAL_PROTOCOL(zig_zag == -1 ? "-" : "+"); - SERIAL_EOL(); - if (isnan(probe_G33_points(z_at_pt, 3, true, false))) return false; - LOOP_CAL_ALL(axis) z_at_pt[axis] -= z_at_pt_base[axis]; - print_G33_results(z_at_pt, true, true); - delta_radius -= 1.0 * zig_zag; - recalc_delta_settings(); - r_fac -= zig_zag * 6.0 / (Z03(__A) +Z03(__B) +Z03(__C) +Z03(_BC) +Z03(_CA) +Z03(_AB)); // Offset by delta radius - } - r_fac /= 2.0; - r_fac *= 3 * norm; // Normalize to 2.25 for Kossel mini - - LOOP_XYZ(axis) { - delta_tower_angle_trim[axis] += 1.0; - delta_endstop_adj[(axis + 1) % 3] -= 1.0 / 4.5; - delta_endstop_adj[(axis + 2) % 3] += 1.0 / 4.5; - z_temp = MAX3(delta_endstop_adj[A_AXIS], delta_endstop_adj[B_AXIS], delta_endstop_adj[C_AXIS]); - delta_height -= z_temp; - LOOP_XYZ(axis) delta_endstop_adj[axis] -= z_temp; - recalc_delta_settings(); - - endstops.enable(true); - if (!home_delta()) return false; - endstops.not_homing(); - - SERIAL_PROTOCOLPGM("Tuning T"); - SERIAL_CHAR(tolower(axis_codes[axis])); - SERIAL_EOL(); - - if (isnan(probe_G33_points(z_at_pt, 3, true, false))) return false; - LOOP_CAL_ALL(axis) z_at_pt[axis] -= z_at_pt_base[axis]; - print_G33_results(z_at_pt, true, true); - - delta_tower_angle_trim[axis] -= 1.0; - delta_endstop_adj[(axis+1) % 3] += 1.0/4.5; - delta_endstop_adj[(axis+2) % 3] -= 1.0/4.5; - z_temp = MAX3(delta_endstop_adj[A_AXIS], delta_endstop_adj[B_AXIS], delta_endstop_adj[C_AXIS]); - delta_height -= z_temp; - LOOP_XYZ(axis) delta_endstop_adj[axis] -= z_temp; - recalc_delta_settings(); - switch (axis) { - case A_AXIS : - a_fac += 4.0 / ( Z06(__B) -Z06(__C) +Z06(_CA) -Z06(_AB)); // Offset by alpha tower angle - break; - case B_AXIS : - a_fac += 4.0 / (-Z06(__A) +Z06(__C) -Z06(_BC) +Z06(_AB)); // Offset by beta tower angle - break; - case C_AXIS : - a_fac += 4.0 / (Z06(__A) -Z06(__B) +Z06(_BC) -Z06(_CA) ); // Offset by gamma tower angle - break; - } - } - a_fac /= 3.0; - a_fac *= norm; // Normalize to 0.83 for Kossel mini - - endstops.enable(true); - if (!home_delta()) return false; - endstops.not_homing(); - print_signed_float(PSTR( "H_FACTOR: "), h_fac); - print_signed_float(PSTR(" R_FACTOR: "), r_fac); - print_signed_float(PSTR(" A_FACTOR: "), a_fac); - SERIAL_EOL(); - SERIAL_PROTOCOLPGM("Copy these values to Configuration.h"); - SERIAL_EOL(); - return true; + LOOP_CAL_ALL(rad) { + const float a = RADIANS(210 + (360 / NPP) * (rad - 1)), + r = (rad == CEN ? 0.0 : delta_calibration_radius); + pos[X_AXIS] = cos(a) * r; + pos[Y_AXIS] = sin(a) * r; + pos[Z_AXIS] = z_pt[rad]; + inverse_kinematics(pos); + LOOP_XYZ(axis) mm_at_pt_axis[rad][axis] = delta[axis]; } +} -#endif // HAS_BED_PROBE +static void forward_kinematics_probe_points(float mm_at_pt_axis[NPP + 1][ABC], float z_pt[NPP + 1]) { + const float r_quot = delta_calibration_radius / delta_radius; + + #define ZPP(N,I,A) ((1 / 3.0 + r_quot * (N) / 3.0 ) * mm_at_pt_axis[I][A]) + #define Z00(I, A) ZPP( 0, I, A) + #define Zp1(I, A) ZPP(+1, I, A) + #define Zm1(I, A) ZPP(-1, I, A) + #define Zp2(I, A) ZPP(+2, I, A) + #define Zm2(I, A) ZPP(-2, I, A) + + z_pt[CEN] = Z00(CEN, A_AXIS) + Z00(CEN, B_AXIS) + Z00(CEN, C_AXIS); + z_pt[__A] = Zp2(__A, A_AXIS) + Zm1(__A, B_AXIS) + Zm1(__A, C_AXIS); + z_pt[__B] = Zm1(__B, A_AXIS) + Zp2(__B, B_AXIS) + Zm1(__B, C_AXIS); + z_pt[__C] = Zm1(__C, A_AXIS) + Zm1(__C, B_AXIS) + Zp2(__C, C_AXIS); + z_pt[_BC] = Zm2(_BC, A_AXIS) + Zp1(_BC, B_AXIS) + Zp1(_BC, C_AXIS); + z_pt[_CA] = Zp1(_CA, A_AXIS) + Zm2(_CA, B_AXIS) + Zp1(_CA, C_AXIS); + z_pt[_AB] = Zp1(_AB, A_AXIS) + Zp1(_AB, B_AXIS) + Zm2(_AB, C_AXIS); +} + +static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], float delta_e[ABC], float delta_r, float delta_t[ABC]) { + const float z_center = z_pt[CEN]; + float diff_mm_at_pt_axis[NPP + 1][ABC], + new_mm_at_pt_axis[NPP + 1][ABC]; + + reverse_kinematics_probe_points(z_pt, diff_mm_at_pt_axis); + + delta_radius += delta_r; + LOOP_XYZ(axis) delta_tower_angle_trim[axis] += delta_t[axis]; + recalc_delta_settings(); + reverse_kinematics_probe_points(z_pt, new_mm_at_pt_axis); + + LOOP_XYZ(axis) LOOP_CAL_ALL(rad) diff_mm_at_pt_axis[rad][axis] -= new_mm_at_pt_axis[rad][axis] + delta_e[axis]; + forward_kinematics_probe_points(diff_mm_at_pt_axis, z_pt); + + LOOP_CAL_RAD(rad) z_pt[rad] -= z_pt[CEN] - z_center; + z_pt[CEN] = z_center; + + delta_radius -= delta_r; + LOOP_XYZ(axis) delta_tower_angle_trim[axis] -= delta_t[axis]; + recalc_delta_settings(); +} + +static float auto_tune_h() { + const float r_quot = delta_calibration_radius / delta_radius; + float h_fac = 0.0; + + h_fac = r_quot / (2.0 / 3.0); + h_fac = 1.0 / h_fac; // (2/3)/CR + return h_fac; +} + +static float auto_tune_r() { + const float diff = 0.01; + float r_fac = 0.0, + z_pt[NPP + 1] = { 0.0 }, + delta_e[ABC] = {0.0}, + delta_r = {0.0}, + delta_t[ABC] = {0.0}; + + delta_r = diff; + calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t); + r_fac = -(z_pt[__A] + z_pt[__B] + z_pt[__C] + z_pt[_BC] + z_pt[_CA] + z_pt[_AB]) / 6.0; + r_fac = diff / r_fac / 3.0; // 1/(3*delta_Z) + return r_fac; +} + +static float auto_tune_a() { + const float diff = 0.01; + float a_fac = 0.0, + z_pt[NPP + 1] = { 0.0 }, + delta_e[ABC] = {0.0}, + delta_r = {0.0}, + delta_t[ABC] = {0.0}; + + LOOP_XYZ(axis) { + LOOP_XYZ(axis_2) delta_t[axis_2] = 0.0; + delta_t[axis] = diff; + calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t); + a_fac += z_pt[uint8_t((axis * _4P_STEP) - _7P_STEP + NPP) % NPP + 1] / 6.0; + a_fac -= z_pt[uint8_t((axis * _4P_STEP) + 1 + _7P_STEP)] / 6.0; + } + a_fac = diff / a_fac / 3.0; // 1/(3*delta_Z) + return a_fac; +} /** * G33 - Delta '1-4-7-point' Auto-Calibration - * Calibrate height, endstops, delta radius, and tower angles. + * Calibrate height, z_offset, endstops, delta radius, and tower angles. * * Parameters: * + * S Setup mode; disables probe protection + * * Pn Number of probe points: - * P0 No probe. Normalize only. - * P1 Probe center and set height only. - * P2 Probe center and towers. Set height, endstops and delta radius. - * P3 Probe all positions: center, towers and opposite towers. Set all. - * P4-P10 Probe all positions + at different intermediate locations and average them. + * P-1 Checks the z_offset with a center probe and paper test. + * P0 Normalizes calibration. + * P1 Calibrates height only with center probe. + * P2 Probe center and towers. Calibrate height, endstops and delta radius. + * P3 Probe all positions: center, towers and opposite towers. Calibrate all. + * P4-P10 Probe all positions at different intermediate locations and average them. * * T Don't calibrate tower angle corrections * @@ -378,8 +421,6 @@ static float probe_G33_points(float z_at_pt[NPP + 1], const int8_t probe_points, * * Fn Force to run at least n iterations and take the best result * - * A Auto-tune calibration factors (set in Configuration.h) - * * Vn Verbose level: * V0 Dry-run mode. Report settings and probe results. No calibration. * V1 Report start and end settings only @@ -390,19 +431,22 @@ static float probe_G33_points(float z_at_pt[NPP + 1], const int8_t probe_points, */ void GcodeSuite::G33() { - const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); - if (!WITHIN(probe_points, 0, 10)) { - SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (0-10)."); + const bool set_up = + #if HAS_BED_PROBE + parser.seen('S'); + #else + false; + #endif + + const int8_t probe_points = set_up ? 2 : parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); + if (!WITHIN(probe_points, -1, 10)) { + SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (-1 - 10)."); return; } - const int8_t verbose_level = parser.byteval('V', 1); - if (!WITHIN(verbose_level, 0, 3)) { - SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-3)."); - return; - } + const bool towers_set = !parser.seen('T'); - const float calibration_precision = parser.floatval('C', 0.0); + const float calibration_precision = set_up ? Z_CLEARANCE_BETWEEN_PROBES / 5.0 : parser.floatval('C', 0.0); if (calibration_precision < 0) { SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>=0)."); return; @@ -410,36 +454,52 @@ void GcodeSuite::G33() { const int8_t force_iterations = parser.intval('F', 0); if (!WITHIN(force_iterations, 0, 30)) { - SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (0-30)."); + SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (0 - 30)."); return; } - const bool towers_set = !parser.boolval('T'), - auto_tune = parser.boolval('A'), - stow_after_each = parser.boolval('E'), - _0p_calibration = probe_points == 0, - _1p_calibration = probe_points == 1, + const int8_t verbose_level = parser.byteval('V', 1); + if (!WITHIN(verbose_level, 0, 3)) { + SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0 - 3)."); + return; + } + + const bool stow_after_each = parser.seen('E'); + + if (set_up) { + delta_height = 999.99; + delta_radius = DELTA_PRINTABLE_RADIUS; + ZERO(delta_endstop_adj); + ZERO(delta_tower_angle_trim); + recalc_delta_settings(); + } + + const bool _0p_calibration = probe_points == 0, + _1p_calibration = probe_points == 1 || probe_points == -1, _4p_calibration = probe_points == 2, - _7p_9_centre = probe_points >= 8, - _tower_results = (_4p_calibration && towers_set) - || probe_points >= 3 || probe_points == 0, - _opposite_results = (_4p_calibration && !towers_set) - || probe_points >= 3 || probe_points == 0, - _endstop_results = probe_points != 1, - _angle_results = (probe_points >= 3 || probe_points == 0) && towers_set; + _4p_opposite_points = _4p_calibration && !towers_set, + _7p_9_center = probe_points >= 8, + _tower_results = (_4p_calibration && towers_set) || probe_points >= 3, + _opposite_results = (_4p_calibration && !towers_set) || probe_points >= 3, + _endstop_results = probe_points != 1 && probe_points != -1 && probe_points != 0, + _angle_results = probe_points >= 3 && towers_set; const static char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h"; int8_t iterations = 0; float test_precision, zero_std_dev = (verbose_level ? 999.0 : 0.0), // 0.0 in dry-run mode : forced end zero_std_dev_min = zero_std_dev, + zero_std_dev_old = zero_std_dev, + h_factor, + r_factor, + a_factor, e_old[ABC] = { delta_endstop_adj[A_AXIS], delta_endstop_adj[B_AXIS], delta_endstop_adj[C_AXIS] }, - dr_old = delta_radius, - zh_old = delta_height, - ta_old[ABC] = { + r_old = delta_radius, + h_old = delta_height, + a_old[ABC] = { delta_tower_angle_trim[A_AXIS], delta_tower_angle_trim[B_AXIS], delta_tower_angle_trim[C_AXIS] @@ -447,10 +507,10 @@ void GcodeSuite::G33() { SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate"); - if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable + if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable LOOP_CAL_RAD(axis) { const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), - r = delta_calibration_radius * (1 + (_7p_9_centre ? 0.1 : 0.0)); + r = delta_calibration_radius; if (!position_is_reachable(cos(a) * r, sin(a) * r)) { SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible."); return; @@ -458,159 +518,137 @@ void GcodeSuite::G33() { } } - stepper.synchronize(); - #if HAS_LEVELING - reset_bed_level(); // After calibration bed-level data is no longer valid - #endif - - #if HOTENDS > 1 - const uint8_t old_tool_index = active_extruder; - tool_change(0, 0, true); - #define G33_CLEANUP() G33_cleanup(old_tool_index) - #else - #define G33_CLEANUP() G33_cleanup() - #endif - - setup_for_endstop_or_probe_move(); - endstops.enable(true); - if (!_0p_calibration) { - if (!home_delta()) - return; - endstops.not_homing(); - } - - if (auto_tune) { - #if HAS_BED_PROBE - G33_auto_tune(); - #else - SERIAL_PROTOCOLLNPGM("A probe is needed for auto-tune"); - #endif - G33_CLEANUP(); - return; - } - // Report settings - PGM_P checkingac = PSTR("Checking... AC"); // TODO: Make translatable string + const char *checkingac = PSTR("Checking... AC"); serialprintPGM(checkingac); if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)"); + if (set_up) SERIAL_PROTOCOLPGM(" (SET-UP)"); SERIAL_EOL(); - lcd_setstatusPGM(checkingac); + char mess[11]; + strcpy_P(mess, checkingac); + lcd_setstatus(mess); - print_G33_settings(_endstop_results, _angle_results); + print_calibration_settings(_endstop_results, _angle_results); - do { + ac_setup(!_0p_calibration && !_1p_calibration); + + if (!_0p_calibration) + if (!ac_home()) return; + + do { // start iterations float z_at_pt[NPP + 1] = { 0.0 }; - test_precision = zero_std_dev; - + test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev; iterations++; // Probe the points - - zero_std_dev = probe_G33_points(z_at_pt, probe_points, towers_set, stow_after_each); - if (isnan(zero_std_dev)) { - SERIAL_PROTOCOLPGM("Correct delta_radius with M665 R or end-stops with M666 X Y Z"); - SERIAL_EOL(); - return G33_CLEANUP(); + zero_std_dev_old = zero_std_dev; + if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each, set_up)) { + SERIAL_PROTOCOLLNPGM("Correct delta settings with M665 and M666"); + return AC_CLEANUP(); } + zero_std_dev = std_dev_points(z_at_pt, _0p_calibration, _1p_calibration, _4p_calibration, _4p_opposite_points); // Solve matrices if ((zero_std_dev < test_precision || iterations <= force_iterations) && zero_std_dev > calibration_precision) { - if (zero_std_dev < zero_std_dev_min) { - COPY(e_old, delta_endstop_adj); - dr_old = delta_radius; - zh_old = delta_height; - COPY(ta_old, delta_tower_angle_trim); - } - - float e_delta[ABC] = { 0.0 }, r_delta = 0.0, t_delta[ABC] = { 0.0 }; - const float r_diff = delta_radius - delta_calibration_radius, - h_factor = 1 / 6.0 * - #ifdef H_FACTOR - (H_FACTOR), // Set in Configuration.h - #else - (1.00 + r_diff * 0.001), // 1.02 for r_diff = 20mm - #endif - r_factor = 1 / 6.0 * - #ifdef R_FACTOR - -(R_FACTOR), // Set in Configuration.h - #else - -(1.75 + 0.005 * r_diff + 0.001 * sq(r_diff)), // 2.25 for r_diff = 20mm - #endif - a_factor = 1 / 6.0 * - #ifdef A_FACTOR - (A_FACTOR); // Set in Configuration.h - #else - (66.66 / delta_calibration_radius); // 0.83 for cal_rd = 80mm - #endif - - #define ZP(N,I) ((N) * z_at_pt[I]) - #define Z6(I) ZP(6, I) - #define Z4(I) ZP(4, I) - #define Z2(I) ZP(2, I) - #define Z1(I) ZP(1, I) #if !HAS_BED_PROBE test_precision = 0.00; // forced end #endif + if (zero_std_dev < zero_std_dev_min) { + // set roll-back point + COPY(e_old, delta_endstop_adj); + r_old = delta_radius; + h_old = delta_height; + COPY(a_old, delta_tower_angle_trim); + } + + float e_delta[ABC] = { 0.0 }, + r_delta = 0.0, + t_delta[ABC] = { 0.0 }; + + /** + * convergence matrices: + * see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for + * - definition of the matrix scaling parameters + * - matrices for 4 and 7 point calibration + */ + #define ZP(N,I) ((N) * z_at_pt[I] / 4.0) // 4.0 = divider to normalize to integers + #define Z12(I) ZP(12, I) + #define Z4(I) ZP(4, I) + #define Z2(I) ZP(2, I) + #define Z1(I) ZP(1, I) + #define Z0(I) ZP(0, I) + + // calculate factors + const float cr_old = delta_calibration_radius; + if (_7p_9_center) delta_calibration_radius *= 0.9; + h_factor = auto_tune_h(); + r_factor = auto_tune_r(); + a_factor = auto_tune_a(); + delta_calibration_radius = cr_old; + switch (probe_points) { + case -1: + #if HAS_BED_PROBE + zprobe_zoffset += probe_z_shift(z_at_pt[CEN]); + #endif + case 0: test_precision = 0.00; // forced end break; case 1: test_precision = 0.00; // forced end - LOOP_XYZ(axis) e_delta[axis] = Z1(CEN); + LOOP_XYZ(axis) e_delta[axis] = +Z4(CEN); break; case 2: - if (towers_set) { - e_delta[A_AXIS] = (Z6(CEN) +Z4(__A) -Z2(__B) -Z2(__C)) * h_factor; - e_delta[B_AXIS] = (Z6(CEN) -Z2(__A) +Z4(__B) -Z2(__C)) * h_factor; - e_delta[C_AXIS] = (Z6(CEN) -Z2(__A) -Z2(__B) +Z4(__C)) * h_factor; - r_delta = (Z6(CEN) -Z2(__A) -Z2(__B) -Z2(__C)) * r_factor; + if (towers_set) { // see 4 point calibration (towers) matrix + e_delta[A_AXIS] = (+Z4(__A) -Z2(__B) -Z2(__C)) * h_factor +Z4(CEN); + e_delta[B_AXIS] = (-Z2(__A) +Z4(__B) -Z2(__C)) * h_factor +Z4(CEN); + e_delta[C_AXIS] = (-Z2(__A) -Z2(__B) +Z4(__C)) * h_factor +Z4(CEN); + r_delta = (+Z4(__A) +Z4(__B) +Z4(__C) -Z12(CEN)) * r_factor; } - else { - e_delta[A_AXIS] = (Z6(CEN) -Z4(_BC) +Z2(_CA) +Z2(_AB)) * h_factor; - e_delta[B_AXIS] = (Z6(CEN) +Z2(_BC) -Z4(_CA) +Z2(_AB)) * h_factor; - e_delta[C_AXIS] = (Z6(CEN) +Z2(_BC) +Z2(_CA) -Z4(_AB)) * h_factor; - r_delta = (Z6(CEN) -Z2(_BC) -Z2(_CA) -Z2(_AB)) * r_factor; + else { // see 4 point calibration (opposites) matrix + e_delta[A_AXIS] = (-Z4(_BC) +Z2(_CA) +Z2(_AB)) * h_factor +Z4(CEN); + e_delta[B_AXIS] = (+Z2(_BC) -Z4(_CA) +Z2(_AB)) * h_factor +Z4(CEN); + e_delta[C_AXIS] = (+Z2(_BC) +Z2(_CA) -Z4(_AB)) * h_factor +Z4(CEN); + r_delta = (+Z4(_BC) +Z4(_CA) +Z4(_AB) -Z12(CEN)) * r_factor; } break; - default: - e_delta[A_AXIS] = (Z6(CEN) +Z2(__A) -Z1(__B) -Z1(__C) -Z2(_BC) +Z1(_CA) +Z1(_AB)) * h_factor; - e_delta[B_AXIS] = (Z6(CEN) -Z1(__A) +Z2(__B) -Z1(__C) +Z1(_BC) -Z2(_CA) +Z1(_AB)) * h_factor; - e_delta[C_AXIS] = (Z6(CEN) -Z1(__A) -Z1(__B) +Z2(__C) +Z1(_BC) +Z1(_CA) -Z2(_AB)) * h_factor; - r_delta = (Z6(CEN) -Z1(__A) -Z1(__B) -Z1(__C) -Z1(_BC) -Z1(_CA) -Z1(_AB)) * r_factor; + default: // see 7 point calibration (towers & opposites) matrix + e_delta[A_AXIS] = (+Z2(__A) -Z1(__B) -Z1(__C) -Z2(_BC) +Z1(_CA) +Z1(_AB)) * h_factor +Z4(CEN); + e_delta[B_AXIS] = (-Z1(__A) +Z2(__B) -Z1(__C) +Z1(_BC) -Z2(_CA) +Z1(_AB)) * h_factor +Z4(CEN); + e_delta[C_AXIS] = (-Z1(__A) -Z1(__B) +Z2(__C) +Z1(_BC) +Z1(_CA) -Z2(_AB)) * h_factor +Z4(CEN); + r_delta = (+Z2(__A) +Z2(__B) +Z2(__C) +Z2(_BC) +Z2(_CA) +Z2(_AB) -Z12(CEN)) * r_factor; - if (towers_set) { - t_delta[A_AXIS] = ( -Z4(__B) +Z4(__C) -Z4(_CA) +Z4(_AB)) * a_factor; - t_delta[B_AXIS] = ( Z4(__A) -Z4(__C) +Z4(_BC) -Z4(_AB)) * a_factor; - t_delta[C_AXIS] = (-Z4(__A) +Z4(__B) -Z4(_BC) +Z4(_CA) ) * a_factor; - e_delta[A_AXIS] += (t_delta[B_AXIS] - t_delta[C_AXIS]) / 4.5; - e_delta[B_AXIS] += (t_delta[C_AXIS] - t_delta[A_AXIS]) / 4.5; - e_delta[C_AXIS] += (t_delta[A_AXIS] - t_delta[B_AXIS]) / 4.5; + if (towers_set) { // see 7 point tower angle calibration (towers & opposites) matrix + t_delta[A_AXIS] = (+Z0(__A) -Z4(__B) +Z4(__C) +Z0(_BC) -Z4(_CA) +Z4(_AB) +Z0(CEN)) * a_factor; + t_delta[B_AXIS] = (+Z4(__A) +Z0(__B) -Z4(__C) +Z4(_BC) +Z0(_CA) -Z4(_AB) +Z0(CEN)) * a_factor; + t_delta[C_AXIS] = (-Z4(__A) +Z4(__B) +Z0(__C) -Z4(_BC) +Z4(_CA) +Z0(_AB) +Z0(CEN)) * a_factor; } break; } - LOOP_XYZ(axis) delta_endstop_adj[axis] += e_delta[axis]; delta_radius += r_delta; LOOP_XYZ(axis) delta_tower_angle_trim[axis] += t_delta[axis]; } - else if (zero_std_dev >= test_precision) { // step one back + else if (zero_std_dev >= test_precision) { + // roll back COPY(delta_endstop_adj, e_old); - delta_radius = dr_old; - delta_height = zh_old; - COPY(delta_tower_angle_trim, ta_old); + delta_radius = r_old; + delta_height = h_old; + COPY(delta_tower_angle_trim, a_old); } if (verbose_level != 0) { // !dry run + // normalise angles to least squares if (_angle_results) { float a_sum = 0.0; @@ -628,15 +666,15 @@ void GcodeSuite::G33() { // print report - if (verbose_level > 2) - print_G33_results(z_at_pt, _tower_results, _opposite_results); + if (verbose_level == 3) + print_calibration_results(z_at_pt, _tower_results, _opposite_results); - if (verbose_level != 0) { // !dry run - if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations + if (verbose_level != 0) { // !dry run + if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations SERIAL_PROTOCOLPGM("Calibration OK"); SERIAL_PROTOCOL_SP(32); #if HAS_BED_PROBE - if (zero_std_dev >= test_precision && !_1p_calibration) + if (zero_std_dev >= test_precision && !_1p_calibration && !_0p_calibration) SERIAL_PROTOCOLPGM("rolling back."); else #endif @@ -652,11 +690,11 @@ void GcodeSuite::G33() { else sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev_min)); lcd_setstatus(mess); - print_G33_settings(_endstop_results, _angle_results); + print_calibration_settings(_endstop_results, _angle_results); serialprintPGM(save_message); SERIAL_EOL(); } - else { // !end iterations + else { // !end iterations char mess[15]; if (iterations < 31) sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations); @@ -669,11 +707,11 @@ void GcodeSuite::G33() { SERIAL_EOL(); lcd_setstatus(mess); if (verbose_level > 1) - print_G33_settings(_endstop_results, _angle_results); + print_calibration_settings(_endstop_results, _angle_results); } } - else { // dry run - PGM_P enddryrun = PSTR("End DRY-RUN"); + else { // dry run + const char *enddryrun = PSTR("End DRY-RUN"); serialprintPGM(enddryrun); SERIAL_PROTOCOL_SP(35); SERIAL_PROTOCOLPGM("std dev:"); @@ -689,16 +727,11 @@ void GcodeSuite::G33() { sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev)); lcd_setstatus(mess); } - - endstops.enable(true); - if (!home_delta()) - return; - endstops.not_homing(); - + if (!ac_home()) return; } while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); - G33_CLEANUP(); + AC_CLEANUP(); } #endif // DELTA_AUTO_CALIBRATION diff --git a/Marlin/src/gcode/calibrate/M665.cpp b/Marlin/src/gcode/calibrate/M665.cpp index 902556460d..75d01b849a 100644 --- a/Marlin/src/gcode/calibrate/M665.cpp +++ b/Marlin/src/gcode/calibrate/M665.cpp @@ -40,7 +40,7 @@ * B = delta calibration radius * X = Alpha (Tower 1) angle trim * Y = Beta (Tower 2) angle trim - * Z = Rotate A and B by this angle + * Z = Gamma (Tower 3) angle trim */ void GcodeSuite::M665() { if (parser.seen('H')) delta_height = parser.value_linear_units(); diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index eebcc4f235..c8b072a238 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -202,7 +202,7 @@ * M600 - Pause for filament change: "M600 X Y Z E L". (Requires ADVANCED_PAUSE_FEATURE) * M603 - Configure filament change: "M603 T U L". (Requires ADVANCED_PAUSE_FEATURE) * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) - * M665 - Set delta configurations: "M665 L R S A B C I J K" (Requires DELTA) + * M665 - Set delta configurations: "M665 H L R S B X Y Z (Requires DELTA) * M666 - Set/get offsets for delta (Requires DELTA) or dual endstops (Requires [XYZ]_DUAL_ENDSTOPS). * M701 - Load filament (requires FILAMENT_LOAD_UNLOAD_GCODES) * M702 - Unload filament (requires FILAMENT_LOAD_UNLOAD_GCODES) diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index b5f2d770eb..9b10c4edf0 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -870,6 +870,9 @@ #ifndef MSG_DELTA_HEIGHT_CALIBRATE #define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Set Delta Height") #endif +#ifndef MSG_DELTA_Z_OFFSET_CALIBRATE + #define MSG_DELTA_Z_OFFSET_CALIBRATE _UxGT("Probe Z-offset") +#endif #ifndef MSG_DELTA_DIAG_ROD #define MSG_DELTA_DIAG_ROD _UxGT("Diag Rod") #endif diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index 69c014280c..c2cf1a1723 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -2712,29 +2712,22 @@ void kill_screen(const char* lcd_msg) { float move_menu_scale; - #if ENABLED(DELTA_CALIBRATION_MENU) || (ENABLED(DELTA_AUTO_CALIBRATION) && !HAS_BED_PROBE) + #if ENABLED(DELTA_CALIBRATION_MENU) || ENABLED(DELTA_AUTO_CALIBRATION) void lcd_move_z(); void _man_probe_pt(const float &rx, const float &ry) { - #if HAS_LEVELING - reset_bed_level(); // After calibration bed-level data is no longer valid - #endif - - line_to_z((Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5); - current_position[X_AXIS] = rx; - current_position[Y_AXIS] = ry; - line_to_current_z(); - line_to_z(Z_CLEARANCE_BETWEEN_PROBES); + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + do_blocking_move_to_xy(rx, ry); lcd_synchronize(); move_menu_scale = PROBE_MANUALLY_STEP; lcd_goto_screen(lcd_move_z); } - #endif // DELTA_CALIBRATION_MENU || (DELTA_AUTO_CALIBRATION && !HAS_BED_PROBE) + #endif // DELTA_CALIBRATION_MENU || DELTA_AUTO_CALIBRATION - #if ENABLED(DELTA_AUTO_CALIBRATION) && !HAS_BED_PROBE + #if ENABLED(DELTA_AUTO_CALIBRATION) float lcd_probe_pt(const float &rx, const float &ry) { _man_probe_pt(rx, ry); @@ -2747,7 +2740,7 @@ void kill_screen(const char* lcd_msg) { return current_position[Z_AXIS]; } - #endif // DELTA_AUTO_CALIBRATION && !HAS_BED_PROBE + #endif // DELTA_AUTO_CALIBRATION #if ENABLED(DELTA_CALIBRATION_MENU) @@ -2759,10 +2752,6 @@ void kill_screen(const char* lcd_msg) { } void _lcd_delta_calibrate_home() { - #if HAS_LEVELING - reset_bed_level(); // After calibration bed-level data is no longer valid - #endif - enqueue_and_echo_commands_P(PSTR("G28")); lcd_goto_screen(_lcd_calibrate_homing); } @@ -2776,18 +2765,25 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(DELTA_CALIBRATION_MENU) || ENABLED(DELTA_AUTO_CALIBRATION) + void _recalc_delta_settings() { + #if HAS_LEVELING + reset_bed_level(); // After changing kinematics bed-level data is no longer valid + #endif + recalc_delta_settings(); + } + void lcd_delta_settings() { START_MENU(); MENU_BACK(MSG_DELTA_CALIBRATE); - MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_DIAG_ROD, &delta_diagonal_rod, delta_diagonal_rod - 5.0, delta_diagonal_rod + 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_HEIGHT, &delta_height, delta_height - 10.0, delta_height + 10.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float43, "Ex", &delta_endstop_adj[A_AXIS], -5.0, 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float43, "Ey", &delta_endstop_adj[B_AXIS], -5.0, 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float43, "Ez", &delta_endstop_adj[C_AXIS], -5.0, 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_RADIUS, &delta_radius, delta_radius - 5.0, delta_radius + 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float43, "Tx", &delta_tower_angle_trim[A_AXIS], -5.0, 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float43, "Ty", &delta_tower_angle_trim[B_AXIS], -5.0, 5.0, recalc_delta_settings); - MENU_ITEM_EDIT_CALLBACK(float43, "Tz", &delta_tower_angle_trim[C_AXIS], -5.0, 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_HEIGHT, &delta_height, delta_height - 10.0, delta_height + 10.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ex", &delta_endstop_adj[A_AXIS], -5.0, 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ey", &delta_endstop_adj[B_AXIS], -5.0, 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ez", &delta_endstop_adj[C_AXIS], -5.0, 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_RADIUS, &delta_radius, delta_radius - 5.0, delta_radius + 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Tx", &delta_tower_angle_trim[A_AXIS], -5.0, 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ty", &delta_tower_angle_trim[B_AXIS], -5.0, 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Tz", &delta_tower_angle_trim[C_AXIS], -5.0, 5.0, _recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_DIAG_ROD, &delta_diagonal_rod, delta_diagonal_rod - 5.0, delta_diagonal_rod + 5.0, _recalc_delta_settings); END_MENU(); } @@ -2797,6 +2793,7 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(DELTA_AUTO_CALIBRATION) MENU_ITEM(gcode, MSG_DELTA_AUTO_CALIBRATE, PSTR("G33")); MENU_ITEM(gcode, MSG_DELTA_HEIGHT_CALIBRATE, PSTR("G33 P1")); + MENU_ITEM(gcode, MSG_DELTA_Z_OFFSET_CALIBRATE, PSTR("G33 P-1")); #if ENABLED(EEPROM_SETTINGS) MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings); MENU_ITEM(function, MSG_LOAD_EEPROM, lcd_load_settings); @@ -4590,7 +4587,7 @@ void kill_screen(const char* lcd_msg) { #if LCD_HEIGHT > _FC_LINES_G + 1 STATIC_ITEM(" "); #endif - HOTEND_STATUS_ITEM(); + HOTEND_STATUS_ITEM(); END_SCREEN(); } @@ -4645,7 +4642,7 @@ void kill_screen(const char* lcd_msg) { case ADVANCED_PAUSE_MESSAGE_OPTION: advanced_pause_menu_response = ADVANCED_PAUSE_RESPONSE_WAIT_FOR; return lcd_advanced_pause_option_menu; #if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE) - case ADVANCED_PAUSE_MESSAGE_CONTINUOUS_PURGE: return lcd_advanced_pause_continuous_purge_menu; + case ADVANCED_PAUSE_MESSAGE_CONTINUOUS_PURGE: return lcd_advanced_pause_continuous_purge_menu; #endif case ADVANCED_PAUSE_MESSAGE_STATUS: default: break; diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h index c9373fd0b4..3d6e5b7635 100644 --- a/Marlin/src/lcd/ultralcd.h +++ b/Marlin/src/lcd/ultralcd.h @@ -148,10 +148,6 @@ float lcd_z_offset_edit(); #endif - #if ENABLED(DELTA_AUTO_CALIBRATION) && !HAS_BED_PROBE - float lcd_probe_pt(const float &rx, const float &ry); - #endif - #else inline void lcd_buttons_update() {} diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 76e5f3483e..ecd31a7ea5 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -617,7 +617,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS }, safe_delay(5); //*/ #endif - + // Get the current position as starting point float raw[XYZE]; COPY(raw, current_position); @@ -1349,12 +1349,12 @@ void homeaxis(const AxisEnum axis) { // so here it re-homes each tower in turn. // Delta homing treats the axes as normal linear axes. - // retrace by the amount specified in delta_endstop_adj + additional 0.1mm in order to have minimum steps + // retrace by the amount specified in delta_endstop_adj + additional dist in order to have minimum steps if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("delta_endstop_adj:"); #endif - do_homing_move(axis, delta_endstop_adj[axis] - 0.1 * Z_HOME_DIR); + do_homing_move(axis, delta_endstop_adj[axis] - MIN_STEPS_PER_SEGMENT / planner.axis_steps_per_mm[axis] * Z_HOME_DIR); } #else diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 932bb3f4b2..3c1a27cb55 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -673,8 +673,9 @@ float probe_pt(const float &rx, const float &ry, const ProbePtRaise raise_after/ if (!DEPLOY_PROBE()) { measured_z = run_z_probe() + zprobe_zoffset; - if (raise_after == PROBE_PT_RAISE) - do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + const bool big_raise = raise_after == PROBE_PT_BIG_RAISE; + if (big_raise || raise_after == PROBE_PT_RAISE) + do_blocking_move_to_z(current_position[Z_AXIS] + (big_raise ? 25 : Z_CLEARANCE_BETWEEN_PROBES), MMM_TO_MMS(Z_PROBE_SPEED_FAST)); else if (raise_after == PROBE_PT_STOW) if (STOW_PROBE()) measured_z = NAN; } diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h index 655fad8701..cfc3141e02 100644 --- a/Marlin/src/module/probe.h +++ b/Marlin/src/module/probe.h @@ -38,7 +38,8 @@ enum ProbePtRaise : unsigned char { PROBE_PT_NONE, // No raise or stow after run_z_probe PROBE_PT_STOW, // Do a complete stow after run_z_probe - PROBE_PT_RAISE // Raise to "between" clearance after run_z_probe + PROBE_PT_RAISE, // Raise to "between" clearance after run_z_probe + PROBE_PT_BIG_RAISE // Raise to big clearance after run_z_probe }; float probe_pt(const float &rx, const float &ry, const ProbePtRaise raise_after=PROBE_PT_NONE, const uint8_t verbose_level=0, const bool probe_relative=true); #define DEPLOY_PROBE() set_probe_deployed(true)