"Calibrate Z" was redefined to let the user move the X axis up

to the Z end stoppers and to re-calibrate the 9 bed point
reference values after the printer has been re-seated or transported.

New "Mesh Bed Leveling" function was added to the menu, doing what
the "Calibrate Z" was doing before.
This commit is contained in:
bubnikv 2016-08-04 17:42:54 +02:00
parent f9f9912fff
commit 32c8e9c2dc
7 changed files with 168 additions and 92 deletions

View File

@ -235,11 +235,6 @@ byte b[2];
int value;
};
#define BABYSTEP_LOADZ_BY_PLANNER
// Number of baby steps applied
int babystepLoadZ = 0;
float homing_feedrate[] = HOMING_FEEDRATE;
// Currently only the extruder axis may be switched to a relative mode.
// Other axes are always absolute or relative based on the common relative_mode flag.
@ -1921,12 +1916,7 @@ void process_commands()
// Reset baby stepping to zero, if the babystepping has already been loaded before. The babystepsTodo value will be
// consumed during the first movements following this statement.
#ifdef BABYSTEP_LOADZ_BY_PLANNER
shift_z(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
#else
babystepsTodoZsubtract(babystepLoadZ);
#endif /* BABYSTEP_LOADZ_BY_PLANNER */
babystepLoadZ = 0;
babystep_undo();
saved_feedrate = feedrate;
saved_feedmultiply = feedmultiply;
@ -2103,11 +2093,8 @@ void process_commands()
#ifndef MESH_BED_LEVELING
// If MESH_BED_LEVELING is not active, then it is the original Prusa i3.
// Offer the user to load the baby step value, which has been adjusted at the previous print session.
if(card.sdprinting) {
EEPROM_read_B(EEPROM_BABYSTEP_Z,&babystepLoadZ);
if(babystepLoadZ != 0)
if(card.sdprinting && eeprom_read_word((uint16_t *)EEPROM_BABYSTEP_Z))
lcd_adjust_z();
}
#endif
// Load the machine correction matrix
@ -2368,12 +2355,7 @@ void process_commands()
// Reset baby stepping to zero, if the babystepping has already been loaded before. The babystepsTodo value will be
// consumed during the first movements following this statement.
#ifdef BABYSTEP_LOADZ_BY_PLANNER
shift_z(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
#else
babystepsTodoZsubtract(babystepLoadZ);
#endif /* BABYSTEP_LOADZ_BY_PLANNER */
babystepLoadZ = 0;
babystep_undo();
// Cycle through all points and probe them
// First move up. During this first movement, the babystepping will be reverted.
@ -2460,28 +2442,7 @@ void process_commands()
clean_up_after_endstop_move();
// Apply Z height correction aka baby stepping before mesh bed leveing gets activated.
if(card.sdprinting || is_usb_printing )
{
if(eeprom_read_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET) == 0x01)
{
// End of G80: Apply the baby stepping value.
EEPROM_read_B(EEPROM_BABYSTEP_Z,&babystepLoadZ);
#if 0
SERIAL_ECHO("Z baby step: ");
SERIAL_ECHO(babystepLoadZ);
SERIAL_ECHO(", current Z: ");
SERIAL_ECHO(current_position[Z_AXIS]);
SERIAL_ECHO("correction: ");
SERIAL_ECHO(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
SERIAL_ECHOLN("");
#endif
#ifdef BABYSTEP_LOADZ_BY_PLANNER
shift_z(- float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
#else
babystepsTodoZadd(babystepLoadZ);
#endif /* BABYSTEP_LOADZ_BY_PLANNER */
}
}
babystep_apply();
bool eeprom_bed_correction_valid = eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1;
for (uint8_t i = 0; i < 4; ++ i) {
@ -2938,46 +2899,68 @@ void process_commands()
// the planner will not perform any adjustments in the XY plane.
// Wait for the motors to stop and update the current position with the absolute values.
world2machine_revert_to_uncorrected();
// Reset the baby step value applied without moving the axes.
babystep_reset();
// Mark all axes as in a need for homing.
memset(axis_known_position, 0, sizeof(axis_known_position));
// Let the user move the Z axes up to the end stoppers.
if (lcd_calibrate_z_end_stop_manual()) {
refresh_cmd_timeout();
// Move the print head close to the bed.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder);
st_synchronize();
// Home in the XY plane.
set_destination_to_current();
setup_for_endstop_move();
home_xy();
int8_t verbosity_level = 0;
if (code_seen('V')) {
// Just 'V' without a number counts as V1.
char c = strchr_pointer[1];
verbosity_level = (c == ' ' || c == '\t' || c == 0) ? 1 : code_value_short();
}
BedSkewOffsetDetectionResultType result = find_bed_offset_and_skew(verbosity_level);
uint8_t point_too_far_mask = 0;
clean_up_after_endstop_move();
// Print head up.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder);
st_synchronize();
if (result >= 0) {
// Second half: The fine adjustment.
// Let the planner use the uncorrected coordinates.
mbl.reset();
world2machine_reset();
// Home in the XY plane.
setup_for_endstop_move();
home_xy();
result = improve_bed_offset_and_skew(1, verbosity_level, point_too_far_mask);
if (code_seen('Z')) {
clean_up_after_endstop_move();
// Z only calibration.
// Load the machine correction matrix
world2machine_initialize();
// and correct the current_position to match the transformed coordinate system.
world2machine_update_current();
//FIXME
bool result = sample_mesh_and_store_reference();
// if (result) babystep_apply();
} else {
// Complete XYZ calibration.
BedSkewOffsetDetectionResultType result = find_bed_offset_and_skew(verbosity_level);
uint8_t point_too_far_mask = 0;
clean_up_after_endstop_move();
// Print head up.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder);
st_synchronize();
if (result >= 0) {
// Second half: The fine adjustment.
// Let the planner use the uncorrected coordinates.
mbl.reset();
world2machine_reset();
// Home in the XY plane.
setup_for_endstop_move();
home_xy();
result = improve_bed_offset_and_skew(1, verbosity_level, point_too_far_mask);
clean_up_after_endstop_move();
// Print head up.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder);
st_synchronize();
// if (result >= 0) babystep_apply();
}
lcd_bed_calibration_show_result(result, point_too_far_mask);
}
lcd_bed_calibration_show_result(result, point_too_far_mask);
} else {
// Timeouted.
}

View File

@ -1085,6 +1085,11 @@ const char * const MSG_MAX_LANG_TABLE[1] PROGMEM = {
MSG_MAX_EN
};
const char MSG_MESH_BED_LEVELING_EN[] PROGMEM = "Mesh Bed Leveling";
const char * const MSG_MESH_BED_LEVELING_LANG_TABLE[1] PROGMEM = {
MSG_MESH_BED_LEVELING_EN
};
const char MSG_MIN_EN[] PROGMEM = " \002 Min";
const char * const MSG_MIN_LANG_TABLE[1] PROGMEM = {
MSG_MIN_EN

View File

@ -286,6 +286,8 @@ extern const char* const MSG_MAIN_LANG_TABLE[LANG_NUM];
#define MSG_MAIN LANG_TABLE_SELECT(MSG_MAIN_LANG_TABLE)
extern const char* const MSG_MAX_LANG_TABLE[1];
#define MSG_MAX LANG_TABLE_SELECT_EXPLICIT(MSG_MAX_LANG_TABLE, 0)
extern const char* const MSG_MESH_BED_LEVELING_LANG_TABLE[1];
#define MSG_MESH_BED_LEVELING LANG_TABLE_SELECT_EXPLICIT(MSG_MESH_BED_LEVELING_LANG_TABLE, 0)
extern const char* const MSG_MIN_LANG_TABLE[1];
#define MSG_MIN LANG_TABLE_SELECT_EXPLICIT(MSG_MIN_LANG_TABLE, 0)
extern const char* const MSG_MOTION_LANG_TABLE[LANG_NUM];

View File

@ -314,4 +314,8 @@
#define MSG_BED_CORRECTION_REAR "Rear side um"
#define MSG_BED_CORRECTION_RESET "Reset"
#define MSG_MESH_BED_LEVELING "Mesh Bed Leveling"
#endif // LANGUAGE_EN_H

View File

@ -1908,6 +1908,42 @@ BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8
}
}
// Sample Z heights for the mesh bed leveling.
// In addition, store the results into an eeprom, to be used later for verification of the bed leveling process.
if (! sample_mesh_and_store_reference())
goto canceled;
enable_endstops(endstops_enabled);
enable_z_endstop(endstop_z_enabled);
// Don't let the manage_inactivity() function remove power from the motors.
refresh_cmd_timeout();
return result;
canceled:
// Don't let the manage_inactivity() function remove power from the motors.
refresh_cmd_timeout();
// Print head up.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
go_to_current(homing_feedrate[Z_AXIS]/60);
// Store the identity matrix to EEPROM.
reset_bed_offset_and_skew();
enable_endstops(endstops_enabled);
enable_z_endstop(endstop_z_enabled);
return result;
}
// Sample the 9 points of the bed and store them into the EEPROM as a reference.
// When calling this function, the X, Y, Z axes should be already homed,
// and the world2machine correction matrix should be active.
// Returns false if the reference values are more than 3mm far away.
bool sample_mesh_and_store_reference()
{
bool endstops_enabled = enable_endstops(false);
bool endstop_z_enabled = enable_z_endstop(false);
// Don't let the manage_inactivity() function remove power from the motors.
refresh_cmd_timeout();
// Sample Z heights for the mesh bed leveling.
// In addition, store the results into an eeprom, to be used later for verification of the bed leveling process.
{
@ -1952,7 +1988,7 @@ BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8
// The span of the Z offsets is extreme. Give up.
// Homing failed on some of the points.
SERIAL_PROTOCOLLNPGM("Exreme span of the Z values!");
goto canceled;
return false;
}
}
@ -2003,21 +2039,7 @@ BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8
enable_endstops(endstops_enabled);
enable_z_endstop(endstop_z_enabled);
// Don't let the manage_inactivity() function remove power from the motors.
refresh_cmd_timeout();
return result;
canceled:
// Don't let the manage_inactivity() function remove power from the motors.
refresh_cmd_timeout();
// Print head up.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
go_to_current(homing_feedrate[Z_AXIS]/60);
// Store the identity matrix to EEPROM.
reset_bed_offset_and_skew();
enable_endstops(endstops_enabled);
enable_z_endstop(endstop_z_enabled);
return result;
return true;
}
bool scan_bed_induction_points(int8_t verbosity_level)
@ -2083,9 +2105,54 @@ bool scan_bed_induction_points(int8_t verbosity_level)
}
// Shift a Z axis by a given delta.
void shift_z(float delta)
// To replace loading of the babystep correction.
static void shift_z(float delta)
{
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] - delta, current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder);
st_synchronize();
plan_set_z_position(current_position[Z_AXIS]);
}
#define BABYSTEP_LOADZ_BY_PLANNER
// Number of baby steps applied
static int babystepLoadZ = 0;
void babystep_apply()
{
// Apply Z height correction aka baby stepping before mesh bed leveing gets activated.
if(eeprom_read_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET) == 0x01)
{
// End of G80: Apply the baby stepping value.
EEPROM_read_B(EEPROM_BABYSTEP_Z,&babystepLoadZ);
#if 0
SERIAL_ECHO("Z baby step: ");
SERIAL_ECHO(babystepLoadZ);
SERIAL_ECHO(", current Z: ");
SERIAL_ECHO(current_position[Z_AXIS]);
SERIAL_ECHO("correction: ");
SERIAL_ECHO(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
SERIAL_ECHOLN("");
#endif
#ifdef BABYSTEP_LOADZ_BY_PLANNER
shift_z(- float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
#else
babystepsTodoZadd(babystepLoadZ);
#endif /* BABYSTEP_LOADZ_BY_PLANNER */
}
}
void babystep_undo()
{
#ifdef BABYSTEP_LOADZ_BY_PLANNER
shift_z(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
#else
babystepsTodoZsubtract(babystepLoadZ);
#endif /* BABYSTEP_LOADZ_BY_PLANNER */
babystepLoadZ = 0;
}
void babystep_reset()
{
babystepLoadZ = 0;
}

View File

@ -159,6 +159,8 @@ enum BedSkewOffsetDetectionResultType {
extern BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level);
extern BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8_t verbosity_level, uint8_t &too_far_mask);
extern bool sample_mesh_and_store_reference();
extern void reset_bed_offset_and_skew();
extern bool is_bed_z_jitter_data_valid();
@ -167,7 +169,13 @@ extern bool is_bed_z_jitter_data_valid();
// Useful for visualizing the behavior of the bed induction detector.
extern bool scan_bed_induction_points(int8_t verbosity_level);
// To replace loading of the babystep correction.
extern void shift_z(float delta);
// Apply Z babystep value from the EEPROM through the planner.
extern void babystep_apply();
// Undo the current Z babystep value.
extern void babystep_undo();
// Reset the current babystep counter without moving the axes.
extern void babystep_reset();
#endif /* MESH_BED_CALIBRATION_H */

View File

@ -1446,19 +1446,16 @@ bool lcd_calibrate_z_end_stop_manual()
previous_millis_cmd = millis();
encoderPosition += abs(encoderDiff / ENCODER_PULSES_PER_STEP);
encoderDiff = 0;
// Only move up, whatever the user does.
current_position[Z_AXIS] += fabs(encoderPosition);
encoderPosition = 0;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[Z_AXIS] / 60, active_extruder);
// Wait for the motors to stop.
st_synchronize();
// Claim we are at Z=0, so the soft end stop will not trigger.
current_position[Z_AXIS] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
if (! planner_queue_full()) {
// Only move up, whatever direction the user rotates the encoder.
current_position[Z_AXIS] += fabs(encoderPosition);
encoderPosition = 0;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[Z_AXIS] / 60, active_extruder);
}
}
if (lcd_clicked()) {
// Wait until the Z up movement is finished.
st_synchronize();
// Abort a move if in progress.
planner_abort_hard();
while (lcd_clicked()) ;
delay(10);
while (lcd_clicked()) ;
@ -2022,7 +2019,7 @@ static void lcd_set_lang(unsigned char lang) {
}
void lcd_force_language_selection() {
eeprom_update_byte((unsigned char *)EEPROM_LANG, LANGUAGE_ID_FORCE_SELECTION);
eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION);
}
static void lcd_language_menu()
@ -2052,6 +2049,12 @@ void lcd_mesh_calibration()
lcd_return_to_status();
}
void lcd_mesh_calibration_z()
{
enquecommand_P(PSTR("M45 Z"));
lcd_return_to_status();
}
static void lcd_settings_menu()
{
EEPROM_read(EEPROM_SILENT, (uint8_t*)&SilentModeMenu, sizeof(SilentModeMenu));
@ -2065,9 +2068,13 @@ static void lcd_settings_menu()
if (!isPrintPaused)
{
#ifndef MESH_BED_LEVELING
// "Calibrate Z"
MENU_ITEM(gcode, MSG_HOMEYZ, PSTR("G28 Z"));
#else
MENU_ITEM(submenu, MSG_HOMEYZ, lcd_mesh_bedleveling);
// "Calibrate Z" with storing the reference values to EEPROM.
MENU_ITEM(submenu, MSG_HOMEYZ, lcd_mesh_calibration_z);
// "Mesh Bed Leveling"
MENU_ITEM(submenu, MSG_MESH_BED_LEVELING, lcd_mesh_bedleveling);
#endif
}