From a8f4207df99a3530801addd13aa23349d08c29fb Mon Sep 17 00:00:00 2001 From: espr14 Date: Thu, 17 Dec 2020 18:19:36 +0100 Subject: [PATCH 01/28] New XYZ calibration algorithm --- Firmware/xyzcal.cpp | 814 +++++++++++++++++++------------------------- Firmware/xyzcal.h | 14 - 2 files changed, 358 insertions(+), 470 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 767024db..2130b223 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -9,7 +9,6 @@ #include "temperature.h" #include "sm4.h" - #define XYZCAL_PINDA_HYST_MIN 20 //50um #define XYZCAL_PINDA_HYST_MAX 100 //250um #define XYZCAL_PINDA_HYST_DIF 5 //12.5um @@ -30,13 +29,83 @@ #define _Z ((int16_t)count_position[Z_AXIS]) #define _E ((int16_t)count_position[E_AXIS]) +#define X_PLUS 0 +#define X_MINUS 1 +#define Y_PLUS 0 +#define Y_MINUS 1 +#define Z_PLUS 0 +#define Z_MINUS 1 + #define _PI 3.14159265F +/// \returns positive value always +#define ABS(a) \ + ({ __typeof__ (a) _a = (a); \ + _a >= 0 ? _a : (-_a); }) + +/// \returns maximum of the two +#define MAX(a, b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a >= _b ? _a : _b; }) + +/// \returns minimum of the two +#define MIN(a, b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a <= _b ? _a : _b; }) + +/// swap values +#define SWAP(a, b) \ + ({ __typeof__ (a) c = (a); \ + a = (b); \ + b = c; }) + +/// Saturates value +/// \returns min if value is less than min +/// \returns max if value is more than min +/// \returns value otherwise +#define CLAMP(value, min, max) \ + ({ __typeof__ (value) a_ = (value); \ + __typeof__ (min) min_ = (min); \ + __typeof__ (max) max_ = (max); \ + ( a_ < min_ ? min_ : (a_ <= max_ ? a_ : max_)); }) + +/// position types +typedef int16_t pos_i16_t; +typedef long pos_i32_t; +typedef float pos_mm_t; +typedef int16_t usteps_t; + uint8_t check_pinda_0(); uint8_t check_pinda_1(); void xyzcal_update_pos(uint16_t dx, uint16_t dy, uint16_t dz, uint16_t de); uint16_t xyzcal_calc_delay(uint16_t nd, uint16_t dd); +uint8_t round_to_u8(float f){ + return (uint8_t)(f + .5f); +} + +uint16_t round_to_u16(float f){ + return (uint16_t)(f + .5f); +} + +int16_t round_to_i16(float f){ + return (int16_t)(f + .5f); +} + +/// converts millimeters to integer position +pos_i16_t mm_2_pos(pos_mm_t mm){ + return (pos_i16_t)(0.5f + mm * 100); +} + +/// converts integer position to millimeters +pos_mm_t pos_2_mm(pos_i16_t pos){ + return pos * 0.01f; +} +pos_mm_t pos_2_mm(float pos){ + return pos * 0.01f; +} void xyzcal_meassure_enter(void) { @@ -142,6 +211,7 @@ uint16_t xyzcal_calc_delay(uint16_t, uint16_t) } #endif //SM4_ACCEL_TEST +/// Moves printer to absolute position [x,y,z] defined in integer position system bool xyzcal_lineXYZ_to(int16_t x, int16_t y, int16_t z, uint16_t delay_us, int8_t check_pinda) { // DBG(_n("xyzcal_lineXYZ_to x=%d y=%d z=%d check=%d\n"), x, y, z, check_pinda); @@ -152,12 +222,17 @@ bool xyzcal_lineXYZ_to(int16_t x, int16_t y, int16_t z, uint16_t delay_us, int8_ sm4_set_dir_bits(xyzcal_dm); sm4_stop_cb = check_pinda?((check_pinda<0)?check_pinda_0:check_pinda_1):0; xyzcal_sm4_delay = delay_us; -// uint32_t u = _micros(); - bool ret = sm4_line_xyze_ui(abs(x), abs(y), abs(z), 0)?true:false; -// u = _micros() - u; + // uint32_t u = _micros(); + bool ret = sm4_line_xyze_ui(abs(x), abs(y), abs(z), 0) ? true : false; + // u = _micros() - u; return ret; } +/// Moves printer to absolute position [x,y,z] defined in millimeters +bool xyzcal_lineXYZ_to_float(pos_mm_t x, pos_mm_t y, pos_mm_t z, uint16_t delay_us, int8_t check_pinda){ + return xyzcal_lineXYZ_to(mm_2_pos(x), mm_2_pos(y), mm_2_pos(z), delay_us, check_pinda); +} + bool xyzcal_spiral2(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16_t radius, int16_t rotation, uint16_t delay_us, int8_t check_pinda, uint16_t* pad) { bool ret = false; @@ -171,7 +246,13 @@ bool xyzcal_spiral2(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16_t radi uint8_t k = 720 / (dad_max - dad_min); //delta calculation constant ad = 0; if (pad) ad = *pad % 720; + DBG(_n("xyzcal_spiral2 cx=%d cy=%d z0=%d dz=%d radius=%d ad=%d\n"), cx, cy, z0, dz, radius, ad); + // lcd_set_cursor(0, 4); + // char text[10]; + // snprintf(text, 10, "%4d", z0); + // lcd_print(text); + for (; ad < 720; ad++) { if (radius > 0) @@ -200,6 +281,10 @@ bool xyzcal_spiral2(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16_t radi ad += dad; } if (pad) *pad = ad; + // if(ret){ + // lcd_set_cursor(0, 4); + // lcd_print(" "); + // } return ret; } @@ -275,426 +360,113 @@ int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t d } #endif //XYZCAL_MEASSURE_PINDA_HYSTEREZIS +void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ + if(!pixels) + return; + int16_t z = _Z; + uint16_t line_buffer[32]; + xyzcal_lineXYZ_to(cx, cy, z, delay_us, 0); + for (uint8_t r = 0; r < 32; r++){ ///< Y axis + xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); + for (int8_t d = 0; d < 2; ++d){ ///< direction + + // xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, z, 2 * delay_us, 0); + // xyzcal_lineXYZ_to(_X, _Y, min_z, delay_us, 1); + // xyzcal_lineXYZ_to(_X, _Y, max_z, delay_us, -1); -void xyzcal_scan_pixels_32x32(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels) -{ - DBG(_n("xyzcal_scan_pixels_32x32 cx=%d cy=%d min_z=%d max_z=%d\n"), cx, cy, min_z, max_z); -// xyzcal_lineXYZ_to(cx - 1024, cy - 1024, max_z, 2*delay_us, 0); -// xyzcal_lineXYZ_to(cx, cy, max_z, delay_us, 0); - int16_t z = (int16_t)count_position[2]; - xyzcal_lineXYZ_to(cx, cy, z, 2*delay_us, 0); - for (uint8_t r = 0; r < 32; r++) - { -// int8_t _pinda = _PINDA; - xyzcal_lineXYZ_to((r&1)?(cx+1024):(cx-1024), cy - 1024 + r*64, z, 2*delay_us, 0); - xyzcal_lineXYZ_to(_X, _Y, min_z, delay_us, 1); - xyzcal_lineXYZ_to(_X, _Y, max_z, delay_us, -1); - z = (int16_t)count_position[2]; - sm4_set_dir(X_AXIS, (r&1)?1:0); - for (uint8_t c = 0; c < 32; c++) - { - uint16_t sum = 0; - int16_t z_sum = 0; - for (uint8_t i = 0; i < 64; i++) - { - int8_t pinda = _PINDA; - int16_t pix = z - min_z; - pix += (pinda)?23:-24; - if (pix < 0) pix = 0; - if (pix > 255) pix = 255; - sum += pix; - z_sum += z; -// if (_pinda != pinda) -// { -// if (pinda) -// DBG(_n("!1 x=%d z=%d\n"), c*64+i, z+23); -// else -// DBG(_n("!0 x=%d z=%d\n"), c*64+i, z-24); -// } - sm4_set_dir(Z_AXIS, !pinda); - if (!pinda) - { - if (z > min_z) - { - sm4_do_step(Z_AXIS_MASK); - z--; - } + xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, min_z, delay_us, 0); + + z = _Z; + sm4_set_dir(X_AXIS, d); + for (uint8_t c = 0; c < 32; c++){ ///< X axis + + /// move up to un-trigger (surpress hysteresis) + sm4_set_dir(Z_AXIS, Z_PLUS); + while (z < max_z && _PINDA){ + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us); + z++; } - else - { - if (z < max_z) - { - sm4_do_step(Z_AXIS_MASK); - z++; - } + int16_t last_top_z = z; + + /// move down to trigger + sm4_set_dir(Z_AXIS, Z_MINUS); + while (z > min_z && !_PINDA){ + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us); + z--; + } + + count_position[2] = z; + if (d == 0){ + line_buffer[c] = (uint16_t)(z - min_z); + } else { + /// data reversed in X + // DBG(_n("%04x"), (line_buffer[31 - c] + (z - min_z)) / 2); + /// save average of both directions + pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z - min_z)) / 2); } - sm4_do_step(X_AXIS_MASK); - delayMicroseconds(600); -// _pinda = pinda; - } - sum >>= 6; //div 64 - if (z_sum < 0) - { - z_sum = -z_sum; - z_sum >>= 6; //div 64 - z_sum = -z_sum; - } - else - z_sum >>= 6; //div 64 - if (pixels) pixels[((uint16_t)r<<5) + ((r&1)?(31-c):c)] = sum; -// DBG(_n("c=%d r=%d l=%d z=%d\n"), c, r, sum, z_sum); - count_position[0] += (r&1)?-64:64; - count_position[2] = z; - } - if (pixels) - for (uint8_t c = 0; c < 32; c++) - DBG(_n("%02x"), pixels[((uint16_t)r<<5) + c]); - DBG(_n("\n")); - } -// xyzcal_lineXYZ_to(cx, cy, z, 2*delay_us, 0); -} -void xyzcal_histo_pixels_32x32(uint8_t* pixels, uint16_t* histo) -{ - for (uint8_t l = 0; l < 16; l++) - histo[l] = 0; - for (uint8_t r = 0; r < 32; r++) - for (uint8_t c = 0; c < 32; c++) - { - uint8_t pix = pixels[((uint16_t)r<<5) + c]; - histo[pix >> 4]++; - } - for (uint8_t l = 0; l < 16; l++) - DBG(_n(" %2d %d\n"), l, histo[l]); -} - -void xyzcal_adjust_pixels(uint8_t* pixels, uint16_t* histo) -{ - uint8_t l; - uint16_t max_c = histo[1]; - uint8_t max_l = 1; - for (l = 1; l < 16; l++) - { - uint16_t c = histo[l]; - if (c > max_c) - { - max_c = c; - max_l = l; - } - } - DBG(_n("max_c=%2d max_l=%d\n"), max_c, max_l); - for (l = 14; l > 8; l--) - if (histo[l] >= 10) - break; - uint8_t pix_min = 0; - uint8_t pix_max = l << 4; - if (histo[0] < (32*32 - 144)) - { - pix_min = (max_l << 4) / 2; - } - uint8_t pix_dif = pix_max - pix_min; - DBG(_n(" min=%d max=%d dif=%d\n"), pix_min, pix_max, pix_dif); - for (int16_t i = 0; i < 32*32; i++) - { - uint16_t pix = pixels[i]; - if (pix > pix_min) pix -= pix_min; - else pix = 0; - pix <<= 8; - pix /= pix_dif; -// if (pix < 0) pix = 0; - if (pix > 255) pix = 255; - pixels[i] = (uint8_t)pix; - } - for (uint8_t r = 0; r < 32; r++) - { - for (uint8_t c = 0; c < 32; c++) - DBG(_n("%02x"), pixels[((uint16_t)r<<5) + c]); - DBG(_n("\n")); - } -} - -/* -void xyzcal_draw_pattern_12x12_in_32x32(uint8_t* pattern, uint32_t* pixels, int w, int h, uint8_t x, uint8_t y, uint32_t and, uint32_t or) -{ - for (int i = 0; i < 8; i++) - for (int j = 0; j < 8; j++) - { - int idx = (x + j) + w * (y + i); - if (pattern[i] & (1 << j)) - { - pixels[idx] &= and; - pixels[idx] |= or; + /// move to the next point + xyzcal_lineXYZ_to(((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx, _Y, (last_top_z + z) / 2, delay_us, 0); + z = _Z; } } + // DBG(_n("\n\n")); + } } -*/ -int16_t xyzcal_match_pattern_12x12_in_32x32(uint16_t* pattern, uint8_t* pixels, uint8_t c, uint8_t r) -{ +/// Returns rate of match +/// max match = 132, min match = 0 +uint8_t xyzcal_match_pattern_12x12_in_32x32(uint16_t* pattern, uint8_t* pixels, uint8_t c, uint8_t r){ uint8_t thr = 16; - int16_t match = 0; - for (uint8_t i = 0; i < 12; i++) - for (uint8_t j = 0; j < 12; j++) - { - if (((i == 0) || (i == 11)) && ((j < 2) || (j >= 10))) continue; //skip corners + uint8_t match = 0; + for (uint8_t i = 0; i < 12; ++i){ + for (uint8_t j = 0; j < 12; ++j){ + /// skip corners (3 pixels in each) + if (((i == 0) || (i == 11)) && ((j < 2) || (j >= 10))) continue; if (((j == 0) || (j == 11)) && ((i < 2) || (i >= 10))) continue; - uint16_t idx = (c + j) + 32 * (r + i); - uint8_t val = pixels[idx]; - if (pattern[i] & (1 << j)) - { - if (val > thr) match ++; - else match --; - } - else - { - if (val <= thr) match ++; - else match --; - } + const uint16_t idx = (c + j) + 32 * ((uint16_t)r + i); + const bool high_pix = pixels[idx] > thr; + const bool high_pat = pattern[i] & (1 << j); + if (high_pix == high_pat) + match++; } + } return match; } -int16_t xyzcal_find_pattern_12x12_in_32x32(uint8_t* pixels, uint16_t* pattern, uint8_t* pc, uint8_t* pr) -{ +/// Searches for best match of pattern by shifting it +/// Returns rate of match and the best location +/// max match = 132, min match = 0 +uint8_t xyzcal_find_pattern_12x12_in_32x32(uint8_t* pixels, uint16_t* pattern, uint8_t* pc, uint8_t* pr){ + if (!pixels || !pattern || !pc || !pr) + return -1; uint8_t max_c = 0; uint8_t max_r = 0; - int16_t max_match = 0; - for (uint8_t r = 0; r < (32 - 12); r++) - for (uint8_t c = 0; c < (32 - 12); c++) - { - int16_t match = xyzcal_match_pattern_12x12_in_32x32(pattern, pixels, c, r); - if (max_match < match) - { + uint8_t max_match = 0; + + // DBG(_n("Matching:\n")); + /// pixel precision + for (uint8_t r = 0; r < (32 - 12); ++r){ + for (uint8_t c = 0; c < (32 - 12); ++c){ + const uint8_t match = xyzcal_match_pattern_12x12_in_32x32(pattern, pixels, c, r); + if (max_match < match){ max_c = c; max_r = r; max_match = match; } + // DBG(_n("%d "), match); } - DBG(_n("max_c=%d max_r=%d max_match=%d\n"), max_c, max_r, max_match); - if (pc) *pc = max_c; - if (pr) *pr = max_r; + // DBG(_n("\n")); + } + DBG(_n("max_c=%f max_r=%f max_match=%d pixel\n"), max_c, max_r, max_match); + + *pc = max_c; + *pr = max_r; return max_match; } -#define MAX_DIAMETR 600 -#define XYZCAL_FIND_CENTER_DIAGONAL -int8_t xyzcal_find_point_center2A(int16_t x0, int16_t y0, int16_t z0, uint16_t delay_us); -int8_t xyzcal_find_point_center2(uint16_t delay_us) -{ - printf_P(PSTR("xyzcal_find_point_center2\n")); - int16_t x0 = _X; - int16_t y0 = _Y; - int16_t z0 = _Z; - printf_P(PSTR(" x0=%d\n"), x0); - printf_P(PSTR(" y0=%d\n"), y0); - printf_P(PSTR(" z0=%d\n"), z0); - - xyzcal_lineXYZ_to(_X, _Y, z0 + 400, 500, -1); - xyzcal_lineXYZ_to(_X, _Y, z0 - 400, 500, 1); - xyzcal_lineXYZ_to(_X, _Y, z0 + 400, 500, -1); - xyzcal_lineXYZ_to(_X, _Y, z0 - 400, 500, 1); - - if (has_temperature_compensation()){ - z0 = _Z - 20; // normal PINDA - return xyzcal_find_point_center2A(x0, y0, z0, delay_us); - } else { - // try searching harder, each PINDA is different - for(z0 = _Z - 20; z0 <= _Z + 140; z0 += 20 ){ // alternate PINDA - int8_t rv = xyzcal_find_point_center2A(x0, y0, z0, delay_us); - printf_P(PSTR(" z0=%d"), z0); - if( rv != 0 ){ - printf_P(PSTR("ok\n")); - return rv; - } else { - printf_P(PSTR("fail\n")); - } - } - } -} - -int8_t xyzcal_find_point_center2A(int16_t x0, int16_t y0, int16_t z0, uint16_t delay_us){ - xyzcal_lineXYZ_to(_X, _Y, z0, 500, 0); - -// xyzcal_lineXYZ_to(x0, y0, z0 - 100, 500, 1); -// z0 = _Z; -// printf_P(PSTR(" z0=%d\n"), z0); -// xyzcal_lineXYZ_to(x0, y0, z0 + 100, 500, -1); -// z0 += _Z; -// z0 /= 2; - printf_P(PSTR(" z0=%d\n"), z0); -// xyzcal_lineXYZ_to(x0, y0, z0 - 100, 500, 1); -// z0 = _Z - 10; - - int8_t ret = 1; - -#ifdef XYZCAL_FIND_CENTER_DIAGONAL - int32_t xc = 0; - int32_t yc = 0; - int16_t ad = 45; - for (; ad < 360; ad += 90) - { - float ar = (float)ad * _PI / 180; - int16_t x = x0 + MAX_DIAMETR * cos(ar); - int16_t y = y0 + MAX_DIAMETR * sin(ar); - if (!xyzcal_lineXYZ_to(x, y, z0, delay_us, -1)) - { - printf_P(PSTR("ERROR ad=%d\n"), ad); - ret = 0; - break; - } - xc += _X; - yc += _Y; - xyzcal_lineXYZ_to(x0, y0, z0, delay_us, 0); - } - if (ret) - { - printf_P(PSTR("OK\n"), ad); - x0 = xc / 4; - y0 = yc / 4; - printf_P(PSTR(" x0=%d\n"), x0); - printf_P(PSTR(" y0=%d\n"), y0); - } - -#else //XYZCAL_FIND_CENTER_DIAGONAL - xyzcal_lineXYZ_to(x0 - MAX_DIAMETR, y0, z0, delay_us, -1); - int16_t dx1 = x0 - _X; - if (dx1 >= MAX_DIAMETR) - { - printf_P(PSTR("!!! dx1 = %d\n"), dx1); - return 0; - } - xyzcal_lineXYZ_to(x0, y0, z0, delay_us, 0); - xyzcal_lineXYZ_to(x0 + MAX_DIAMETR, y0, z0, delay_us, -1); - int16_t dx2 = _X - x0; - if (dx2 >= MAX_DIAMETR) - { - printf_P(PSTR("!!! dx2 = %d\n"), dx2); - return 0; - } - xyzcal_lineXYZ_to(x0, y0, z0, delay_us, 0); - xyzcal_lineXYZ_to(x0 , y0 - MAX_DIAMETR, z0, delay_us, -1); - int16_t dy1 = y0 - _Y; - if (dy1 >= MAX_DIAMETR) - { - printf_P(PSTR("!!! dy1 = %d\n"), dy1); - return 0; - } - xyzcal_lineXYZ_to(x0, y0, z0, delay_us, 0); - xyzcal_lineXYZ_to(x0, y0 + MAX_DIAMETR, z0, delay_us, -1); - int16_t dy2 = _Y - y0; - if (dy2 >= MAX_DIAMETR) - { - printf_P(PSTR("!!! dy2 = %d\n"), dy2); - return 0; - } - printf_P(PSTR("dx1=%d\n"), dx1); - printf_P(PSTR("dx2=%d\n"), dx2); - printf_P(PSTR("dy1=%d\n"), dy1); - printf_P(PSTR("dy2=%d\n"), dy2); - - x0 += (dx2 - dx1) / 2; - y0 += (dy2 - dy1) / 2; - - printf_P(PSTR(" x0=%d\n"), x0); - printf_P(PSTR(" y0=%d\n"), y0); - -#endif //XYZCAL_FIND_CENTER_DIAGONAL - - xyzcal_lineXYZ_to(x0, y0, z0, delay_us, 0); - - return ret; -} - -#ifdef XYZCAL_FIND_POINT_CENTER -int8_t xyzcal_find_point_center(int16_t x0, int16_t y0, int16_t z0, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t turns) -{ - uint8_t n; - uint16_t ad; - float ar; - float _cos; - float _sin; - int16_t r_min = 0; - int16_t r_max = 0; - int16_t x_min = 0; - int16_t x_max = 0; - int16_t y_min = 0; - int16_t y_max = 0; - int16_t r = 10; - int16_t x = x0; - int16_t y = y0; - int16_t z = z0; - int8_t _pinda = _PINDA; - for (n = 0; n < turns; n++) - { - uint32_t r_sum = 0; - for (ad = 0; ad < 720; ad++) - { - ar = ad * _PI / 360; - _cos = cos(ar); - _sin = sin(ar); - x = x0 + (int)(_cos * r); - y = y0 + (int)(_sin * r); - xyzcal_lineXYZ_to(x, y, z, 1000, 0); - int8_t pinda = _PINDA; - if (pinda) - r += 1; - else - { - r -= 1; - ad--; - r_sum -= r; - } - if (ad == 0) - { - x_min = x0; - x_max = x0; - y_min = y0; - y_max = y0; - r_min = r; - r_max = r; - } - else if (pinda) - { - if (x_min > x) x_min = (2*x + x_min) / 3; - if (x_max < x) x_max = (2*x + x_max) / 3; - if (y_min > y) y_min = (2*y + y_min) / 3; - if (y_max < y) y_max = (2*y + y_max) / 3; -/* if (x_min > x) x_min = x; - if (x_max < x) x_max = x; - if (y_min > y) y_min = y; - if (y_max < y) y_max = y;*/ - if (r_min > r) r_min = r; - if (r_max < r) r_max = r; - } - r_sum += r; -/* if (_pinda != pinda) - { - if (pinda) - DBG(_n("!1 x=%d y=%d\n"), x, y); - else - DBG(_n("!0 x=%d y=%d\n"), x, y); - }*/ - _pinda = pinda; -// DBG(_n("x=%d y=%d rx=%d ry=%d\n"), x, y, rx, ry); - } - DBG(_n("x_min=%d x_max=%d y_min=%d y_max=%d r_min=%d r_max=%d r_avg=%d\n"), x_min, x_max, y_min, y_max, r_min, r_max, r_sum / 720); - if ((n > 2) && (n & 1)) - { - x0 += (x_min + x_max); - y0 += (y_min + y_max); - x0 /= 3; - y0 /= 3; - int rx = (x_max - x_min) / 2; - int ry = (y_max - y_min) / 2; - r = (rx + ry) / 3;//(rx < ry)?rx:ry; - DBG(_n("x0=%d y0=%d r=%d\n"), x0, y0, r); - } - } - xyzcal_lineXYZ_to(x0, y0, z, 200, 0); -} -#endif //XYZCAL_FIND_POINT_CENTER - - uint8_t xyzcal_xycoords2point(int16_t x, int16_t y) { uint8_t ix = (x > 10000)?1:0; @@ -742,91 +514,221 @@ bool xyzcal_searchZ(void) return false; } -bool xyzcal_scan_and_process(void) -{ +/// returns value of any location within data +/// uses bilinear interpolation +float get_value(uint8_t * matrix_32x32, float c, float r){ + if (c <= 0 || r <= 0 || c >= 31 || r >= 31) + return 0; + + /// calculate weights of nearby points + const float wc1 = c - floor(c); + const float wr1 = r - floor(r); + const float wc0 = 1 - wc1; + const float wr0 = 1 - wr1; + + const float w00 = wc0 * wr0; + const float w01 = wc0 * wr1; + const float w10 = wc1 * wr0; + const float w11 = wc1 * wr1; + + const uint16_t c0 = c; + const uint16_t c1 = c0 + 1; + const uint16_t r0 = r; + const uint16_t r1 = r0 + 1; + + const uint16_t idx00 = c0 + 32 * r0; + const uint16_t idx01 = c0 + 32 * r1; + const uint16_t idx10 = c1 + 32 * r0; + const uint16_t idx11 = c1 + 32 * r1; + + /// bilinear resampling + return w00 * matrix_32x32[idx00] + w01 * matrix_32x32[idx01] + w10 * matrix_32x32[idx10] + w11 * matrix_32x32[idx11]; +} + +const constexpr float m_infinity = -1000.f; + +/// replaces the highest number by m_infinity +void remove_highest(float *points, const uint8_t num_points){ + if (num_points <= 0) + return; + + float max = points[0]; + uint8_t max_i = 0; + for (uint8_t i = 0; i < num_points; ++i){ + if (max < points[i]){ + max = points[i]; + max_i = i; + } + } + points[max_i] = m_infinity; +} + +/// return the highest number in the list +float highest(float *points, const uint8_t num_points){ + if (num_points <= 0) + return 0; + + float max = points[0]; + for (uint8_t i = 0; i < num_points; ++i){ + if (max < points[i]){ + max = points[i]; + } + } + return max; +} + +/// Searches for circle iteratively +/// Uses points on the perimeter. If point is high it pushes circle out of the center (shift or change of radius), +/// otherwise to the center. +/// Algorithm is stopped after fixed number of iterations. Move is limited to 0.5 px per iteration. +void dynamic_circle(uint8_t *matrix_32x32, float &x, float &y, float &r, uint8_t iterations){ + /// circle of 10.5 diameter has 33 in circumference, don't go much above + const constexpr uint8_t num_points = 33; + float points[num_points]; + float pi_2_div_num_points = 2 * M_PI / num_points; + const constexpr uint8_t target_z = 32; ///< target z height of the circle + float norm; + float angle; + float max_val = 0.5f; + const uint8_t blocks = 7; + float shifts_x[blocks]; + float shifts_y[blocks]; + float shifts_r[blocks]; + + for (int8_t i = iterations; i > 0; --i){ + + // DBG(_n(" [%f, %f][%f] circle\n"), x, y, r); + + /// read points on the circle + for (uint8_t p = 0; p < num_points; ++p){ + angle = p * pi_2_div_num_points; + points[p] = get_value(matrix_32x32, r * cos(angle) + x, r * sin(angle) + y) - target_z; + // DBG(_n("%f "), points[p]); + } + // DBG(_n(" points\n")); + + /// sum blocks + for (uint8_t j = 0; j < blocks; ++j){ + shifts_x[j] = shifts_y[j] = shifts_r[j] = 0; + /// first part + for (uint8_t p = 0; p < num_points * 3 / 4; ++p){ + uint8_t idx = (p + j * num_points / blocks) % num_points; + + angle = idx * pi_2_div_num_points; + shifts_x[j] += cos(angle) * points[idx]; + shifts_y[j] += sin(angle) * points[idx]; + shifts_r[j] += points[idx]; + } + } + + /// remove extreme values (slow but simple) + for (uint8_t j = 0; j < blocks / 2; ++j){ + remove_highest(shifts_x, blocks); + remove_highest(shifts_y, blocks); + remove_highest(shifts_r, blocks); + } + + /// median is the highest now + norm = 1.f / (32.f * (num_points * 3 / 4)); + x += CLAMP(highest(shifts_x, blocks) * norm, -max_val, max_val); + y += CLAMP(highest(shifts_y, blocks) * norm, -max_val, max_val); + r += CLAMP(highest(shifts_r, blocks) * norm, -max_val, max_val); + + r = MAX(2, r); + + } + DBG(_n(" [%f, %f][%f] final circle\n"), x, y, r); +} + +/// Prints matrix in hex to debug output (serial line) +void print_image(uint8_t *matrix_32x32){ + for (uint8_t y = 0; y < 32; ++y){ + const uint16_t idx_y = y * 32; + for (uint8_t x = 0; x < 32; ++x){ + DBG(_n("%02x"), matrix_32x32[idx_y + x]); + } + DBG(_n("\n")); + } + DBG(_n("\n")); +} + +/// scans area around the current head location and +/// searches for the center of the calibration pin +bool xyzcal_scan_and_process(void){ DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE); -// DBG(_n("sizeof(pixels)=%d\n"), 32*32); -// DBG(_n("sizeof(histo)=%d\n"), 2*16); -// DBG(_n("sizeof(pattern)=%d\n"), 2*12); - DBG(_n("sizeof(total)=%d\n"), 32*32+2*16+2*12); bool ret = false; int16_t x = _X; int16_t y = _Y; int16_t z = _Z; - uint8_t* pixels = (uint8_t*)block_buffer; - xyzcal_scan_pixels_32x32(x, y, z - 72, 2400, 200, pixels); + uint8_t *matrix32 = (uint8_t *)block_buffer; + uint16_t *pattern = (uint16_t *)(matrix32 + 32 * 32); - uint16_t* histo = (uint16_t*)(pixels + 32*32); - xyzcal_histo_pixels_32x32(pixels, histo); + xyzcal_scan_pixels_32x32_Zhop(x, y, z - 72, 2400, 300, matrix32); + print_image(matrix32); - xyzcal_adjust_pixels(pixels, histo); - - uint16_t* pattern = (uint16_t*)(histo + 2*16); - for (uint8_t i = 0; i < 12; i++) - { + for (uint8_t i = 0; i < 12; i++){ pattern[i] = pgm_read_word((uint16_t*)(xyzcal_point_pattern + i)); // DBG(_n(" pattern[%d]=%d\n"), i, pattern[i]); } - uint8_t c = 0; - uint8_t r = 0; - if (xyzcal_find_pattern_12x12_in_32x32(pixels, pattern, &c, &r) > 66) //total pixels=144, corner=12 (1/2 = 66) - { - DBG(_n(" pattern found at %d %d\n"), c, r); - c += 6; - r += 6; - x += ((int16_t)c - 16) << 6; - y += ((int16_t)r - 16) << 6; - DBG(_n(" x=%d y=%d z=%d\n"), x, y, z); + + /// SEARCH FOR BINARY CIRCLE + uint8_t uc = 0; + uint8_t ur = 0; + /// max match = 132, 1/2 good = 66, 2/3 good = 88 + if (xyzcal_find_pattern_12x12_in_32x32(matrix32, pattern, &uc, &ur) >= 88){ + /// find precise circle + /// move to the center of the pattern (+5.5) + float xf = uc + 5.5f; + float yf = ur + 5.5f; + float radius = 5; ///< default radius + const uint8_t iterations = 20; + dynamic_circle(matrix32, xf, yf, radius, iterations); + if (ABS(xf - uc + 5.5f) > 3 || ABS(yf - ur + 5.5f) > 3 || ABS(radius - 5) > 3){ + /// dynamic algorithm diverged, use original position instead + xf = uc + 5.5f; + yf = ur + 5.5f; + } + + /// move to the center of area and convert to position + xf = (float)x + (xf - 15.5f) * 64; + yf = (float)y + (yf - 15.5f) * 64; + DBG(_n(" [%f %f] mm pattern center\n"), pos_2_mm(xf), pos_2_mm(yf)); + x = round_to_i16(xf); + y = round_to_i16(yf); xyzcal_lineXYZ_to(x, y, z, 200, 0); ret = true; } + + /// wipe buffer for (uint16_t i = 0; i < sizeof(block_t)*BLOCK_BUFFER_SIZE; i++) - pixels[i] = 0; + matrix32[i] = 0; return ret; } -bool xyzcal_find_bed_induction_sensor_point_xy(void) -{ - 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]); +bool xyzcal_find_bed_induction_sensor_point_xy(void){ bool ret = false; + + 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(); - int16_t x = _X; - int16_t y = _Y; - int16_t z = _Z; + pos_i16_t x = _X; + pos_i16_t y = _Y; + pos_i16_t z = _Z; + uint8_t point = xyzcal_xycoords2point(x, y); - x = pgm_read_word((uint16_t*)(xyzcal_point_xcoords + point)); - y = pgm_read_word((uint16_t*)(xyzcal_point_ycoords + point)); + x = pgm_read_word((uint16_t *)(xyzcal_point_xcoords + point)); + y = pgm_read_word((uint16_t *)(xyzcal_point_ycoords + point)); DBG(_n("point=%d x=%d y=%d z=%d\n"), point, x, y, z); xyzcal_meassure_enter(); xyzcal_lineXYZ_to(x, y, z, 200, 0); - if (xyzcal_searchZ()) - { + + if (xyzcal_searchZ()){ int16_t z = _Z; xyzcal_lineXYZ_to(x, y, z, 200, 0); - if (xyzcal_scan_and_process()) - { - if (xyzcal_find_point_center2(500)) - { - uint32_t x_avg = 0; - uint32_t y_avg = 0; - uint8_t n; for (n = 0; n < 4; n++) - { - if (!xyzcal_find_point_center2(1000)) break; - x_avg += _X; - y_avg += _Y; - } - if (n == 4) - { - xyzcal_lineXYZ_to(x_avg >> 2, y_avg >> 2, _Z, 200, 0); - ret = true; - } - } - } + ret = xyzcal_scan_and_process(); } xyzcal_meassure_leave(); return ret; } - #endif //NEW_XYZCAL diff --git a/Firmware/xyzcal.h b/Firmware/xyzcal.h index 5590396e..348ff3ce 100644 --- a/Firmware/xyzcal.h +++ b/Firmware/xyzcal.h @@ -17,20 +17,6 @@ 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 void xyzcal_scan_pixels_32x32(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels); - -extern void xyzcal_histo_pixels_32x32(uint8_t* pixels, uint16_t* histo); - -extern void xyzcal_adjust_pixels(uint8_t* pixels, uint16_t* histo); - -extern int16_t xyzcal_match_pattern_12x12_in_32x32(uint16_t* pattern, uint8_t* pixels, uint8_t x, uint8_t y); - -extern int16_t xyzcal_find_pattern_12x12_in_32x32(uint8_t* pixels, uint16_t* pattern, uint8_t* pc, uint8_t* pr); - -extern int8_t xyzcal_find_point_center2(uint16_t delay_us); - -//extern int8_t xyzcal_find_point_center(int16_t x0, int16_t y0, int16_t z0, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t turns); - extern bool xyzcal_searchZ(void); extern bool xyzcal_scan_and_process(void); From ccf26e4e7a7c3ca1d476f6d5f40c8da523fe0fe2 Mon Sep 17 00:00:00 2001 From: espr14 Date: Fri, 18 Dec 2020 20:04:00 +0100 Subject: [PATCH 02/28] Basic acceleration --- Firmware/xyzcal.cpp | 54 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 2130b223..3a794f9b 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -360,20 +360,36 @@ int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t d } #endif //XYZCAL_MEASSURE_PINDA_HYSTEREZIS +uint8_t slow_down_z(uint16_t delay_us){ + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us / 3 * 4); + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us * 2); + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us * 4); + return 3; +} + +uint8_t speed_up_z(int16_t &z, uint8_t direction, uint16_t delay_us){ + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us * 4); + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us * 2); + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us / 3 * 4); + return 3; +} + void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ if(!pixels) return; int16_t z = _Z; + int16_t z_trig; uint16_t line_buffer[32]; - xyzcal_lineXYZ_to(cx, cy, z, delay_us, 0); + xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); for (uint8_t r = 0; r < 32; r++){ ///< Y axis xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); - for (int8_t d = 0; d < 2; ++d){ ///< direction - - // xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, z, 2 * delay_us, 0); - // xyzcal_lineXYZ_to(_X, _Y, min_z, delay_us, 1); - // xyzcal_lineXYZ_to(_X, _Y, max_z, delay_us, -1); - + for (int8_t d = 0; d < 2; ++d){ ///< direction xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, min_z, delay_us, 0); z = _Z; @@ -382,29 +398,47 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ /// move up to un-trigger (surpress hysteresis) sm4_set_dir(Z_AXIS, Z_PLUS); + z += speed_up_z(delay_us); while (z < max_z && _PINDA){ sm4_do_step(Z_AXIS_MASK); delayMicroseconds(delay_us); z++; } int16_t last_top_z = z; + z += slow_down_z(delay_us); /// move down to trigger sm4_set_dir(Z_AXIS, Z_MINUS); + + /// speed up + do (){ + if (z <= min_z || _PINDA) break; + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us * 4); + if (z <= min_z || _PINDA) break; + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us * 2); + if (z <= min_z || _PINDA) break; + sm4_do_step(Z_AXIS_MASK); + delayMicroseconds(delay_us / 3 * 4); + } while (0); + while (z > min_z && !_PINDA){ sm4_do_step(Z_AXIS_MASK); delayMicroseconds(delay_us); z--; } - + z_trig = z; + z -= slow_down_z(delay_us); + count_position[2] = z; if (d == 0){ - line_buffer[c] = (uint16_t)(z - min_z); + line_buffer[c] = (uint16_t)(z_trig - min_z); } else { /// data reversed in X // DBG(_n("%04x"), (line_buffer[31 - c] + (z - min_z)) / 2); /// save average of both directions - pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z - min_z)) / 2); + pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); } /// move to the next point From f39a0999e1d0aefe7949c52e170c6f67e11591d0 Mon Sep 17 00:00:00 2001 From: espr14 Date: Fri, 18 Dec 2020 21:33:43 +0100 Subject: [PATCH 03/28] Prepare full acceleration control --- Firmware/xyzcal.cpp | 49 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 3a794f9b..1c03c4c3 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -36,6 +36,11 @@ #define Z_PLUS 0 #define Z_MINUS 1 +/// 10000 = 1 mm/s +#define MAX_DELAY 10000 +#define Z_ACCEL 300 +#define XY_ACCEL 1000 + #define _PI 3.14159265F /// \returns positive value always @@ -360,8 +365,40 @@ int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t d } #endif //XYZCAL_MEASSURE_PINDA_HYSTEREZIS -uint8_t slow_down_z(uint16_t delay_us){ - sm4_do_step(Z_AXIS_MASK); +void accelerate(uint8_t axis, int16_t acc, uint16_t &delay_us, uint16_t min_delay_us){ + sm4_do_step(axis); + + if (acc > 0 && delay_us == min_delay_us){ + delayMicroseconds(delay_us); + return; + } + + // v1 = v0 + a * t + // 0.01 = length of a step + const float d0 = delay_us * 0.000001f; + const float v1 = (0.01f / d0 + acc * d0); + uint16_t d1; + if (v1 <= 0.1f){ + d1 = MAX_DELAY; ///< already too slow so it wants to move back + } else { + d1 = MAX(min_delay_us, round_to_u16(0.01f / v1)); + } + + /// make sure delay has changed a bit at least + if (d1 == delay_us && acc != 0){ + if (acc > 0) + d1--; + else + d1++; + } + + delayMicroseconds(d1); + delay_us = d1; +} + + +uint8_t slow_down_z(uint8_t axis, uint16_t delay_us){ + sm4_do_step(axis); delayMicroseconds(delay_us / 3 * 4); sm4_do_step(Z_AXIS_MASK); delayMicroseconds(delay_us * 2); @@ -370,7 +407,7 @@ uint8_t slow_down_z(uint16_t delay_us){ return 3; } -uint8_t speed_up_z(int16_t &z, uint8_t direction, uint16_t delay_us){ +uint8_t speed_up_z(uint8_t axis, uint16_t delay_us){ sm4_do_step(Z_AXIS_MASK); delayMicroseconds(delay_us * 4); sm4_do_step(Z_AXIS_MASK); @@ -386,6 +423,7 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ int16_t z = _Z; int16_t z_trig; uint16_t line_buffer[32]; + uint16_t current_delay_us = MAX_DELAY; xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); for (uint8_t r = 0; r < 32; r++){ ///< Y axis xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); @@ -398,10 +436,9 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ /// move up to un-trigger (surpress hysteresis) sm4_set_dir(Z_AXIS, Z_PLUS); - z += speed_up_z(delay_us); + current_delay_us = MAX_DELAY; while (z < max_z && _PINDA){ - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us); + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, delay_us); z++; } int16_t last_top_z = z; From 9b55ff9de1599ebf81cfb3f9853b00f950351e7f Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 13:05:26 +0100 Subject: [PATCH 04/28] Acceleration up and down --- Firmware/xyzcal.cpp | 163 +++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 56 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 1c03c4c3..fc7597b2 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -36,8 +36,11 @@ #define Z_PLUS 0 #define Z_MINUS 1 -/// 10000 = 1 mm/s +/// Max. jerk in PrusaSlicer, 10000 = 1 mm/s #define MAX_DELAY 10000 +#define MIN_SPEED (0.01f / (MAX_DELAY * 0.000001f)) +/// 200 = 50 mm/s +#define Z_MIN_DELAY 200 #define Z_ACCEL 300 #define XY_ACCEL 1000 @@ -76,6 +79,11 @@ __typeof__ (max) max_ = (max); \ ( a_ < min_ ? min_ : (a_ <= max_ ? a_ : max_)); }) +/// \returns square of the value +#define SQR(a) \ + ({ __typeof__ (a) a_ = (a); \ + (a_ * a_); }) + /// position types typedef int16_t pos_i16_t; typedef long pos_i32_t; @@ -365,9 +373,11 @@ int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t d } #endif //XYZCAL_MEASSURE_PINDA_HYSTEREZIS +/// Accelerate up to max.speed (defined by @min_delay_us) void accelerate(uint8_t axis, int16_t acc, uint16_t &delay_us, uint16_t min_delay_us){ sm4_do_step(axis); + /// keep max speed (avoid extra computation) if (acc > 0 && delay_us == min_delay_us){ delayMicroseconds(delay_us); return; @@ -375,47 +385,66 @@ void accelerate(uint8_t axis, int16_t acc, uint16_t &delay_us, uint16_t min_dela // v1 = v0 + a * t // 0.01 = length of a step - const float d0 = delay_us * 0.000001f; - const float v1 = (0.01f / d0 + acc * d0); - uint16_t d1; - if (v1 <= 0.1f){ - d1 = MAX_DELAY; ///< already too slow so it wants to move back + const float t0 = delay_us * 0.000001f; + const float v1 = (0.01f / t0 + acc * t0); + uint16_t t1; + if (v1 <= 0.16f){ ///< slowest speed convertible to uint16_t delay + t1 = MAX_DELAY; ///< already too slow so it wants to move back } else { - d1 = MAX(min_delay_us, round_to_u16(0.01f / v1)); + /// don't exceed max.speed + t1 = MAX(min_delay_us, round_to_u16(0.01f / v1 * 1000000.f)); } /// make sure delay has changed a bit at least - if (d1 == delay_us && acc != 0){ + if (t1 == delay_us && acc != 0){ if (acc > 0) - d1--; + t1--; else - d1++; + t1++; } - delayMicroseconds(d1); - delay_us = d1; + //DBG(_n("%d "), t1); + + delayMicroseconds(t1); + delay_us = t1; } +void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps){ + if (steps <= 0 || dec <= 0) + return; -uint8_t slow_down_z(uint8_t axis, uint16_t delay_us){ - sm4_do_step(axis); - delayMicroseconds(delay_us / 3 * 4); - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us * 2); - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us * 4); - return 3; + /// deceleration distance in steps, s = 1/2 v^2 / a + uint16_t s = round_to_u16(100 * 0.5f * SQR(0.01f) / (SQR((float)delay_us) * dec)); + if (steps > s){ + /// go steady + sm4_do_step(axis) + delayMicroseconds(delay_us); + } else { + /// decelerate + accelerate(axis, -dec, &delay_us, min_delay_us); + } + --steps; } -uint8_t speed_up_z(uint8_t axis, uint16_t delay_us){ - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us * 4); - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us * 2); - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us / 3 * 4); - return 3; -} +// uint8_t slow_down_z(uint8_t axis, uint16_t delay_us){ +// sm4_do_step(axis); +// delayMicroseconds(delay_us / 3 * 4); +// sm4_do_step(Z_AXIS_MASK); +// delayMicroseconds(delay_us * 2); +// sm4_do_step(Z_AXIS_MASK); +// delayMicroseconds(delay_us * 4); +// return 3; +// } + +// uint8_t speed_up_z(uint8_t axis, uint16_t delay_us){ +// sm4_do_step(Z_AXIS_MASK); +// delayMicroseconds(delay_us * 4); +// sm4_do_step(Z_AXIS_MASK); +// delayMicroseconds(delay_us * 2); +// sm4_do_step(Z_AXIS_MASK); +// delayMicroseconds(delay_us / 3 * 4); +// return 3; +// } void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ if(!pixels) @@ -423,8 +452,12 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ int16_t z = _Z; int16_t z_trig; uint16_t line_buffer[32]; - uint16_t current_delay_us = MAX_DELAY; + uint16_t current_delay_us = MAX_DELAY; ///< defines current speed xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); + uint16_t min_decel_z; + int16_t start_z; + int16_t last_top_z; + for (uint8_t r = 0; r < 32; r++){ ///< Y axis xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); for (int8_t d = 0; d < 2; ++d){ ///< direction @@ -433,40 +466,58 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ z = _Z; sm4_set_dir(X_AXIS, d); for (uint8_t c = 0; c < 32; c++){ ///< X axis - + /// move up to un-trigger (surpress hysteresis) sm4_set_dir(Z_AXIS, Z_PLUS); + /// speed up from stop, go half the way current_delay_us = MAX_DELAY; - while (z < max_z && _PINDA){ - accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, delay_us); - z++; + for (start_z = z; z < (max_z + start_z) / 2; ++z){ + if (!_PINDA){ + last_top_z = z; + break; + } + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + } + + if(_PINDA){ + uint16_t steps_to_go = MAX(0, max_z - z); + while (_PINDA && z < max_z){ + go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + ++z; + } + last_top_z = z; + } + /// slow down to stop + while (current_delay_us < MAX_DELAY){ + accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); + ++z; } - int16_t last_top_z = z; - z += slow_down_z(delay_us); /// move down to trigger sm4_set_dir(Z_AXIS, Z_MINUS); - /// speed up - do (){ - if (z <= min_z || _PINDA) break; - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us * 4); - if (z <= min_z || _PINDA) break; - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us * 2); - if (z <= min_z || _PINDA) break; - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us / 3 * 4); - } while (0); - - while (z > min_z && !_PINDA){ - sm4_do_step(Z_AXIS_MASK); - delayMicroseconds(delay_us); - z--; + current_delay_us = MAX_DELAY; + for (start_z = z; z > (min_z + start_z) / 2; --z){ + if (_PINDA){ + z_trig = z; + break; + } + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + } + /// slow down + if(!_PINDA){ + uint16_t steps_to_go = MAX(0, z - min_z); + while (!_PINDA && z > min_z){ + go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + --z; + } + z_trig = z; + } + /// slow down to stop + while (z > min_z && current_delay_us < MAX_DELAY){ + accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); + --z; } - z_trig = z; - z -= slow_down_z(delay_us); count_position[2] = z; if (d == 0){ @@ -735,7 +786,7 @@ bool xyzcal_scan_and_process(void){ uint8_t *matrix32 = (uint8_t *)block_buffer; uint16_t *pattern = (uint16_t *)(matrix32 + 32 * 32); - xyzcal_scan_pixels_32x32_Zhop(x, y, z - 72, 2400, 300, matrix32); + xyzcal_scan_pixels_32x32_Zhop(x, y, z - 72, 2400, 600, matrix32); print_image(matrix32); for (uint8_t i = 0; i < 12; i++){ From 27ff6b0057380e467f67867851a5ebcba23961f9 Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 13:11:48 +0100 Subject: [PATCH 05/28] Fix build --- Firmware/xyzcal.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index fc7597b2..18b4de9e 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -417,11 +417,11 @@ void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps) uint16_t s = round_to_u16(100 * 0.5f * SQR(0.01f) / (SQR((float)delay_us) * dec)); if (steps > s){ /// go steady - sm4_do_step(axis) + sm4_do_step(axis); delayMicroseconds(delay_us); } else { /// decelerate - accelerate(axis, -dec, &delay_us, min_delay_us); + accelerate(axis, -dec, delay_us, delay_us); } --steps; } @@ -454,7 +454,6 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ uint16_t line_buffer[32]; uint16_t current_delay_us = MAX_DELAY; ///< defines current speed xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); - uint16_t min_decel_z; int16_t start_z; int16_t last_top_z; @@ -467,6 +466,9 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ sm4_set_dir(X_AXIS, d); for (uint8_t c = 0; c < 32; c++){ ///< X axis + z_trig = min_z; + last_top_z = max_z; + /// move up to un-trigger (surpress hysteresis) sm4_set_dir(Z_AXIS, Z_PLUS); /// speed up from stop, go half the way From 9a59369c77b28ad45dcd7ee82e57e014413545b9 Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 15:32:09 +0100 Subject: [PATCH 06/28] Diagonal acceleration --- Firmware/xyzcal.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 18b4de9e..d82877d8 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -455,7 +455,8 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ uint16_t current_delay_us = MAX_DELAY; ///< defines current speed xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); int16_t start_z; - int16_t last_top_z; + // int16_t last_top_z; + uint16_t steps_to_go; for (uint8_t r = 0; r < 32; r++){ ///< Y axis xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); @@ -475,7 +476,7 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ current_delay_us = MAX_DELAY; for (start_z = z; z < (max_z + start_z) / 2; ++z){ if (!_PINDA){ - last_top_z = z; + // last_top_z = z; break; } accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); @@ -487,7 +488,7 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); ++z; } - last_top_z = z; + // last_top_z = z; } /// slow down to stop while (current_delay_us < MAX_DELAY){ @@ -508,7 +509,7 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ } /// slow down if(!_PINDA){ - uint16_t steps_to_go = MAX(0, z - min_z); + steps_to_go = MAX(0, z - min_z); while (!_PINDA && z > min_z){ go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); --z; @@ -531,9 +532,30 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); } - /// move to the next point - xyzcal_lineXYZ_to(((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx, _Y, (last_top_z + z) / 2, delay_us, 0); - z = _Z; + /// move to the next point and move Z up diagonally + current_delay_us = MAX_DELAY; + // const int8_t dir = (d & 1) ? -1 : 1; + const int16_t end_x = ((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx; + const int16_t length_x = ABS(end_x - _X); + const int16_t half_x = length_x / 2; + int16_t x = 0; + + sm4_set_dir(Z_AXIS, Z_PLUS); + /// speed up + for (x = 0; x <= half_x; ++x, ++z){ + accelerate(X_AXIS_MASK | Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + } + /// slow down + steps_to_go = length_x - x; + for (; x < length_x; ++x, ++z){ + go_and_stop(X_AXIS_MASK | Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + } + + count_position[0] = end_x; + count_position[2] = z; + + // xyzcal_lineXYZ_to(((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx, _Y, (last_top_z + z) / 2, delay_us, 0); + // z = _Z; } } // DBG(_n("\n\n")); From 3c9168f8f6c5c27c73b8b8442c4a7922b748d737 Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 15:52:25 +0100 Subject: [PATCH 07/28] Optimize diagonal --- Firmware/xyzcal.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index d82877d8..b25be971 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -539,16 +539,18 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ const int16_t length_x = ABS(end_x - _X); const int16_t half_x = length_x / 2; int16_t x = 0; - + /// don't go up if PINDA not triggered + int8_t axis = _PINDA ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; + sm4_set_dir(Z_AXIS, Z_PLUS); /// speed up for (x = 0; x <= half_x; ++x, ++z){ - accelerate(X_AXIS_MASK | Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + accelerate(axis, Z_ACCEL, current_delay_us, Z_MIN_DELAY); } /// slow down steps_to_go = length_x - x; for (; x < length_x; ++x, ++z){ - go_and_stop(X_AXIS_MASK | Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); } count_position[0] = end_x; From de23a845b44d89f803d6a048254095fe27cd5354 Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 15:53:51 +0100 Subject: [PATCH 08/28] Remove unused --- Firmware/xyzcal.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index b25be971..af68ea22 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -455,7 +455,6 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ uint16_t current_delay_us = MAX_DELAY; ///< defines current speed xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); int16_t start_z; - // int16_t last_top_z; uint16_t steps_to_go; for (uint8_t r = 0; r < 32; r++){ ///< Y axis @@ -468,7 +467,6 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ for (uint8_t c = 0; c < 32; c++){ ///< X axis z_trig = min_z; - last_top_z = max_z; /// move up to un-trigger (surpress hysteresis) sm4_set_dir(Z_AXIS, Z_PLUS); @@ -476,7 +474,6 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ current_delay_us = MAX_DELAY; for (start_z = z; z < (max_z + start_z) / 2; ++z){ if (!_PINDA){ - // last_top_z = z; break; } accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); @@ -488,7 +485,6 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); ++z; } - // last_top_z = z; } /// slow down to stop while (current_delay_us < MAX_DELAY){ @@ -552,12 +548,8 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ for (; x < length_x; ++x, ++z){ go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); } - count_position[0] = end_x; count_position[2] = z; - - // xyzcal_lineXYZ_to(((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx, _Y, (last_top_z + z) / 2, delay_us, 0); - // z = _Z; } } // DBG(_n("\n\n")); From 744763f0a9f1f20546d09eda6560553497ce434f Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 17:34:54 +0100 Subject: [PATCH 09/28] Fix diagonal movement --- Firmware/xyzcal.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index af68ea22..df6f12b3 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -41,7 +41,7 @@ #define MIN_SPEED (0.01f / (MAX_DELAY * 0.000001f)) /// 200 = 50 mm/s #define Z_MIN_DELAY 200 -#define Z_ACCEL 300 +#define Z_ACCEL 5000 #define XY_ACCEL 1000 #define _PI 3.14159265F @@ -536,17 +536,22 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ const int16_t half_x = length_x / 2; int16_t x = 0; /// don't go up if PINDA not triggered - int8_t axis = _PINDA ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; + const bool up = _PINDA; + int8_t axis = up ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; sm4_set_dir(Z_AXIS, Z_PLUS); /// speed up - for (x = 0; x <= half_x; ++x, ++z){ + for (x = 0; x <= half_x; ++x){ accelerate(axis, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + if (up) + ++z; } /// slow down steps_to_go = length_x - x; - for (; x < length_x; ++x, ++z){ + for (; x < length_x; ++x){ go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); + if (up) + ++z; } count_position[0] = end_x; count_position[2] = z; @@ -600,7 +605,7 @@ uint8_t xyzcal_find_pattern_12x12_in_32x32(uint8_t* pixels, uint16_t* pattern, u } // DBG(_n("\n")); } - DBG(_n("max_c=%f max_r=%f max_match=%d pixel\n"), max_c, max_r, max_match); + DBG(_n("max_c=%d max_r=%d max_match=%d pixel\n"), max_c, max_r, max_match); *pc = max_c; *pr = max_r; From 1610c96fc4d49f9d34f3ab6ead9b1b30b176c1e8 Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 18:05:52 +0100 Subject: [PATCH 10/28] Fix and report circle divergence --- Firmware/mesh_bed_calibration.cpp | 2 +- Firmware/xyzcal.cpp | 27 ++++----------------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index 12fca582..897e3a9e 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -2271,7 +2271,7 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level /*} else { // if first iteration failed, count corrected point coordinates as initial - // Use the coorrected coordinate, which is a result of find_bed_offset_and_skew(). + // Use the corrected coordinate, which is a result of find_bed_offset_and_skew(). current_position[X_AXIS] = vec_x[0] * pgm_read_float(bed_ref_points_4 + k * 2) + vec_y[0] * pgm_read_float(bed_ref_points_4 + k * 2 + 1) + cntr[0]; current_position[Y_AXIS] = vec_x[1] * pgm_read_float(bed_ref_points_4 + k * 2) + vec_y[1] * pgm_read_float(bed_ref_points_4 + k * 2 + 1) + cntr[1]; diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index df6f12b3..4e55996a 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -37,7 +37,7 @@ #define Z_MINUS 1 /// Max. jerk in PrusaSlicer, 10000 = 1 mm/s -#define MAX_DELAY 10000 +#define MAX_DELAY 1000 #define MIN_SPEED (0.01f / (MAX_DELAY * 0.000001f)) /// 200 = 50 mm/s #define Z_MIN_DELAY 200 @@ -426,26 +426,6 @@ void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps) --steps; } -// uint8_t slow_down_z(uint8_t axis, uint16_t delay_us){ -// sm4_do_step(axis); -// delayMicroseconds(delay_us / 3 * 4); -// sm4_do_step(Z_AXIS_MASK); -// delayMicroseconds(delay_us * 2); -// sm4_do_step(Z_AXIS_MASK); -// delayMicroseconds(delay_us * 4); -// return 3; -// } - -// uint8_t speed_up_z(uint8_t axis, uint16_t delay_us){ -// sm4_do_step(Z_AXIS_MASK); -// delayMicroseconds(delay_us * 4); -// sm4_do_step(Z_AXIS_MASK); -// delayMicroseconds(delay_us * 2); -// sm4_do_step(Z_AXIS_MASK); -// delayMicroseconds(delay_us / 3 * 4); -// return 3; -// } - void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ if(!pixels) return; @@ -528,7 +508,7 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); } - /// move to the next point and move Z up diagonally + /// move to the next point and move Z up diagonally (if needed) current_delay_us = MAX_DELAY; // const int8_t dir = (d & 1) ? -1 : 1; const int16_t end_x = ((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx; @@ -829,7 +809,8 @@ bool xyzcal_scan_and_process(void){ float radius = 5; ///< default radius const uint8_t iterations = 20; dynamic_circle(matrix32, xf, yf, radius, iterations); - if (ABS(xf - uc + 5.5f) > 3 || ABS(yf - ur + 5.5f) > 3 || ABS(radius - 5) > 3){ + if (ABS(xf - (uc + 5.5f)) > 3 || ABS(yf - (ur + 5.5f)) > 3 || ABS(radius - 5) > 3){ + DBG(_n(" [%f %f][%f] mm divergence\n"), xf - (uc + 5.5f), yf - (ur + 5.5f), radius - 5); /// dynamic algorithm diverged, use original position instead xf = uc + 5.5f; yf = ur + 5.5f; From c397e9249ae8aa7239d172be7d2194718c4c4c74 Mon Sep 17 00:00:00 2001 From: espr14 Date: Mon, 21 Dec 2020 19:33:36 +0100 Subject: [PATCH 11/28] Restart scanning --- Firmware/xyzcal.cpp | 217 ++++++++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 86 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 4e55996a..d68bfbc1 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -426,8 +426,41 @@ void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps) --steps; } +/// Count number of zeros on the 32 byte array +/// If the number is less than 16, it changes @min_z so it will be next time +bool more_zeros(uint8_t* pixels, int16_t &min_z){ + uint8_t hist[256]; + uint8_t i = 0; + + /// clear + do { + hist[i] = 0; + } while (i++ < 255); + + /// fill + for (i = 0; i < 32; ++i){ + ++hist[pixels[i]]; + } + + /// already more zeros on the line + if (hist[0] >= 16) + return true; + + /// find threshold + uint8_t sum = 0; + i = 0; + do { + sum += hist[i]; + if (sum >= 16) + break; + } while (i++ < 255); + + min_z += i; + return false; +} + void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ - if(!pixels) + if (!pixels) return; int16_t z = _Z; int16_t z_trig; @@ -436,109 +469,121 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); int16_t start_z; uint16_t steps_to_go; + uint8_t restart = 0; ///< restart if needed but just once + int16_t corr_min_z = min_z; ///< shifted min_z if it's too low - for (uint8_t r = 0; r < 32; r++){ ///< Y axis - xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); - for (int8_t d = 0; d < 2; ++d){ ///< direction - xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, min_z, delay_us, 0); + do { + if (restart == 1) + restart = 2; + for (uint8_t r = 0; r < 32; r++){ ///< Y axis + xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); + for (int8_t d = 0; d < 2; ++d){ ///< direction + xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, corr_min_z, delay_us, 0); - z = _Z; - sm4_set_dir(X_AXIS, d); - for (uint8_t c = 0; c < 32; c++){ ///< X axis + z = _Z; + sm4_set_dir(X_AXIS, d); + for (uint8_t c = 0; c < 32; c++){ ///< X axis - z_trig = min_z; + z_trig = corr_min_z; - /// move up to un-trigger (surpress hysteresis) - sm4_set_dir(Z_AXIS, Z_PLUS); - /// speed up from stop, go half the way - current_delay_us = MAX_DELAY; - for (start_z = z; z < (max_z + start_z) / 2; ++z){ - if (!_PINDA){ - break; + /// move up to un-trigger (surpress hysteresis) + sm4_set_dir(Z_AXIS, Z_PLUS); + /// speed up from stop, go half the way + current_delay_us = MAX_DELAY; + for (start_z = z; z < (max_z + start_z) / 2; ++z){ + if (!_PINDA){ + break; + } + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); } - accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); - } - if(_PINDA){ - uint16_t steps_to_go = MAX(0, max_z - z); - while (_PINDA && z < max_z){ - go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + if(_PINDA){ + uint16_t steps_to_go = MAX(0, max_z - z); + while (_PINDA && z < max_z){ + go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + ++z; + } + } + /// slow down to stop + while (current_delay_us < MAX_DELAY){ + accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); ++z; } - } - /// slow down to stop - while (current_delay_us < MAX_DELAY){ - accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); - ++z; - } - /// move down to trigger - sm4_set_dir(Z_AXIS, Z_MINUS); - /// speed up - current_delay_us = MAX_DELAY; - for (start_z = z; z > (min_z + start_z) / 2; --z){ - if (_PINDA){ - z_trig = z; - break; + /// move down to trigger + sm4_set_dir(Z_AXIS, Z_MINUS); + /// speed up + current_delay_us = MAX_DELAY; + for (start_z = z; z > (corr_min_z + start_z) / 2; --z){ + if (_PINDA){ + z_trig = z; + break; + } + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); } - accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); - } - /// slow down - if(!_PINDA){ - steps_to_go = MAX(0, z - min_z); - while (!_PINDA && z > min_z){ - go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + /// slow down + if(!_PINDA){ + steps_to_go = MAX(0, z - corr_min_z); + while (!_PINDA && z > corr_min_z){ + go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); + --z; + } + z_trig = z; + } + /// slow down to stop + while (z > corr_min_z && current_delay_us < MAX_DELAY){ + accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); --z; } - z_trig = z; - } - /// slow down to stop - while (z > min_z && current_delay_us < MAX_DELAY){ - accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); - --z; - } - count_position[2] = z; - if (d == 0){ - line_buffer[c] = (uint16_t)(z_trig - min_z); - } else { - /// data reversed in X - // DBG(_n("%04x"), (line_buffer[31 - c] + (z - min_z)) / 2); - /// save average of both directions - pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); - } + count_position[2] = z; + if (d == 0){ + line_buffer[c] = (uint16_t)(z_trig - corr_min_z); + } else { + /// data reversed in X + // DBG(_n("%04x"), (line_buffer[31 - c] + (z - corr_min_z)) / 2); + /// save average of both directions + pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - corr_min_z)) / 2); + } - /// move to the next point and move Z up diagonally (if needed) - current_delay_us = MAX_DELAY; - // const int8_t dir = (d & 1) ? -1 : 1; - const int16_t end_x = ((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx; - const int16_t length_x = ABS(end_x - _X); - const int16_t half_x = length_x / 2; - int16_t x = 0; - /// don't go up if PINDA not triggered - const bool up = _PINDA; - int8_t axis = up ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; + /// move to the next point and move Z up diagonally (if needed) + current_delay_us = MAX_DELAY; + // const int8_t dir = (d & 1) ? -1 : 1; + const int16_t end_x = ((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx; + const int16_t length_x = ABS(end_x - _X); + const int16_t half_x = length_x / 2; + int16_t x = 0; + /// don't go up if PINDA not triggered + const bool up = _PINDA; + int8_t axis = up ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; - sm4_set_dir(Z_AXIS, Z_PLUS); - /// speed up - for (x = 0; x <= half_x; ++x){ - accelerate(axis, Z_ACCEL, current_delay_us, Z_MIN_DELAY); - if (up) - ++z; + sm4_set_dir(Z_AXIS, Z_PLUS); + /// speed up + for (x = 0; x <= half_x; ++x){ + accelerate(axis, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + if (up) + ++z; + } + /// slow down + steps_to_go = length_x - x; + for (; x < length_x; ++x){ + go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); + if (up) + ++z; + } + count_position[0] = end_x; + count_position[2] = z; } - /// slow down - steps_to_go = length_x - x; - for (; x < length_x; ++x){ - go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); - if (up) - ++z; - } - count_position[0] = end_x; - count_position[2] = z; } + if (r == 0 && restart == 0){ + if (!more_zeros(pixels, corr_min_z)) + restart = 1; + } + if (restart == 1) + break; + // DBG(_n("\n\n")); } - // DBG(_n("\n\n")); - } + } while (restart == 1); } /// Returns rate of match From 20659ec818ca3964f7276651781c20b943a1a616 Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 12:51:22 +0100 Subject: [PATCH 12/28] Add debug output --- Firmware/xyzcal.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index d68bfbc1..86a2440b 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -427,7 +427,7 @@ void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps) } /// Count number of zeros on the 32 byte array -/// If the number is less than 16, it changes @min_z so it will be next time +/// If the number is less than 16, it moves @min_z up bool more_zeros(uint8_t* pixels, int16_t &min_z){ uint8_t hist[256]; uint8_t i = 0; @@ -441,11 +441,22 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ for (i = 0; i < 32; ++i){ ++hist[pixels[i]]; } - + + /// print histogram + i = 0; + DBG(_n("hist: ")); + do { + DBG(_n("%d "), hist[i]); + } while (i++ < 255); + DBG(_n("\n")); + + /// already more zeros on the line - if (hist[0] >= 16) + if (hist[0] >= 16){ + DBG(_n("zeros: %d\n"), hist[0]); return true; - + } + /// find threshold uint8_t sum = 0; i = 0; @@ -455,7 +466,14 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ break; } while (i++ < 255); + /// avoid too much zeros + if (sum >= 24) + --i; + + DBG(_n("sum %d, index %d\n"), sum, i); + DBG(_n("min_z %d\n"), min_z); min_z += i; + DBG(_n("min_z %d\n"), min_z); return false; } From 90c8045f7dc0a98e50f7cc95255bc661ed364acc Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 13:59:50 +0100 Subject: [PATCH 13/28] Clean the code --- Firmware/xyzcal.cpp | 62 +++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 86a2440b..f99c0c9b 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -442,13 +442,13 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ ++hist[pixels[i]]; } - /// print histogram - i = 0; - DBG(_n("hist: ")); - do { - DBG(_n("%d "), hist[i]); - } while (i++ < 255); - DBG(_n("\n")); + // /// print histogram + // i = 0; + // DBG(_n("hist: ")); + // do { + // DBG(_n("%d "), hist[i]); + // } while (i++ < 255); + // DBG(_n("\n")); /// already more zeros on the line @@ -471,12 +471,18 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ --i; DBG(_n("sum %d, index %d\n"), sum, i); - DBG(_n("min_z %d\n"), min_z); + // DBG(_n("min_z %d\n"), min_z); min_z += i; - DBG(_n("min_z %d\n"), min_z); + // DBG(_n("min_z %d\n"), min_z); return false; } +enum { + RESTART_INIT, + DO_RESTART, + WAS_RESTARTED +}; + void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ if (!pixels) return; @@ -487,22 +493,23 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); int16_t start_z; uint16_t steps_to_go; - uint8_t restart = 0; ///< restart if needed but just once - int16_t corr_min_z = min_z; ///< shifted min_z if it's too low + /// restart if needed but just once + /// 0 = init, 1 = do restart, 2 = restart was done, don't restart any more + uint8_t restart = RESTART_INIT; do { - if (restart == 1) - restart = 2; + if (restart == DO_RESTART) + restart = WAS_RESTARTED; for (uint8_t r = 0; r < 32; r++){ ///< Y axis xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); for (int8_t d = 0; d < 2; ++d){ ///< direction - xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, corr_min_z, delay_us, 0); + xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, min_z, delay_us, 0); z = _Z; sm4_set_dir(X_AXIS, d); for (uint8_t c = 0; c < 32; c++){ ///< X axis - z_trig = corr_min_z; + z_trig = min_z; /// move up to un-trigger (surpress hysteresis) sm4_set_dir(Z_AXIS, Z_PLUS); @@ -532,7 +539,7 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ sm4_set_dir(Z_AXIS, Z_MINUS); /// speed up current_delay_us = MAX_DELAY; - for (start_z = z; z > (corr_min_z + start_z) / 2; --z){ + for (start_z = z; z > (min_z + start_z) / 2; --z){ if (_PINDA){ z_trig = z; break; @@ -541,27 +548,27 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ } /// slow down if(!_PINDA){ - steps_to_go = MAX(0, z - corr_min_z); - while (!_PINDA && z > corr_min_z){ + steps_to_go = MAX(0, z - min_z); + while (!_PINDA && z > min_z){ go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); --z; } z_trig = z; } /// slow down to stop - while (z > corr_min_z && current_delay_us < MAX_DELAY){ + while (z > min_z && current_delay_us < MAX_DELAY){ accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); --z; } count_position[2] = z; if (d == 0){ - line_buffer[c] = (uint16_t)(z_trig - corr_min_z); + line_buffer[c] = (uint16_t)(z_trig - min_z); } else { /// data reversed in X - // DBG(_n("%04x"), (line_buffer[31 - c] + (z - corr_min_z)) / 2); + // DBG(_n("%04x"), (line_buffer[31 - c] + (z - min_z)) / 2); /// save average of both directions - pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - corr_min_z)) / 2); + pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); } /// move to the next point and move Z up diagonally (if needed) @@ -593,15 +600,16 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ count_position[2] = z; } } - if (r == 0 && restart == 0){ - if (!more_zeros(pixels, corr_min_z)) - restart = 1; + /// do this in the first row only + if (r == 0 && restart == RESTART_INIT){ + if (!more_zeros(pixels, min_z)) + restart = DO_RESTART; } - if (restart == 1) + if (restart == DO_RESTART) break; // DBG(_n("\n\n")); } - } while (restart == 1); + } while (restart == DO_RESTART); } /// Returns rate of match From 25d6e247781d6c3590bf0f2721e87941bfe4c7cb Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 14:16:20 +0100 Subject: [PATCH 14/28] Add comments --- Firmware/xyzcal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index f99c0c9b..22cec618 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -426,8 +426,9 @@ void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps) --steps; } -/// Count number of zeros on the 32 byte array +/// Count number of zeros in the 32 byte array /// If the number is less than 16, it moves @min_z up +/// Zeros make measuring faster but there cannot be too much bool more_zeros(uint8_t* pixels, int16_t &min_z){ uint8_t hist[256]; uint8_t i = 0; From 8df2eccf45f0d03c5e2baaa3ecf0ed354db75cd6 Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 14:36:37 +0100 Subject: [PATCH 15/28] Remove defines and unused vars --- Firmware/xyzcal.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 22cec618..8c7a3f53 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -29,22 +29,19 @@ #define _Z ((int16_t)count_position[Z_AXIS]) #define _E ((int16_t)count_position[E_AXIS]) -#define X_PLUS 0 -#define X_MINUS 1 -#define Y_PLUS 0 -#define Y_MINUS 1 -#define Z_PLUS 0 -#define Z_MINUS 1 +const constexpr uint8_t X_PLUS = 0; +const constexpr uint8_t X_MINUS = 1; +const constexpr uint8_t Y_PLUS = 0; +const constexpr uint8_t Y_MINUS = 1; +const constexpr uint8_t Z_PLUS = 0; +const constexpr uint8_t Z_MINUS = 1; /// Max. jerk in PrusaSlicer, 10000 = 1 mm/s -#define MAX_DELAY 1000 -#define MIN_SPEED (0.01f / (MAX_DELAY * 0.000001f)) +const constexpr uint16_t MAX_DELAY = 1000; +const constexpr float MIN_SPEED = 0.01f / (MAX_DELAY * 0.000001f); /// 200 = 50 mm/s -#define Z_MIN_DELAY 200 -#define Z_ACCEL 5000 -#define XY_ACCEL 1000 - -#define _PI 3.14159265F +const constexpr uint16_t Z_MIN_DELAY = 200; +const constexpr uint16_t Z_ACCEL = 5000; /// \returns positive value always #define ABS(a) \ @@ -250,7 +247,6 @@ bool xyzcal_spiral2(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16_t radi { bool ret = false; float r = 0; //radius - uint8_t n = 0; //point number uint16_t ad = 0; //angle [deg] float ar; //angle [rad] uint8_t dad = 0; //delta angle [deg] @@ -278,11 +274,9 @@ bool xyzcal_spiral2(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16_t radi dad = dad_max - ((719 - ad) / k); r = (float)(((uint32_t)(719 - ad)) * (-radius)) / 720; } - ar = (ad + rotation)* (float)_PI / 180; - float _cos = cos(ar); - float _sin = sin(ar); - int x = (int)(cx + (_cos * r)); - int y = (int)(cy + (_sin * r)); + ar = (ad + rotation)* (float)M_PI / 180; + int x = (int)(cx + (cos(ar) * r)); + int y = (int)(cy + (sin(ar) * r)); int z = (int)(z0 - ((float)((int32_t)dz * ad) / 720)); if (xyzcal_lineXYZ_to(x, y, z, delay_us, check_pinda)) { @@ -290,7 +284,6 @@ bool xyzcal_spiral2(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16_t radi ret = true; break; } - n++; ad += dad; } if (pad) *pad = ad; From e24a763e46b1b62c2fd76d8d2bfcc50a98875b14 Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 14:45:55 +0100 Subject: [PATCH 16/28] Cleanup --- Firmware/xyzcal.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 8c7a3f53..3c2a6bb2 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -29,6 +29,10 @@ #define _Z ((int16_t)count_position[Z_AXIS]) #define _E ((int16_t)count_position[E_AXIS]) +#ifndef M_PI +const constexpr float M_PI = 3.1415926535897932384626433832795f; +#endif + const constexpr uint8_t X_PLUS = 0; const constexpr uint8_t X_MINUS = 1; const constexpr uint8_t Y_PLUS = 0; @@ -447,7 +451,7 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ /// already more zeros on the line if (hist[0] >= 16){ - DBG(_n("zeros: %d\n"), hist[0]); + DBG(_n("zeros %d\n"), hist[0]); return true; } @@ -464,7 +468,7 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ if (sum >= 24) --i; - DBG(_n("sum %d, index %d\n"), sum, i); + DBG(_n("zeros %d, index %d\n"), sum, i); // DBG(_n("min_z %d\n"), min_z); min_z += i; // DBG(_n("min_z %d\n"), min_z); From 25d138d198d5a532634bbb6ea60133c1570ba48b Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 15:10:01 +0100 Subject: [PATCH 17/28] Revert max.speed --- Firmware/xyzcal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 3c2a6bb2..783740e1 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -858,7 +858,7 @@ bool xyzcal_scan_and_process(void){ uint8_t *matrix32 = (uint8_t *)block_buffer; uint16_t *pattern = (uint16_t *)(matrix32 + 32 * 32); - xyzcal_scan_pixels_32x32_Zhop(x, y, z - 72, 2400, 600, matrix32); + xyzcal_scan_pixels_32x32_Zhop(x, y, z - 72, 2400, 200, matrix32); print_image(matrix32); for (uint8_t i = 0; i < 12; i++){ From 979525f0283dad989b356eecb56d9078a2696498 Mon Sep 17 00:00:00 2001 From: espr14 Date: Tue, 22 Dec 2020 19:34:12 +0100 Subject: [PATCH 18/28] Add more restarts --- Firmware/xyzcal.cpp | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 783740e1..5c21b4fb 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -475,12 +475,6 @@ bool more_zeros(uint8_t* pixels, int16_t &min_z){ return false; } -enum { - RESTART_INIT, - DO_RESTART, - WAS_RESTARTED -}; - void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ if (!pixels) return; @@ -491,13 +485,10 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); int16_t start_z; uint16_t steps_to_go; - /// restart if needed but just once - /// 0 = init, 1 = do restart, 2 = restart was done, don't restart any more - uint8_t restart = RESTART_INIT; + /// available restarts (if needed) + uint8_t restarts = 2; do { - if (restart == DO_RESTART) - restart = WAS_RESTARTED; for (uint8_t r = 0; r < 32; r++){ ///< Y axis xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); for (int8_t d = 0; d < 2; ++d){ ///< direction @@ -598,16 +589,16 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ count_position[2] = z; } } - /// do this in the first row only - if (r == 0 && restart == RESTART_INIT){ - if (!more_zeros(pixels, min_z)) - restart = DO_RESTART; + /// do the min_z addjusting in the first row only + if (r == 0 && restarts){ + if (more_zeros(pixels, min_z)) + restarts = 0; } - if (restart == DO_RESTART) + if (restarts) break; // DBG(_n("\n\n")); } - } while (restart == DO_RESTART); + } while (restarts--); } /// Returns rate of match From e6eb3be2472538694827301d516a757be5be7924 Mon Sep 17 00:00:00 2001 From: espr14 Date: Wed, 23 Dec 2020 16:56:04 +0100 Subject: [PATCH 19/28] Set jerk = 1, accel. = 1000 --- Firmware/xyzcal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 5c21b4fb..25863ae8 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -41,11 +41,11 @@ const constexpr uint8_t Z_PLUS = 0; const constexpr uint8_t Z_MINUS = 1; /// Max. jerk in PrusaSlicer, 10000 = 1 mm/s -const constexpr uint16_t MAX_DELAY = 1000; +const constexpr uint16_t MAX_DELAY = 10000; const constexpr float MIN_SPEED = 0.01f / (MAX_DELAY * 0.000001f); /// 200 = 50 mm/s const constexpr uint16_t Z_MIN_DELAY = 200; -const constexpr uint16_t Z_ACCEL = 5000; +const constexpr uint16_t Z_ACCEL = 1000; /// \returns positive value always #define ABS(a) \ From 62c36f718b30037095ab43aa4da680bed9f3480c Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 7 Dec 2020 15:32:19 +0100 Subject: [PATCH 20/28] =?UTF-8?q?Add=20SuperPINDA=20support=20for=20MK2.5/?= =?UTF-8?q?S=20-=20Changed=20DETECT=5FSUPERPINDA=20to=20SUPERPINDA=5FSUPPO?= =?UTF-8?q?RT=20as=20on=20miniRAMo=20the=20thermistor=20readings=20below?= =?UTF-8?q?=2030=C2=B0C=20=20=20aren't=20accurate=20egnough=20to=20determi?= =?UTF-8?q?ne=20if=20SUPERPINDA=20is=20connected=20or=20not=20-=20Add=20LC?= =?UTF-8?q?D=20toggle=20menu=20Settings=20->=20HW=20Setup=20->=20SuperPIND?= =?UTF-8?q?A=20[Yes/No]=20to=20overwrite=20SuperPINDA=20detection=20=20=20?= =?UTF-8?q?-=20If=20EEPROM=5FPINDA=5FTEMP=5FCOMPENSTATION=20is=20empty=20?= =?UTF-8?q?=3D=200xff=20then=20detect=20SuperPINDA=20by=20checking=20therm?= =?UTF-8?q?istor=20=20=20-=20If=20EEPROM=5FPINDA=5FTEMP=5FCOMPENSTAION=20i?= =?UTF-8?q?s=200=20then=20forec=20enable=20for=20temperature=20compensatio?= =?UTF-8?q?n=20menues=20and=20functions=20=20=20-=20If=20EEPROM=5FPINDA=5F?= =?UTF-8?q?TEMP=5FCOMPENSATION=20is=201=20then=20force=20disable=20for=20t?= =?UTF-8?q?emperature=20compensation=20menues=20and=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Firmware/Marlin_main.cpp | 8 ++++---- Firmware/eeprom.h | 7 +++++-- Firmware/temperature.cpp | 14 ++++++++++++-- Firmware/ultralcd.cpp | 19 +++++++++++++++++++ Firmware/ultralcd.h | 2 ++ .../variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 2 ++ .../variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 2 ++ .../1_75mm_MK25S-RAMBo10a-E3Dv6full.h | 2 ++ .../1_75mm_MK25S-RAMBo13a-E3Dv6full.h | 2 ++ .../variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 +- .../variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 +- 11 files changed, 52 insertions(+), 10 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a83d64b8..f6509cdc 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4572,7 +4572,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) The Original i3 Prusa MK2/s uses PINDAv1 and this calibration improves the temperature drift, but not as good as the PINDAv2. superPINDA sensor has internal temperature compensation and no thermistor output. There is no point of doing temperature calibration in such case. - If PINDA_THERMISTOR and DETECT_SUPERPINDA is defined during compilation, calibration is skipped with serial message "No PINDA thermistor". + If PINDA_THERMISTOR and SUPERPINDA_SUPPORT is defined during compilation, calibration is skipped with serial message "No PINDA thermistor". This can be caused also if PINDA thermistor connection is broken or PINDA temperature is lower than PINDA_MINTEMP. #### Example @@ -10502,9 +10502,9 @@ float temp_comp_interpolation(float inp_temperature) { #ifdef PINDA_THERMISTOR constexpr int start_compensating_temp = 35; temp_C[i] = start_compensating_temp + i * 5; //temperature in degrees C -#ifdef DETECT_SUPERPINDA - static_assert(start_compensating_temp >= PINDA_MINTEMP, "Temperature compensation start point is lower than PINDA_MINTEMP."); -#endif //DETECT_SUPERPINDA +#ifdef SUPERPINDA_SUPPORT + static_assert(start_compensating_temp >= PINDA_MINTEMP, "Temperature compensation start point is lower than PINDA_MINTEMP."); +#endif //SUPERPINDA_SUPPORT #else temp_C[i] = 50 + i * 10; //temperature in C #endif diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 5cb7ddb8..f234bb71 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -365,6 +365,9 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | ffh 255 | ffh 255 | Experimental menu visibility unknown state | LCD menu | D3 Ax0d2a C1 | ^ | ^ | ^ | 00h 0 | ^ | Experimental menu visibility hidden | ^ | ^ | ^ | ^ | ^ | 01h 1 | ^ | Experimental menu visibility visible | ^ | ^ +| 0x0D29 3369 | uint8 | EEPROM_PINDA_TEMP_COMPENSATION | ffh 255 | ffh 255 | PINDA temp compensation unknown state | LCD menu | D3 Ax0d29 C1 +| ^ | ^ | ^ | 00h 0 | ^ | PINDA has no temp compensation PINDA v1/2 | ^ | ^ +| ^ | ^ | ^ | 01h 1 | ^ | PINDA has temp compensation aka SuperPINDA | ^ | ^ | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code @@ -569,9 +572,9 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_ALTFAN_OVERRIDE (EEPROM_UVLO_LA_K-1) //uint8 #define EEPROM_EXPERIMENTAL_VISIBILITY (EEPROM_ALTFAN_OVERRIDE-1) //uint8 - +#define EEPROM_PINDA_TEMP_COMPENSATION (EEPROM_EXPERIMENTAL_VISIBILITY-1) //uint8 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_EXPERIMENTAL_VISIBILITY +#define EEPROM_LAST_ITEM EEPROM_PINDA_TEMP_COMPENSATION // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index cb4fc8ae..a7ff4dff 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -2325,11 +2325,21 @@ float unscalePID_d(float d) //! //! @retval true firmware should do temperature compensation and allow calibration //! @retval false PINDA thermistor is not detected, disable temperature compensation and calibration +//! @retval true/false when overwritten in LCD menu Settings->HW Setup->SuperPINDA //! bool has_temperature_compensation() { -#ifdef DETECT_SUPERPINDA - return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; +#ifdef SUPERPINDA_SUPPORT + uint8_t pinda_temp_compensation = eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION); + if (pinda_temp_compensation == EEPROM_EMPTY_VALUE) //Unkown PINDA temp compenstation, so check it. + { + //SERIAL_ECHOLNPGM("Current PINDATEMP:"); + //SERIAL_ECHO(current_temperature_pinda); + //SERIAL_ECHOLN(PINDA_MINTEMP); + return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; + } + else if (pinda_temp_compensation == 0) return true; //Overwritten via LCD menu SuperPINDA [No] + else return false; //Overwritten via LCD menu SuperPINDA [YES] #else return true; #endif diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 44c2dff7..e20180b6 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5753,6 +5753,15 @@ void lcd_hw_setup_menu(void) // can not be "static" MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu);////MSG_MENU_EXPERIMENTAL c=18 } +#ifdef SUPERPINDA_SUPPORT + //! The SuperPINDA is detected when the PINDA temp is below its defined limit. + //! This works well on the EINSY board but not on the miniRAMBo board as + //! as a disconnected SuperPINDA will show higher temps compared to an EINSY board. + //! + //! This menu allows the user to en-/disable the SuperPINDA manualy + MENU_ITEM_TOGGLE_P(_N("SuperPINDA"), eeprom_read_byte((unsigned char *)EEPROM_PINDA_TEMP_COMPENSATION) ? _T(MSG_YES) : _T(MSG_NO), lcd_pinda_temp_compensation_toggle); +#endif //SUPERPINDA_SUPPORT + MENU_END(); } @@ -9235,3 +9244,13 @@ void lcd_experimental_menu() MENU_END(); } + +void lcd_pinda_temp_compensation_toggle() +{ + uint8_t pinda_temp_compensation = eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION); + if (pinda_temp_compensation == EEPROM_EMPTY_VALUE) + pinda_temp_compensation = 1; + else + pinda_temp_compensation = !pinda_temp_compensation; + eeprom_update_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION, pinda_temp_compensation); +} \ No newline at end of file diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 7c361332..e45daaa1 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -262,4 +262,6 @@ void lcd_wizard(WizState state); extern void lcd_experimental_toggle(); extern void lcd_experimental_menu(); +extern void lcd_pinda_temp_compensation_toggle(); + #endif //ULTRALCD_H diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index f2ef69e9..19f54b48 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -175,6 +175,8 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif +#define SUPERPINDA_SUPPORT +#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index 7eaba3d6..42f60454 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -176,6 +176,8 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif +#define SUPERPINDA_SUPPORT +#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h index ee245bd4..2e5fc638 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h @@ -175,6 +175,8 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif +#define SUPERPINDA_SUPPORT +#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h index 6bf30f19..55b899a4 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h @@ -176,6 +176,8 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif +#define SUPERPINDA_SUPPORT +#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 04b4c526..4f8bacf2 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -294,7 +294,7 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif -#define DETECT_SUPERPINDA +#define SUPERPINDA_SUPPORT #define PINDA_MINTEMP BED_MINTEMP #define AMBIENT_MINTEMP -30 diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index c869ec51..f4a53be1 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -296,7 +296,7 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif -#define DETECT_SUPERPINDA +#define SUPERPINDA_SUPPORT #define PINDA_MINTEMP BED_MINTEMP #define AMBIENT_MINTEMP -30 From 732b6e0cad10fe2d05fe642078bce3406dd2e40e Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 7 Dec 2020 15:44:49 +0100 Subject: [PATCH 21/28] Cleanup --- Firmware/temperature.cpp | 5 +---- Firmware/ultralcd.cpp | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index a7ff4dff..dbd5fd9d 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -2325,7 +2325,7 @@ float unscalePID_d(float d) //! //! @retval true firmware should do temperature compensation and allow calibration //! @retval false PINDA thermistor is not detected, disable temperature compensation and calibration -//! @retval true/false when overwritten in LCD menu Settings->HW Setup->SuperPINDA +//! @retval true/false when forced via LCD menu Settings->HW Setup->SuperPINDA //! bool has_temperature_compensation() { @@ -2333,9 +2333,6 @@ bool has_temperature_compensation() uint8_t pinda_temp_compensation = eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION); if (pinda_temp_compensation == EEPROM_EMPTY_VALUE) //Unkown PINDA temp compenstation, so check it. { - //SERIAL_ECHOLNPGM("Current PINDATEMP:"); - //SERIAL_ECHO(current_temperature_pinda); - //SERIAL_ECHOLN(PINDA_MINTEMP); return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; } else if (pinda_temp_compensation == 0) return true; //Overwritten via LCD menu SuperPINDA [No] diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e20180b6..d721e044 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -9253,4 +9253,6 @@ void lcd_pinda_temp_compensation_toggle() else pinda_temp_compensation = !pinda_temp_compensation; eeprom_update_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION, pinda_temp_compensation); -} \ No newline at end of file + SERIAL_ECHOLNPGM("LCD U SuperPINDA:"); + SERIAL_ECHOLN(pinda_temp_compensation); +} From a97587f373eda83e862a70e14f85a2ae3a7b6baf Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Tue, 8 Dec 2020 17:27:00 +0100 Subject: [PATCH 22/28] Changed PINDA_MINTEMP having own value Prevent bad readings/issues if someone changes the bed thermistor that is "better" with lower min values and creates a custom firmware. The firmware will now be in the range of the PINDAv2 thermistor independant from the bed thermistor (which may change and need adjustments) --- Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 2 +- Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 2 +- Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h | 2 +- Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h | 2 +- Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 +- Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index 19f54b48..fedb1c04 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -176,7 +176,7 @@ #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif #define SUPERPINDA_SUPPORT -#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index 42f60454..314aaf6e 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -177,7 +177,7 @@ #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif #define SUPERPINDA_SUPPORT -#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h index 2e5fc638..ba05843d 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h @@ -176,7 +176,7 @@ #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif #define SUPERPINDA_SUPPORT -#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h index 55b899a4..857acbab 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h @@ -177,7 +177,7 @@ #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif #define SUPERPINDA_SUPPORT -#define PINDA_MINTEMP BED_MINTEMP //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 4f8bacf2..f2b302ae 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -295,7 +295,7 @@ #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif #define SUPERPINDA_SUPPORT -#define PINDA_MINTEMP BED_MINTEMP +#define PINDA_MINTEMP 10 #define AMBIENT_MINTEMP -30 // Maxtemps diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index f4a53be1..668f3000 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -297,7 +297,7 @@ #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif #define SUPERPINDA_SUPPORT -#define PINDA_MINTEMP BED_MINTEMP +#define PINDA_MINTEMP 10 #define AMBIENT_MINTEMP -30 // Maxtemps From 4b510fef0aec47b9eb5cae97bd5a16a117201b0e Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Tue, 8 Dec 2020 17:50:04 +0100 Subject: [PATCH 23/28] Add PINDA_TEMP_COMP variable to enable SuperPINDA toggle menu/function --- Firmware/temperature.cpp | 4 ++++ Firmware/ultralcd.cpp | 8 +++++--- Firmware/ultralcd.h | 2 ++ Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 1 + Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 1 + Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h | 1 + Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h | 1 + Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 1 + Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 1 + 9 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index dbd5fd9d..d429bb88 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -2330,13 +2330,17 @@ float unscalePID_d(float d) bool has_temperature_compensation() { #ifdef SUPERPINDA_SUPPORT +#ifdef PINDA_TEMP_COMP uint8_t pinda_temp_compensation = eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION); if (pinda_temp_compensation == EEPROM_EMPTY_VALUE) //Unkown PINDA temp compenstation, so check it. { +#endif //PINDA_TEMP_COMP return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; +#ifdef PINDA_TEMP_COMP } else if (pinda_temp_compensation == 0) return true; //Overwritten via LCD menu SuperPINDA [No] else return false; //Overwritten via LCD menu SuperPINDA [YES] +#endif //PINDA_TEMP_COMP #else return true; #endif diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index d721e044..7dca76be 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5753,14 +5753,14 @@ void lcd_hw_setup_menu(void) // can not be "static" MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu);////MSG_MENU_EXPERIMENTAL c=18 } -#ifdef SUPERPINDA_SUPPORT +#ifdef PINDA_TEMP_COMP //! The SuperPINDA is detected when the PINDA temp is below its defined limit. //! This works well on the EINSY board but not on the miniRAMBo board as //! as a disconnected SuperPINDA will show higher temps compared to an EINSY board. //! //! This menu allows the user to en-/disable the SuperPINDA manualy MENU_ITEM_TOGGLE_P(_N("SuperPINDA"), eeprom_read_byte((unsigned char *)EEPROM_PINDA_TEMP_COMPENSATION) ? _T(MSG_YES) : _T(MSG_NO), lcd_pinda_temp_compensation_toggle); -#endif //SUPERPINDA_SUPPORT +#endif //PINDA_TEMP_COMP MENU_END(); } @@ -9245,6 +9245,7 @@ void lcd_experimental_menu() MENU_END(); } +#ifdef PINDA_TEMP_COMP void lcd_pinda_temp_compensation_toggle() { uint8_t pinda_temp_compensation = eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION); @@ -9253,6 +9254,7 @@ void lcd_pinda_temp_compensation_toggle() else pinda_temp_compensation = !pinda_temp_compensation; eeprom_update_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION, pinda_temp_compensation); - SERIAL_ECHOLNPGM("LCD U SuperPINDA:"); + SERIAL_ECHOLNPGM("SuperPINDA:"); SERIAL_ECHOLN(pinda_temp_compensation); } +#endif //PINDA_TEMP_COMP diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index e45daaa1..cca4eced 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -262,6 +262,8 @@ void lcd_wizard(WizState state); extern void lcd_experimental_toggle(); extern void lcd_experimental_menu(); +#ifdef PINDA_TEMP_COMP extern void lcd_pinda_temp_compensation_toggle(); +#endif //PINDA_TEMP_COMP #endif //ULTRALCD_H diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index fedb1c04..1e77dce8 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -177,6 +177,7 @@ #endif #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index 314aaf6e..2d4d73c2 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -178,6 +178,7 @@ #endif #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h index ba05843d..4670d218 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h @@ -177,6 +177,7 @@ #endif #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h index 857acbab..22af4341 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h @@ -178,6 +178,7 @@ #endif #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 30 //The miniRAMBo thermistor readings below 30°C aren't very accurate +#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index f2b302ae..b7c5d54c 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -297,6 +297,7 @@ #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 10 #define AMBIENT_MINTEMP -30 +//#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index 668f3000..b278ab00 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -299,6 +299,7 @@ #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 10 #define AMBIENT_MINTEMP -30 +//#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) From 76eb7431392aa509ec9668509dc2f209c7697914 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Tue, 8 Dec 2020 18:39:54 +0100 Subject: [PATCH 24/28] Set default SuperPINDA toggle on MK2.5/S to NO --- Firmware/eeprom.cpp | 4 ++++ Firmware/ultralcd.cpp | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Firmware/eeprom.cpp b/Firmware/eeprom.cpp index 93098e93..4f519cae 100644 --- a/Firmware/eeprom.cpp +++ b/Firmware/eeprom.cpp @@ -93,6 +93,10 @@ void eeprom_init() eeprom_switch_to_next_sheet(); } check_babystep(); + +#ifdef PINDA_TEMP_COMP +if (eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_PINDA_TEMP_COMPENSATION, 0); +#endif //PINDA_TEMP_COMP } //! @brief Get default sheet name for index diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 7dca76be..27466d0d 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5759,7 +5759,7 @@ void lcd_hw_setup_menu(void) // can not be "static" //! as a disconnected SuperPINDA will show higher temps compared to an EINSY board. //! //! This menu allows the user to en-/disable the SuperPINDA manualy - MENU_ITEM_TOGGLE_P(_N("SuperPINDA"), eeprom_read_byte((unsigned char *)EEPROM_PINDA_TEMP_COMPENSATION) ? _T(MSG_YES) : _T(MSG_NO), lcd_pinda_temp_compensation_toggle); + MENU_ITEM_TOGGLE_P(_N("SuperPINDA"), eeprom_read_byte((uint8_t *)EEPROM_PINDA_TEMP_COMPENSATION) ? _T(MSG_YES) : _T(MSG_NO), lcd_pinda_temp_compensation_toggle); #endif //PINDA_TEMP_COMP MENU_END(); @@ -9249,8 +9249,8 @@ void lcd_experimental_menu() void lcd_pinda_temp_compensation_toggle() { uint8_t pinda_temp_compensation = eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION); - if (pinda_temp_compensation == EEPROM_EMPTY_VALUE) - pinda_temp_compensation = 1; + if (pinda_temp_compensation == EEPROM_EMPTY_VALUE) // On MK2.5/S the EEPROM_EMPTY_VALUE will be set to 0 during eeprom_init. + pinda_temp_compensation = 1; // But for MK3/S it should be 1 so SuperPINDA is "active" else pinda_temp_compensation = !pinda_temp_compensation; eeprom_update_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION, pinda_temp_compensation); From 12f41022720a84b2ef6d5286669f4b6e42503fd3 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Tue, 8 Dec 2020 18:45:34 +0100 Subject: [PATCH 25/28] Group PINDA defines --- Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 +- Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index b7c5d54c..7bd7be43 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -296,8 +296,8 @@ #endif #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 10 -#define AMBIENT_MINTEMP -30 //#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function +#define AMBIENT_MINTEMP -30 // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index b278ab00..3056c436 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -298,8 +298,8 @@ #endif #define SUPERPINDA_SUPPORT #define PINDA_MINTEMP 10 -#define AMBIENT_MINTEMP -30 //#define PINDA_TEMP_COMP //Used to enable SuperPINDA toggle menu/function +#define AMBIENT_MINTEMP -30 // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) From 80e32ce1a5213dd7731f0aaa16a180201bd29e80 Mon Sep 17 00:00:00 2001 From: espr14 Date: Fri, 25 Dec 2020 15:27:42 +0100 Subject: [PATCH 26/28] Turn off speed optimization due to MK2.5 --- Firmware/xyzcal.cpp | 237 ++++++++++++++++---------------------------- 1 file changed, 87 insertions(+), 150 deletions(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 25863ae8..7ad6dd75 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -423,58 +423,6 @@ void go_and_stop(uint8_t axis, int16_t dec, uint16_t &delay_us, uint16_t &steps) --steps; } -/// Count number of zeros in the 32 byte array -/// If the number is less than 16, it moves @min_z up -/// Zeros make measuring faster but there cannot be too much -bool more_zeros(uint8_t* pixels, int16_t &min_z){ - uint8_t hist[256]; - uint8_t i = 0; - - /// clear - do { - hist[i] = 0; - } while (i++ < 255); - - /// fill - for (i = 0; i < 32; ++i){ - ++hist[pixels[i]]; - } - - // /// print histogram - // i = 0; - // DBG(_n("hist: ")); - // do { - // DBG(_n("%d "), hist[i]); - // } while (i++ < 255); - // DBG(_n("\n")); - - - /// already more zeros on the line - if (hist[0] >= 16){ - DBG(_n("zeros %d\n"), hist[0]); - return true; - } - - /// find threshold - uint8_t sum = 0; - i = 0; - do { - sum += hist[i]; - if (sum >= 16) - break; - } while (i++ < 255); - - /// avoid too much zeros - if (sum >= 24) - --i; - - DBG(_n("zeros %d, index %d\n"), sum, i); - // DBG(_n("min_z %d\n"), min_z); - min_z += i; - // DBG(_n("min_z %d\n"), min_z); - return false; -} - void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t* pixels){ if (!pixels) return; @@ -485,120 +433,109 @@ void xyzcal_scan_pixels_32x32_Zhop(int16_t cx, int16_t cy, int16_t min_z, int16_ xyzcal_lineXYZ_to(cx - 1024, cy - 1024, min_z, delay_us, 0); int16_t start_z; uint16_t steps_to_go; - /// available restarts (if needed) - uint8_t restarts = 2; - do { - for (uint8_t r = 0; r < 32; r++){ ///< Y axis - xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); - for (int8_t d = 0; d < 2; ++d){ ///< direction - xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, min_z, delay_us, 0); + for (uint8_t r = 0; r < 32; r++){ ///< Y axis + xyzcal_lineXYZ_to(_X, cy - 1024 + r * 64, z, delay_us, 0); + for (int8_t d = 0; d < 2; ++d){ ///< direction + xyzcal_lineXYZ_to((d & 1) ? (cx + 1024) : (cx - 1024), _Y, min_z, delay_us, 0); - z = _Z; - sm4_set_dir(X_AXIS, d); - for (uint8_t c = 0; c < 32; c++){ ///< X axis + z = _Z; + sm4_set_dir(X_AXIS, d); + for (uint8_t c = 0; c < 32; c++){ ///< X axis - z_trig = min_z; + z_trig = min_z; - /// move up to un-trigger (surpress hysteresis) - sm4_set_dir(Z_AXIS, Z_PLUS); - /// speed up from stop, go half the way - current_delay_us = MAX_DELAY; - for (start_z = z; z < (max_z + start_z) / 2; ++z){ - if (!_PINDA){ - break; - } - accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + /// move up to un-trigger (surpress hysteresis) + sm4_set_dir(Z_AXIS, Z_PLUS); + /// speed up from stop, go half the way + current_delay_us = MAX_DELAY; + for (start_z = z; z < (max_z + start_z) / 2; ++z){ + if (!_PINDA){ + break; } + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + } - if(_PINDA){ - uint16_t steps_to_go = MAX(0, max_z - z); - while (_PINDA && z < max_z){ - go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); - ++z; - } - } - /// slow down to stop - while (current_delay_us < MAX_DELAY){ - accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); + if(_PINDA){ + uint16_t steps_to_go = MAX(0, max_z - z); + while (_PINDA && z < max_z){ + go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); ++z; } + } + /// slow down to stop + while (current_delay_us < MAX_DELAY){ + accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); + ++z; + } - /// move down to trigger - sm4_set_dir(Z_AXIS, Z_MINUS); - /// speed up - current_delay_us = MAX_DELAY; - for (start_z = z; z > (min_z + start_z) / 2; --z){ - if (_PINDA){ - z_trig = z; - break; - } - accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); - } - /// slow down - if(!_PINDA){ - steps_to_go = MAX(0, z - min_z); - while (!_PINDA && z > min_z){ - go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); - --z; - } + /// move down to trigger + sm4_set_dir(Z_AXIS, Z_MINUS); + /// speed up + current_delay_us = MAX_DELAY; + for (start_z = z; z > (min_z + start_z) / 2; --z){ + if (_PINDA){ z_trig = z; + break; } - /// slow down to stop - while (z > min_z && current_delay_us < MAX_DELAY){ - accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); + accelerate(Z_AXIS_MASK, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + } + /// slow down + if(!_PINDA){ + steps_to_go = MAX(0, z - min_z); + while (!_PINDA && z > min_z){ + go_and_stop(Z_AXIS_MASK, Z_ACCEL, current_delay_us, steps_to_go); --z; } - - count_position[2] = z; - if (d == 0){ - line_buffer[c] = (uint16_t)(z_trig - min_z); - } else { - /// data reversed in X - // DBG(_n("%04x"), (line_buffer[31 - c] + (z - min_z)) / 2); - /// save average of both directions - pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); - } - - /// move to the next point and move Z up diagonally (if needed) - current_delay_us = MAX_DELAY; - // const int8_t dir = (d & 1) ? -1 : 1; - const int16_t end_x = ((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx; - const int16_t length_x = ABS(end_x - _X); - const int16_t half_x = length_x / 2; - int16_t x = 0; - /// don't go up if PINDA not triggered - const bool up = _PINDA; - int8_t axis = up ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; - - sm4_set_dir(Z_AXIS, Z_PLUS); - /// speed up - for (x = 0; x <= half_x; ++x){ - accelerate(axis, Z_ACCEL, current_delay_us, Z_MIN_DELAY); - if (up) - ++z; - } - /// slow down - steps_to_go = length_x - x; - for (; x < length_x; ++x){ - go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); - if (up) - ++z; - } - count_position[0] = end_x; - count_position[2] = z; + z_trig = z; } + /// slow down to stop + while (z > min_z && current_delay_us < MAX_DELAY){ + accelerate(Z_AXIS_MASK, -Z_ACCEL, current_delay_us, Z_MIN_DELAY); + --z; + } + + count_position[2] = z; + if (d == 0){ + line_buffer[c] = (uint16_t)(z_trig - min_z); + } else { + /// data reversed in X + // DBG(_n("%04x"), (line_buffer[31 - c] + (z - min_z)) / 2); + /// save average of both directions + pixels[(uint16_t)r * 32 + (31 - c)] = (uint8_t)MIN((uint32_t)255, ((uint32_t)line_buffer[31 - c] + (z_trig - min_z)) / 2); + } + + /// move to the next point and move Z up diagonally (if needed) + current_delay_us = MAX_DELAY; + // const int8_t dir = (d & 1) ? -1 : 1; + const int16_t end_x = ((d & 1) ? 1 : -1) * (64 * (16 - c) - 32) + cx; + const int16_t length_x = ABS(end_x - _X); + const int16_t half_x = length_x / 2; + int16_t x = 0; + /// don't go up if PINDA not triggered + const bool up = _PINDA; + int8_t axis = up ? X_AXIS_MASK | Z_AXIS_MASK : X_AXIS_MASK; + + sm4_set_dir(Z_AXIS, Z_PLUS); + /// speed up + for (x = 0; x <= half_x; ++x){ + accelerate(axis, Z_ACCEL, current_delay_us, Z_MIN_DELAY); + if (up) + ++z; + } + /// slow down + steps_to_go = length_x - x; + for (; x < length_x; ++x){ + go_and_stop(axis, Z_ACCEL, current_delay_us, steps_to_go); + if (up) + ++z; + } + count_position[0] = end_x; + count_position[2] = z; } - /// do the min_z addjusting in the first row only - if (r == 0 && restarts){ - if (more_zeros(pixels, min_z)) - restarts = 0; - } - if (restarts) - break; - // DBG(_n("\n\n")); } - } while (restarts--); + // DBG(_n("\n\n")); + } } /// Returns rate of match From 7e02a7f118cad642f7526d4a87565c0d04545630 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Sat, 26 Dec 2020 15:45:34 +0100 Subject: [PATCH 27/28] Version changed (3.9.3-RC1 build 3555) --- Firmware/Configuration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 45874e31..fda3bc9e 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -16,8 +16,8 @@ extern uint16_t nPrinterType; extern PGM_P sPrinterName; // Firmware version -#define FW_VERSION "3.9.2" -#define FW_COMMIT_NR 3524 +#define FW_VERSION "3.9.3-RC1" +#define FW_COMMIT_NR 3555 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN From 603d704178d6742c175f537fdab242eeeeafedaf Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Thu, 7 Jan 2021 12:50:58 +0100 Subject: [PATCH 28/28] Version changed (3.9.3 build 3556) --- Firmware/Configuration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index fda3bc9e..315f808a 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -16,8 +16,8 @@ extern uint16_t nPrinterType; extern PGM_P sPrinterName; // Firmware version -#define FW_VERSION "3.9.3-RC1" -#define FW_COMMIT_NR 3555 +#define FW_VERSION "3.9.3" +#define FW_COMMIT_NR 3556 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN