Browse Source

Improved handling of unknown Z position

- Introduce raise_z_above to move Z carefully when the current position
  is potentially unknown, using stallguard
- Use raise_z_above for:
  * filament loading/unloading clearance
  * extruder spacing when preheating (to avoid buildplate marks on PEI)
  * before homing to avoid damaging the build plate and to avoid
    repeated Z moves as well

Since raise_z_above is conditional, it will only raise when needed.

Calling raise_z_above when the extruder position is unknown and already
at maximum travel is safe and will prevent further vertical moves.
Yuri D'Elia 5 years ago
parent
commit
50231b76da
5 changed files with 69 additions and 29 deletions
  1. 7 1
      Firmware/Configuration.h
  2. 1 1
      Firmware/Marlin.h
  3. 54 24
      Firmware/Marlin_main.cpp
  4. 1 1
      Firmware/mmu.cpp
  5. 6 2
      Firmware/ultralcd.cpp

+ 7 - 1
Firmware/Configuration.h

@@ -345,7 +345,7 @@ your extruder heater takes 2 minutes to hit the target on heating.
   #define Y_PROBE_OFFSET_FROM_EXTRUDER -29
   #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35
 
-  #define Z_RAISE_BEFORE_HOMING 4       // (in mm) Raise Z before homing (G28) for Probe Clearance.
+  #define Z_RAISE_BEFORE_HOMING 5       // (in mm) Raise Z before homing (G28) for Probe Clearance.
                                         // Be sure you have this distance over your Z_MAX_POS in case
 
   #define XY_TRAVEL_SPEED 8000         // X and Y axis travel speed between probes, in mm/min
@@ -549,6 +549,12 @@ enum CalibrationStatus
     CALIBRATION_STATUS_UNKNOWN = 0,
 };
 
+// Try to maintain a minimum distance from the bed even when Z is
+// unknown when doing the following operations
+#define MIN_Z_FOR_LOAD    50
+#define MIN_Z_FOR_UNLOAD  20
+#define MIN_Z_FOR_PREHEAT 10
+
 #include "Configuration_adv.h"
 #include "thermistortables.h"
 

+ 1 - 1
Firmware/Marlin.h

@@ -513,4 +513,4 @@ void M600_wait_for_user(float HotendTempBckp);
 void M600_check_state(float nozzle_temp);
 void load_filament_final_feed();
 void marlin_wait_for_click();
-void marlin_rise_z(void);
+void raise_z_above(float target, bool plan=true);

+ 54 - 24
Firmware/Marlin_main.cpp

@@ -2104,6 +2104,52 @@ bool check_commands() {
 	
 }
 
