Probe Offset Wizard improvements (#20239)
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							c86ede8cfb
						
					
				
				
					commit
					0c24347cdb
				
			| @@ -1084,8 +1084,14 @@ | ||||
|   #if HAS_BED_PROBE | ||||
|     //#define PROBE_OFFSET_WIZARD | ||||
|     #if ENABLED(PROBE_OFFSET_WIZARD) | ||||
|       #define PROBE_OFFSET_START -4.0   // Estimated nozzle-to-probe Z offset, plus a little extra | ||||
|       //#define PROBE_OFFSET_WIZARD_XY_POS XY_CENTER // Set a convenient position to do the measurement | ||||
|       // | ||||
|       // Enable to init the Probe Z-Offset when starting the Wizard. | ||||
|       // Use the estimated nozzle-to-probe Z offset, plus a little more. | ||||
|       // | ||||
|       //#define PROBE_OFFSET_WIZARD_START_Z -4.0 | ||||
|  | ||||
|       // Set a convenient position to do the calibration (probing point and nozzle/bed-distance) | ||||
|       //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER } | ||||
|     #endif | ||||
|   #endif | ||||
|  | ||||
|   | ||||
| @@ -324,7 +324,7 @@ void GcodeSuite::G28() { | ||||
|         ? 0 | ||||
|         : (parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT); | ||||
|  | ||||
|     if (z_homing_height && (doX || doY || (ENABLED(Z_SAFE_HOMING) && doZ))) { | ||||
|     if (z_homing_height && (doX || doY || TERN0(Z_SAFE_HOMING, doZ))) { | ||||
|       // Raise Z before homing any other axes and z is not already high enough (never lower z) | ||||
|       if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height); | ||||
|       do_z_clearance(z_homing_height, true, DISABLED(UNKNOWN_Z_NO_RAISE)); | ||||
| @@ -337,7 +337,7 @@ void GcodeSuite::G28() { | ||||
|     #endif | ||||
|  | ||||
|     // Home Y (before X) | ||||
|     if (ENABLED(HOME_Y_BEFORE_X) && (doY || (ENABLED(CODEPENDENT_XY_HOMING) && doX))) | ||||
|     if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX))) | ||||
|       homeaxis(Y_AXIS); | ||||
|  | ||||
|     // Home X | ||||
|   | ||||
| @@ -525,6 +525,8 @@ | ||||
|   #error "EVENT_GCODE_SD_STOP is now EVENT_GCODE_SD_ABORT." | ||||
| #elif defined(GRAPHICAL_TFT_ROTATE_180) | ||||
|   #error "GRAPHICAL_TFT_ROTATE_180 is now TFT_ROTATION set to TFT_ROTATE_180." | ||||
| #elif defined(PROBE_OFFSET_START) | ||||
|   #error "PROBE_OFFSET_START is now PROBE_OFFSET_WIZARD_START_Z." | ||||
| #elif defined(POWER_LOSS_PULL) | ||||
|   #error "POWER_LOSS_PULL is now specifically POWER_LOSS_PULL(UP|DOWN)." | ||||
| #elif defined(FIL_RUNOUT_INVERTING) | ||||
| @@ -1345,25 +1347,32 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | ||||
|     #error "Z_MIN_PROBE_PIN must be defined if Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN is not enabled." | ||||
|   #endif | ||||
|  | ||||
|   /** | ||||
|    * Check for improper NOZZLE_TO_PROBE_OFFSET | ||||
|    */ | ||||
|   constexpr xyz_pos_t sanity_nozzle_to_probe_offset = NOZZLE_TO_PROBE_OFFSET; | ||||
|   #if ENABLED(NOZZLE_AS_PROBE) | ||||
|     constexpr float sanity_nozzle_to_probe_offset[] = NOZZLE_TO_PROBE_OFFSET; | ||||
|     static_assert(sanity_nozzle_to_probe_offset[0] == 0.0 && sanity_nozzle_to_probe_offset[1] == 0.0, | ||||
|                   "NOZZLE_AS_PROBE requires the X,Y offsets in NOZZLE_TO_PROBE_OFFSET to be 0,0."); | ||||
|   #endif | ||||
|  | ||||
|   #if DISABLED(NOZZLE_AS_PROBE) | ||||
|     static_assert(PROBING_MARGIN >= 0, "PROBING_MARGIN must be >= 0."); | ||||
|     static_assert(PROBING_MARGIN_BACK >= 0, "PROBING_MARGIN_BACK must be >= 0."); | ||||
|     static_assert(sanity_nozzle_to_probe_offset.x == 0 && sanity_nozzle_to_probe_offset.y == 0, | ||||
|                   "NOZZLE_AS_PROBE requires the XY offsets in NOZZLE_TO_PROBE_OFFSET to both be 0."); | ||||
|   #else | ||||
|     static_assert(sanity_nozzle_to_probe_offset.z <= 0.25, | ||||
|                   "Are you sure your Probe triggers above the nozzle? Set a negative Z value in the NOZZLE_TO_PROBE_OFFSET."); | ||||
|     #ifdef PROBE_OFFSET_WIZARD_START_Z | ||||
|       static_assert(PROBE_OFFSET_WIZARD_START_Z <= 0.25, | ||||
|                     "Are you sure your Probe triggers above the nozzle? Set a negative value for PROBE_OFFSET_WIZARD_START_Z."); | ||||
|     #endif | ||||
|     static_assert(PROBING_MARGIN       >= 0, "PROBING_MARGIN must be >= 0."); | ||||
|     static_assert(PROBING_MARGIN_BACK  >= 0, "PROBING_MARGIN_BACK must be >= 0."); | ||||
|     static_assert(PROBING_MARGIN_FRONT >= 0, "PROBING_MARGIN_FRONT must be >= 0."); | ||||
|     static_assert(PROBING_MARGIN_LEFT >= 0, "PROBING_MARGIN_LEFT must be >= 0."); | ||||
|     static_assert(PROBING_MARGIN_LEFT  >= 0, "PROBING_MARGIN_LEFT must be >= 0."); | ||||
|     static_assert(PROBING_MARGIN_RIGHT >= 0, "PROBING_MARGIN_RIGHT must be >= 0."); | ||||
|   #endif | ||||
|  | ||||
|   #define _MARGIN(A) TERN(IS_SCARA, SCARA_PRINTABLE_RADIUS, TERN(DELTA, DELTA_PRINTABLE_RADIUS, ((A##_BED_SIZE) / 2))) | ||||
|   static_assert(PROBING_MARGIN < _MARGIN(X), "PROBING_MARGIN is too large."); | ||||
|   static_assert(PROBING_MARGIN_BACK < _MARGIN(Y), "PROBING_MARGIN_BACK is too large."); | ||||
|   static_assert(PROBING_MARGIN       < _MARGIN(X), "PROBING_MARGIN is too large."); | ||||
|   static_assert(PROBING_MARGIN_BACK  < _MARGIN(Y), "PROBING_MARGIN_BACK is too large."); | ||||
|   static_assert(PROBING_MARGIN_FRONT < _MARGIN(Y), "PROBING_MARGIN_FRONT is too large."); | ||||
|   static_assert(PROBING_MARGIN_LEFT < _MARGIN(X), "PROBING_MARGIN_LEFT is too large."); | ||||
|   static_assert(PROBING_MARGIN_LEFT  < _MARGIN(X), "PROBING_MARGIN_LEFT is too large."); | ||||
|   static_assert(PROBING_MARGIN_RIGHT < _MARGIN(X), "PROBING_MARGIN_RIGHT is too large."); | ||||
|   #undef _MARGIN | ||||
|  | ||||
|   | ||||
| @@ -673,6 +673,8 @@ namespace Language_en { | ||||
|   PROGMEM Language_Str MSG_REHEATING                       = _UxGT("Reheating..."); | ||||
|  | ||||
|   PROGMEM Language_Str MSG_PROBE_WIZARD                    = _UxGT("Z Probe Wizard"); | ||||
|   PROGMEM Language_Str MSG_PROBE_WIZARD_PROBING            = _UxGT("Probing Z Reference"); | ||||
|   PROGMEM Language_Str MSG_PROBE_WIZARD_MOVING             = _UxGT("Moving to Probing Pos"); | ||||
|  | ||||
|   PROGMEM Language_Str MSG_SOUND                           = _UxGT("Sound"); | ||||
|  | ||||
|   | ||||
| @@ -624,7 +624,7 @@ public: | ||||
|   // | ||||
|   // Special handling if a move is underway | ||||
|   // | ||||
|   #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION) || (ENABLED(LCD_BED_LEVELING) && EITHER(PROBE_MANUALLY, MESH_BED_LEVELING)) || (ENABLED(PROBE_OFFSET_WIZARD) && defined(PROBE_OFFSET_WIZARD_XY_POS)) | ||||
|   #if ANY(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION, PROBE_OFFSET_WIZARD) || (ENABLED(LCD_BED_LEVELING) && EITHER(PROBE_MANUALLY, MESH_BED_LEVELING)) | ||||
|     #define LCD_HAS_WAIT_FOR_MOVE 1 | ||||
|     static bool wait_for_move; | ||||
|   #else | ||||
|   | ||||
| @@ -220,7 +220,7 @@ void _lcd_draw_homing(); | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(PROBE_OFFSET_WIZARD) | ||||
|   void home_and_goto_probe_offset_wizard(); | ||||
|   void goto_probe_offset_wizard(); | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS)) | ||||
|   | ||||
| @@ -488,7 +488,7 @@ void menu_backlash(); | ||||
|       EDIT_ITEM(LCD_Z_OFFSET_TYPE, MSG_ZPROBE_ZOFFSET, &probe.offset.z, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); | ||||
|  | ||||
|       #if ENABLED(PROBE_OFFSET_WIZARD) | ||||
|         SUBMENU(MSG_PROBE_WIZARD, home_and_goto_probe_offset_wizard); | ||||
|         SUBMENU(MSG_PROBE_WIZARD, goto_probe_offset_wizard); | ||||
|       #endif | ||||
|  | ||||
|       END_MENU(); | ||||
|   | ||||
| @@ -28,12 +28,6 @@ | ||||
|  | ||||
| #if ENABLED(PROBE_OFFSET_WIZARD) | ||||
|  | ||||
| #ifndef PROBE_OFFSET_START | ||||
|   #error "PROBE_OFFSET_WIZARD requires a PROBE_OFFSET_START with a negative value." | ||||
| #else | ||||
|   static_assert(PROBE_OFFSET_START < 0, "PROBE_OFFSET_START must be < 0. Please update your configuration."); | ||||
| #endif | ||||
|  | ||||
| #include "menu_item.h" | ||||
| #include "menu_addon.h" | ||||
| #include "../../gcode/queue.h" | ||||
| @@ -46,21 +40,20 @@ | ||||
| #endif | ||||
|  | ||||
| // Global storage | ||||
| float z_offset_backup, calculated_z_offset; | ||||
| float z_offset_backup, calculated_z_offset, z_offset_ref; | ||||
|  | ||||
| TERN_(HAS_LEVELING, bool leveling_was_active); | ||||
|  | ||||
| void prepare_for_calibration() { | ||||
|   z_offset_backup = probe.offset.z; | ||||
|  | ||||
|   // Disable soft endstops for free Z movement | ||||
|   SET_SOFT_ENDSTOP_LOOSE(true); | ||||
|  | ||||
|   // Disable leveling for raw planner motion | ||||
|   #if HAS_LEVELING | ||||
|     leveling_was_active = planner.leveling_active; | ||||
|     set_bed_leveling_enabled(false); | ||||
|   #endif | ||||
| inline void z_clearance_move() { | ||||
|   do_z_clearance( | ||||
|     #ifdef Z_AFTER_HOMING | ||||
|       Z_AFTER_HOMING | ||||
|     #elif defined(Z_HOMING_HEIGHT) | ||||
|       Z_HOMING_HEIGHT | ||||
|     #else | ||||
|       10 | ||||
|     #endif | ||||
|   ); | ||||
| } | ||||
|  | ||||
| void set_offset_and_go_back(const float &z) { | ||||
| @@ -77,7 +70,7 @@ void _goto_manual_move_z(const float scale) { | ||||
|  | ||||
| void probe_offset_wizard_menu() { | ||||
|   START_MENU(); | ||||
|   calculated_z_offset = probe.offset.z + current_position.z; | ||||
|   calculated_z_offset = probe.offset.z + current_position.z - z_offset_ref; | ||||
|  | ||||
|   if (LCD_HEIGHT >= 4) | ||||
|     STATIC_ITEM(MSG_MOVE_NOZZLE_TO_BED, SS_CENTER|SS_INVERT); | ||||
| @@ -92,7 +85,7 @@ void probe_offset_wizard_menu() { | ||||
|     char tmp[20], numstr[10]; | ||||
|     // Determine digits needed right of decimal | ||||
|     const uint8_t digs = !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) * 1000 - int((SHORT_MANUAL_Z_MOVE) * 1000)) ? 4 : | ||||
|                           !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) *  100 - int((SHORT_MANUAL_Z_MOVE) *  100)) ? 3 : 2; | ||||
|                          !UNEAR_ZERO((SHORT_MANUAL_Z_MOVE) *  100 - int((SHORT_MANUAL_Z_MOVE) *  100)) ? 3 : 2; | ||||
|     sprintf_P(tmp, GET_TEXT(MSG_MOVE_Z_DIST), dtostrf(SHORT_MANUAL_Z_MOVE, 1, digs, numstr)); | ||||
|     #if DISABLED(HAS_GRAPHICAL_TFT) | ||||
|       extern const char NUL_STR[]; | ||||
| @@ -107,47 +100,86 @@ void probe_offset_wizard_menu() { | ||||
|  | ||||
|   ACTION_ITEM(MSG_BUTTON_DONE, []{ | ||||
|     set_offset_and_go_back(calculated_z_offset); | ||||
|     do_z_clearance(20.0 | ||||
|       #ifdef Z_AFTER_HOMING | ||||
|         - 20.0 + Z_AFTER_HOMING | ||||
|       #endif | ||||
|     ); | ||||
|     current_position.z = z_offset_ref;  // Set Z to z_offset_ref, as we can expect it is at probe height | ||||
|     sync_plan_position(); | ||||
|     z_clearance_move();                 // Raise Z as if it was homed | ||||
|   }); | ||||
|  | ||||
|   ACTION_ITEM(MSG_BUTTON_CANCEL, []{ | ||||
|     set_offset_and_go_back(z_offset_backup); | ||||
|     // If wizard-homing was done by probe with with PROBE_OFFSET_WIZARD_START_Z | ||||
|     #if EITHER(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, USE_PROBE_FOR_Z_HOMING) && defined(PROBE_OFFSET_WIZARD_START_Z) | ||||
|       set_axis_never_homed(Z_AXIS); // On cancel the Z position needs correction | ||||
|       queue.inject_P(PSTR("G28Z")); | ||||
|     #else // Otherwise do a Z clearance move like after Homing | ||||
|       z_clearance_move(); | ||||
|     #endif | ||||
|   }); | ||||
|  | ||||
|   END_MENU(); | ||||
| } | ||||
|  | ||||
| #ifdef PROBE_OFFSET_WIZARD_XY_POS | ||||
| void prepare_for_probe_offset_wizard() { | ||||
|   if (ui.wait_for_move) return; | ||||
|  | ||||
|   #define HAS_PROBE_OFFSET_WIZARD_XY_POS 1 | ||||
|   #if defined(PROBE_OFFSET_WIZARD_XY_POS) || NONE(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, USE_PROBE_FOR_Z_HOMING) | ||||
|     if (ui.should_draw()) MenuItem_static::draw(1, GET_TEXT(MSG_PROBE_WIZARD_PROBING)); | ||||
|  | ||||
|   inline void goto_probe_offset_wizard() { | ||||
|     if (ui.wait_for_move) return; | ||||
|     #ifndef PROBE_OFFSET_WIZARD_XY_POS | ||||
|       #define PROBE_OFFSET_WIZARD_XY_POS XY_CENTER | ||||
|     #endif | ||||
|     // Get X and Y from configuration, or use center | ||||
|     constexpr xy_pos_t wizard_pos = PROBE_OFFSET_WIZARD_XY_POS; | ||||
|     current_position = wizard_pos; | ||||
|  | ||||
|     // Probe for Z reference | ||||
|     ui.wait_for_move = true; | ||||
|     line_to_current_position(MMM_TO_MMS(HOMING_FEEDRATE_XY)); // Could invoke idle() | ||||
|     z_offset_ref = probe.probe_at_point(wizard_pos, PROBE_PT_STOW, 0, true); | ||||
|     ui.wait_for_move = false; | ||||
|     ui.synchronize(); | ||||
|     prepare_for_calibration(); | ||||
|     probe.offset.z = PROBE_OFFSET_START; | ||||
|     ui.goto_screen(probe_offset_wizard_menu); | ||||
|     ui.defer_status_screen(); | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|   #endif | ||||
|  | ||||
| void home_and_goto_probe_offset_wizard() { | ||||
|   // Move Nozzle to Probing/Homing Position | ||||
|   ui.wait_for_move = true; | ||||
|   current_position += probe.offset_xy; | ||||
|   line_to_current_position(MMM_TO_MMS(HOMING_FEEDRATE_XY)); | ||||
|   ui.synchronize(GET_TEXT(MSG_PROBE_WIZARD_MOVING)); | ||||
|   ui.wait_for_move = false; | ||||
|  | ||||
|   // Go to Calibration Menu | ||||
|   ui.goto_screen(probe_offset_wizard_menu); | ||||
|   ui.defer_status_screen(); | ||||
| } | ||||
|  | ||||
| void goto_probe_offset_wizard() { | ||||
|   ui.defer_status_screen(); | ||||
|   set_all_unhomed(); | ||||
|  | ||||
|   // Store probe.offset.z for Case: Cancel | ||||
|   z_offset_backup = probe.offset.z; | ||||
|  | ||||
|   #ifdef PROBE_OFFSET_WIZARD_START_Z | ||||
|     probe.offset.z = PROBE_OFFSET_WIZARD_START_Z; | ||||
|   #endif | ||||
|  | ||||
|   // Store Bed-Leveling-State and disable | ||||
|   #if HAS_LEVELING | ||||
|     leveling_was_active = planner.leveling_active; | ||||
|     set_bed_leveling_enabled(false); | ||||
|   #endif | ||||
|  | ||||
|   // Home all axes | ||||
|   queue.inject_P(G28_STR); | ||||
|  | ||||
|   ui.goto_screen([]{ | ||||
|     _lcd_draw_homing(); | ||||
|     if (all_axes_homed()) | ||||
|       ui.goto_screen(TERN(HAS_PROBE_OFFSET_WIZARD_XY_POS, goto_probe_offset_wizard, probe_offset_wizard_menu)); | ||||
|     if (all_axes_homed()) { | ||||
|       SET_SOFT_ENDSTOP_LOOSE(true); // Disable soft endstops for free Z movement | ||||
|       z_offset_ref = 0;             // Set Z Value for Wizard Position to 0 | ||||
|       ui.goto_screen(prepare_for_probe_offset_wizard); | ||||
|       ui.defer_status_screen(); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // PROBE_OFFSET_WIZARD | ||||
|   | ||||
		Reference in New Issue
	
	Block a user