Browse Source

Calibration: detect biased PINDA and retry calibration

PFW-1223
espr14 3 years ago
parent
commit
99206884b5
4 changed files with 84 additions and 37 deletions
  1. 32 11
      Firmware/mesh_bed_calibration.cpp
  2. 9 8
      Firmware/mesh_bed_calibration.h
  3. 40 8
      Firmware/xyzcal.cpp
  4. 3 10
      Firmware/xyzcal.h

+ 32 - 11
Firmware/mesh_bed_calibration.cpp

@@ -1,4 +1,3 @@
-#include "Marlin.h"
 #include "Configuration.h"
 #include "ConfigurationStore.h"
 #include "language.h"
@@ -1065,7 +1064,7 @@ error:
 }
 
 #ifdef NEW_XYZCAL
-bool xyzcal_find_bed_induction_sensor_point_xy();
+BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy();
 #endif //NEW_XYZCAL
 // Search around the current_position[X,Y],
 // look for the induction sensor response.
@@ -1081,7 +1080,7 @@ bool xyzcal_find_bed_induction_sensor_point_xy();
 #endif //HEATBED_V2
 
 #ifdef HEATBED_V2
-bool find_bed_induction_sensor_point_xy(int
+BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int
 #if !defined (NEW_XYZCAL) && defined (SUPPORT_VERBOSITY)
         verbosity_level
 #endif
@@ -1137,7 +1136,7 @@ bool find_bed_induction_sensor_point_xy(int
 
 		//        go_xyz(current_position[X_AXIS], current_position[Y_AXIS], MESH_HOME_Z_SEARCH, homing_feedrate[Z_AXIS]/60);
 		go_xyz(x0, y0, current_position[Z_AXIS], feedrate);
-		// Continously lower the Z axis.
+		// Continuously lower the Z axis.
 		endstops_hit_on_purpose();
 		enable_z_endstop(true);
 		bool direction = false;
@@ -1335,7 +1334,7 @@ bool find_bed_induction_sensor_point_xy(int
 #endif //NEW_XYZCAL
 }
 #else //HEATBED_V2
-bool find_bed_induction_sensor_point_xy(int verbosity_level)
+BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level)
 {
 #ifdef NEW_XYZCAL
 	return xyzcal_find_bed_induction_sensor_point_xy();
@@ -1531,7 +1530,9 @@ bool find_bed_induction_sensor_point_xy(int verbosity_level)
 	}
 
 	enable_z_endstop(false);
-	return found;
+    if (found)
+        return BED_SKEW_OFFSET_DETECTION_POINT_FOUND;
+    return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
 #endif //NEW_XYZCAL
 }
 
@@ -2238,9 +2239,15 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
 
     // Collect the rear 2x3 points.
 	current_position[Z_AXIS] = MESH_HOME_Z_SEARCH + FIND_BED_INDUCTION_SENSOR_POINT_Z_STEP * iteration * 0.3;
-	for (int k = 0; k < 4; ++k) {
-		// Don't let the manage_inactivity() function remove power from the motors.
-		refresh_cmd_timeout();
+
+    /// Retry point scanning if a point with bad data appears.
+    /// Bad data could be cause by "cold" sensor.
+    /// This behavior vanishes after few point scans so retry will help.
+    for (int retries = 0; retries <= 1; ++retries) {
+        bool retry = false;
+        for (int k = 0; k < 4; ++k) {
+            // Don't let the manage_inactivity() function remove power from the motors.
+            refresh_cmd_timeout();
 #ifdef MESH_BED_CALIBRATION_SHOW_LCD
 		lcd_set_cursor(0, next_line);
 		lcd_print(k + 1);
@@ -2304,8 +2311,19 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
 		if (verbosity_level >= 10)
 			delay_keep_alive(3000);
 		#endif // SUPPORT_VERBOSITY
-		if (!find_bed_induction_sensor_point_xy(verbosity_level))
-			return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
+
+        BedSkewOffsetDetectionResultType result;
+        result = find_bed_induction_sensor_point_xy(verbosity_level);
+        switch(result){
+            case BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND:
+                return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
+            case BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED:
+                retry = true;
+                break;
+            default:
+                break;
+        }
+
 #ifndef NEW_XYZCAL
 #ifndef HEATBED_V2
 		
@@ -2380,6 +2398,9 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
 			}
 			#endif // SUPPORT_VERBOSITY
         }
+        if (!retry)
+            break;
+    }
         DBG(_n("All 4 calibration points found.\n"));
         delay_keep_alive(0); //manage_heater, reset watchdog, manage inactivity
 		

+ 9 - 8
Firmware/mesh_bed_calibration.h

@@ -1,5 +1,6 @@
-#ifndef MESH_BED_CALIBRATION_H
-#define MESH_BED_CALIBRATION_H
+#pragma once
+
+#include "Marlin.h"
 
 #define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1
 #define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4.f) // -0.6 + 5 + 4 = 8.4
@@ -145,11 +146,6 @@ inline bool world2machine_clamp(float &x, float &y)
         machine2world(tmpx, tmpy, x, y);
     return clamped;
 }