+
+// raise_z_above: slowly raise Z to the requested height
+//
+// contrarily to a simple move, this function will carefully plan a move
+// when the current Z position is unknown. In such cases, stallguard is
+// enabled and will prevent prolonged pushing against the Z tops
+void raise_z_above(float target, bool plan)
+{
+    if (current_position[Z_AXIS] >= target)
+        return;
+
+    // Z needs raising
+    current_position[Z_AXIS] = target;
+
+    if (axis_known_position[Z_AXIS])
+    {
+        // current position is known, it's safe to raise Z
+        if(plan) plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder);
+        return;
+    }
+
+    // ensure Z is powered in normal mode to overcome initial load
+    enable_z();
+    st_synchronize();
+
+    // rely on crashguard to limit damage
+    bool z_endstop_enabled = enable_z_endstop(true);
+#ifdef TMC2130
+    tmc2130_home_enter(Z_AXIS_MASK);
+#endif //TMC2130
+    plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60, active_extruder);
+    st_synchronize();
+#ifdef TMC2130
+    if (endstop_z_hit_on_purpose())
+    {
+        // not necessarily exact, but will avoid further vertical moves
+        current_position[Z_AXIS] = max_pos[Z_AXIS];
+        plan_set_position(current_position[X_AXIS], current_position[Y_AXIS],
+                          current_position[Z_AXIS], current_position[E_AXIS]);
+    }
+    tmc2130_home_exit();
+#endif //TMC2130
+    enable_z_endstop(z_endstop_enabled);
+}
+
+
 #ifdef TMC2130
 bool calibrate_z_auto()
 {
@@ -2484,9 +2530,7 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
 
 	//if we are homing all axes, first move z higher to protect heatbed/steel sheet
 	if (home_all_axes) {
-		current_position[Z_AXIS] += MESH_HOME_Z_SEARCH;
-		feedrate = homing_feedrate[Z_AXIS];
-		plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
+        raise_z_above(MESH_HOME_Z_SEARCH);
 		st_synchronize();
 	}
 #ifdef ENABLE_AUTO_BED_LEVELING
@@ -2597,26 +2641,21 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
         #ifndef Z_SAFE_HOMING
           if(home_z) {
             #if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
-              destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1);    // Set destination away from bed
-              feedrate = max_feedrate[Z_AXIS];
-              plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
+              raise_z_above(Z_RAISE_BEFORE_HOMING);
               st_synchronize();
             #endif // defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
             #if (defined(MESH_BED_LEVELING) && !defined(MK1BP))  // If Mesh bed leveling, move X&Y to safe position for home
-      			  if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] )) 
-      			  {
-                homeaxis(X_AXIS);
-                homeaxis(Y_AXIS);
-      			  } 
+              raise_z_above(MESH_HOME_Z_SEARCH);
+              st_synchronize();
+              if (!axis_known_position[X_AXIS]) homeaxis(X_AXIS);
+              if (!axis_known_position[Y_AXIS]) homeaxis(Y_AXIS);
               // 1st mesh bed leveling measurement point, corrected.
               world2machine_initialize();
               world2machine(pgm_read_float(bed_ref_points_4), pgm_read_float(bed_ref_points_4+1), destination[X_AXIS], destination[Y_AXIS]);
               world2machine_reset();
               if (destination[Y_AXIS] < Y_MIN_POS)
                   destination[Y_AXIS] = Y_MIN_POS;
-              destination[Z_AXIS] = MESH_HOME_Z_SEARCH;    // Set destination away from bed
-              feedrate = homing_feedrate[Z_AXIS]/10;
-              current_position[Z_AXIS] = 0;
+              feedrate = homing_feedrate[X_AXIS] / 20;
               enable_endstops(false);
 #ifdef DEBUG_BUILD
               SERIAL_ECHOLNPGM("plan_set_position()");
@@ -3143,15 +3182,6 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     custom_message_type = CustomMsg::Status;
 }
 
-//! @brief Rise Z if too low to avoid blob/jam before filament loading
-//!
-//! It doesn't plan_buffer_line(), as it expects plan_buffer_line() to be called after
-//! during extruding (loading) filament.
-void marlin_rise_z(void)
-{
-    if (current_position[Z_AXIS] < 20) current_position[Z_AXIS] += 30;
-}
-
 void gcode_M701()
 {
 	printf_P(PSTR("gcode_M701 begin\n"));
@@ -3180,7 +3210,7 @@ void gcode_M701()
 		plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence
 		st_synchronize();
 
-		marlin_rise_z();
+        raise_z_above(MIN_Z_FOR_LOAD, false);
 		current_position[E_AXIS] += 30;
 		plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence
 		

+ 1 - 1
Firmware/mmu.cpp

@@ -1355,7 +1355,7 @@ void lcd_mmu_load_to_nozzle(uint8_t filament_nr)
         manage_response(true, true, MMU_TCODE_MOVE);
         mmu_continue_loading(false);
         mmu_extruder = tmp_extruder; //filament change is finished
-        marlin_rise_z();
+        raise_z_above(MIN_Z_FOR_LOAD, false);
         mmu_load_to_nozzle();
         load_filament_final_feed();
         st_synchronize();

+ 6 - 2
Firmware/ultralcd.cpp

@@ -2374,9 +2374,11 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
             {
                 lcd_commands_type = LcdCommands::Layer1Cal;
             }
-            else if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
+            else
             {
-                lcd_wizard(WizState::LoadFilHot);
+                raise_z_above(MIN_Z_FOR_PREHEAT);
+                if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
+                    lcd_wizard(WizState::LoadFilHot);
             }
             return;
         }
@@ -6360,6 +6362,8 @@ void unload_filament()
 	custom_message_type = CustomMsg::FilamentLoading;
 	lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
 
+    raise_z_above(MIN_Z_FOR_UNLOAD);
+
 	//		extr_unload2();
 
 	current_position[E_AXIS] -= 45;