Merge pull request #5452 from thinkyhead/rc_save_your_mesh

Save Bed Leveling to EEPROM
master
Scott Lahteine 8 years ago committed by GitHub
commit 78d6d6e076

@ -805,8 +805,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -330,8 +330,14 @@ float code_value_temp_diff();
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
extern int bilinear_grid_spacing[2]; extern int bilinear_grid_spacing[2], bilinear_start[2];
extern float bed_level_grid[ABL_GRID_MAX_POINTS_X][ABL_GRID_MAX_POINTS_Y];
float bilinear_z_offset(float logical[XYZ]); float bilinear_z_offset(float logical[XYZ]);
void set_bed_leveling_enabled(bool enable=true);
#endif
#if PLANNER_LEVELING
void reset_bed_level();
#endif #endif
#if ENABLED(Z_DUAL_ENDSTOPS) #if ENABLED(Z_DUAL_ENDSTOPS)

@ -575,8 +575,9 @@ static uint8_t target_extruder;
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
int bilinear_grid_spacing[2] = { 0 }, bilinear_start[2] = { 0 }; #define UNPROBED 9999.0f
float bed_level_grid[ABL_GRID_POINTS_X][ABL_GRID_POINTS_Y]; int bilinear_grid_spacing[2], bilinear_start[2];
float bed_level_grid[ABL_GRID_MAX_POINTS_X][ABL_GRID_MAX_POINTS_Y];
#endif #endif
#if IS_SCARA #if IS_SCARA
@ -2228,7 +2229,7 @@ static void clean_up_after_endstop_or_probe_move() {
* Disable: Current position = physical position * Disable: Current position = physical position
* Enable: Current position = "unleveled" physical position * Enable: Current position = "unleveled" physical position
*/ */
void set_bed_leveling_enabled(bool enable=true) { void set_bed_leveling_enabled(bool enable/*=true*/) {
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
if (enable != mbl.active()) { if (enable != mbl.active()) {
@ -2243,7 +2244,13 @@ static void clean_up_after_endstop_or_probe_move() {
#elif HAS_ABL #elif HAS_ABL
if (enable != planner.abl_enabled) { #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
const bool can_change = (!enable || (bilinear_grid_spacing[0] && bilinear_grid_spacing[1]));
#else
constexpr bool can_change = true;
#endif
if (can_change && enable != planner.abl_enabled) {
planner.abl_enabled = enable; planner.abl_enabled = enable;
if (!enable) if (!enable)
set_current_from_steppers_for_axis( set_current_from_steppers_for_axis(
@ -2289,23 +2296,24 @@ static void clean_up_after_endstop_or_probe_move() {
* Reset calibration results to zero. * Reset calibration results to zero.
*/ */
void reset_bed_level() { void reset_bed_level() {
set_bed_leveling_enabled(false);
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
if (mbl.has_mesh()) { if (mbl.has_mesh()) {
set_bed_leveling_enabled(false);
mbl.reset(); mbl.reset();
mbl.set_has_mesh(false); mbl.set_has_mesh(false);
} }
#else #else
planner.abl_enabled = false;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level"); if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level");
#endif #endif
#if ABL_PLANAR #if ABL_PLANAR
planner.bed_level_matrix.set_to_identity(); planner.bed_level_matrix.set_to_identity();
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) bilinear_start[X_AXIS] = bilinear_start[Y_AXIS] =
for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++) bilinear_grid_spacing[X_AXIS] = bilinear_grid_spacing[Y_AXIS] = 0;
bed_level_grid[x][y] = 1000.0; for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++)
for (uint8_t y = 0; y < ABL_GRID_MAX_POINTS_Y; y++)
bed_level_grid[x][y] = UNPROBED;
#endif #endif
#endif #endif
} }
@ -2331,7 +2339,7 @@ static void clean_up_after_endstop_or_probe_move() {
SERIAL_CHAR(']'); SERIAL_CHAR(']');
} }
#endif #endif
if (bed_level_grid[x][y] < 999.0) { if (bed_level_grid[x][y] != UNPROBED) {
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM(" (done)"); if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM(" (done)");
#endif #endif
@ -2345,13 +2353,13 @@ static void clean_up_after_endstop_or_probe_move() {
c1 = bed_level_grid[x + xdir][y + ydir], c2 = bed_level_grid[x + xdir * 2][y + ydir * 2]; c1 = bed_level_grid[x + xdir][y + ydir], c2 = bed_level_grid[x + xdir * 2][y + ydir * 2];
// Treat far unprobed points as zero, near as equal to far // Treat far unprobed points as zero, near as equal to far
if (a2 > 999.0) a2 = 0.0; if (a1 > 999.0) a1 = a2; if (a2 == UNPROBED) a2 = 0.0; if (a1 == UNPROBED) a1 = a2;
if (b2 > 999.0) b2 = 0.0; if (b1 > 999.0) b1 = b2; if (b2 == UNPROBED) b2 = 0.0; if (b1 == UNPROBED) b1 = b2;
if (c2 > 999.0) c2 = 0.0; if (c1 > 999.0) c1 = c2; if (c2 == UNPROBED) c2 = 0.0; if (c1 == UNPROBED) c1 = c2;
float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2; float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2;
// Take the average intstead of the median // Take the average instead of the median
bed_level_grid[x][y] = (a + b + c) / 3.0; bed_level_grid[x][y] = (a + b + c) / 3.0;
// Median is robust (ignores outliers). // Median is robust (ignores outliers).
@ -2363,9 +2371,9 @@ static void clean_up_after_endstop_or_probe_move() {
//#define EXTRAPOLATE_FROM_EDGE //#define EXTRAPOLATE_FROM_EDGE
#if ENABLED(EXTRAPOLATE_FROM_EDGE) #if ENABLED(EXTRAPOLATE_FROM_EDGE)
#if ABL_GRID_POINTS_X < ABL_GRID_POINTS_Y #if ABL_GRID_MAX_POINTS_X < ABL_GRID_MAX_POINTS_Y
#define HALF_IN_X #define HALF_IN_X
#elif ABL_GRID_POINTS_Y < ABL_GRID_POINTS_X #elif ABL_GRID_MAX_POINTS_Y < ABL_GRID_MAX_POINTS_X
#define HALF_IN_Y #define HALF_IN_Y
#endif #endif
#endif #endif
@ -2376,18 +2384,18 @@ static void clean_up_after_endstop_or_probe_move() {
*/ */
static void extrapolate_unprobed_bed_level() { static void extrapolate_unprobed_bed_level() {
#ifdef HALF_IN_X #ifdef HALF_IN_X
const uint8_t ctrx2 = 0, xlen = ABL_GRID_POINTS_X - 1; const uint8_t ctrx2 = 0, xlen = ABL_GRID_MAX_POINTS_X - 1;
#else #else
const uint8_t ctrx1 = (ABL_GRID_POINTS_X - 1) / 2, // left-of-center const uint8_t ctrx1 = (ABL_GRID_MAX_POINTS_X - 1) / 2, // left-of-center
ctrx2 = ABL_GRID_POINTS_X / 2, // right-of-center ctrx2 = ABL_GRID_MAX_POINTS_X / 2, // right-of-center
xlen = ctrx1; xlen = ctrx1;
#endif #endif
#ifdef HALF_IN_Y #ifdef HALF_IN_Y
const uint8_t ctry2 = 0, ylen = ABL_GRID_POINTS_Y - 1; const uint8_t ctry2 = 0, ylen = ABL_GRID_MAX_POINTS_Y - 1;
#else #else
const uint8_t ctry1 = (ABL_GRID_POINTS_Y - 1) / 2, // top-of-center const uint8_t ctry1 = (ABL_GRID_MAX_POINTS_Y - 1) / 2, // top-of-center
ctry2 = ABL_GRID_POINTS_Y / 2, // bottom-of-center ctry2 = ABL_GRID_MAX_POINTS_Y / 2, // bottom-of-center
ylen = ctry1; ylen = ctry1;
#endif #endif
@ -2415,21 +2423,21 @@ static void clean_up_after_endstop_or_probe_move() {
/** /**
* Print calibration results for plotting or manual frame adjustment. * Print calibration results for plotting or manual frame adjustment.
*/ */
static void print_bed_level() { static void print_bilinear_leveling_grid() {
SERIAL_ECHOPGM("Bilinear Leveling Grid:\n "); SERIAL_ECHOPGM("Bilinear Leveling Grid:\n ");
for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) { for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++) {
SERIAL_PROTOCOLPGM(" "); SERIAL_PROTOCOLPGM(" ");
if (x < 10) SERIAL_PROTOCOLCHAR(' '); if (x < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x); SERIAL_PROTOCOL((int)x);
} }
SERIAL_EOL; SERIAL_EOL;
for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++) { for (uint8_t y = 0; y < ABL_GRID_MAX_POINTS_Y; y++) {
if (y < 10) SERIAL_PROTOCOLCHAR(' '); if (y < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y); SERIAL_PROTOCOL((int)y);
for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) { for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++) {
SERIAL_PROTOCOLCHAR(' '); SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid[x][y]; float offset = bed_level_grid[x][y];
if (offset < 999.0) { if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+'); if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2); SERIAL_PROTOCOL_F(offset, 2);
} }
@ -2442,10 +2450,10 @@ static void clean_up_after_endstop_or_probe_move() {
} }
#if ENABLED(ABL_BILINEAR_SUBDIVISION) #if ENABLED(ABL_BILINEAR_SUBDIVISION)
#define ABL_GRID_POINTS_VIRT_X (ABL_GRID_POINTS_X - 1) * (BILINEAR_SUBDIVISIONS) + 1 #define ABL_GRID_POINTS_VIRT_X (ABL_GRID_MAX_POINTS_X - 1) * (BILINEAR_SUBDIVISIONS) + 1
#define ABL_GRID_POINTS_VIRT_Y (ABL_GRID_POINTS_Y - 1) * (BILINEAR_SUBDIVISIONS) + 1 #define ABL_GRID_POINTS_VIRT_Y (ABL_GRID_MAX_POINTS_Y - 1) * (BILINEAR_SUBDIVISIONS) + 1
float bed_level_grid_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y]; float bed_level_grid_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
float bed_level_grid_virt_temp[ABL_GRID_POINTS_X + 2][ABL_GRID_POINTS_Y + 2]; //temporary for calculation (maybe dynamical?) float bed_level_grid_virt_temp[ABL_GRID_MAX_POINTS_X + 2][ABL_GRID_MAX_POINTS_Y + 2]; //temporary for calculation (maybe dynamical?)
int bilinear_grid_spacing_virt[2] = { 0 }; int bilinear_grid_spacing_virt[2] = { 0 };
static void bed_level_virt_print() { static void bed_level_virt_print() {
@ -2462,7 +2470,7 @@ static void clean_up_after_endstop_or_probe_move() {
for (uint8_t x = 0; x < ABL_GRID_POINTS_VIRT_X; x++) { for (uint8_t x = 0; x < ABL_GRID_POINTS_VIRT_X; x++) {
SERIAL_PROTOCOLCHAR(' '); SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid_virt[x][y]; float offset = bed_level_grid_virt[x][y];
if (offset < 999.0) { if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+'); if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 5); SERIAL_PROTOCOL_F(offset, 5);
} }
@ -2474,10 +2482,10 @@ static void clean_up_after_endstop_or_probe_move() {
SERIAL_EOL; SERIAL_EOL;
} }
#define LINEAR_EXTRAPOLATION(E, I) (E * 2 - I) #define LINEAR_EXTRAPOLATION(E, I) (E * 2 - I)
static void bed_level_virt_prepare() { void bed_level_virt_prepare() {
for (uint8_t y = 1; y <= ABL_GRID_POINTS_Y; y++) { for (uint8_t y = 1; y <= ABL_GRID_MAX_POINTS_Y; y++) {
for (uint8_t x = 1; x <= ABL_GRID_POINTS_X; x++) for (uint8_t x = 1; x <= ABL_GRID_MAX_POINTS_X; x++)
bed_level_grid_virt_temp[x][y] = bed_level_grid[x - 1][y - 1]; bed_level_grid_virt_temp[x][y] = bed_level_grid[x - 1][y - 1];
bed_level_grid_virt_temp[0][y] = LINEAR_EXTRAPOLATION( bed_level_grid_virt_temp[0][y] = LINEAR_EXTRAPOLATION(
@ -2485,21 +2493,21 @@ static void clean_up_after_endstop_or_probe_move() {
bed_level_grid_virt_temp[2][y] bed_level_grid_virt_temp[2][y]
); );
bed_level_grid_virt_temp[(ABL_GRID_POINTS_X + 2) - 1][y] = bed_level_grid_virt_temp[(ABL_GRID_MAX_POINTS_X + 2) - 1][y] =
LINEAR_EXTRAPOLATION( LINEAR_EXTRAPOLATION(
bed_level_grid_virt_temp[(ABL_GRID_POINTS_X + 2) - 2][y], bed_level_grid_virt_temp[(ABL_GRID_MAX_POINTS_X + 2) - 2][y],
bed_level_grid_virt_temp[(ABL_GRID_POINTS_X + 2) - 3][y] bed_level_grid_virt_temp[(ABL_GRID_MAX_POINTS_X + 2) - 3][y]
); );
} }
for (uint8_t x = 0; x < ABL_GRID_POINTS_X + 2; x++) { for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X + 2; x++) {
bed_level_grid_virt_temp[x][0] = LINEAR_EXTRAPOLATION( bed_level_grid_virt_temp[x][0] = LINEAR_EXTRAPOLATION(
bed_level_grid_virt_temp[x][1], bed_level_grid_virt_temp[x][1],
bed_level_grid_virt_temp[x][2] bed_level_grid_virt_temp[x][2]
); );
bed_level_grid_virt_temp[x][(ABL_GRID_POINTS_Y + 2) - 1] = bed_level_grid_virt_temp[x][(ABL_GRID_MAX_POINTS_Y + 2) - 1] =
LINEAR_EXTRAPOLATION( LINEAR_EXTRAPOLATION(
bed_level_grid_virt_temp[x][(ABL_GRID_POINTS_Y + 2) - 2], bed_level_grid_virt_temp[x][(ABL_GRID_MAX_POINTS_Y + 2) - 2],
bed_level_grid_virt_temp[x][(ABL_GRID_POINTS_Y + 2) - 3] bed_level_grid_virt_temp[x][(ABL_GRID_MAX_POINTS_Y + 2) - 3]
); );
} }
} }
@ -2520,12 +2528,12 @@ static void clean_up_after_endstop_or_probe_move() {
} }
return bed_level_virt_cmr(row, 1, tx); return bed_level_virt_cmr(row, 1, tx);
} }
static void bed_level_virt_interpolate() { void bed_level_virt_interpolate() {
for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++) for (uint8_t y = 0; y < ABL_GRID_MAX_POINTS_Y; y++)
for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++)
for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++) for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++)
for (uint8_t tx = 0; tx < BILINEAR_SUBDIVISIONS; tx++) { for (uint8_t tx = 0; tx < BILINEAR_SUBDIVISIONS; tx++) {
if ((ty && y == ABL_GRID_POINTS_Y - 1) || (tx && x == ABL_GRID_POINTS_X - 1)) if ((ty && y == ABL_GRID_MAX_POINTS_Y - 1) || (tx && x == ABL_GRID_MAX_POINTS_X - 1))
continue; continue;
bed_level_grid_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] = bed_level_grid_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] =
bed_level_virt_2cmr( bed_level_virt_2cmr(
@ -3422,9 +3430,9 @@ inline void gcode_G28() {
// Wait for planner moves to finish! // Wait for planner moves to finish!
stepper.synchronize(); stepper.synchronize();
// For auto bed leveling, clear the level matrix // Disable the leveling matrix before homing
#if HAS_ABL #if PLANNER_LEVELING
reset_bed_level(); set_bed_leveling_enabled(false);
#endif #endif
// Always home with tool 0 active // Always home with tool 0 active
@ -3693,6 +3701,20 @@ inline void gcode_G28() {
// Save 130 bytes with non-duplication of PSTR // Save 130 bytes with non-duplication of PSTR
void say_not_entered() { SERIAL_PROTOCOLLNPGM(" not entered."); } void say_not_entered() { SERIAL_PROTOCOLLNPGM(" not entered."); }
void mbl_mesh_report() {
SERIAL_PROTOCOLLNPGM("Num X,Y: " STRINGIFY(MESH_NUM_X_POINTS) "," STRINGIFY(MESH_NUM_Y_POINTS));
SERIAL_PROTOCOLLNPGM("Z search height: " STRINGIFY(MESH_HOME_SEARCH_Z));
SERIAL_PROTOCOLPGM("Z offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5);
SERIAL_PROTOCOLLNPGM("\nMeasured points:");
for (uint8_t py = 0; py < MESH_NUM_Y_POINTS; py++) {
for (uint8_t px = 0; px < MESH_NUM_X_POINTS; px++) {
SERIAL_PROTOCOLPGM(" ");
SERIAL_PROTOCOL_F(mbl.z_values[py][px], 5);
}
SERIAL_EOL;
}
}
/** /**
* G29: Mesh-based Z probe, probes a grid and produces a * G29: Mesh-based Z probe, probes a grid and produces a
* mesh to compensate for variable bed height * mesh to compensate for variable bed height
@ -3728,21 +3750,11 @@ inline void gcode_G28() {
switch (state) { switch (state) {
case MeshReport: case MeshReport:
if (mbl.has_mesh()) { if (mbl.has_mesh()) {
SERIAL_PROTOCOLPAIR("State: ", mbl.active() ? MSG_ON : MSG_OFF); SERIAL_PROTOCOLLNPAIR("State: ", mbl.active() ? MSG_ON : MSG_OFF);
SERIAL_PROTOCOLLNPGM("\nNum X,Y: " STRINGIFY(MESH_NUM_X_POINTS) "," STRINGIFY(MESH_NUM_Y_POINTS)); mbl_mesh_report();
SERIAL_PROTOCOLLNPGM("Z search height: " STRINGIFY(MESH_HOME_SEARCH_Z));
SERIAL_PROTOCOLPGM("Z offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5);
SERIAL_PROTOCOLLNPGM("\nMeasured points:");
for (py = 0; py < MESH_NUM_Y_POINTS; py++) {
for (px = 0; px < MESH_NUM_X_POINTS; px++) {
SERIAL_PROTOCOLPGM(" ");
SERIAL_PROTOCOL_F(mbl.z_values[py][px], 5);
}
SERIAL_EOL;
}
} }
else else
SERIAL_PROTOCOLLNPGM("Mesh bed leveling not active."); SERIAL_PROTOCOLLNPGM("Mesh bed leveling has no data.");
break; break;
case MeshStart: case MeshStart:
@ -3863,7 +3875,7 @@ inline void gcode_G28() {
* *
* Enhanced G29 Auto Bed Leveling Probe Routine * Enhanced G29 Auto Bed Leveling Probe Routine
* *
* Parameters With ABL_GRID: * Parameters With LINEAR and BILINEAR:
* *
* P Set the size of the grid that will be probed (P x P points). * P Set the size of the grid that will be probed (P x P points).
* Not supported by non-linear delta printer bed leveling. * Not supported by non-linear delta printer bed leveling.
@ -3887,6 +3899,10 @@ inline void gcode_G28() {
* L Set the Left limit of the probing grid * L Set the Left limit of the probing grid
* R Set the Right limit of the probing grid * R Set the Right limit of the probing grid
* *
* Parameters with BILINEAR only:
*
* Z Supply an additional Z probe offset
*
* Global Parameters: * Global Parameters:
* *
* E/e By default G29 will engage the Z probe, test the bed, then disengage. * E/e By default G29 will engage the Z probe, test the bed, then disengage.
@ -3934,8 +3950,8 @@ inline void gcode_G28() {
// X and Y specify points in each direction, overriding the default // X and Y specify points in each direction, overriding the default
// These values may be saved with the completed mesh // These values may be saved with the completed mesh
int abl_grid_points_x = code_seen('X') ? code_value_int() : ABL_GRID_POINTS_X, int abl_grid_points_x = code_seen('X') ? code_value_int() : ABL_GRID_MAX_POINTS_X,
abl_grid_points_y = code_seen('Y') ? code_value_int() : ABL_GRID_POINTS_Y; abl_grid_points_y = code_seen('Y') ? code_value_int() : ABL_GRID_MAX_POINTS_Y;
if (code_seen('P')) abl_grid_points_x = abl_grid_points_y = code_value_int(); if (code_seen('P')) abl_grid_points_x = abl_grid_points_y = code_value_int();
@ -3946,7 +3962,7 @@ inline void gcode_G28() {
#else #else
const int abl_grid_points_x = ABL_GRID_POINTS_X, abl_grid_points_y = ABL_GRID_POINTS_Y; const uint8_t abl_grid_points_x = ABL_GRID_MAX_POINTS_X, abl_grid_points_y = ABL_GRID_MAX_POINTS_Y;
#endif #endif
@ -4030,7 +4046,11 @@ inline void gcode_G28() {
|| left_probe_bed_position != bilinear_start[X_AXIS] || left_probe_bed_position != bilinear_start[X_AXIS]
|| front_probe_bed_position != bilinear_start[Y_AXIS] || front_probe_bed_position != bilinear_start[Y_AXIS]
) { ) {
// Before reset bed level, re-enable to correct the position
planner.abl_enabled = abl_should_enable;
// Reset grid to 0.0 or "not probed". (Also disables ABL)
reset_bed_level(); reset_bed_level();
#if ENABLED(ABL_BILINEAR_SUBDIVISION) #if ENABLED(ABL_BILINEAR_SUBDIVISION)
bilinear_grid_spacing_virt[X_AXIS] = xGridSpacing / (BILINEAR_SUBDIVISIONS); bilinear_grid_spacing_virt[X_AXIS] = xGridSpacing / (BILINEAR_SUBDIVISIONS);
bilinear_grid_spacing_virt[Y_AXIS] = yGridSpacing / (BILINEAR_SUBDIVISIONS); bilinear_grid_spacing_virt[Y_AXIS] = yGridSpacing / (BILINEAR_SUBDIVISIONS);
@ -4039,6 +4059,7 @@ inline void gcode_G28() {
bilinear_grid_spacing[Y_AXIS] = yGridSpacing; bilinear_grid_spacing[Y_AXIS] = yGridSpacing;
bilinear_start[X_AXIS] = RAW_X_POSITION(left_probe_bed_position); bilinear_start[X_AXIS] = RAW_X_POSITION(left_probe_bed_position);
bilinear_start[Y_AXIS] = RAW_Y_POSITION(front_probe_bed_position); bilinear_start[Y_AXIS] = RAW_Y_POSITION(front_probe_bed_position);
// Can't re-enable (on error) until the new grid is written // Can't re-enable (on error) until the new grid is written
abl_should_enable = false; abl_should_enable = false;
} }
@ -4203,7 +4224,7 @@ inline void gcode_G28() {
#if ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (!dryrun) extrapolate_unprobed_bed_level(); if (!dryrun) extrapolate_unprobed_bed_level();
print_bed_level(); print_bilinear_leveling_grid();
#if ENABLED(ABL_BILINEAR_SUBDIVISION) #if ENABLED(ABL_BILINEAR_SUBDIVISION)
bed_level_virt_prepare(); bed_level_virt_prepare();
@ -4322,45 +4343,34 @@ inline void gcode_G28() {
// Correct the current XYZ position based on the tilted plane. // Correct the current XYZ position based on the tilted plane.
// //
// 1. Get the distance from the current position to the reference point.
float x_dist = RAW_CURRENT_POSITION(X_AXIS) - X_TILT_FULCRUM,
y_dist = RAW_CURRENT_POSITION(Y_AXIS) - Y_TILT_FULCRUM,
z_real = current_position[Z_AXIS],
z_zero = 0;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("G29 uncorrected XYZ", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("G29 uncorrected XYZ", current_position);
#endif #endif
matrix_3x3 inverse = matrix_3x3::transpose(planner.bed_level_matrix); float converted[XYZ];
memcpy(converted, current_position, sizeof(converted));
// 2. Apply the inverse matrix to the distance
// from the reference point to X, Y, and zero.
apply_rotation_xyz(inverse, x_dist, y_dist, z_zero);
// 3. Get the matrix-based corrected Z. planner.abl_enabled = true;
// (Even if not used, get it for comparison.) planner.unapply_leveling(converted); // use conversion machinery
float new_z = z_real + z_zero; planner.abl_enabled = false;
// 4. Use the last measured distance to the bed, if possible // Use the last measured distance to the bed, if possible
if ( NEAR(current_position[X_AXIS], xProbe - (X_PROBE_OFFSET_FROM_EXTRUDER)) if ( NEAR(current_position[X_AXIS], xProbe - (X_PROBE_OFFSET_FROM_EXTRUDER))
&& NEAR(current_position[Y_AXIS], yProbe - (Y_PROBE_OFFSET_FROM_EXTRUDER)) && NEAR(current_position[Y_AXIS], yProbe - (Y_PROBE_OFFSET_FROM_EXTRUDER))
) { ) {
float simple_z = z_real - (measured_z - (-zprobe_zoffset)); float simple_z = current_position[Z_AXIS] - (measured_z - (-zprobe_zoffset));
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
SERIAL_ECHOPAIR("Z from Probe:", simple_z); SERIAL_ECHOPAIR("Z from Probe:", simple_z);
SERIAL_ECHOPAIR(" Matrix:", new_z); SERIAL_ECHOPAIR(" Matrix:", converted[Z_AXIS]);
SERIAL_ECHOLNPAIR(" Discrepancy:", simple_z - new_z); SERIAL_ECHOLNPAIR(" Discrepancy:", simple_z - converted[Z_AXIS]);
} }
#endif #endif
new_z = simple_z; converted[Z_AXIS] = simple_z;
} }
// 5. The rotated XY and corrected Z are now current_position // The rotated XY and corrected Z are now current_position
current_position[X_AXIS] = LOGICAL_X_POSITION(x_dist) + X_TILT_FULCRUM; memcpy(current_position, converted, sizeof(converted));
current_position[Y_AXIS] = LOGICAL_Y_POSITION(y_dist) + Y_TILT_FULCRUM;
current_position[Z_AXIS] = new_z;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("G29 corrected XYZ", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("G29 corrected XYZ", current_position);
@ -5041,7 +5051,8 @@ inline void gcode_M42() {
// Disable bed level correction in M48 because we want the raw data when we probe // Disable bed level correction in M48 because we want the raw data when we probe
#if HAS_ABL #if HAS_ABL
reset_bed_level(); const bool abl_was_enabled = planner.abl_enabled;
set_bed_leveling_enabled(false);
#endif #endif
setup_for_endstop_or_probe_move(); setup_for_endstop_or_probe_move();
@ -5192,6 +5203,11 @@ inline void gcode_M42() {
clean_up_after_endstop_or_probe_move(); clean_up_after_endstop_or_probe_move();
// Re-enable bed level correction if it has been on
#if HAS_ABL
set_bed_leveling_enabled(abl_was_enabled);
#endif
report_current_position(); report_current_position();
} }
@ -7000,12 +7016,54 @@ void quickstop_stepper() {
* *
* S[bool] Turns leveling on or off * S[bool] Turns leveling on or off
* Z[height] Sets the Z fade height (0 or none to disable) * Z[height] Sets the Z fade height (0 or none to disable)
* V[bool] Verbose - Print the levelng grid
*/ */
inline void gcode_M420() { inline void gcode_M420() {
if (code_seen('S')) set_bed_leveling_enabled(code_value_bool()); bool to_enable = false;
if (code_seen('S')) {
to_enable = code_value_bool();
set_bed_leveling_enabled(to_enable);
}
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (code_seen('Z')) set_z_fade_height(code_value_linear_units()); if (code_seen('Z')) set_z_fade_height(code_value_linear_units());
#endif #endif
if (to_enable && !(
#if ENABLED(MESH_BED_LEVELING)
mbl.active()
#else
planner.abl_enabled
#endif
) ) {
to_enable = false;
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_ERR_M420_FAILED);
}
SERIAL_ECHO_START;
SERIAL_ECHOLNPAIR("Bed Leveling ", to_enable ? MSG_ON : MSG_OFF);
// V to print the matrix or mesh
if (code_seen('V')) {
#if ABL_PLANAR
planner.bed_level_matrix.debug("Bed Level Correction Matrix:");
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (bilinear_grid_spacing[X_AXIS]) {
print_bilinear_leveling_grid();
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
bed_level_virt_print();
#endif
}
#elif ENABLED(MESH_BED_LEVELING)
if (mbl.has_mesh()) {
SERIAL_ECHOLNPGM("Mesh Bed Level data:");
mbl_mesh_report();
}
#endif
}
} }
#endif #endif
@ -7048,6 +7106,40 @@ void quickstop_stepper() {
} }
} }
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
/**
* M421: Set a single Mesh Bed Leveling Z coordinate
*
* M421 I<xindex> J<yindex> Z<linear>
*/
inline void gcode_M421() {
int8_t px = 0, py = 0;
float z = 0;
bool hasI, hasJ, hasZ;
if ((hasI = code_seen('I'))) px = code_value_axis_units(X_AXIS);
if ((hasJ = code_seen('J'))) py = code_value_axis_units(Y_AXIS);
if ((hasZ = code_seen('Z'))) z = code_value_axis_units(Z_AXIS);
if (hasI && hasJ && hasZ) {
if (px >= 0 && px < ABL_GRID_MAX_POINTS_X && py >= 0 && py < ABL_GRID_MAX_POINTS_X) {
bed_level_grid[px][py] = z;
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
bed_level_virt_prepare();
bed_level_virt_interpolate();
#endif
}
else {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
}
}
else {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
}
}
#endif #endif
/** /**
@ -8757,8 +8849,8 @@ void ok_to_send() {
#define ABL_BG_GRID(X,Y) bed_level_grid_virt[X][Y] #define ABL_BG_GRID(X,Y) bed_level_grid_virt[X][Y]
#else #else
#define ABL_BG_SPACING(A) bilinear_grid_spacing[A] #define ABL_BG_SPACING(A) bilinear_grid_spacing[A]
#define ABL_BG_POINTS_X ABL_GRID_POINTS_X #define ABL_BG_POINTS_X ABL_GRID_MAX_POINTS_X
#define ABL_BG_POINTS_Y ABL_GRID_POINTS_Y #define ABL_BG_POINTS_Y ABL_GRID_MAX_POINTS_Y
#define ABL_BG_GRID(X,Y) bed_level_grid[X][Y] #define ABL_BG_GRID(X,Y) bed_level_grid[X][Y]
#endif #endif

@ -142,7 +142,9 @@
#elif defined(AUTO_BED_LEVELING_FEATURE) #elif defined(AUTO_BED_LEVELING_FEATURE)
#error "AUTO_BED_LEVELING_FEATURE is deprecated. Specify AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_3POINT." #error "AUTO_BED_LEVELING_FEATURE is deprecated. Specify AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_3POINT."
#elif defined(ABL_GRID_POINTS) #elif defined(ABL_GRID_POINTS)
#error "ABL_GRID_POINTS is now ABL_GRID_POINTS_X and ABL_GRID_POINTS_Y. Please update your configuration." #error "ABL_GRID_POINTS is now ABL_GRID_MAX_POINTS_X and ABL_GRID_MAX_POINTS_Y. Please update your configuration."
#elif defined(ABL_GRID_POINTS_X) || defined(ABL_GRID_POINTS_Y)
#error "ABL_GRID_POINTS_[XY] is now ABL_GRID_MAX_POINTS_[XY]. Please update your configuration."
#elif defined(BEEPER) #elif defined(BEEPER)
#error "BEEPER is now BEEPER_PIN. Please update your pins definitions." #error "BEEPER is now BEEPER_PIN. Please update your pins definitions."
#elif defined(SDCARDDETECT) #elif defined(SDCARDDETECT)
@ -212,10 +214,10 @@
#error "You probably want to use Max Endstops for DELTA!" #error "You probably want to use Max Endstops for DELTA!"
#endif #endif
#if ABL_GRID #if ABL_GRID
#if (ABL_GRID_POINTS_X & 1) == 0 || (ABL_GRID_POINTS_Y & 1) == 0 #if (ABL_GRID_MAX_POINTS_X & 1) == 0 || (ABL_GRID_MAX_POINTS_Y & 1) == 0
#error "DELTA requires ABL_GRID_POINTS_X and ABL_GRID_POINTS_Y to be odd numbers." #error "DELTA requires ABL_GRID_MAX_POINTS_X and ABL_GRID_MAX_POINTS_Y to be odd numbers."
#elif ABL_GRID_POINTS_X < 3 #elif ABL_GRID_MAX_POINTS_X < 3
#error "DELTA requires ABL_GRID_POINTS_X and ABL_GRID_POINTS_Y to be 3 or higher." #error "DELTA requires ABL_GRID_MAX_POINTS_X and ABL_GRID_MAX_POINTS_Y to be 3 or higher."
#endif #endif
#endif #endif
#endif #endif

@ -36,18 +36,18 @@
* *
*/ */
#define EEPROM_VERSION "V28" #define EEPROM_VERSION "V29"
// Change EEPROM version if these are changed: // Change EEPROM version if these are changed:
#define EEPROM_OFFSET 100 #define EEPROM_OFFSET 100
/** /**
* V28 EEPROM Layout: * V29 EEPROM Layout:
* *
* 100 Version (char x4) * 100 Version (char x4)
* 104 EEPROM Checksum (uint16_t) * 104 EEPROM Checksum (uint16_t)
* *
* 106 E_STEPPERS (uint8_t) * 106 E_STEPPERS (uint8_t)
* 107 M92 XYZE planner.axis_steps_per_mm (float x4 ... x7) * 107 M92 XYZE planner.axis_steps_per_mm (float x4 ... x7)
* 123 M203 XYZE planner.max_feedrate_mm_s (float x4 ... x7) * 123 M203 XYZE planner.max_feedrate_mm_s (float x4 ... x7)
* 139 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x7) * 139 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x7)
@ -65,60 +65,71 @@
* 207 M218 XYZ hotend_offset (float x3 per additional hotend) * 207 M218 XYZ hotend_offset (float x3 per additional hotend)
* *
* Mesh bed leveling: * Mesh bed leveling:
* 219 M420 S status (uint8) * 219 M420 S from mbl.status (bool)
* 220 z_offset (float) * 220 mbl.z_offset (float)
* 224 mesh_num_x (uint8 as set in firmware) * 224 MESH_NUM_X_POINTS (uint8 as set in firmware)
* 225 mesh_num_y (uint8 as set in firmware) * 225 MESH_NUM_Y_POINTS (uint8 as set in firmware)
* 226 G29 S3 XYZ z_values[][] (float x9, by default, up to float x 81) * 226 G29 S3 XYZ z_values[][] (float x9, by default, up to float x 81) +288
* *
* AUTO BED LEVELING * AUTO BED LEVELING
* 262 M851 zprobe_zoffset (float) * 262 M851 zprobe_zoffset (float)
* *
* DELTA: * ABL_PLANAR (or placeholder): 36 bytes
* 266 M666 XYZ endstop_adj (float x3) * 266 planner.bed_level_matrix (matrix_3x3 = float x9)
* 278 M665 R delta_radius (float)
* 282 M665 L delta_diagonal_rod (float)
* 286 M665 S delta_segments_per_second (float)
* 290 M665 A delta_diagonal_rod_trim_tower_1 (float)
* 294 M665 B delta_diagonal_rod_trim_tower_2 (float)
* 298 M665 C delta_diagonal_rod_trim_tower_3 (float)
* *
* Z_DUAL_ENDSTOPS: * AUTO_BED_LEVELING_BILINEAR (or placeholder): 47 bytes
* 302 M666 Z z_endstop_adj (float) * 302 ABL_GRID_MAX_POINTS_X (uint8_t)
* 303 ABL_GRID_MAX_POINTS_Y (uint8_t)
* 304 bilinear_grid_spacing (int x2) from G29: (B-F)/X, (R-L)/Y
* 308 G29 L F bilinear_start (int x2)
* 312 bed_level_grid[][] (float x9, up to float x256) +988
* *
* ULTIPANEL: * DELTA (if deltabot): 36 bytes
* 306 M145 S0 H lcd_preheat_hotend_temp (int x2) * 348 M666 XYZ endstop_adj (float x3)
* 310 M145 S0 B lcd_preheat_bed_temp (int x2) * 360 M665 R delta_radius (float)
* 314 M145 S0 F lcd_preheat_fan_speed (int x2) * 364 M665 L delta_diagonal_rod (float)
* 368 M665 S delta_segments_per_second (float)
* 372 M665 A delta_diagonal_rod_trim_tower_1 (float)
* 376 M665 B delta_diagonal_rod_trim_tower_2 (float)
* 380 M665 C delta_diagonal_rod_trim_tower_3 (float)
* *
* PIDTEMP: * Z_DUAL_ENDSTOPS: 4 bytes
* 318 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) * 384 M666 Z z_endstop_adj (float)
* 334 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) *
* 350 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) * ULTIPANEL: 6 bytes
* 366 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) * 388 M145 S0 H lcd_preheat_hotend_temp (int x2)
* 382 M301 L lpq_len (int) * 392 M145 S0 B lcd_preheat_bed_temp (int x2)
* 396 M145 S0 F lcd_preheat_fan_speed (int x2)
*
* PIDTEMP: 66 bytes
* 400 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4)
* 416 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4)
* 432 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4)
* 448 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4)
* 464 M301 L lpq_len (int)
* *
* PIDTEMPBED: * PIDTEMPBED:
* 384 M304 PID thermalManager.bedKp, thermalManager.bedKi, thermalManager.bedKd (float x3) * 466 M304 PID thermalManager.bedKp, thermalManager.bedKi, thermalManager.bedKd (float x3)
* *
* DOGLCD: * DOGLCD: 2 bytes
* 396 M250 C lcd_contrast (int) * 478 M250 C lcd_contrast (int)
* *
* FWRETRACT: * FWRETRACT: 29 bytes
* 398 M209 S autoretract_enabled (bool) * 480 M209 S autoretract_enabled (bool)
* 399 M207 S retract_length (float) * 481 M207 S retract_length (float)
* 403 M207 W retract_length_swap (float) * 485 M207 W retract_length_swap (float)
* 407 M207 F retract_feedrate_mm_s (float) * 489 M207 F retract_feedrate_mm_s (float)
* 411 M207 Z retract_zlift (float) * 493 M207 Z retract_zlift (float)
* 415 M208 S retract_recover_length (float) * 497 M208 S retract_recover_length (float)
* 419 M208 W retract_recover_length_swap (float) * 501 M208 W retract_recover_length_swap (float)
* 423 M208 F retract_recover_feedrate_mm_s (float) * 505 M208 F retract_recover_feedrate_mm_s (float)
* *
* Volumetric Extrusion: * Volumetric Extrusion: 17 bytes
* 427 M200 D volumetric_enabled (bool) * 509 M200 D volumetric_enabled (bool)
* 428 M200 T D filament_size (float x4) (T0..3) * 510 M200 T D filament_size (float x4) (T0..3)
* *
* 444 This Slot is Available! * 526 Minimum end-point
* 1847 (526 + 36 + 9 + 288 + 988) Maximum end-point
* *
*/ */
#include "Marlin.h" #include "Marlin.h"
@ -133,6 +144,11 @@
#include "mesh_bed_leveling.h" #include "mesh_bed_leveling.h"
#endif #endif
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
extern void bed_level_virt_prepare();
extern void bed_level_virt_interpolate();
#endif
/** /**
* Post-process after Retrieve or Reset * Post-process after Retrieve or Reset
*/ */
@ -188,10 +204,11 @@ void Config_Postprocess() {
value++; value++;
}; };
} }
bool eeprom_read_error;
void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) { void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) {
do { do {
uint8_t c = eeprom_read_byte((unsigned char*)pos); uint8_t c = eeprom_read_byte((unsigned char*)pos);
*value = c; if (!eeprom_read_error) *value = c;
eeprom_checksum += c; eeprom_checksum += c;
pos++; pos++;
value++; value++;
@ -203,6 +220,7 @@ void Config_Postprocess() {
#define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR) #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR)
#define EEPROM_WRITE(VAR) _EEPROM_writeData(eeprom_index, (uint8_t*)&VAR, sizeof(VAR)) #define EEPROM_WRITE(VAR) _EEPROM_writeData(eeprom_index, (uint8_t*)&VAR, sizeof(VAR))
#define EEPROM_READ(VAR) _EEPROM_readData(eeprom_index, (uint8_t*)&VAR, sizeof(VAR)) #define EEPROM_READ(VAR) _EEPROM_readData(eeprom_index, (uint8_t*)&VAR, sizeof(VAR))
#define EEPROM_ASSERT(TST,ERR) if () do{ SERIAL_ERROR_START; SERIAL_ERRORLNPGM(ERR); eeprom_read_error |= true; }while(0)
/** /**
* M500 - Store Configuration * M500 - Store Configuration
@ -241,28 +259,30 @@ void Config_Postprocess() {
LOOP_XYZ(i) EEPROM_WRITE(hotend_offset[i][e]); LOOP_XYZ(i) EEPROM_WRITE(hotend_offset[i][e]);
#endif #endif
//
// Mesh Bed Leveling
//
#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];
uint8_t mesh_num_x = MESH_NUM_X_POINTS, const bool leveling_is_on = TEST(mbl.status, MBL_STATUS_HAS_MESH_BIT);
mesh_num_y = MESH_NUM_Y_POINTS, const uint8_t mesh_num_x = MESH_NUM_X_POINTS, mesh_num_y = MESH_NUM_Y_POINTS;
dummy_uint8 = mbl.status & _BV(MBL_STATUS_HAS_MESH_BIT); EEPROM_WRITE(leveling_is_on);
EEPROM_WRITE(dummy_uint8);
EEPROM_WRITE(mbl.z_offset); EEPROM_WRITE(mbl.z_offset);
EEPROM_WRITE(mesh_num_x); EEPROM_WRITE(mesh_num_x);
EEPROM_WRITE(mesh_num_y); EEPROM_WRITE(mesh_num_y);
EEPROM_WRITE(mbl.z_values); EEPROM_WRITE(mbl.z_values);
#else #else
// For disabled MBL write a default mesh // For disabled MBL write a default mesh
uint8_t mesh_num_x = 3, const bool leveling_is_on = false;
mesh_num_y = 3,
dummy_uint8 = 0;
dummy = 0.0f; dummy = 0.0f;
EEPROM_WRITE(dummy_uint8); const uint8_t mesh_num_x = 3, mesh_num_y = 3;
EEPROM_WRITE(dummy); EEPROM_WRITE(leveling_is_on);
EEPROM_WRITE(dummy); // z_offset
EEPROM_WRITE(mesh_num_x); EEPROM_WRITE(mesh_num_x);
EEPROM_WRITE(mesh_num_y); EEPROM_WRITE(mesh_num_y);
for (uint8_t q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_WRITE(dummy); for (uint8_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_WRITE(dummy);
#endif // MESH_BED_LEVELING #endif // MESH_BED_LEVELING
#if !HAS_BED_PROBE #if !HAS_BED_PROBE
@ -270,6 +290,42 @@ void Config_Postprocess() {
#endif #endif
EEPROM_WRITE(zprobe_zoffset); EEPROM_WRITE(zprobe_zoffset);
//
// Planar Bed Leveling matrix
//
#if ABL_PLANAR
EEPROM_WRITE(planner.bed_level_matrix);
#else
dummy = 0.0;
for (uint8_t q = 9; q--;) EEPROM_WRITE(dummy);
#endif
//
// Bilinear Auto Bed Leveling
//
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Compile time test that sizeof(bed_level_grid) is as expected
typedef char c_assert[(sizeof(bed_level_grid) == (ABL_GRID_MAX_POINTS_X) * (ABL_GRID_MAX_POINTS_Y) * sizeof(dummy)) ? 1 : -1];
const uint8_t grid_max_x = ABL_GRID_MAX_POINTS_X, grid_max_y = ABL_GRID_MAX_POINTS_Y;
EEPROM_WRITE(grid_max_x); // 1 byte
EEPROM_WRITE(grid_max_y); // 1 byte
EEPROM_WRITE(bilinear_grid_spacing); // 2 ints
EEPROM_WRITE(bilinear_start); // 2 ints
EEPROM_WRITE(bed_level_grid); // 9-256 floats
#else
// For disabled Bilinear Grid write an empty 3x3 grid
const uint8_t grid_max_x = 3, grid_max_y = 3;
const int bilinear_start[2] = { 0 }, bilinear_grid_spacing[2] = { 0 };
dummy = 0.0f;
EEPROM_WRITE(grid_max_x);
EEPROM_WRITE(grid_max_y);
EEPROM_WRITE(bilinear_grid_spacing);
EEPROM_WRITE(bilinear_start);
for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_WRITE(dummy);
#endif // AUTO_BED_LEVELING_BILINEAR
// 9 floats for DELTA / Z_DUAL_ENDSTOPS // 9 floats for DELTA / Z_DUAL_ENDSTOPS
#if ENABLED(DELTA) #if ENABLED(DELTA)
EEPROM_WRITE(endstop_adj); // 3 floats EEPROM_WRITE(endstop_adj); // 3 floats
@ -371,17 +427,21 @@ void Config_Postprocess() {
EEPROM_WRITE(dummy); EEPROM_WRITE(dummy);
} }
uint16_t final_checksum = eeprom_checksum, if (!eeprom_write_error) {
eeprom_size = eeprom_index;
uint16_t final_checksum = eeprom_checksum,
eeprom_size = eeprom_index;
eeprom_index = EEPROM_OFFSET; // Write the EEPROM header
EEPROM_WRITE(version); eeprom_index = EEPROM_OFFSET;
EEPROM_WRITE(final_checksum); EEPROM_WRITE(version);
EEPROM_WRITE(final_checksum);
// Report storage size // Report storage size
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOPAIR("Settings Stored (", eeprom_size); SERIAL_ECHOPAIR("Settings Stored (", eeprom_size);
SERIAL_ECHOLNPGM(" bytes)"); SERIAL_ECHOLNPGM(" bytes)");
}
} }
/** /**
@ -390,6 +450,7 @@ void Config_Postprocess() {
void Config_RetrieveSettings() { void Config_RetrieveSettings() {
EEPROM_START(); EEPROM_START();
eeprom_read_error = false; // If set EEPROM_READ won't write into RAM
char stored_ver[4]; char stored_ver[4];
EEPROM_READ(stored_ver); EEPROM_READ(stored_ver);
@ -418,9 +479,9 @@ void Config_Postprocess() {
// Get only the number of E stepper parameters previously stored // Get only the number of E stepper parameters previously stored
// Any steppers added later are set to their defaults // Any steppers added later are set to their defaults
const float def1[] = DEFAULT_AXIS_STEPS_PER_UNIT, def2[] = DEFAULT_MAX_FEEDRATE; const float def1[] = DEFAULT_AXIS_STEPS_PER_UNIT, def2[] = DEFAULT_MAX_FEEDRATE;
const long def3[] = DEFAULT_MAX_ACCELERATION; const uint32_t def3[] = DEFAULT_MAX_ACCELERATION;
float tmp1[XYZ + esteppers], tmp2[XYZ + esteppers]; float tmp1[XYZ + esteppers], tmp2[XYZ + esteppers];
long tmp3[XYZ + esteppers]; uint32_t tmp3[XYZ + esteppers];
EEPROM_READ(tmp1); EEPROM_READ(tmp1);
EEPROM_READ(tmp2); EEPROM_READ(tmp2);
EEPROM_READ(tmp3); EEPROM_READ(tmp3);
@ -445,13 +506,19 @@ void Config_Postprocess() {
LOOP_XYZ(i) EEPROM_READ(hotend_offset[i][e]); LOOP_XYZ(i) EEPROM_READ(hotend_offset[i][e]);
#endif #endif
uint8_t dummy_uint8 = 0, mesh_num_x = 0, mesh_num_y = 0; //
EEPROM_READ(dummy_uint8); // Mesh (Manual) Bed Leveling
//
bool leveling_is_on;
uint8_t mesh_num_x, mesh_num_y;
EEPROM_READ(leveling_is_on);
EEPROM_READ(dummy); EEPROM_READ(dummy);
EEPROM_READ(mesh_num_x); EEPROM_READ(mesh_num_x);
EEPROM_READ(mesh_num_y); EEPROM_READ(mesh_num_y);
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
mbl.status = dummy_uint8; mbl.status = leveling_is_on ? _BV(MBL_STATUS_HAS_MESH_BIT) : 0;
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 data fits the current mesh // EEPROM data fits the current mesh
@ -460,11 +527,11 @@ void Config_Postprocess() {
else { else {
// EEPROM data is stale // EEPROM data is stale
mbl.reset(); mbl.reset();
for (uint8_t q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_READ(dummy); for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummy);
} }
#else #else
// MBL is disabled - skip the stored data // MBL is disabled - skip the stored data
for (uint8_t q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_READ(dummy); for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummy);
#endif // MESH_BED_LEVELING #endif // MESH_BED_LEVELING
#if !HAS_BED_PROBE #if !HAS_BED_PROBE
@ -472,6 +539,45 @@ void Config_Postprocess() {
#endif #endif
EEPROM_READ(zprobe_zoffset); EEPROM_READ(zprobe_zoffset);
//
// Planar Bed Leveling matrix
//
#if ABL_PLANAR
EEPROM_READ(planner.bed_level_matrix);
#else
for (uint8_t q = 9; q--;) EEPROM_READ(dummy);
#endif
//
// Bilinear Auto Bed Leveling
//
uint8_t grid_max_x, grid_max_y;
EEPROM_READ(grid_max_x); // 1 byte
EEPROM_READ(grid_max_y); // 1 byte
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (grid_max_x == ABL_GRID_MAX_POINTS_X && grid_max_y == ABL_GRID_MAX_POINTS_Y) {
set_bed_leveling_enabled(false);
EEPROM_READ(bilinear_grid_spacing); // 2 ints
EEPROM_READ(bilinear_start); // 2 ints
EEPROM_READ(bed_level_grid); // 9 to 256 floats
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
bed_level_virt_prepare();
bed_level_virt_interpolate();
#endif
//set_bed_leveling_enabled(leveling_is_on);
}
else // EEPROM data is stale
#endif // AUTO_BED_LEVELING_BILINEAR
{
// Skip past disabled (or stale) Bilinear Grid data
int bgs[2], bs[2];
EEPROM_READ(bgs);
EEPROM_READ(bs);
for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummy);
}
#if ENABLED(DELTA) #if ENABLED(DELTA)
EEPROM_READ(endstop_adj); // 3 floats EEPROM_READ(endstop_adj); // 3 floats
EEPROM_READ(delta_radius); // 1 float EEPROM_READ(delta_radius); // 1 float
@ -568,11 +674,15 @@ void Config_Postprocess() {
} }
if (eeprom_checksum == stored_checksum) { if (eeprom_checksum == stored_checksum) {
Config_Postprocess(); if (eeprom_read_error)
SERIAL_ECHO_START; Config_ResetDefault();
SERIAL_ECHO(version); else {
SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index); Config_Postprocess();
SERIAL_ECHOLNPGM(" bytes)"); SERIAL_ECHO_START;
SERIAL_ECHO(version);
SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index);
SERIAL_ECHOLNPGM(" bytes)");
}
} }
else { else {
SERIAL_ERROR_START; SERIAL_ERROR_START;
@ -600,7 +710,7 @@ void Config_Postprocess() {
*/ */
void Config_ResetDefault() { void Config_ResetDefault() {
const float tmp1[] = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] = DEFAULT_MAX_FEEDRATE; const float tmp1[] = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] = DEFAULT_MAX_FEEDRATE;
const long tmp3[] = DEFAULT_MAX_ACCELERATION; const uint32_t tmp3[] = DEFAULT_MAX_ACCELERATION;
LOOP_XYZE_N(i) { LOOP_XYZE_N(i) {
planner.axis_steps_per_mm[i] = tmp1[i < COUNT(tmp1) ? i : COUNT(tmp1) - 1]; planner.axis_steps_per_mm[i] = tmp1[i < COUNT(tmp1) ? i : COUNT(tmp1) - 1];
planner.max_feedrate_mm_s[i] = tmp2[i < COUNT(tmp2) ? i : COUNT(tmp2) - 1]; planner.max_feedrate_mm_s[i] = tmp2[i < COUNT(tmp2) ? i : COUNT(tmp2) - 1];
@ -636,8 +746,9 @@ void Config_ResetDefault() {
LOOP_XYZ(i) HOTEND_LOOP() hotend_offset[i][e] = tmp4[i][e]; LOOP_XYZ(i) HOTEND_LOOP() hotend_offset[i][e] = tmp4[i][e];
#endif #endif
#if ENABLED(MESH_BED_LEVELING) // Applies to all MBL and ABL
mbl.reset(); #if PLANNER_LEVELING
reset_bed_level();
#endif #endif
#if HAS_BED_PROBE #if HAS_BED_PROBE
@ -649,9 +760,9 @@ void Config_ResetDefault() {
endstop_adj[A_AXIS] = adj[A_AXIS]; endstop_adj[A_AXIS] = adj[A_AXIS];
endstop_adj[B_AXIS] = adj[B_AXIS]; endstop_adj[B_AXIS] = adj[B_AXIS];
endstop_adj[C_AXIS] = adj[C_AXIS]; endstop_adj[C_AXIS] = adj[C_AXIS];
delta_radius = DELTA_RADIUS; delta_radius = DELTA_RADIUS;
delta_diagonal_rod = DELTA_DIAGONAL_ROD; delta_diagonal_rod = DELTA_DIAGONAL_ROD;
delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
delta_diagonal_rod_trim_tower_1 = DELTA_DIAGONAL_ROD_TRIM_TOWER_1; delta_diagonal_rod_trim_tower_1 = DELTA_DIAGONAL_ROD_TRIM_TOWER_1;
delta_diagonal_rod_trim_tower_2 = DELTA_DIAGONAL_ROD_TRIM_TOWER_2; delta_diagonal_rod_trim_tower_2 = DELTA_DIAGONAL_ROD_TRIM_TOWER_2;
delta_diagonal_rod_trim_tower_3 = DELTA_DIAGONAL_ROD_TRIM_TOWER_3; delta_diagonal_rod_trim_tower_3 = DELTA_DIAGONAL_ROD_TRIM_TOWER_3;
@ -852,13 +963,10 @@ void Config_ResetDefault() {
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
if (!forReplay) { if (!forReplay) {
SERIAL_ECHOLNPGM("Mesh bed leveling:"); SERIAL_ECHOLNPGM("Mesh Bed Leveling:");
CONFIG_ECHO_START; CONFIG_ECHO_START;
} }
SERIAL_ECHOPAIR(" M420 S", mbl.has_mesh() ? 1 : 0); SERIAL_ECHOLNPAIR(" M420 S", mbl.has_mesh() ? 1 : 0);
SERIAL_ECHOPAIR(" X", MESH_NUM_X_POINTS);
SERIAL_ECHOPAIR(" Y", MESH_NUM_Y_POINTS);
SERIAL_EOL;
for (uint8_t py = 1; py <= MESH_NUM_Y_POINTS; py++) { for (uint8_t py = 1; py <= MESH_NUM_Y_POINTS; py++) {
for (uint8_t px = 1; px <= MESH_NUM_X_POINTS; px++) { for (uint8_t px = 1; px <= MESH_NUM_X_POINTS; px++) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
@ -869,6 +977,12 @@ void Config_ResetDefault() {
SERIAL_EOL; SERIAL_EOL;
} }
} }
#elif HAS_ABL
if (!forReplay) {
SERIAL_ECHOLNPGM("Auto Bed Leveling:");
CONFIG_ECHO_START;
}
SERIAL_ECHOLNPAIR(" M420 S", planner.abl_enabled ? 1 : 0);
#endif #endif
#if ENABLED(DELTA) #if ENABLED(DELTA)

@ -805,8 +805,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -788,8 +788,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -788,8 +788,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -797,8 +797,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -799,8 +799,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER #define LEFT_PROBE_BED_POSITION X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER

@ -834,8 +834,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -805,8 +805,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -805,8 +805,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -805,8 +805,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -804,8 +804,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -820,8 +820,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -826,8 +826,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -797,8 +797,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -805,8 +805,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -898,8 +898,8 @@
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
// Works best with 5 or more points in each dimension. // Works best with 5 or more points in each dimension.
#define ABL_GRID_POINTS_X 9 #define ABL_GRID_MAX_POINTS_X 9
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10)

@ -892,8 +892,8 @@
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
// Works best with 5 or more points in each dimension. // Works best with 5 or more points in each dimension.
#define ABL_GRID_POINTS_X 9 #define ABL_GRID_MAX_POINTS_X 9
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10)

@ -895,8 +895,8 @@
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
// Works best with 5 or more points in each dimension. // Works best with 5 or more points in each dimension.
#define ABL_GRID_POINTS_X 9 #define ABL_GRID_MAX_POINTS_X 9
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10)

@ -894,8 +894,8 @@
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
// Works best with 5 or more points in each dimension. // Works best with 5 or more points in each dimension.
#define ABL_GRID_POINTS_X 7 #define ABL_GRID_MAX_POINTS_X 7
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS-25) #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS-25)

@ -898,8 +898,8 @@
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
// Works best with 5 or more points in each dimension. // Works best with 5 or more points in each dimension.
#define ABL_GRID_POINTS_X 5 #define ABL_GRID_MAX_POINTS_X 5
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10)

@ -808,8 +808,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -801,8 +801,8 @@
#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension. // Set the number of grid points per dimension.
#define ABL_GRID_POINTS_X 3 #define ABL_GRID_MAX_POINTS_X 3
#define ABL_GRID_POINTS_Y ABL_GRID_POINTS_X #define ABL_GRID_MAX_POINTS_Y ABL_GRID_MAX_POINTS_X
// Set the boundaries for probing (where the probe can reach). // Set the boundaries for probing (where the probe can reach).
#define LEFT_PROBE_BED_POSITION 15 #define LEFT_PROBE_BED_POSITION 15

@ -153,10 +153,11 @@
#define MSG_Z2_MAX "z2_max: " #define MSG_Z2_MAX "z2_max: "
#define MSG_Z_PROBE "z_probe: " #define MSG_Z_PROBE "z_probe: "
#define MSG_ERR_MATERIAL_INDEX "M145 S<index> out of range (0-1)" #define MSG_ERR_MATERIAL_INDEX "M145 S<index> out of range (0-1)"
#define MSG_ERR_M421_PARAMETERS "M421 requires XYZ or IJZ parameters" #define MSG_ERR_M421_PARAMETERS "M421 required parameters missing"
#define MSG_ERR_MESH_XY "Mesh XY or IJ cannot be resolved" #define MSG_ERR_MESH_XY "Mesh point cannot be resolved"
#define MSG_ERR_ARC_ARGS "G2/G3 bad parameters" #define MSG_ERR_ARC_ARGS "G2/G3 bad parameters"
#define MSG_ERR_PROTECTED_PIN "Protected Pin" #define MSG_ERR_PROTECTED_PIN "Protected Pin"
#define MSG_ERR_M420_FAILED "Failed to enable Bed Leveling"
#define MSG_ERR_M428_TOO_FAR "Too far from reference point" #define MSG_ERR_M428_TOO_FAR "Too far from reference point"
#define MSG_ERR_M303_DISABLED "PIDTEMP disabled" #define MSG_ERR_M303_DISABLED "PIDTEMP disabled"
#define MSG_M119_REPORT "Reporting endstop status" #define MSG_M119_REPORT "Reporting endstop status"

@ -148,8 +148,8 @@ class Planner {
static float max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second static float max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second
axis_steps_per_mm[XYZE_N], axis_steps_per_mm[XYZE_N],
steps_to_mm[XYZE_N]; steps_to_mm[XYZE_N];
static unsigned long max_acceleration_steps_per_s2[XYZE_N], static uint32_t max_acceleration_steps_per_s2[XYZE_N],
max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software
static millis_t min_segment_time; static millis_t min_segment_time;
static float min_feedrate_mm_s, static float min_feedrate_mm_s,

Loading…
Cancel
Save