diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h index b288c34b0b0..506f3d464ce 100644 --- a/Marlin/Conditionals_post.h +++ b/Marlin/Conditionals_post.h @@ -1020,8 +1020,13 @@ #define _MESH_MAX_Y (MAX_PROBE_Y - (MESH_INSET)) #else // Boundaries for Cartesian probing based on set limits - #define _MESH_MIN_X (max(X_MIN_BED + MESH_INSET, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) - #define _MESH_MIN_Y (max(Y_MIN_BED + MESH_INSET, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #if ENABLED(AUTO_BED_LEVELING_UBL) + #define _MESH_MIN_X (max(X_MIN_BED + MESH_INSET, X_MIN_POS)) // UBL is careful not to probe off the bed. It does not + #define _MESH_MIN_Y (max(Y_MIN_BED + MESH_INSET, Y_MIN_POS)) // need *_PROBE_OFFSET_FROM_EXTRUDER in the mesh dimensions + #else + #define _MESH_MIN_X (max(X_MIN_BED + MESH_INSET, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MESH_MIN_Y (max(Y_MIN_BED + MESH_INSET, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #endif #define _MESH_MAX_X (min(X_MAX_BED - (MESH_INSET), X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) #define _MESH_MAX_Y (min(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) #endif diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp index e1d47a84a4f..3f18f5a225d 100644 --- a/Marlin/G26_Mesh_Validation_Tool.cpp +++ b/Marlin/G26_Mesh_Validation_Tool.cpp @@ -166,7 +166,7 @@ if (!is_lcd_clicked()) return false; // Return if the button isn't pressed lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); #if ENABLED(ULTIPANEL) - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif wait_for_release(); return true; @@ -280,7 +280,7 @@ strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue; // So... We cheat to get a message up. lcd_setstatusPGM(PSTR("Done Priming"), 99); - lcd_quick_feedback(); + lcd_quick_feedback(true); lcd_external_control = false; } else @@ -288,7 +288,7 @@ { #if ENABLED(ULTRA_LCD) lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99); - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif set_destination_from_current(); destination[E_AXIS] += g26_prime_length; @@ -483,7 +483,7 @@ #if ENABLED(ULTRA_LCD) if (g26_bed_temp > 25) { lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99); - lcd_quick_feedback(); + lcd_quick_feedback(true); lcd_external_control = true; #endif thermalManager.setTargetBed(g26_bed_temp); @@ -503,7 +503,7 @@ #if ENABLED(ULTRA_LCD) } lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99); - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif #endif @@ -525,7 +525,7 @@ #if ENABLED(ULTRA_LCD) lcd_reset_status(); - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif return G26_OK; diff --git a/Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h index 8b4fed11638..23e2bc15ceb 100644 --- a/Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h +++ b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h @@ -128,7 +128,7 @@ // Optional custom name for your RepStrap or other custom machine // Displayed in the LCD "Ready" message -#define CUSTOM_MACHINE_NAME "FT-2020 v4" +#define CUSTOM_MACHINE_NAME "FT-2020 v5" // Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) @@ -545,7 +545,7 @@ * Override with M203 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_MAX_FEEDRATE { 250, 250, 2, 17 } +#define DEFAULT_MAX_FEEDRATE { 250, 250, 6, 17 } /** * Default Max Acceleration (change/s) change = mm/s @@ -553,7 +553,7 @@ * Override with M201 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 4, 750 } +#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 10, 750 } /** * Default Acceleration (change/s) change = mm/s @@ -724,8 +724,8 @@ * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. */ -#define Z_CLEARANCE_DEPLOY_PROBE 3 // Z Clearance for Deploy/Stow -#define Z_CLEARANCE_BETWEEN_PROBES 3 // Z Clearance between probe points +#define Z_CLEARANCE_DEPLOY_PROBE 5 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points // For M851 give a range for adjusting the Z probe offset #define Z_PROBE_OFFSET_RANGE_MIN -20 @@ -796,8 +796,8 @@ #define X_MIN_POS 6 #define Y_MIN_POS 3 #define Z_MIN_POS 0 -#define X_MAX_POS 207 -#define Y_MAX_POS 182 +#define X_MAX_POS 212 +#define Y_MAX_POS 190 #define Z_MAX_POS 175 /** @@ -906,7 +906,7 @@ /** * Enable the G26 Mesh Validation Pattern tool. */ - //#define G26_MESH_VALIDATION + #define G26_MESH_VALIDATION #if ENABLED(G26_MESH_VALIDATION) #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for the G26 Mesh Validation Tool. @@ -971,7 +971,7 @@ //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh - #define MESH_INSET 1 // Mesh inset margin on print area + #define MESH_INSET 0 // Mesh inset margin on print area #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. #define GRID_MAX_POINTS_Y 10 @@ -1179,7 +1179,7 @@ // Specify a park position as { X, Y, Z } #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } #define NOZZLE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) - #define NOZZLE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define NOZZLE_PARK_Z_FEEDRATE 8 // Z axis feedrate in mm/s (not used for delta printers) #endif /** diff --git a/Marlin/ubl.h b/Marlin/ubl.h index 754e387dc39..db134c9ef2d 100644 --- a/Marlin/ubl.h +++ b/Marlin/ubl.h @@ -65,7 +65,7 @@ #if ENABLED(ULTRA_LCD) extern char lcd_status_message[]; - void lcd_quick_feedback(); + void lcd_quick_feedback(const bool clear_buttons); #endif #define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1)) @@ -91,7 +91,7 @@ #if ENABLED(NEWPANEL) static void move_z_with_encoder(const float &multiplier); static float measure_point_with_encoder(); - static float measure_business_card_thickness(const float&); + static float measure_business_card_thickness(const float); static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool); static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map); #endif diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index e1b00b47519..a047a81dab7 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -97,8 +97,9 @@ * C Continue G29 P1 C continues the generation of a partially-constructed Mesh without invalidating * previous measurements. * - * C Constant G29 P2 C specifies a Constant and tells the Manual Probe subsystem to use the current - * location in its search for the closest unmeasured Mesh Point. + * C G29 P2 C tells the Manual Probe subsystem to not use the current nozzle + * location in its search for the closest unmeasured Mesh Point. Instead, attempt to + * start at one end of the uprobed points and Continue sequentually. * * G29 P3 C specifies the Constant for the fill. Otherwise, uses a "reasonable" value. * @@ -414,6 +415,7 @@ tilt_mesh_based_on_3pts(z1, z2, z3); restore_ubl_active_state_and_leave(); } + do_blocking_move_to_xy(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y))); } #endif // HAS_BED_PROBE @@ -449,8 +451,10 @@ SERIAL_PROTOCOL(g29_y_pos); SERIAL_PROTOCOLLNPGM(").\n"); } +SERIAL_ECHO("Going into probe_entire_mesh()\n"); probe_entire_mesh(g29_x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, g29_y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, parser.seen('T'), parser.seen('E'), parser.seen('U')); +SERIAL_ECHO("Back from probe_entire_mesh()\n"); break; #endif // HAS_BED_PROBE @@ -463,7 +467,7 @@ SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations."); do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - if (!g29_x_flag && !g29_y_flag) { + if (parser.seen('C') && !g29_x_flag && !g29_y_flag) { /** * Use a good default location for the path. * The flipped > and < operators in these comparisons is intentional. @@ -480,10 +484,6 @@ #endif } - if (parser.seen('C')) { - g29_x_pos = current_position[X_AXIS]; - g29_y_pos = current_position[Y_AXIS]; - } if (parser.seen('B')) { g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness(Z_CLEARANCE_BETWEEN_PROBES); @@ -579,6 +579,7 @@ case 6: shift_mesh_height(); break; } +SERIAL_ECHO("at end of if (parser.seen('P')) {\n"); } // @@ -671,7 +672,7 @@ #if ENABLED(NEWPANEL) lcd_reset_alert_level(); LCD_MESSAGEPGM(""); - lcd_quick_feedback(); + lcd_quick_feedback(true); lcd_external_control = false; #endif @@ -729,12 +730,13 @@ bool click_and_hold(const clickFunc_t func=NULL) { if (is_lcd_clicked()) { - lcd_quick_feedback(); + lcd_quick_feedback(false); // Do NOT clear button status! If cleared, the code + // code can not look for a 'click and hold' const millis_t nxt = millis() + 1500UL; while (is_lcd_clicked()) { // Loop while the encoder is pressed. Uses hardware flag! idle(); // idle, of course if (ELAPSED(millis(), nxt)) { // After 1.5 seconds - lcd_quick_feedback(); + lcd_quick_feedback(true); if (func) (*func)(); wait_for_release(); safe_delay(50); // Debounce the Encoder wheel @@ -742,6 +744,7 @@ } } } + safe_delay(15); return false; } @@ -770,11 +773,13 @@ #if ENABLED(NEWPANEL) if (is_lcd_clicked()) { SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n"); - lcd_quick_feedback(); + lcd_quick_feedback(false); STOW_PROBE(); - wait_for_release(); + while (is_lcd_clicked()) idle(); lcd_external_control = false; restore_ubl_active_state_and_leave(); + lcd_quick_feedback(true); + safe_delay(50); // Debounce the Encoder wheel return; } #endif @@ -931,7 +936,7 @@ static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); } - float unified_bed_leveling::measure_business_card_thickness(const float &in_height) { + float unified_bed_leveling::measure_business_card_thickness(float in_height) { lcd_external_control = true; save_ubl_active_state_and_disable(); // Disable bed level correction for probing @@ -976,6 +981,7 @@ do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); lcd_external_control = false; KEEPALIVE_STATE(IN_HANDLER); + lcd_quick_feedback(true); ubl.restore_ubl_active_state_and_leave(); } @@ -984,7 +990,7 @@ lcd_external_control = true; save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe - do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); + do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_clearance); lcd_return_to_status(); @@ -1033,7 +1039,7 @@ } } while (location.x_index >= 0 && location.y_index >= 0); - if (do_ubl_mesh_map) display_map(g29_map_type); + if (do_ubl_mesh_map) display_map(g29_map_type); // show user where we're probing restore_ubl_active_state_and_leave(); KEEPALIVE_STATE(IN_HANDLER); @@ -1046,7 +1052,7 @@ #if ENABLED(NEWPANEL) LCD_MESSAGEPGM(MSG_UBL_DOING_G29); - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif g29_constant = 0.0; @@ -1169,7 +1175,7 @@ SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); #if ENABLED(NEWPANEL) LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif return; } @@ -1184,7 +1190,7 @@ SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); #if ENABLED(NEWPANEL) LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); - lcd_quick_feedback(); + lcd_quick_feedback(true); #endif return; } @@ -1225,17 +1231,20 @@ #endif SERIAL_ECHOLNPAIR("MESH_MIN_X " STRINGIFY(MESH_MIN_X) "=", MESH_MIN_X); + safe_delay(50); SERIAL_ECHOLNPAIR("MESH_MIN_Y " STRINGIFY(MESH_MIN_Y) "=", MESH_MIN_Y); - safe_delay(25); + safe_delay(50); SERIAL_ECHOLNPAIR("MESH_MAX_X " STRINGIFY(MESH_MAX_X) "=", MESH_MAX_X); + safe_delay(50); SERIAL_ECHOLNPAIR("MESH_MAX_Y " STRINGIFY(MESH_MAX_Y) "=", MESH_MAX_Y); - safe_delay(25); + safe_delay(50); SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X ", GRID_MAX_POINTS_X); + safe_delay(50); SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y ", GRID_MAX_POINTS_Y); - safe_delay(25); + safe_delay(50); SERIAL_ECHOLNPAIR("MESH_X_DIST ", MESH_X_DIST); SERIAL_ECHOLNPAIR("MESH_Y_DIST ", MESH_Y_DIST); - safe_delay(25); + safe_delay(50); SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: "); for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { @@ -1473,6 +1482,7 @@ lcd_return_to_status(); do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); LCD_MESSAGEPGM(MSG_EDITING_STOPPED); + lcd_quick_feedback(true); } void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) { @@ -1532,13 +1542,13 @@ lcd_mesh_edit_setup(new_z); - while (!is_lcd_clicked()) { + do { new_z = lcd_mesh_edit(); #if ENABLED(UBL_MESH_EDIT_MOVES_Z) do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited #endif idle(); - } + } while (!is_lcd_clicked()); if (!lcd_map_control) lcd_return_to_status(); @@ -1547,9 +1557,6 @@ // Let's work on specifying a proper API for the LCD ASAP, OK? lcd_external_control = true; - // this sequence to detect an is_lcd_clicked() debounce it and leave if it is - // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This - // should be redone and compressed. if (click_and_hold(abort_fine_tune)) goto FINE_TUNE_EXIT; @@ -1593,10 +1600,10 @@ y1 = y + ydir, y2 = y1 + ydir; // A NAN next to a pair of real values? if (isnan(z_values[x][y]) && !isnan(z_values[x1][y1]) && !isnan(z_values[x2][y2])) { - if (z_values[x1][y1] < z_values[x2][y2]) // Angled downward? - z_values[x][y] = z_values[x1][y1]; // Use nearest (maybe a little too high.) + if (z_values[x1][y1] < z_values[x2][y2]) // Angled downward? + z_values[x][y] = z_values[x1][y1]; // Use nearest (maybe a little too high.) else - z_values[x][y] = 2.0 * z_values[x1][y1] - z_values[x2][y2]; // Angled upward... + z_values[x][y] = 2.0 * z_values[x1][y1] - z_values[x2][y2]; // Angled upward... return true; } return false; @@ -1754,7 +1761,7 @@ #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { - rotation.debug(PSTR("rotation matrix:")); + rotation.debug(PSTR("rotation matrix:\n")); SERIAL_ECHOPGM("LSF Results A="); SERIAL_PROTOCOL_F(lsf_results.A, 7); SERIAL_ECHOPGM(" B="); @@ -1775,7 +1782,6 @@ } #endif - if (do_ubl_mesh_map) display_map(g29_map_type); } #endif // HAS_BED_PROBE diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index da8fb9abda5..998d8a3da1c 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -766,9 +766,10 @@ void kill_screen(const char* lcd_msg) { #endif } - void lcd_quick_feedback() { + void lcd_quick_feedback(const bool clear_buttons) { lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; - buttons = 0; + if (clear_buttons) + buttons = 0; next_button_update_ms = millis() + 500; // Buzz and wait. The delay is needed for buttons to settle! @@ -4664,8 +4665,8 @@ void kill_screen(const char* lcd_msg) { if (encoderDirection == -1) { // side effect which signals we are inside a menu if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM; else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; - else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) { menu_action_back(); lcd_quick_feedback(); } - else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) { lcd_return_to_status(); lcd_quick_feedback(); } + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) { menu_action_back(); lcd_quick_feedback(true); } + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) { lcd_return_to_status(); lcd_quick_feedback(true); } } else { if (buttons_reprapworld_keypad & (EN_REPRAPWORLD_KEYPAD_DOWN|EN_REPRAPWORLD_KEYPAD_UP|EN_REPRAPWORLD_KEYPAD_RIGHT)) { @@ -4933,7 +4934,7 @@ void lcd_update() { wait_for_unclick = true; // Set debounce flag to ignore continous clicks lcd_clicked = !wait_for_user && !no_reentry; // Keep the click if not waiting for a user-click wait_for_user = false; // Any click clears wait for user - lcd_quick_feedback(); // Always make a click sound + lcd_quick_feedback(true); // Always make a click sound } } else wait_for_unclick = false; diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index 5ce7cf366ce..02e0cb5047a 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -95,7 +95,7 @@ extern volatile uint8_t buttons; // The last-checked buttons in a bit array. void lcd_buttons_update(); - void lcd_quick_feedback(); // Audible feedback for a button click - could also be visual + void lcd_quick_feedback(const bool clear_buttons); // Audible feedback for a button click - could also be visual void lcd_completion_feedback(const bool good=true); #if ENABLED(ADVANCED_PAUSE_FEATURE)