Mesh Bed Leveling rewritten, upcaling of tiles, better bed finding method and minor other tweaks.
This commit is contained in:
parent
4263792793
commit
d7417e1dd3
|
|
@ -486,7 +486,9 @@ void serial_echopair_P(const char *s_P, unsigned long v)
|
||||||
}
|
}
|
||||||
#endif //!SDSUPPORT
|
#endif //!SDSUPPORT
|
||||||
|
|
||||||
|
#ifdef MESH_BED_LEVELING
|
||||||
|
static void find_bed();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//adds an command to the main command buffer
|
//adds an command to the main command buffer
|
||||||
|
|
@ -1076,6 +1078,28 @@ static void axis_is_at_home(int axis) {
|
||||||
inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); }
|
inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); }
|
||||||
inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); }
|
inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); }
|
||||||
|
|
||||||
|
|
||||||
|
static void setup_for_endstop_move() {
|
||||||
|
saved_feedrate = feedrate;
|
||||||
|
saved_feedmultiply = feedmultiply;
|
||||||
|
feedmultiply = 100;
|
||||||
|
previous_millis_cmd = millis();
|
||||||
|
|
||||||
|
enable_endstops(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clean_up_after_endstop_move() {
|
||||||
|
#ifdef ENDSTOPS_ONLY_FOR_HOMING
|
||||||
|
enable_endstops(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
feedrate = saved_feedrate;
|
||||||
|
feedmultiply = saved_feedmultiply;
|
||||||
|
previous_millis_cmd = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_AUTO_BED_LEVELING
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
||||||
#ifdef AUTO_BED_LEVELING_GRID
|
#ifdef AUTO_BED_LEVELING_GRID
|
||||||
static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
|
static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
|
||||||
|
|
@ -1184,24 +1208,6 @@ static void do_blocking_move_relative(float offset_x, float offset_y, float offs
|
||||||
do_blocking_move_to(current_position[X_AXIS] + offset_x, current_position[Y_AXIS] + offset_y, current_position[Z_AXIS] + offset_z);
|
do_blocking_move_to(current_position[X_AXIS] + offset_x, current_position[Y_AXIS] + offset_y, current_position[Z_AXIS] + offset_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_for_endstop_move() {
|
|
||||||
saved_feedrate = feedrate;
|
|
||||||
saved_feedmultiply = feedmultiply;
|
|
||||||
feedmultiply = 100;
|
|
||||||
previous_millis_cmd = millis();
|
|
||||||
|
|
||||||
enable_endstops(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clean_up_after_endstop_move() {
|
|
||||||
#ifdef ENDSTOPS_ONLY_FOR_HOMING
|
|
||||||
enable_endstops(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
feedrate = saved_feedrate;
|
|
||||||
feedmultiply = saved_feedmultiply;
|
|
||||||
previous_millis_cmd = millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void engage_z_probe() {
|
static void engage_z_probe() {
|
||||||
// Engage Z Servo endstop if enabled
|
// Engage Z Servo endstop if enabled
|
||||||
|
|
@ -2174,18 +2180,18 @@ void process_commands()
|
||||||
#endif // ENABLE_AUTO_BED_LEVELING
|
#endif // ENABLE_AUTO_BED_LEVELING
|
||||||
|
|
||||||
#ifdef MESH_BED_LEVELING
|
#ifdef MESH_BED_LEVELING
|
||||||
/**
|
/**
|
||||||
* G80: Mesh-based Z probe, probes a grid and produces a
|
* G80: Mesh-based Z probe, probes a grid and produces a
|
||||||
* mesh to compensate for variable bed height
|
* mesh to compensate for variable bed height
|
||||||
*
|
*
|
||||||
* The S0 report the points as below
|
* The S0 report the points as below
|
||||||
*
|
*
|
||||||
* +----> X-axis
|
* +----> X-axis
|
||||||
* |
|
* |
|
||||||
* |
|
* |
|
||||||
* v Y-axis
|
* v Y-axis
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
case 80:
|
case 80:
|
||||||
{
|
{
|
||||||
// Firstly check if we know where we are
|
// Firstly check if we know where we are
|
||||||
|
|
@ -2217,8 +2223,8 @@ void process_commands()
|
||||||
int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS]/20;
|
int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS]/20;
|
||||||
int Z_PROBE_FEEDRATE = homing_feedrate[Z_AXIS]/60;
|
int Z_PROBE_FEEDRATE = homing_feedrate[Z_AXIS]/60;
|
||||||
int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS]/40;
|
int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS]/40;
|
||||||
|
setup_for_endstop_move();
|
||||||
while (!(mesh_point == ((MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS)) )) {
|
while (!(mesh_point == ((MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) ))) {
|
||||||
|
|
||||||
// Move Z to proper distance
|
// Move Z to proper distance
|
||||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
||||||
|
|
@ -2227,12 +2233,12 @@ void process_commands()
|
||||||
st_synchronize();
|
st_synchronize();
|
||||||
|
|
||||||
// Get cords of measuring point
|
// Get cords of measuring point
|
||||||
ix = mesh_point % MESH_NUM_X_POINTS;
|
ix = mesh_point % MESH_MEAS_NUM_X_POINTS;
|
||||||
iy = mesh_point / MESH_NUM_X_POINTS;
|
iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
|
||||||
if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag
|
if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag
|
||||||
|
|
||||||
current_position[X_AXIS] = mbl.get_x(ix);
|
current_position[X_AXIS] = mbl.get_meas_x(ix);
|
||||||
current_position[Y_AXIS] = mbl.get_y(iy);
|
current_position[Y_AXIS] = mbl.get_meas_y(iy);
|
||||||
|
|
||||||
current_position[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER;
|
current_position[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER;
|
||||||
current_position[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER;
|
current_position[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER;
|
||||||
|
|
@ -2241,14 +2247,9 @@ void process_commands()
|
||||||
st_synchronize();
|
st_synchronize();
|
||||||
|
|
||||||
// Go down until endstop is hit
|
// Go down until endstop is hit
|
||||||
while ((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING ) == 0) {
|
|
||||||
|
|
||||||
current_position[Z_AXIS] -= MBL_Z_STEP;
|
find_bed();
|
||||||
|
|
||||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], Z_PROBE_FEEDRATE, active_extruder);
|
|
||||||
st_synchronize();
|
|
||||||
delay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mbl.set_z(ix, iy, current_position[Z_AXIS]);
|
mbl.set_z(ix, iy, current_position[Z_AXIS]);
|
||||||
|
|
@ -2256,8 +2257,10 @@ void process_commands()
|
||||||
mesh_point++;
|
mesh_point++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
clean_up_after_endstop_move();
|
||||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
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], Z_LIFT_FEEDRATE, active_extruder);
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], Z_LIFT_FEEDRATE, active_extruder);
|
||||||
|
mbl.upsample_3x3();
|
||||||
mbl.active = 1;
|
mbl.active = 1;
|
||||||
current_position[X_AXIS] = X_MIN_POS+0.2;
|
current_position[X_AXIS] = X_MIN_POS+0.2;
|
||||||
current_position[Y_AXIS] = Y_MIN_POS+0.2;
|
current_position[Y_AXIS] = Y_MIN_POS+0.2;
|
||||||
|
|
@ -2268,6 +2271,9 @@ void process_commands()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G81: Print mesh bed leveling status and bed profile if activated
|
||||||
|
*/
|
||||||
case 81:
|
case 81:
|
||||||
if (mbl.active) {
|
if (mbl.active) {
|
||||||
SERIAL_PROTOCOLPGM("Num X,Y: ");
|
SERIAL_PROTOCOLPGM("Num X,Y: ");
|
||||||
|
|
@ -2288,6 +2294,21 @@ void process_commands()
|
||||||
else
|
else
|
||||||
SERIAL_PROTOCOLLNPGM("Mesh bed leveling not active.");
|
SERIAL_PROTOCOLLNPGM("Mesh bed leveling not active.");
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* G82: Single Z probe at current location
|
||||||
|
*
|
||||||
|
* WARNING! USE WITH CAUTION! If you'll try to probe where is no leveling pad, nasty things can happen!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
case 82:
|
||||||
|
SERIAL_PROTOCOLLNPGM("Finding bed ");
|
||||||
|
setup_for_endstop_move();
|
||||||
|
find_bed();
|
||||||
|
clean_up_after_endstop_move();
|
||||||
|
SERIAL_PROTOCOLPGM("Bed found at: ");
|
||||||
|
SERIAL_PROTOCOL_F(current_position[Z_AXIS], 5);
|
||||||
|
SERIAL_PROTOCOLPGM("\n");
|
||||||
|
break;
|
||||||
#endif // ENABLE_MESH_BED_LEVELING
|
#endif // ENABLE_MESH_BED_LEVELING
|
||||||
|
|
||||||
case 90: // G90
|
case 90: // G90
|
||||||
|
|
@ -4623,58 +4644,58 @@ void calculate_delta(float cartesian[3])
|
||||||
|
|
||||||
#ifdef MESH_BED_LEVELING
|
#ifdef MESH_BED_LEVELING
|
||||||
|
|
||||||
// This function is used to split lines on mesh borders so each segment is only part of one mesh area
|
static void find_bed() {
|
||||||
#define X_MID_POS (0.5f*(X_MIN_POS+X_MAX_POS))
|
feedrate = homing_feedrate[Z_AXIS];
|
||||||
#define Y_MID_POS (0.5f*(Y_MIN_POS+Y_MAX_POS))
|
|
||||||
|
|
||||||
void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_rate, const uint8_t& extruder) {
|
// move down until you find the bed
|
||||||
int tileDiff = 0;
|
float zPosition = -10;
|
||||||
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
|
||||||
|
st_synchronize();
|
||||||
|
|
||||||
|
// we have to let the planner know where we are right now as it is not where we said to go.
|
||||||
|
zPosition = st_get_position_mm(Z_AXIS);
|
||||||
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
|
||||||
|
|
||||||
|
// move up the retract distance
|
||||||
|
zPosition += home_retract_mm(Z_AXIS);
|
||||||
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
|
||||||
|
st_synchronize();
|
||||||
|
|
||||||
|
// move back down slowly to find bed
|
||||||
|
feedrate = homing_feedrate[Z_AXIS]/4;
|
||||||
|
zPosition -= home_retract_mm(Z_AXIS) * 2;
|
||||||
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
|
||||||
|
st_synchronize();
|
||||||
|
|
||||||
|
current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
|
||||||
|
// make sure the planner knows where we are as it may be a bit different than we last said to move to
|
||||||
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder) {
|
||||||
|
float dx = x - current_position[X_AXIS];
|
||||||
|
float dy = y - current_position[Y_AXIS];
|
||||||
|
float dz = z - current_position[Z_AXIS];
|
||||||
|
int n_segments = 0;
|
||||||
if (mbl.active) {
|
if (mbl.active) {
|
||||||
// In which of the four tiles the start and the end points fall?
|
float len = abs(dx) + abs(dy) + abs(dz);
|
||||||
// tileDiff is a bitmask,
|
if (len > 0)
|
||||||
// 1st bit indicates a crossing of the tile boundary in the X axis,
|
n_segments = int(floor(len / 30.f));
|
||||||
// 2nd bit indicates a crossing of the tile boundary in the Y axis.
|
|
||||||
tileDiff =
|
|
||||||
((current_position[X_AXIS] > X_MID_POS) | ((current_position[Y_AXIS] > Y_MID_POS) << 1)) ^
|
|
||||||
((x > X_MID_POS) | ((y > Y_MID_POS) << 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalized parameters for the crossing of the tile boundary.
|
if (n_segments > 1) {
|
||||||
float s1, s2;
|
float de = e - current_position[E_AXIS];
|
||||||
// Interpolate a linear movement at the tile boundary, in X, Y and E axes.
|
for (int i = 1; i < n_segments; ++ i) {
|
||||||
#define INRPL_X(u) (current_position[X_AXIS] + (x - current_position[X_AXIS]) * u)
|
float t = float(i) / float(n_segments);
|
||||||
#define INRPL_Y(u) (current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * u)
|
plan_buffer_line(
|
||||||
#define INRPL_E(u) (current_position[E_AXIS] + (e - current_position[E_AXIS]) * u)
|
current_position[X_AXIS] + t * dx,
|
||||||
switch (tileDiff) {
|
current_position[Y_AXIS] + t * dy,
|
||||||
case 0:
|
current_position[Z_AXIS] + t * dz,
|
||||||
// The start and end points on same tile, or the mesh bed leveling is not active.
|
current_position[E_AXIS] + t * de,
|
||||||
break;
|
feed_rate, extruder);
|
||||||
case 1:
|
}
|
||||||
// The start and end tiles differ in X only.
|
|
||||||
s1 = (X_MID_POS - current_position[X_AXIS]) / (x - current_position[X_AXIS]);
|
|
||||||
plan_buffer_line(X_MID_POS, INRPL_Y(s1), z, INRPL_E(s1), feed_rate, extruder);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// The start and end tiles differ in Y only.
|
|
||||||
s1 = (Y_MID_POS - current_position[Y_AXIS]) / (y - current_position[Y_AXIS]);
|
|
||||||
plan_buffer_line(INRPL_X(s1), Y_MID_POS, z, INRPL_E(s1), feed_rate, extruder);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// The start and end tiles differ in both coordinates.
|
|
||||||
// assert(tileDiff == 3);
|
|
||||||
s1 = (X_MID_POS - current_position[X_AXIS]) / (x - current_position[X_AXIS]);
|
|
||||||
s2 = (Y_MID_POS - current_position[Y_AXIS]) / (y - current_position[Y_AXIS]);
|
|
||||||
if (s1 < s2) {
|
|
||||||
plan_buffer_line(X_MID_POS, INRPL_Y(s1), z, INRPL_E(s1), feed_rate, extruder);
|
|
||||||
plan_buffer_line(INRPL_X(s2), Y_MID_POS, z, INRPL_E(s2), feed_rate, extruder);
|
|
||||||
} else {
|
|
||||||
plan_buffer_line(INRPL_X(s1), Y_MID_POS, z, INRPL_E(s1), feed_rate, extruder);
|
|
||||||
plan_buffer_line(X_MID_POS, INRPL_Y(s2), z, INRPL_E(s2), feed_rate, extruder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#undef INRPL_X
|
|
||||||
#undef INRPL_Y
|
|
||||||
#undef INRPL_E
|
|
||||||
// The rest of the path.
|
// The rest of the path.
|
||||||
plan_buffer_line(x, y, z, e, feed_rate, extruder);
|
plan_buffer_line(x, y, z, e, feed_rate, extruder);
|
||||||
set_current_to_destination();
|
set_current_to_destination();
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,65 @@
|
||||||
|
|
||||||
#ifdef MESH_BED_LEVELING
|
#ifdef MESH_BED_LEVELING
|
||||||
|
|
||||||
mesh_bed_leveling mbl;
|
mesh_bed_leveling mbl;
|
||||||
|
|
||||||
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;
|
active = 0;
|
||||||
for (int y = 0; y < MESH_NUM_Y_POINTS; y++)
|
for (int y = 0; y < MESH_NUM_Y_POINTS; y++)
|
||||||
for (int x = 0; x < MESH_NUM_X_POINTS; x++)
|
for (int x = 0; x < MESH_NUM_X_POINTS; x++)
|
||||||
z_values[y][x] = 0;
|
z_values[y][x] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MESH_NUM_X_POINTS>=5 && MESH_NUM_Y_POINTS>=5 && (MESH_NUM_X_POINTS&1)==1 && (MESH_NUM_Y_POINTS&1)==1
|
||||||
|
// Works for an odd number of MESH_NUM_X_POINTS and MESH_NUM_Y_POINTS
|
||||||
|
void mesh_bed_leveling::upsample_3x3()
|
||||||
|
{
|
||||||
|
int idx0 = 0;
|
||||||
|
int idx1 = MESH_NUM_X_POINTS / 2;
|
||||||
|
int idx2 = MESH_NUM_X_POINTS - 1;
|
||||||
|
{
|
||||||
|
// First interpolate the points in X axis.
|
||||||
|
static const float x0 = MESH_MIN_X;
|
||||||
|
static const float x1 = 0.5f * float(MESH_MIN_X + MESH_MAX_X);
|
||||||
|
static const float x2 = MESH_MAX_X;
|
||||||
|
for (int j = 0; j < 3; ++ j) {
|
||||||
|
// 1) Copy the source points to their new destination.
|
||||||
|
z_values[j][idx2] = z_values[j][2];
|
||||||
|
z_values[j][idx1] = z_values[j][1];
|
||||||
|
// 2) Interpolate the remaining values by Largrangian polynomials.
|
||||||
|
for (int i = idx0 + 1; i < idx2; ++ i) {
|
||||||
|
if (i == idx1)
|
||||||
|
continue;
|
||||||
|
float x = get_x(i);
|
||||||
|
z_values[j][i] = z_values[j][idx0] * (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2)) +
|
||||||
|
z_values[j][idx1] * (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2)) +
|
||||||
|
z_values[j][idx2] * (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Second interpolate the points in Y axis.
|
||||||
|
static const float y0 = MESH_MIN_Y;
|
||||||
|
static const float y1 = 0.5f * float(MESH_MIN_Y + MESH_MAX_Y);
|
||||||
|
static const float y2 = MESH_MAX_Y;
|
||||||
|
for (int i = 0; i < MESH_NUM_X_POINTS; ++ i) {
|
||||||
|
// 1) Copy the intermediate points to their new destination.
|
||||||
|
z_values[idx2][i] = z_values[2][i];
|
||||||
|
z_values[idx1][i] = z_values[1][i];
|
||||||
|
// 2) Interpolate the remaining values by Largrangian polynomials.
|
||||||
|
for (int j = 1; j + 1 < MESH_NUM_Y_POINTS; ++ j) {
|
||||||
|
if (j == idx1)
|
||||||
|
continue;
|
||||||
|
float y = get_y(j);
|
||||||
|
z_values[j][i] = z_values[idx0][i] * (y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2)) +
|
||||||
|
z_values[idx1][i] * (y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2)) +
|
||||||
|
z_values[idx2][i] * (y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // MESH_BED_LEVELING
|
#endif // MESH_BED_LEVELING
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
|
|
||||||
#ifdef MESH_BED_LEVELING
|
#ifdef MESH_BED_LEVELING
|
||||||
|
|
||||||
#define MESH_X_DIST ((MESH_MAX_X - MESH_MIN_X)/(MESH_NUM_X_POINTS - 1))
|
#define MEAS_NUM_X_DIST (float(MESH_MAX_X - MESH_MIN_X)/float(MESH_MEAS_NUM_X_POINTS - 1))
|
||||||
#define MESH_Y_DIST ((MESH_MAX_Y - MESH_MIN_Y)/(MESH_NUM_Y_POINTS - 1))
|
#define MEAS_NUM_Y_DIST (float(MESH_MAX_Y - MESH_MIN_Y)/float(MESH_MEAS_NUM_Y_POINTS - 1))
|
||||||
|
|
||||||
class mesh_bed_leveling {
|
#define MESH_X_DIST (float(MESH_MAX_X - MESH_MIN_X)/float(MESH_NUM_X_POINTS - 1))
|
||||||
public:
|
#define MESH_Y_DIST (float(MESH_MAX_Y - MESH_MIN_Y)/float(MESH_NUM_Y_POINTS - 1))
|
||||||
|
|
||||||
|
class mesh_bed_leveling {
|
||||||
|
public:
|
||||||
uint8_t active;
|
uint8_t active;
|
||||||
float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS];
|
float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS];
|
||||||
|
|
||||||
|
|
@ -14,44 +17,107 @@
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
float get_x(int i) { return MESH_MIN_X + MESH_X_DIST * i; }
|
#if MESH_NUM_X_POINTS>=5 && MESH_NUM_Y_POINTS>=5 && (MESH_NUM_X_POINTS&1)==1 && (MESH_NUM_Y_POINTS&1)==1
|
||||||
float get_y(int i) { return MESH_MIN_Y + MESH_Y_DIST * i; }
|
void upsample_3x3();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float get_x(int i) { return float(MESH_MIN_X) + float(MESH_X_DIST) * float(i); }
|
||||||
|
float get_y(int i) { return float(MESH_MIN_Y) + float(MESH_Y_DIST) * float(i); }
|
||||||
|
|
||||||
|
float get_meas_x(int i) { return float(MESH_MIN_X) + float(MEAS_NUM_X_DIST) * float(i); }
|
||||||
|
float get_meas_y(int i) { return float(MESH_MIN_Y) + float(MEAS_NUM_Y_DIST) * float(i); }
|
||||||
|
|
||||||
void set_z(int ix, int iy, float z) { z_values[iy][ix] = z; }
|
void set_z(int ix, int iy, float z) { z_values[iy][ix] = z; }
|
||||||
|
|
||||||
int select_x_index(float x) {
|
int select_x_index(float x) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while (x > get_x(i) && i < MESH_NUM_X_POINTS - 1) i++;
|
while (x > get_x(i) && i < MESH_NUM_X_POINTS - 1) i++;
|
||||||
return i - 1;
|
return i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int select_y_index(float y) {
|
int select_y_index(float y) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while (y > get_y(i) && i < MESH_NUM_Y_POINTS - 1) i++;
|
while (y > get_y(i) && i < MESH_NUM_Y_POINTS - 1) i++;
|
||||||
return i - 1;
|
return i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float calc_z0(float a0, float a1, float z1, float a2, float z2) {
|
float get_z(float x, float y) {
|
||||||
float delta_z = (z2 - z1) / (a2 - a1);
|
int i, j;
|
||||||
float delta_a = a0 - a1;
|
float s, t;
|
||||||
return z1 + delta_a * delta_z;
|
|
||||||
|
#if MESH_NUM_X_POINTS==3 && MESH_NUM_Y_POINTS==3
|
||||||
|
#define MESH_MID_X (0.5f*(MESH_MIN_X+MESH_MAX_X))
|
||||||
|
#define MESH_MID_Y (0.5f*(MESH_MIN_Y+MESH_MAX_Y))
|
||||||
|
if (x < MESH_MID_X) {
|
||||||
|
i = 0;
|
||||||
|
s = (x - MESH_MIN_X) / MESH_X_DIST;
|
||||||
|
if (s > 1.f)
|
||||||
|
s = 1.f;
|
||||||
|
} else {
|
||||||
|
i = 1;
|
||||||
|
s = (x - MESH_MID_X) / MESH_X_DIST;
|
||||||
|
if (s < 0)
|
||||||
|
s = 0;
|
||||||
|
}
|
||||||
|
if (y < MESH_MID_Y) {
|
||||||
|
j = 0;
|
||||||
|
t = (y - MESH_MIN_Y) / MESH_Y_DIST;
|
||||||
|
if (t > 1.f)
|
||||||
|
t = 1.f;
|
||||||
|
} else {
|
||||||
|
j = 1;
|
||||||
|
t = (y - MESH_MID_Y) / MESH_Y_DIST;
|
||||||
|
if (t < 0)
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
i = int(floor((x - MESH_MIN_X) / MESH_X_DIST));
|
||||||
|
if (i < 0) {
|
||||||
|
i = 0;
|
||||||
|
s = (x - MESH_MIN_X) / MESH_X_DIST;
|
||||||
|
if (s > 1.f)
|
||||||
|
s = 1.f;
|
||||||
|
}
|
||||||
|
else if (i > MESH_NUM_X_POINTS - 2) {
|
||||||
|
i = MESH_NUM_X_POINTS - 2;
|
||||||
|
s = (x - get_x(i)) / MESH_X_DIST;
|
||||||
|
if (s < 0)
|
||||||
|
s = 0;
|
||||||
|
} else {
|
||||||
|
s = (x - get_x(i)) / MESH_X_DIST;
|
||||||
|
if (s < 0)
|
||||||
|
s = 0;
|
||||||
|
else if (s > 1.f)
|
||||||
|
s = 1.f;
|
||||||
|
}
|
||||||
|
j = int(floor((y - MESH_MIN_Y) / MESH_Y_DIST));
|
||||||
|
if (j < 0) {
|
||||||
|
j = 0;
|
||||||
|
t = (y - MESH_MIN_Y) / MESH_Y_DIST;
|
||||||
|
if (t > 1.f)
|
||||||
|
t = 1.f;
|
||||||
|
} else if (j > MESH_NUM_Y_POINTS - 2) {
|
||||||
|
j = MESH_NUM_Y_POINTS - 2;
|
||||||
|
t = (y - get_y(j)) / MESH_Y_DIST;
|
||||||
|
if (t < 0)
|
||||||
|
t = 0;
|
||||||
|
} else {
|
||||||
|
t = (y - get_y(j)) / MESH_Y_DIST;
|
||||||
|
if (t < 0)
|
||||||
|
t = 0;
|
||||||
|
else if (t > 1.f)
|
||||||
|
t = 1.f;
|
||||||
|
}
|
||||||
|
#endif /* MESH_NUM_X_POINTS==3 && MESH_NUM_Y_POINTS==3 */
|
||||||
|
|
||||||
|
float si = 1.f-s;
|
||||||
|
float z0 = si * z_values[j ][i] + s * z_values[j ][i+1];
|
||||||
|
float z1 = si * z_values[j+1][i] + s * z_values[j+1][i+1];
|
||||||
|
return (1.f-t) * z0 + t * z1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_z(float x0, float y0) {
|
};
|
||||||
int x_index = select_x_index(x0);
|
|
||||||
int y_index = select_y_index(y0);
|
|
||||||
float z1 = calc_z0(x0,
|
|
||||||
get_x(x_index), z_values[y_index][x_index],
|
|
||||||
get_x(x_index + 1), z_values[y_index][x_index + 1]);
|
|
||||||
float z2 = calc_z0(x0,
|
|
||||||
get_x(x_index), z_values[y_index + 1][x_index],
|
|
||||||
get_x(x_index + 1), z_values[y_index + 1][x_index + 1]);
|
|
||||||
float z0 = calc_z0(y0,
|
|
||||||
get_y(y_index), z1,
|
|
||||||
get_y(y_index + 1), z2);
|
|
||||||
return z0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern mesh_bed_leveling mbl;
|
extern mesh_bed_leveling mbl;
|
||||||
|
|
||||||
#endif // MESH_BED_LEVELING
|
#endif // MESH_BED_LEVELING
|
||||||
|
|
|
||||||
|
|
@ -538,20 +538,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
|
||||||
void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder)
|
void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder)
|
||||||
#endif //ENABLE_AUTO_BED_LEVELING
|
#endif //ENABLE_AUTO_BED_LEVELING
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef DEVELOPER
|
|
||||||
SERIAL_PROTOCOLPGM("MESHING TO:");
|
|
||||||
SERIAL_PROTOCOLPGM(" X:");
|
|
||||||
SERIAL_PROTOCOL(x);
|
|
||||||
SERIAL_PROTOCOLPGM(" Y:");
|
|
||||||
SERIAL_PROTOCOL(y);
|
|
||||||
SERIAL_PROTOCOLPGM(" Z:");
|
|
||||||
SERIAL_PROTOCOL(z);
|
|
||||||
SERIAL_PROTOCOLPGM(" E:");
|
|
||||||
SERIAL_PROTOCOL(e);
|
|
||||||
SERIAL_PROTOCOLPGM("\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Calculate the buffer head after we push this byte
|
// Calculate the buffer head after we push this byte
|
||||||
int next_buffer_head = next_block_index(block_buffer_head);
|
int next_buffer_head = next_block_index(block_buffer_head);
|
||||||
|
|
||||||
|
|
@ -576,7 +562,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
|
||||||
target[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
|
target[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
|
||||||
#ifdef MESH_BED_LEVELING
|
#ifdef MESH_BED_LEVELING
|
||||||
if (mbl.active){
|
if (mbl.active){
|
||||||
target[Z_AXIS] += lround((z+mbl.get_z(x, y))*axis_steps_per_unit[Z_AXIS]);
|
target[Z_AXIS] = lround((z+mbl.get_z(x, y))*axis_steps_per_unit[Z_AXIS]);
|
||||||
}else{
|
}else{
|
||||||
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
||||||
}
|
}
|
||||||
|
|
@ -584,7 +570,6 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
|
||||||
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
||||||
#endif // ENABLE_MESH_BED_LEVELING
|
#endif // ENABLE_MESH_BED_LEVELING
|
||||||
target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
|
target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
|
||||||
|
|
||||||
#ifdef PREVENT_DANGEROUS_EXTRUDE
|
#ifdef PREVENT_DANGEROUS_EXTRUDE
|
||||||
if(target[E_AXIS]!=position[E_AXIS])
|
if(target[E_AXIS]!=position[E_AXIS])
|
||||||
{
|
{
|
||||||
|
|
@ -1090,7 +1075,7 @@ void plan_set_position(const float &x, const float &y, const float &z, const flo
|
||||||
position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
|
position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
|
||||||
#ifdef MESH_BED_LEVELING
|
#ifdef MESH_BED_LEVELING
|
||||||
if (mbl.active){
|
if (mbl.active){
|
||||||
position[Z_AXIS] += lround((z+mbl.get_z(x, y))*axis_steps_per_unit[Z_AXIS]);
|
position[Z_AXIS] = lround((z+mbl.get_z(x, y))*axis_steps_per_unit[Z_AXIS]);
|
||||||
}else{
|
}else{
|
||||||
position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1061,13 +1061,13 @@ long st_get_position(uint8_t axis)
|
||||||
return count_pos;
|
return count_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_AUTO_BED_LEVELING
|
|
||||||
float st_get_position_mm(uint8_t axis)
|
float st_get_position_mm(uint8_t axis)
|
||||||
{
|
{
|
||||||
float steper_position_in_steps = st_get_position(axis);
|
float steper_position_in_steps = st_get_position(axis);
|
||||||
return steper_position_in_steps / axis_steps_per_unit[axis];
|
return steper_position_in_steps / axis_steps_per_unit[axis];
|
||||||
}
|
}
|
||||||
#endif // ENABLE_AUTO_BED_LEVELING
|
|
||||||
|
|
||||||
void finishAndDisableSteppers()
|
void finishAndDisableSteppers()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@ void st_set_e_position(const long &e);
|
||||||
// Get current position in steps
|
// Get current position in steps
|
||||||
long st_get_position(uint8_t axis);
|
long st_get_position(uint8_t axis);
|
||||||
|
|
||||||
#ifdef ENABLE_AUTO_BED_LEVELING
|
|
||||||
// Get current position in mm
|
// Get current position in mm
|
||||||
float st_get_position_mm(uint8_t axis);
|
float st_get_position_mm(uint8_t axis);
|
||||||
#endif //ENABLE_AUTO_BED_LEVELING
|
|
||||||
|
|
||||||
// The stepper subsystem goes to sleep when it runs out of things to execute. Call this
|
// The stepper subsystem goes to sleep when it runs out of things to execute. Call this
|
||||||
// to notify the subsystem that it is time to go to work.
|
// to notify the subsystem that it is time to go to work.
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
|
||||||
#if MOTHERBOARD == 102 || MOTHERBOARD == 302
|
#if MOTHERBOARD == 102 || MOTHERBOARD == 302
|
||||||
#define MOTOR_CURRENT_PWM_RANGE 2000
|
#define MOTOR_CURRENT_PWM_RANGE 2000
|
||||||
#define DEFAULT_PWM_MOTOR_CURRENT {270, 450, 450} // {XY,Z,E}
|
#define DEFAULT_PWM_MOTOR_CURRENT {270, 450, 450} // {XY,Z,E}
|
||||||
#define DEFAULT_PWM_MOTOR_CURRENT_LOUD {540, 530, 500} // {XY,Z,E}
|
#define DEFAULT_PWM_MOTOR_CURRENT_LOUD {540, 830, 500} // {XY,Z,E}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------
|
/*------------------------------------
|
||||||
|
|
@ -170,8 +170,13 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
|
||||||
#define MESH_MIN_Y 7
|
#define MESH_MIN_Y 7
|
||||||
#define MESH_MAX_Y 203
|
#define MESH_MAX_Y 203
|
||||||
|
|
||||||
#define MESH_NUM_X_POINTS 3 // Don't use more than 7 points per axis, implementation limited.
|
// Mesh upsample definition
|
||||||
#define MESH_NUM_Y_POINTS 3
|
#define MESH_NUM_X_POINTS 7
|
||||||
|
#define MESH_NUM_Y_POINTS 7
|
||||||
|
// Mesh measure definition
|
||||||
|
#define MESH_MEAS_NUM_X_POINTS 3
|
||||||
|
#define MESH_MEAS_NUM_Y_POINTS 3
|
||||||
|
|
||||||
#define MESH_HOME_Z_CALIB 0.2
|
#define MESH_HOME_Z_CALIB 0.2
|
||||||
#define MESH_HOME_Z_SEARCH 5
|
#define MESH_HOME_Z_SEARCH 5
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue