1
0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2024-11-27 22:08:02 +00:00

Regression fixes for UBL's G29 P1, G29 P2, G29 P4 and G26 (#9213)

The changes to ultralcd.cpp for is_lcd_clicked() did not encompass the
full functionality of UBL's G29 P1, P2 and P4.   It also broke G26's
ability to abort in several of its phases.

This is the first pass at fixing the problem.   It has been tested for
correctness for several hours but more testing  needs to be done.
There may be a few follow up patches to finish covering all the corner
cases, but right now I need to merge this before any conflicts show up.

Some of these changes will need to be moved over to the bugfix-v2.0.0
branch.   That will happen a few days from now.
This commit is contained in:
Roxy-3D 2018-01-17 00:27:50 -06:00 committed by GitHub
parent 333bd8f394
commit c11665e92f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 70 additions and 58 deletions

View File

@ -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

View File

@ -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;

View File

@ -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
/**

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)