diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index b4490e93..22a8d7b9 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/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 diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h index 7ca93c95..c539d4b5 100644 --- a/Firmware/mesh_bed_calibration.h +++ b/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 */ diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 9293c2e8..e738c353 100644 --- a/Firmware/xyzcal.cpp +++ b/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(); diff --git a/Firmware/xyzcal.h b/Firmware/xyzcal.h index 348ff3ce..8f908bbe 100644 --- a/Firmware/xyzcal.h +++ b/Firmware/xyzcal.h @@ -1,9 +1,9 @@ //xyzcal.h - xyz calibration with image processing -#ifndef _XYZCAL_H -#define _XYZCAL_H +#pragma once #include +#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();