-
-bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0);
-bool find_bed_induction_sensor_point_xy(int verbosity_level = 0);
-void go_home_with_z_lift();
-
 /**
  * @brief Bed skew and offest detection result
  *
@@ -159,8 +155,10 @@ void go_home_with_z_lift();
 
 enum BedSkewOffsetDetectionResultType {
 	// Detection failed, some point was not found.
+	BED_SKEW_OFFSET_DETECTION_POINT_FOUND       =  0, //!< Point found
 	BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND   = -1, //!< Point not found.
 	BED_SKEW_OFFSET_DETECTION_FITTING_FAILED    = -2, //!< Fitting failed
+	BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED = -3, //!< Point scan failed, try again
 	
 	// Detection finished with success.
 	BED_SKEW_OFFSET_DETECTION_PERFECT 			= 0,  //!< Perfect.
@@ -168,6 +166,10 @@ enum BedSkewOffsetDetectionResultType {
 	BED_SKEW_OFFSET_DETECTION_SKEW_EXTREME		= 2   //!< Extremely skewed.
 };
 
+bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0);
+BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level = 0);
+void go_home_with_z_lift();
+
 extern BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level, uint8_t &too_far_mask);
 #ifndef NEW_XYZCAL
 extern BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8_t verbosity_level, uint8_t &too_far_mask);
@@ -213,4 +215,3 @@ extern void mbl_settings_init();
 
 extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bool zigzag);
 extern void mbl_interpolation(uint8_t meas_points);
-#endif /* MESH_BED_CALIBRATION_H */

+ 40 - 8
Firmware/xyzcal.cpp

@@ -837,7 +837,7 @@ void dynamic_circle(uint8_t *matrix_32x32, float &x, float &y, float &r, uint8_t
 	for (int8_t i = iterations; i > 0; --i){
 	
         //@size=128B
-		DBG(_n(" [%f, %f][%f] circle\n"), x, y, r);
+		// DBG(_n(" [%f, %f][%f] circle\n"), x, y, r);
 
 		/// read points on the circle
 		for (uint8_t p = 0; p < num_points; ++p){
@@ -904,12 +904,42 @@ uint8_t find_patterns(uint8_t *matrix32, uint16_t *pattern08, uint16_t *pattern1
 	return match10;
 }
 
+/// Scan should include normal data.
+/// If it's too extreme (00, FF) it could be caused by biased sensor.
+/// \return true if data looks normal
+bool check_scan(uint8_t *matrix32){
+	/// magic constants that define normality
+	const int16_t threshold_total = 900;
+	const int threshold_extreme = 50;
+
+	int16_t mins = 0;
+	int16_t maxs = 0;
+
+	for (int16_t i = 0; i < 32*32;++i){
+		if (matrix32[i] == 0) {
+			++mins;
+		} else {
+			++maxs;
+		}
+	}
+	const int16_t rest = 1024 - mins - maxs;
+
+	if (mins + maxs > threshold_total
+		&& mins > threshold_extreme
+		&& maxs > threshold_extreme
+		&& mins > rest
+		&& maxs > rest)
+		return false;
+
+	return true;
+}
+
 /// scans area around the current head location and
 /// searches for the center of the calibration pin
-bool xyzcal_scan_and_process(void){
+BedSkewOffsetDetectionResultType xyzcal_scan_and_process(){
     //@size=44
-	DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE);
-	bool ret = false;
+	// DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE);
+	BedSkewOffsetDetectionResultType ret = BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
 	int16_t x = _X;
 	int16_t y = _Y;
 	const int16_t z = _Z;
@@ -925,6 +955,8 @@ bool xyzcal_scan_and_process(void){
 
 	xyzcal_scan_pixels_32x32_Zhop(x, y, z, 2400, 200, matrix32);
 	print_image(matrix32);
+	if (!check_scan(matrix32))
+		return BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED;
 
 	/// SEARCH FOR BINARY CIRCLE
 	uint8_t uc = 0;
@@ -955,7 +987,7 @@ bool xyzcal_scan_and_process(void){
 		x = round_to_i16(xf);
 		y = round_to_i16(yf);
 		xyzcal_lineXYZ_to(x, y, z, 200, 0);
-		ret = true;
+		ret = BED_SKEW_OFFSET_DETECTION_POINT_FOUND;
 	}
 
 	/// wipe buffer
@@ -964,11 +996,11 @@ bool xyzcal_scan_and_process(void){
 	return ret;
 }
 
-bool xyzcal_find_bed_induction_sensor_point_xy(void){
-	bool ret = false;
+BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy(void){
+	BedSkewOffsetDetectionResultType ret = BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
 
     //@size=258
-    DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
+    // DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
 	st_synchronize();
 
 	xyzcal_meassure_enter();

+ 3 - 10
Firmware/xyzcal.h

@@ -1,9 +1,9 @@
 //xyzcal.h - xyz calibration with image processing
-#ifndef _XYZCAL_H
-#define _XYZCAL_H
+#pragma once
 
 #include <inttypes.h>
 
+#include "mesh_bed_calibration.h"
 
 extern void xyzcal_meassure_enter(void);
 
@@ -17,11 +17,4 @@ extern bool xyzcal_spiral8(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16
 
 //extern int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t samples);
 
-extern bool xyzcal_searchZ(void);
-
-extern bool xyzcal_scan_and_process(void);
-
-extern bool xyzcal_find_bed_induction_sensor_point_xy(void);
-
-
-#endif //_XYZCAL_H
+extern BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy();