Merge pull request #3956 from thinkyhead/rc_mbl_single_axis_fix

MBL: Keep active when homing single axes (#3750)
This commit is contained in:
Scott Lahteine 2016-06-03 21:56:12 -07:00
commit 4bdcf3afe4
6 changed files with 88 additions and 40 deletions

View File

@ -2644,8 +2644,16 @@ inline void gcode_G28() {
* on again when homing all axis * on again when homing all axis
*/ */
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
uint8_t mbl_was_active = mbl.active; float pre_home_z = MESH_HOME_SEARCH_Z;
mbl.active = false; if (mbl.active()) {
// Save known Z position if already homed
if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) {
pre_home_z = current_position[Z_AXIS];
pre_home_z += mbl.get_z(current_position[X_AXIS] - home_offset[X_AXIS],
current_position[Y_AXIS] - home_offset[Y_AXIS]);
}
mbl.set_active(false);
}
#endif #endif
setup_for_endstop_move(); setup_for_endstop_move();
@ -2945,20 +2953,31 @@ inline void gcode_G28() {
// Enable mesh leveling again // Enable mesh leveling again
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
if (mbl_was_active && home_all_axis) { if (mbl.has_mesh()) {
current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; if (home_all_axis || (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && homeZ)) {
sync_plan_position(); current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
mbl.active = 1; sync_plan_position();
#if ENABLED(MESH_G28_REST_ORIGIN) mbl.set_active(true);
current_position[Z_AXIS] = 0.0; #if ENABLED(MESH_G28_REST_ORIGIN)
set_destination_to_current(); current_position[Z_AXIS] = 0.0;
feedrate = homing_feedrate[Z_AXIS]; set_destination_to_current();
line_to_destination(); feedrate = homing_feedrate[Z_AXIS];
stepper.synchronize(); line_to_destination();
#endif stepper.synchronize();
#if ENABLED(DEBUG_LEVELING_FEATURE) #else
if (DEBUGGING(LEVELING)) DEBUG_POS("mbl_was_active", current_position); current_position[Z_AXIS] = MESH_HOME_SEARCH_Z -
#endif mbl.get_z(current_position[X_AXIS] - home_offset[X_AXIS],
current_position[Y_AXIS] - home_offset[Y_AXIS]);
#endif
}
else if ((axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) && (homeX || homeY)) {
current_position[Z_AXIS] = pre_home_z;
sync_plan_position();
mbl.set_active(true);
current_position[Z_AXIS] = pre_home_z -
mbl.get_z(current_position[X_AXIS] - home_offset[X_AXIS],
current_position[Y_AXIS] - home_offset[Y_AXIS]);
}
} }
#endif #endif
@ -2978,7 +2997,7 @@ inline void gcode_G28() {
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset }; enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset, MeshReset };
inline void _mbl_goto_xy(float x, float y) { inline void _mbl_goto_xy(float x, float y) {
saved_feedrate = feedrate; saved_feedrate = feedrate;
@ -3015,6 +3034,7 @@ inline void gcode_G28() {
* S2 Probe the next mesh point * S2 Probe the next mesh point
* S3 Xn Yn Zn.nn Manually modify a single point * S3 Xn Yn Zn.nn Manually modify a single point
* S4 Zn.nn Set z offset. Positive away from bed, negative closer to bed. * S4 Zn.nn Set z offset. Positive away from bed, negative closer to bed.
* S5 Reset and disable mesh
* *
* The S0 report the points as below * The S0 report the points as below
* *
@ -3028,8 +3048,8 @@ inline void gcode_G28() {
static int probe_point = -1; static int probe_point = -1;
MeshLevelingState state = code_seen('S') ? (MeshLevelingState)code_value_short() : MeshReport; MeshLevelingState state = code_seen('S') ? (MeshLevelingState)code_value_short() : MeshReport;
if (state < 0 || state > 4) { if (state < 0 || state > 5) {
SERIAL_PROTOCOLLNPGM("S out of range (0-4)."); SERIAL_PROTOCOLLNPGM("S out of range (0-5).");
return; return;
} }
@ -3038,8 +3058,13 @@ inline void gcode_G28() {
switch (state) { switch (state) {
case MeshReport: case MeshReport:
if (mbl.active) { if (mbl.has_mesh()) {
SERIAL_PROTOCOLPGM("Num X,Y: "); SERIAL_PROTOCOLPGM("State: ");
if (mbl.active())
SERIAL_PROTOCOLPGM("On");
else
SERIAL_PROTOCOLPGM("Off");
SERIAL_PROTOCOLPGM("\nNum X,Y: ");
SERIAL_PROTOCOL(MESH_NUM_X_POINTS); SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
SERIAL_PROTOCOLCHAR(','); SERIAL_PROTOCOLCHAR(',');
SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
@ -3100,7 +3125,7 @@ inline void gcode_G28() {
// After recording the last point, activate the mbl and home // After recording the last point, activate the mbl and home
SERIAL_PROTOCOLLNPGM("Mesh probing done."); SERIAL_PROTOCOLLNPGM("Mesh probing done.");
probe_point = -1; probe_point = -1;
mbl.active = true; mbl.set_has_mesh(true);
enqueue_and_echo_commands_P(PSTR("G28")); enqueue_and_echo_commands_P(PSTR("G28"));
} }
break; break;
@ -3147,6 +3172,19 @@ inline void gcode_G28() {
return; return;
} }
mbl.z_offset = z; mbl.z_offset = z;
break;
case MeshReset:
if (mbl.active()) {
current_position[Z_AXIS] +=
mbl.get_z(current_position[X_AXIS] - home_offset[X_AXIS],
current_position[Y_AXIS] - home_offset[Y_AXIS]) - MESH_HOME_SEARCH_Z;
mbl.reset();
sync_plan_position();
}
else
mbl.reset();
} // switch(state) } // switch(state)
report_current_position(); report_current_position();
@ -5944,7 +5982,7 @@ inline void gcode_M410() {
/** /**
* M420: Enable/Disable Mesh Bed Leveling * M420: Enable/Disable Mesh Bed Leveling
*/ */
inline void gcode_M420() { if (code_seen('S') && code_has_value()) mbl.active = !!code_value_short(); } inline void gcode_M420() { if (code_seen('S') && code_has_value()) mbl.set_has_mesh(!!code_value_short()); }
/** /**
* M421: Set a single Mesh Bed Leveling Z coordinate * M421: Set a single Mesh Bed Leveling Z coordinate
@ -7335,7 +7373,7 @@ void clamp_to_software_endstops(float target[3]) {
// This function is used to split lines on mesh borders so each segment is only part of one mesh area // This function is used to split lines on mesh borders so each segment is only part of one mesh area
void mesh_buffer_line(float x, float y, float z, const float e, float feed_rate, const uint8_t& extruder, uint8_t x_splits = 0xff, uint8_t y_splits = 0xff) { void mesh_buffer_line(float x, float y, float z, const float e, float feed_rate, const uint8_t& extruder, uint8_t x_splits = 0xff, uint8_t y_splits = 0xff) {
if (!mbl.active) { if (!mbl.active()) {
planner.buffer_line(x, y, z, e, feed_rate, extruder); planner.buffer_line(x, y, z, e, feed_rate, extruder);
set_current_to_destination(); set_current_to_destination();
return; return;

View File

@ -58,8 +58,8 @@
* 188 M206 XYZ home_offset (float x3) * 188 M206 XYZ home_offset (float x3)
* *
* Mesh bed leveling: * Mesh bed leveling:
* 200 M420 S active (bool) * 200 M420 S status (uint8)
* 201 z_offset (float) (added in V23) * 201 z_offset (float)
* 205 mesh_num_x (uint8 as set in firmware) * 205 mesh_num_x (uint8 as set in firmware)
* 206 mesh_num_y (uint8 as set in firmware) * 206 mesh_num_y (uint8 as set in firmware)
* 207 G29 S3 XYZ z_values[][] (float x9, by default) * 207 G29 S3 XYZ z_values[][] (float x9, by default)
@ -187,20 +187,21 @@ void Config_StoreSettings() {
EEPROM_WRITE_VAR(i, planner.max_e_jerk); EEPROM_WRITE_VAR(i, planner.max_e_jerk);
EEPROM_WRITE_VAR(i, home_offset); EEPROM_WRITE_VAR(i, home_offset);
uint8_t mesh_num_x = 3;
uint8_t mesh_num_y = 3;
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
// Compile time test that sizeof(mbl.z_values) is as expected // Compile time test that sizeof(mbl.z_values) is as expected
typedef char c_assert[(sizeof(mbl.z_values) == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS) * sizeof(dummy)) ? 1 : -1]; typedef char c_assert[(sizeof(mbl.z_values) == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS) * sizeof(dummy)) ? 1 : -1];
mesh_num_x = MESH_NUM_X_POINTS; uint8_t mesh_num_x = MESH_NUM_X_POINTS,
mesh_num_y = MESH_NUM_Y_POINTS; mesh_num_y = MESH_NUM_Y_POINTS,
EEPROM_WRITE_VAR(i, mbl.active); dummy_uint8 = mbl.status & _BV(MBL_STATUS_HAS_MESH_BIT);
EEPROM_WRITE_VAR(i, dummy_uint8);
EEPROM_WRITE_VAR(i, mbl.z_offset); EEPROM_WRITE_VAR(i, mbl.z_offset);
EEPROM_WRITE_VAR(i, mesh_num_x); EEPROM_WRITE_VAR(i, mesh_num_x);
EEPROM_WRITE_VAR(i, mesh_num_y); EEPROM_WRITE_VAR(i, mesh_num_y);
EEPROM_WRITE_VAR(i, mbl.z_values); EEPROM_WRITE_VAR(i, mbl.z_values);
#else #else
uint8_t dummy_uint8 = 0; uint8_t mesh_num_x = 3,
mesh_num_y = 3,
dummy_uint8 = 0;
dummy = 0.0f; dummy = 0.0f;
EEPROM_WRITE_VAR(i, dummy_uint8); EEPROM_WRITE_VAR(i, dummy_uint8);
EEPROM_WRITE_VAR(i, dummy); EEPROM_WRITE_VAR(i, dummy);
@ -376,7 +377,7 @@ void Config_RetrieveSettings() {
EEPROM_READ_VAR(i, mesh_num_x); EEPROM_READ_VAR(i, mesh_num_x);
EEPROM_READ_VAR(i, mesh_num_y); EEPROM_READ_VAR(i, mesh_num_y);
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
mbl.active = dummy_uint8; mbl.status = dummy_uint8;
mbl.z_offset = dummy; mbl.z_offset = dummy;
if (mesh_num_x == MESH_NUM_X_POINTS && mesh_num_y == MESH_NUM_Y_POINTS) { if (mesh_num_x == MESH_NUM_X_POINTS && mesh_num_y == MESH_NUM_Y_POINTS) {
EEPROM_READ_VAR(i, mbl.z_values); EEPROM_READ_VAR(i, mbl.z_values);
@ -550,7 +551,7 @@ void Config_ResetDefault() {
home_offset[X_AXIS] = home_offset[Y_AXIS] = home_offset[Z_AXIS] = 0; home_offset[X_AXIS] = home_offset[Y_AXIS] = home_offset[Z_AXIS] = 0;
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
mbl.active = false; mbl.reset();
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_FEATURE) #if ENABLED(AUTO_BED_LEVELING_FEATURE)
@ -729,7 +730,7 @@ void Config_PrintSettings(bool forReplay) {
SERIAL_ECHOLNPGM("Mesh bed leveling:"); SERIAL_ECHOLNPGM("Mesh bed leveling:");
CONFIG_ECHO_START; CONFIG_ECHO_START;
} }
SERIAL_ECHOPAIR(" M420 S", mbl.active); SERIAL_ECHOPAIR(" M420 S", mbl.has_mesh() ? 1 : 0);
SERIAL_ECHOPAIR(" X", MESH_NUM_X_POINTS); SERIAL_ECHOPAIR(" X", MESH_NUM_X_POINTS);
SERIAL_ECHOPAIR(" Y", MESH_NUM_Y_POINTS); SERIAL_ECHOPAIR(" Y", MESH_NUM_Y_POINTS);
SERIAL_EOL; SERIAL_EOL;

View File

@ -29,7 +29,7 @@
mesh_bed_leveling::mesh_bed_leveling() { reset(); } mesh_bed_leveling::mesh_bed_leveling() { reset(); }
void mesh_bed_leveling::reset() { void mesh_bed_leveling::reset() {
active = 0; status = MBL_STATUS_NONE;
z_offset = 0; z_offset = 0;
for (int8_t y = MESH_NUM_Y_POINTS; y--;) for (int8_t y = MESH_NUM_Y_POINTS; y--;)
for (int8_t x = MESH_NUM_X_POINTS; x--;) for (int8_t x = MESH_NUM_X_POINTS; x--;)

View File

@ -24,12 +24,14 @@
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
enum MBLStatus { MBL_STATUS_NONE = 0, MBL_STATUS_HAS_MESH_BIT = 0, MBL_STATUS_ACTIVE_BIT = 1 };
#define MESH_X_DIST ((MESH_MAX_X - (MESH_MIN_X))/(MESH_NUM_X_POINTS - 1)) #define MESH_X_DIST ((MESH_MAX_X - (MESH_MIN_X))/(MESH_NUM_X_POINTS - 1))
#define MESH_Y_DIST ((MESH_MAX_Y - (MESH_MIN_Y))/(MESH_NUM_Y_POINTS - 1)) #define MESH_Y_DIST ((MESH_MAX_Y - (MESH_MIN_Y))/(MESH_NUM_Y_POINTS - 1))
class mesh_bed_leveling { class mesh_bed_leveling {
public: public:
bool active; uint8_t status; // Has Mesh and Is Active bits
float z_offset; float z_offset;
float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS]; float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS];
@ -41,6 +43,11 @@
static FORCE_INLINE float get_probe_y(int8_t i) { return MESH_MIN_Y + (MESH_Y_DIST) * i; } static FORCE_INLINE float get_probe_y(int8_t i) { return MESH_MIN_Y + (MESH_Y_DIST) * i; }
void set_z(const int8_t px, const int8_t py, const float z) { z_values[py][px] = z; } void set_z(const int8_t px, const int8_t py, const float z) { z_values[py][px] = z; }
bool active() { return TEST(status, MBL_STATUS_ACTIVE_BIT); }
void set_active(bool onOff) { if (onOff) SBI(status, MBL_STATUS_ACTIVE_BIT); else CBI(status, MBL_STATUS_ACTIVE_BIT); }
bool has_mesh() { return TEST(status, MBL_STATUS_HAS_MESH_BIT); }
void set_has_mesh(bool onOff) { if (onOff) SBI(status, MBL_STATUS_HAS_MESH_BIT); else CBI(status, MBL_STATUS_HAS_MESH_BIT); }
inline void zigzag(int8_t index, int8_t &px, int8_t &py) { inline void zigzag(int8_t index, int8_t &px, int8_t &py) {
px = index % (MESH_NUM_X_POINTS); px = index % (MESH_NUM_X_POINTS);
py = index / (MESH_NUM_X_POINTS); py = index / (MESH_NUM_X_POINTS);

View File

@ -539,7 +539,8 @@ void Planner::check_axes_activity() {
while (block_buffer_tail == next_buffer_head) idle(); while (block_buffer_tail == next_buffer_head) idle();
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
if (mbl.active) z += mbl.get_z(x - home_offset[X_AXIS], y - home_offset[Y_AXIS]); if (mbl.active())
z += mbl.get_z(x - home_offset[X_AXIS], y - home_offset[Y_AXIS]);
#elif ENABLED(AUTO_BED_LEVELING_FEATURE) #elif ENABLED(AUTO_BED_LEVELING_FEATURE)
apply_rotation_xyz(bed_level_matrix, x, y, z); apply_rotation_xyz(bed_level_matrix, x, y, z);
#endif #endif
@ -1120,7 +1121,8 @@ void Planner::check_axes_activity() {
#endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING #endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING
{ {
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
if (mbl.active) z += mbl.get_z(x - home_offset[X_AXIS], y - home_offset[Y_AXIS]); if (mbl.active())
z += mbl.get_z(x - home_offset[X_AXIS], y - home_offset[Y_AXIS]);
#elif ENABLED(AUTO_BED_LEVELING_FEATURE) #elif ENABLED(AUTO_BED_LEVELING_FEATURE)
apply_rotation_xyz(bed_level_matrix, x, y, z); apply_rotation_xyz(bed_level_matrix, x, y, z);
#endif #endif

View File

@ -970,7 +970,7 @@ void lcd_cooldown() {
line_to_current(Z_AXIS); line_to_current(Z_AXIS);
stepper.synchronize(); stepper.synchronize();
mbl.active = true; mbl.set_has_mesh(true);
enqueue_and_echo_commands_P(PSTR("G28")); enqueue_and_echo_commands_P(PSTR("G28"));
lcd_return_to_status(); lcd_return_to_status();
//LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE); //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE);