Squash and rebase

This commit is contained in:
Scott Lahteine 2026-02-05 14:11:15 -06:00 committed by Andrew
parent 8da0d0871c
commit 5f34637233
30 changed files with 1163 additions and 777 deletions

View file

@ -37,12 +37,12 @@
LevelingBilinear bedlevel;
xy_pos_t LevelingBilinear::grid_spacing,
LevelingBilinear::grid_start;
xy_float_t LevelingBilinear::grid_factor;
xy_pos_t LevelingBilinear::grid_spacing,
LevelingBilinear::grid_start,
LevelingBilinear::cached_rel;
xy_int8_t LevelingBilinear::cached_g;
bed_mesh_t LevelingBilinear::z_values;
xy_pos_t LevelingBilinear::cached_rel;
xy_int8_t LevelingBilinear::cached_g;
/**
* Extrapolate a single point from its neighbors
@ -106,9 +106,24 @@ void LevelingBilinear::reset() {
}
}
/**
* Set grid spacing and start position
*/
#if ENABLED(PROUI_MESH_EDIT)
#define MESH_X_DIST (float((MESH_MAX_X) - (MESH_MIN_X)) / (GRID_MAX_CELLS_X))
#define MESH_Y_DIST (float((MESH_MAX_Y) - (MESH_MIN_Y)) / (GRID_MAX_CELLS_Y))
#endif
void LevelingBilinear::set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _grid_start) {
grid_spacing = _grid_spacing;
grid_start = _grid_start;
#if ENABLED(PROUI_MESH_EDIT)
grid_start.x = MESH_MIN_X;
grid_start.y = MESH_MIN_Y;
grid_spacing.x = MESH_X_DIST;
grid_spacing.y = MESH_Y_DIST;
#else
grid_spacing = _grid_spacing;
grid_start = _grid_start;
#endif
grid_factor = grid_spacing.reciprocal();
}
@ -120,16 +135,16 @@ void LevelingBilinear::extrapolate_unprobed_bed_level() {
#ifdef HALF_IN_X
constexpr uint8_t ctrx2 = 0, xend = GRID_MAX_POINTS_X - 1;
#else
constexpr uint8_t ctrx1 = (GRID_MAX_CELLS_X) / 2, // left-of-center
ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center
constexpr uint8_t ctrx1 = (GRID_MAX_CELLS_X) / 2, // left-of-center
ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center
xend = ctrx1;
#endif
#ifdef HALF_IN_Y
constexpr uint8_t ctry2 = 0, yend = GRID_MAX_POINTS_Y - 1;
#else
constexpr uint8_t ctry1 = (GRID_MAX_CELLS_Y) / 2, // top-of-center
ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center
constexpr uint8_t ctry1 = (GRID_MAX_CELLS_Y) / 2, // top-of-center
ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center
yend = ctry1;
#endif

View file

@ -46,8 +46,16 @@
#include "../../lcd/extui/ui_api.h"
#endif
#if ALL(HAS_MESH, DWIN_LCD_PROUI)
#include "../../lcd/dwin/proui/bedlevel_tools.h"
#endif
bool leveling_is_valid() {
return TERN1(HAS_MESH, bedlevel.mesh_is_valid());
#if ALL(HAS_MESH, DWIN_LCD_PROUI)
return bedLevelTools.meshValidate();
#else
return TERN1(HAS_MESH, bedlevel.mesh_is_valid());
#endif
}
/**

View file

@ -34,18 +34,12 @@
mesh_bed_leveling bedlevel;
float mesh_bed_leveling::z_offset,
mesh_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y],
mesh_bed_leveling::index_to_xpos[GRID_MAX_POINTS_X],
float mesh_bed_leveling::z_offset;
float mesh_bed_leveling::index_to_xpos[GRID_MAX_POINTS_X],
mesh_bed_leveling::index_to_ypos[GRID_MAX_POINTS_Y];
float mesh_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
mesh_bed_leveling::mesh_bed_leveling() {
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; ++i)
index_to_xpos[i] = MESH_MIN_X + i * (MESH_X_DIST);
for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; ++i)
index_to_ypos[i] = MESH_MIN_Y + i * (MESH_Y_DIST);
reset();
}
mesh_bed_leveling::mesh_bed_leveling() { initialize(); }
void mesh_bed_leveling::reset() {
z_offset = 0;
@ -55,6 +49,19 @@
#endif
}
void mesh_bed_leveling::initialize() {
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; ++i)
index_to_xpos[i] = MESH_MIN_X + i * (MESH_X_DIST);
for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; ++j)
index_to_ypos[j] = MESH_MIN_Y + j * (MESH_Y_DIST);
reset();
}
void mesh_bed_leveling::report_mesh() {
SERIAL_ECHOLN(F(STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh. Z offset: "), p_float_t(z_offset, 5), F("\nMeasured points:"));
print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 5, z_values[0]);
}
#if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES)
/**
@ -122,9 +129,4 @@
#endif // IS_CARTESIAN && !SEGMENT_LEVELED_MOVES
void mesh_bed_leveling::report_mesh() {
SERIAL_ECHOLN(F(STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh. Z offset: "), p_float_t(z_offset, 5), F("\nMeasured points:"));
print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 5, z_values[0]);
}
#endif // MESH_BED_LEVELING

View file

@ -37,17 +37,19 @@ enum MeshLevelingState : char {
class mesh_bed_leveling {
public:
static float z_offset,
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y],
index_to_xpos[GRID_MAX_POINTS_X],
static float z_offset;
static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
static float index_to_xpos[GRID_MAX_POINTS_X],
index_to_ypos[GRID_MAX_POINTS_Y];
mesh_bed_leveling();
static void report_mesh();
static void reset();
static void initialize();
static void report_mesh();
FORCE_INLINE static bool has_mesh() {
GRID_LOOP(x, y) if (z_values[x][y]) return true;
return false;
@ -70,7 +72,7 @@ public:
}
static float get_mesh_x(const uint8_t i) { return index_to_xpos[i]; }
static float get_mesh_y(const uint8_t i) { return index_to_ypos[i]; }
static float get_mesh_y(const uint8_t j) { return index_to_ypos[j]; }
static uint8_t cell_index_x(const float x) {
int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST);

View file

@ -63,23 +63,25 @@ void unified_bed_leveling::report_state() {
int8_t unified_bed_leveling::storage_slot;
float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
bed_mesh_t unified_bed_leveling::z_values;
#define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST))
#if DISABLED(PROUI_MESH_EDIT)
#define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST))
const float
unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X,
_GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3),
_GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7),
_GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11),
_GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15)
),
unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y,
_GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3),
_GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7),
_GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11),
_GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15)
);
const float
unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X,
_GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3),
_GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7),
_GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11),
_GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15)
),
unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y,
_GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3),
_GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7),
_GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11),
_GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15)
);
#endif
volatile int16_t unified_bed_leveling::encoder_diff;
@ -165,7 +167,7 @@ static void serial_echo_column_labels(const uint8_t sp) {
void unified_bed_leveling::display_map(const uint8_t map_type) {
const bool was = gcode.set_autoreport_paused(true);
constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567]
constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567]
twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each
const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4;
@ -207,6 +209,7 @@ void unified_bed_leveling::display_map(const uint8_t map_type) {
const float f = z_values[i][j];
if (lcd) {
// TODO: Display on Graphical LCD
TERN_(DWIN_LCD_PROUI, dwinMeshViewer());
}
else if (isnan(f))
SERIAL_ECHO(human ? F(" . ") : F("NAN"));

View file

@ -110,14 +110,17 @@ public:
static void smart_fill_wlsf(const float ) __O2; // O2 gives smaller code than Os on A2560
static int8_t storage_slot;
static bed_mesh_t z_values;
#if ENABLED(OPTIMIZED_MESH_STORAGE)
static void set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values);
static void set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values);
#endif
static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X],
_mesh_index_to_ypos[GRID_MAX_POINTS_Y];
#if DISABLED(PROUI_MESH_EDIT)
static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X],
_mesh_index_to_ypos[GRID_MAX_POINTS_Y];
#endif
#if HAS_MARLINUI_MENU
static bool lcd_map_control;
@ -287,12 +290,21 @@ public:
static constexpr float get_z_offset() { return 0.0f; }
static float get_mesh_x(const uint8_t i) {
return i < (GRID_MAX_POINTS_X) ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST);
}
static float get_mesh_y(const uint8_t i) {
return i < (GRID_MAX_POINTS_Y) ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST);
}
#if ENABLED(PROUI_MESH_EDIT)
static float get_mesh_x(const uint8_t i) {
return MESH_MIN_X + i * (MESH_X_DIST);
}
static float get_mesh_y(const uint8_t j) {
return MESH_MIN_Y + j * (MESH_Y_DIST);
}
#else
static float get_mesh_x(const uint8_t i) {
return i < (GRID_MAX_POINTS_X) ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST);
}
static float get_mesh_y(const uint8_t j) {
return j < (GRID_MAX_POINTS_Y) ? pgm_read_float(&_mesh_index_to_ypos[j]) : MESH_MIN_Y + j * (MESH_Y_DIST);
}
#endif
#if UBL_SEGMENTED
static bool line_to_destination_segmented(const feedRate_t scaled_fr_mm_s);

View file

@ -43,6 +43,10 @@
#include "../../../lcd/extui/ui_api.h"
#endif
#if ENABLED(DWIN_LCD_PROUI)
#include "../../../lcd/dwin/proui/meshviewer.h"
#endif
#if ENABLED(UBL_HILBERT_CURVE)
#include "../hilbert_curve.h"
#endif
@ -318,7 +322,7 @@ void unified_bed_leveling::G29() {
// Check for commands that require the printer to be homed
if (may_move) {
planner.synchronize();
#if ALL(DWIN_LCD_PROUI, ZHOME_BEFORE_LEVELING)
#if ENABLED(DWIN_LCD_PROUI)
save_ubl_active_state_and_disable();
gcode.process_subcommands_now(F("G28Z"));
restore_ubl_active_state(false); // ...without telling ExtUI "done"
@ -782,6 +786,7 @@ void unified_bed_leveling::shift_mesh_height(const float zoffs) {
SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
TERN_(DWIN_LCD_PROUI, if (!hmiFlag.cancel_lev) { dwinRedrawScreen(); } else { break; })
#if HAS_MARLINUI_MENU
if (ui.button_pressed()) {
@ -811,11 +816,14 @@ void unified_bed_leveling::shift_mesh_height(const float zoffs) {
ExtUI::onMeshUpdate(best.pos, ExtUI::G29_POINT_FINISH);
ExtUI::onMeshUpdate(best.pos, measured_z);
#endif
TERN_(DWIN_LCD_PROUI, meshViewer.drawMeshPoint(best.pos.x, best.pos.y, measured_z));
}
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
} while (best.pos.x >= 0 && --count);
TERN_(DWIN_LCD_PROUI, if (hmiFlag.cancel_lev) { goto EXIT_PROBE_MESH; })
GRID_LOOP(x, y) if (z_values[x][y] == HUGE_VALF) z_values[x][y] = NAN; // Restore NAN for HUGE_VALF marks
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_FINISH));
@ -825,13 +833,18 @@ void unified_bed_leveling::shift_mesh_height(const float zoffs) {
probe.stow();
TERN_(HAS_MARLINUI_MENU, ui.capture());
probe.move_z_after_probing();
TERN_(Z_AFTER_PROBING, probe.move_z_after_probing());
do_blocking_move_to_xy(
constrain(nearby.x - probe.offset_xy.x, MESH_MIN_X, MESH_MAX_X),
constrain(nearby.y - probe.offset_xy.y, MESH_MIN_Y, MESH_MAX_Y)
);
#if ENABLED(DWIN_LCD_PROUI)
bedlevel.smart_fill_mesh();
#else
do_blocking_move_to_xy(
constrain(nearby.x - probe.offset_xy.x, MESH_MIN_X, MESH_MAX_X),
constrain(nearby.y - probe.offset_xy.y, MESH_MIN_Y, MESH_MAX_Y)
);
#endif
TERN_(DWIN_LCD_PROUI, EXIT_PROBE_MESH:);
restore_ubl_active_state();
}
@ -1191,9 +1204,9 @@ bool unified_bed_leveling::G29_parse_parameters() {
}
param.XY_seen.x = parser.seenval('X');
float sx = param.XY_seen.x ? parser.value_float() : current_position.x;
float sx = param.XY_seen.x ? parser.value_float() : current_position.x - TERN0(HAS_BED_PROBE, probe.offset.x);
param.XY_seen.y = parser.seenval('Y');
float sy = param.XY_seen.y ? parser.value_float() : current_position.y;
float sy = param.XY_seen.y ? parser.value_float() : current_position.y - TERN0(HAS_BED_PROBE, probe.offset.y);
if (param.XY_seen.x != param.XY_seen.y) {
SERIAL_ECHOLNPGM("Both X & Y locations must be specified.\n");
@ -1202,8 +1215,8 @@ bool unified_bed_leveling::G29_parse_parameters() {
// If X or Y are not valid, use center of the bed values
// (for UBL_HILBERT_CURVE default to lower-left corner instead)
if (!COORDINATE_OKAY(sx, X_MIN_BED, X_MAX_BED)) sx = TERN(UBL_HILBERT_CURVE, 0, X_CENTER);
if (!COORDINATE_OKAY(sy, Y_MIN_BED, Y_MAX_BED)) sy = TERN(UBL_HILBERT_CURVE, 0, Y_CENTER);
if (!COORDINATE_OKAY(sx, X_MIN_BED, X_MAX_BED)) sx = TERN(UBL_HILBERT_CURVE, 0, X_CENTER - TERN0(HAS_BED_PROBE, probe.offset.x));
if (!COORDINATE_OKAY(sy, Y_MIN_BED, Y_MAX_BED)) sy = TERN(UBL_HILBERT_CURVE, 0, Y_CENTER - TERN0(HAS_BED_PROBE, probe.offset.y));
if (err_flag) return UBL_ERR;
@ -1523,7 +1536,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
probe.stow();
probe.move_z_after_probing();
TERN_(Z_AFTER_PROBING, probe.move_z_after_probing());
if (abort_flag) {
SERIAL_ECHOLNPGM("?Error probing point. Aborting operation.");
@ -1609,7 +1622,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
}
probe.stow();
probe.move_z_after_probing();
TERN_(Z_AFTER_PROBING, probe.move_z_after_probing());
if (abort_flag || finish_incremental_LSF(&lsf_results)) {
SERIAL_ECHOLNPGM("Could not complete LSF!");
@ -1777,8 +1790,8 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_EOL();
SERIAL_ECHOPGM("Y-Axis Mesh Points at: ");
for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; ++i) {
SERIAL_ECHO(p_float_t(LOGICAL_Y_POSITION(get_mesh_y(i)), 3), F(" "));
for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; ++j) {
SERIAL_ECHO(p_float_t(LOGICAL_Y_POSITION(get_mesh_y(j)), 3), F(" "));
serial_delay(25);
}
SERIAL_EOL();

View file

@ -56,6 +56,10 @@
#include "../../../lcd/sovol_rts/sovol_rts.h"
#endif
#if ENABLED(DWIN_LCD_PROUI)
#include "../../../lcd/dwin/proui/meshviewer.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../../../core/debug_out.h"
@ -257,6 +261,10 @@ G29_TYPE GcodeSuite::G29() {
// Send 'N' to force homing before G29 (internal only)
if (parser.seen_test('N'))
process_subcommands_now(TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR)));
#if ENABLED(DWIN_LCD_PROUI)
else
process_subcommands_now(F("G28Z"));
#endif
// Don't allow auto-leveling without homing first
if (homing_needed_error()) G29_RETURN(false, false);
@ -681,6 +689,8 @@ G29_TYPE GcodeSuite::G29() {
int8_t inStart, inStop, inInc;
TERN_(DWIN_LCD_PROUI, if (hmiFlag.cancel_lev) break);
if (zig) { // Zig away from origin
inStart = 0; // Left or front
inStop = PR_INNER_SIZE; // Right or back
@ -793,6 +803,7 @@ G29_TYPE GcodeSuite::G29() {
const float z = abl.measured_z + abl.Z_offset;
abl.z_values[abl.meshCount.x][abl.meshCount.y] = z;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z));
TERN_(DWIN_LCD_PROUI, meshViewer.drawMeshPoint(abl.meshCount.x, abl.meshCount.y, z));
#if ENABLED(SOVOL_SV06_RTS)
if (pt_index <= GRID_MAX_POINTS) rts.sendData(pt_index, AUTO_BED_LEVEL_ICON_VP);
@ -804,6 +815,7 @@ G29_TYPE GcodeSuite::G29() {
abl.reenable = false; // Don't re-enable after modifying the mesh
marlin.idle_no_sleep();
TERN_(DWIN_LCD_PROUI, if (hmiFlag.cancel_lev) break);
} // inner
} // outer
@ -1009,7 +1021,7 @@ G29_TYPE GcodeSuite::G29() {
// Restore state after probing
if (!faux) restore_feedrate_and_scaling();
TERN_(HAS_BED_PROBE, probe.move_z_after_probing());
TERN_(Z_AFTER_PROBING, probe.move_z_after_probing());
#ifdef EVENT_GCODE_AFTER_G29
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("After G29 G-code: ", EVENT_GCODE_AFTER_G29);

View file

@ -574,7 +574,7 @@
#endif
// Extender cable doesn't support SD_DETECT_PIN
#if ENABLED(NO_SD_DETECT)
#if ENABLED(NO_SD_DETECT) && DISABLED(DWIN_LCD_PROUI)
#undef SD_DETECT_PIN
#endif
@ -3445,7 +3445,7 @@
#ifndef MESH_MAX_Y
#define MESH_MAX_Y _MESH_MAX_Y
#endif
#else
#elif DISABLED(DWIN_LCD_PROUI)
#undef MESH_MIN_X
#undef MESH_MIN_Y
#undef MESH_MAX_X

View file

@ -51,3 +51,8 @@
#ifndef __MARLIN_DEPS__
#include HAL_PATH(.., inc/Conditionals_adv.h)
#endif
// ProUI extra features
#if ENABLED(DWIN_LCD_PROUI)
#include "../lcd/dwin/proui/dwin_defines.h"
#endif

View file

@ -1593,13 +1593,15 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
static_assert(Z_AFTER_PROBING >= 0, "Probes require Z_AFTER_PROBING >= 0.");
#endif
#if MULTIPLE_PROBING > 0 || EXTRA_PROBING > 0
#if MULTIPLE_PROBING == 0
#error "EXTRA_PROBING requires MULTIPLE_PROBING."
#elif MULTIPLE_PROBING < 2
#error "MULTIPLE_PROBING must be 2 or more."
#elif MULTIPLE_PROBING <= EXTRA_PROBING
#error "EXTRA_PROBING must be less than MULTIPLE_PROBING."
#if DISABLED(DWIN_LCD_PROUI)
#if MULTIPLE_PROBING > 0 || EXTRA_PROBING > 0
#if MULTIPLE_PROBING == 0
#error "EXTRA_PROBING requires MULTIPLE_PROBING."
#elif MULTIPLE_PROBING < 2
#error "MULTIPLE_PROBING must be 2 or more."
#elif MULTIPLE_PROBING <= EXTRA_PROBING
#error "EXTRA_PROBING must be less than MULTIPLE_PROBING."
#endif
#endif
#endif

View file

@ -60,13 +60,16 @@
#include "dwin_popup.h"
#include "bedlevel_tools.h"
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../../../core/debug_out.h"
BedLevelTools bedLevelTools;
#if ENABLED(USE_GRID_MESHVIEWER)
bool BedLevelTools::grid_meshview = false;
bool BedLevelTools::viewer_print_value = false;
#endif
bool BedLevelTools::goto_mesh_value = false;
bool BedLevelTools::goto_mesh_value = false;
uint8_t BedLevelTools::mesh_x = 0;
uint8_t BedLevelTools::mesh_y = 0;
uint8_t BedLevelTools::tilt_grid = 1;
@ -97,17 +100,21 @@ bool drawing_mesh = false;
GRID_LOOP(i, j) {
float mx = bedlevel.get_mesh_x(i), my = bedlevel.get_mesh_y(j), mz = bedlevel.z_values[i][j];
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLN(F("before rotation = ["), p_float_t(mx, 7), C(','), p_float_t(my, 7), C(','), p_float_t(mz, 7), F("] ---> "));
DEBUG_DELAY(20);
}
#if DEBUG_OUT
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLN(F("before rotation = ["), p_float_t(mx, 7), C(','), p_float_t(my, 7), C(','), p_float_t(mz, 7), F("] ---> "));
DEBUG_DELAY(20);
}
#endif
rotation.apply_rotation_xyz(mx, my, mz);
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLN(F("after rotation = ["), p_float_t(mx, 7), C(','), p_float_t(my, 7), C(','), p_float_t(mz, 7), F("] ---> "));
DEBUG_DELAY(20);
}
#if DEBUG_OUT
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLN(F("after rotation = ["), p_float_t(mx, 7), C(','), p_float_t(my, 7), C(','), p_float_t(mz, 7), F("] ---> "));
DEBUG_DELAY(20);
}
#endif
bedlevel.z_values[i][j] = mz - lsf_results.D;
}
@ -127,7 +134,7 @@ void BedLevelTools::manualMove(const uint8_t mesh_x, const uint8_t mesh_y, bool
if (!zmove) {
dwinShowPopup(ICON_BLTouch, F("Moving to Point"), F("Please wait until done."));
hmiSaveProcessID(ID_NothingToDo);
gcode.process_subcommands_now(TS(F("G0 F300 Z"), p_float_t(Z_CLEARANCE_BETWEEN_PROBES, 3)));
gcode.process_subcommands_now(F("G0F600Z" STRINGIFY(Z_CLEARANCE_BETWEEN_PROBES)));
gcode.process_subcommands_now(TS(F("G42 F4000 I"), mesh_x, F(" J"), mesh_y));
}
planner.synchronize();
@ -152,7 +159,7 @@ void BedLevelTools::moveToZ() {
}
void BedLevelTools::probeXY() {
gcode.process_subcommands_now(
MString<MAX_CMD_SIZE>(
TS(
F("G28O\nG0Z"), uint16_t(Z_CLEARANCE_DEPLOY_PROBE),
F("\nG30X"), p_float_t(bedlevel.get_mesh_x(mesh_x), 2),
F("Y"), p_float_t(bedlevel.get_mesh_y(mesh_y), 2)
@ -161,6 +168,7 @@ void BedLevelTools::probeXY() {
}
void BedLevelTools::meshReset() {
set_bed_leveling_enabled(false);
ZERO(bedlevel.z_values);
TERN_(AUTO_BED_LEVELING_BILINEAR, bedlevel.refresh_bed_level());
}
@ -168,18 +176,25 @@ void BedLevelTools::meshReset() {
// Accessors
float BedLevelTools::getMaxValue() {
float max = -(__FLT_MAX__);
GRID_LOOP(x, y) { const float z = bedlevel.z_values[x][y]; if (!isnan(z)) NOLESS(max, z); }
GRID_LOOP(x, y) {
const float z = bedlevel.z_values[x][y];
if (!isnan(z)) NOLESS(max, z);
}
return max;
}
float BedLevelTools::getMinValue() {
float min = __FLT_MAX__;
GRID_LOOP(x, y) { const float z = bedlevel.z_values[x][y]; if (!isnan(z)) NOMORE(min, z); }
GRID_LOOP(x, y) {
const float z = bedlevel.z_values[x][y];
if (!isnan(z)) NOMORE(min, z);
}
return min;
}
// Return 'true' if mesh is good and within LCD limits
bool BedLevelTools::meshValidate() {
TERN_(PROUI_MESH_EDIT, if ((MESH_MAX_X <= MESH_MIN_X) || (MESH_MAX_Y <= MESH_MIN_Y)) return false);
GRID_LOOP(x, y) {
const float z = bedlevel.z_values[x][y];
if (isnan(z) || !WITHIN(z, Z_OFFSET_MIN, Z_OFFSET_MAX)) return false;
@ -187,9 +202,7 @@ bool BedLevelTools::meshValidate() {
return true;
}
#if ENABLED(USE_GRID_MESHVIEWER)
constexpr uint8_t meshfont = TERN(TJC_DISPLAY, font8x16, font6x12);
#if USE_GRID_MESHVIEWER
void BedLevelTools::drawBedMesh(int16_t selected/*=-1*/, uint8_t gridline_width/*=1*/, uint16_t padding_x/*=8*/, uint16_t padding_y_top/*=(40 + 53 - 7)*/) {
drawing_mesh = true;
@ -216,8 +229,8 @@ bool BedLevelTools::meshValidate() {
const auto end_y_px = start_y_px + cell_height_px - 1 - gridline_width;
const float z = bedlevel.z_values[x][y];
const uint16_t color = isnan(z) ? COLOR_GREY : ( // Gray if undefined
(z < 0 ? uint16_t(LROUND(0x1F * -z / rmax)) << 11 // Red for negative mesh point
: uint16_t(LROUND(0x3F * z / rmax)) << 5) // Green for positive mesh point
(z > 0 ? uint16_t(LROUND(0x1F * z / rmax)) << 11 // Red for positive mesh point
: uint16_t(LROUND(0x3F * -z / rmax)) << 5) // Green for negative mesh point
| _MIN(0x1F, (uint8_t(abs(z) * 0.4))) // + Blue stepping for every mm
);
@ -229,22 +242,22 @@ bool BedLevelTools::meshValidate() {
// Draw value text on
if (!viewer_print_value) continue;
const uint8_t fs = DWINUI::fontWidth(meshfont);
const uint8_t fs = DWINUI::fontWidth(title.meshfont);
const int8_t offset_y = cell_height_px / 2 - fs;
if (isnan(z)) { // undefined
dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X"));
dwinDrawString(false, title.meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X"));
}
else { // has value
MString<12> msg;
constexpr bool is_wide = (GRID_MAX_POINTS_X) >= TERN(TJC_DISPLAY, 8, 10);
const bool is_wide = (GRID_MAX_POINTS_X) >= TERN(TJC_DISPLAY, 8, 10);
if (is_wide)
msg.setf(F("%02i"), uint16_t(z * 100) % 100);
else
msg.set(p_float_t(abs(z), 2));
const int8_t offset_x = cell_width_px / 2 - (fs / 2) * msg.length() - 2;
if (is_wide)
dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y, F("."));
dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y, msg);
dwinDrawString(false, title.meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y, F("."));
dwinDrawString(false, title.meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y, msg);
}
safe_delay(10);

View file

@ -53,7 +53,6 @@ public:
static bool goto_mesh_value;
static uint8_t mesh_x, mesh_y;
static uint8_t tilt_grid;
#if ENABLED(AUTO_BED_LEVELING_UBL)
static bool createPlaneFromMesh();
#endif

File diff suppressed because it is too large Load diff

View file

@ -105,72 +105,6 @@ enum processID : uint8_t {
#define DWIN_CHINESE 123
#define DWIN_ENGLISH 0
typedef struct {
// Color settings
uint16_t colorBackground;
uint16_t colorCursor;
uint16_t colorTitleBg;
uint16_t colorTitleTxt;
uint16_t colorText;
uint16_t colorSelected;
uint16_t colorSplitLine;
uint16_t colorHighlight;
uint16_t colorStatusBg;
uint16_t colorStatusTxt;
uint16_t colorPopupBg;
uint16_t colorPopupTxt;
uint16_t colorAlertBg;
uint16_t colorAlertTxt;
uint16_t colorPercentTxt;
uint16_t colorBarfill;
uint16_t colorIndicator;
uint16_t colorCoordinate;
// Temperatures
#if HAS_PID_HEATING
int16_t pidCycles = DEF_PIDCYCLES;
#if ENABLED(PIDTEMP)
celsius_t hotendPIDT = DEF_HOTENDPIDT;
#endif
#if ENABLED(PIDTEMPBED)
celsius_t bedPIDT = DEF_BEDPIDT;
#endif
#if ENABLED(PIDTEMPCHAMBER)
celsius_t chamberPIDT = DEF_CHAMBERPIDT;
#endif
#endif
#if ENABLED(PREVENT_COLD_EXTRUSION)
celsius_t extMinT = EXTRUDE_MINTEMP;
#endif
#if ENABLED(PREHEAT_BEFORE_LEVELING)
celsius_t bedLevT = LEVELING_BED_TEMP;
#endif
#if ENABLED(BAUD_RATE_GCODE)
bool baud115K = false;
#endif
#if ALL(LCD_BED_TRAMMING, HAS_BED_PROBE)
bool fullManualTramming = false;
#endif
#if ENABLED(PROUI_MEDIASORT)
bool mediaSort = true;
#endif
bool mediaAutoMount = ENABLED(HAS_SD_EXTENDER);
#if ALL(INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING)
uint8_t zAfterHoming = DEF_Z_AFTER_HOMING;
#define Z_POST_CLEARANCE hmiData.zAfterHoming
#endif
#if ALL(LED_CONTROL_MENU, HAS_COLOR_LEDS)
LED1Color_t ledColor = defColorLeds;
#endif
#if HAS_GCODE_PREVIEW
bool enablePreview = true;
#endif
} hmi_data_t;
extern hmi_data_t hmiData;
#define EXTUI_EEPROM_DATA_SIZE sizeof(hmi_data_t)
typedef struct {
int8_t r, g, b;
void set(int8_t _r, int8_t _g, int8_t _b) { r = _r; g = _g; b = _b; }
@ -202,6 +136,7 @@ typedef struct {
bool pause_flag:1; // printing is paused
bool select_flag:1; // Popup button selected
bool home_flag:1; // homing in course
bool cancel_lev:1; // cancel abl
} hmi_flag_t;
extern hmi_flag_t hmiFlag;
@ -225,11 +160,16 @@ uint32_t getHash(char * str);
void saveMesh();
#endif
#endif
#if HAS_BED_PROBE
void autoLevel();
#else
void homeZAndDisable();
#endif
void rebootPrinter();
void disableMotors();
void autoLevel();
void autoHome();
#if HAS_PREHEAT
void drawPreheatHotendMenu();
#define _DOPREHEAT(N) void DoPreheat##N();
REPEAT_1(PREHEAT_COUNT, _DOPREHEAT)
#endif
@ -259,9 +199,6 @@ void doCoolDown();
void ublMeshSave();
void ublMeshLoad();
#endif
#if DISABLED(HAS_BED_PROBE)
void homeZAndDisable();
#endif
// Other
void gotoPrintProcess();
@ -290,8 +227,10 @@ void dwinHomingDone();
#if HAS_MESH
void dwinMeshUpdate(const int8_t cpos, const int8_t tpos, const float zval);
#endif
void dwinLevelingStart();
void dwinLevelingDone();
#if HAS_LEVELING
void dwinLevelingStart();
void dwinLevelingDone();
#endif
void dwinPrintStarted();
void dwinPrintPause();
void dwinPrintResume();
@ -336,6 +275,7 @@ void drawPrintFileMenu();
void drawControlMenu();
void drawAdvancedSettingsMenu();
void drawPrepareMenu();
void drawLevelMenu();
void drawMoveMenu();
void drawTrammingMenu();
#if HAS_HOME_OFFSET
@ -381,6 +321,7 @@ void drawMaxAccelMenu();
#if HAS_MESH
void drawMeshSetMenu();
#if ENABLED(PROUI_MESH_EDIT)
void drawMeshInsetMenu();
void drawEditMeshMenu();
#endif
#endif

View file

@ -30,22 +30,12 @@
*/
#include "../../../inc/MarlinConfigPre.h"
#include <stddef.h>
#include "../../../core/types.h"
//#define TJC_DISPLAY // Enable for TJC display
//#define DACAI_DISPLAY // Enable for DACAI display
//#define TITLE_CENTERED // Center Menu Title Text
#if HAS_MESH
#define USE_GRID_MESHVIEWER 1
#endif
#if HAS_MESH
#define PROUI_MESH_EDIT // Add a menu to edit mesh points
#if ENABLED(PROUI_MESH_EDIT)
#define Z_OFFSET_MIN -3.0 // (mm)
#define Z_OFFSET_MAX 3.0 // (mm)
#endif
#endif
//#define TJC_DISPLAY // Enable for TJC display
//#define DACAI_DISPLAY // Enable for DACAI display
//#define TITLE_CENTERED // Center Menu Title Text
#if defined(__STM32F1__) || defined(STM32F1)
#define DASH_REDRAW 1
@ -115,6 +105,14 @@
/**
* ProUI internal feature flags
*/
#if HAS_MESH
#define PROUI_MESH_EDIT // Add a menu to edit mesh inset + points
#define Z_OFFSET_MIN -3.0 // (mm)
#define Z_OFFSET_MAX 3.0 // (mm)
#endif
#if HAS_BED_PROBE
#define PROUI_ITEM_ZFR // Add a menu item to change Z_PROBE_FEEDRATE_SLOW - probe speed
#endif
#if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE)
#define PROUI_MEDIASORT // Enable option to sort G-code files
#endif
@ -127,7 +125,7 @@
#if HAS_LIN_ADVANCE_K
#define PROUI_ITEM_ADVK 1 // Tune > Linear Advance
#endif
#if ANY(HAS_PID_HEATING, MPC_AUTOTUNE) && DISABLED(DISABLE_TUNING_GRAPH)
#if DISABLED(DISABLE_TUNING_GRAPH)
#define PROUI_TUNING_GRAPH 1
#endif
#if PROUI_TUNING_GRAPH
@ -138,3 +136,143 @@
#define HAS_ESDIAG 1 // View End-stop/Runout switch continuity
#define HAS_LOCKSCREEN 1 // Simple lockscreen
#define HAS_SD_EXTENDER 1 // Enable to support SD card extender cables
#define USE_GRID_MESHVIEWER 1 // Enable for two mesh graph types
#if ENABLED(PROUI_MESH_EDIT)
#ifndef MESH_INSET
#define MESH_INSET 10
#endif
#ifndef MESH_MIN_X
#define MESH_MIN_X MESH_INSET
#endif
#ifndef MESH_MIN_Y
#define MESH_MIN_Y MESH_INSET
#endif
#ifndef MESH_MAX_X
#define MESH_MAX_X X_BED_SIZE - (MESH_INSET)
#endif
#ifndef MESH_MAX_Y
#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
#endif
constexpr uint16_t DEF_MESH_MIN_X = MESH_MIN_X;
constexpr uint16_t DEF_MESH_MAX_X = MESH_MAX_X;
constexpr uint16_t DEF_MESH_MIN_Y = MESH_MIN_Y;
constexpr uint16_t DEF_MESH_MAX_Y = MESH_MAX_Y;
#define MIN_MESH_INSET 0
#define MAX_MESH_INSET X_BED_SIZE
#endif
#ifndef MULTIPLE_PROBING
#define MULTIPLE_PROBING 0
#endif
#if HAS_BED_PROBE
constexpr uint16_t DEF_Z_PROBE_FEEDRATE_SLOW = Z_PROBE_FEEDRATE_SLOW;
#endif
#if HAS_EXTRUDERS
constexpr bool DEF_INVERT_E0_DIR = INVERT_E0_DIR;
#endif
typedef struct {
// Color settings
uint16_t colorBackground;
uint16_t colorCursor;
uint16_t colorTitleBg;
uint16_t colorTitleTxt;
uint16_t colorText;
uint16_t colorSelected;
uint16_t colorSplitLine;
uint16_t colorHighlight;
uint16_t colorStatusBg;
uint16_t colorStatusTxt;
uint16_t colorPopupBg;
uint16_t colorPopupTxt;
uint16_t colorAlertBg;
uint16_t colorAlertTxt;
uint16_t colorPercentTxt;
uint16_t colorBarfill;
uint16_t colorIndicator;
uint16_t colorCoordinate;
// Temperatures
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
int16_t pidCycles = DEF_PIDCYCLES;
#endif
#if ENABLED(PIDTEMP)
celsius_t hotendPIDT = DEF_HOTENDPIDT;
#endif
#if ENABLED(PIDTEMPBED)
celsius_t bedPIDT = DEF_BEDPIDT;
#endif
#if ENABLED(PIDTEMPCHAMBER)
celsius_t chamberPIDT = DEF_CHAMBERPIDT;
#endif
#if ENABLED(PREVENT_COLD_EXTRUSION)
celsius_t extMinT = EXTRUDE_MINTEMP;
#endif
#if ENABLED(PREHEAT_BEFORE_LEVELING)
celsius_t bedLevT = LEVELING_BED_TEMP;
#endif
// Various Options
#if ENABLED(BAUD_RATE_GCODE)
bool baud115K = false;
#endif
#if ALL(LCD_BED_TRAMMING, HAS_BED_PROBE)
bool fullManualTramming = false;
#endif
#if ENABLED(PROUI_MEDIASORT)
bool mediaSort = true;
#endif
bool mediaAutoMount = ENABLED(HAS_SD_EXTENDER);
#if ALL(INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING)
uint8_t zAfterHoming = DEF_Z_AFTER_HOMING;
#define Z_POST_CLEARANCE hmiData.zAfterHoming
#endif
#if ALL(LED_CONTROL_MENU, HAS_COLOR_LEDS)
LED1Color_t ledColor = defColorLeds;
#endif
#if HAS_GCODE_PREVIEW
bool enablePreview = true;
#endif
#if ENABLED(PROUI_MESH_EDIT)
float mesh_min_x = DEF_MESH_MIN_X;
float mesh_max_x = DEF_MESH_MAX_X;
float mesh_min_y = DEF_MESH_MIN_Y;
float mesh_max_y = DEF_MESH_MAX_Y;
#endif
#if HAS_BED_PROBE
IF_DISABLED(BD_SENSOR, uint8_t multiple_probing = MULTIPLE_PROBING);
uint16_t zprobeFeed = DEF_Z_PROBE_FEEDRATE_SLOW;
#endif
#if HAS_EXTRUDERS
bool Invert_E0 = DEF_INVERT_E0_DIR;
#endif
} hmi_data_t;
extern hmi_data_t hmiData;
#define EXTUI_EEPROM_DATA_SIZE sizeof(hmi_data_t)
// ProUI extra feature redefines
#if ENABLED(PROUI_MESH_EDIT)
#undef MESH_MIN_X
#undef MESH_MAX_X
#undef MESH_MIN_Y
#undef MESH_MAX_Y
#define MESH_MIN_X hmiData.mesh_min_x
#define MESH_MAX_X hmiData.mesh_max_x
#define MESH_MIN_Y hmiData.mesh_min_y
#define MESH_MAX_Y hmiData.mesh_max_y
#endif
#if HAS_BED_PROBE
#undef Z_PROBE_FEEDRATE_SLOW
#define Z_PROBE_FEEDRATE_SLOW hmiData.zprobeFeed
#endif
#if HAS_EXTRUDERS
#undef INVERT_E0_DIR
#define INVERT_E0_DIR hmiData.Invert_E0
#endif

View file

@ -32,7 +32,6 @@
#if ENABLED(DWIN_LCD_PROUI)
#include "dwin.h"
#include "dwinui.h"
#include "dwin_popup.h"

View file

@ -29,7 +29,6 @@
* Date: 2022/02/28
*/
#include "dwinui.h"
#include "dwin.h"
typedef void (*popupDrawFunc_t)();

View file

@ -57,7 +57,6 @@
#define ICON_HSMode ICON_MaxAccZ
#define ICON_InputShaping ICON_MaxAccelerated
#define ICON_JDmm ICON_MaxJerk
#define ICON_Level ICON_Mesh
#define ICON_Lock ICON_Checkbox
#define ICON_ManualMesh ICON_Mesh
#define ICON_MaxPosX ICON_MoveX
@ -209,6 +208,7 @@ typedef struct { uint16_t x, y, w, h; } frame_rect_t;
class Title {
public:
const uint8_t meshfont = TERN(TJC_DISPLAY, font8x16, font6x12);
char caption[32] = "";
uint8_t frameid = 0;
rect_t frame = {0};

View file

@ -29,57 +29,42 @@
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_LCD_PROUI)
#include "dwin_defines.h"
#if HAS_GCODE_PREVIEW
#if ALL(DWIN_LCD_PROUI, HAS_GCODE_PREVIEW)
#include "gcode_preview.h"
#include "../../marlinui.h"
#include "../../../sd/cardreader.h"
#include "../../../MarlinCore.h" // for wait_for_user
#include "dwin.h"
#include "dwin_popup.h"
#include "base64.h"
#define THUMBWIDTH 230
#define THUMBHEIGHT 180
Preview preview;
typedef struct {
char name[13] = ""; // 8.3 + null
uint32_t thumbstart = 0;
int thumbsize = 0;
int thumbheight = 0, thumbwidth = 0;
float time = 0;
float filament = 0;
float layer = 0;
float width = 0, height = 0, length = 0;
void setname(const char * const fn) {
const uint8_t len = _MIN(sizeof(name) - 1, strlen(fn));
memcpy(name, fn, len);
name[len] = '\0';
}
void clear() {
name[0] = '\0';
thumbstart = 0;
thumbsize = 0;
thumbheight = thumbwidth = 0;
time = 0;
filament = 0;
layer = 0;
height = width = length = 0;
}
} fileprop_t;
#if ENABLED(TJC_DISPLAY)
#define THUMBWIDTH 180
#define THUMBHEIGHT 180
#else
#define THUMBWIDTH 200
#define THUMBHEIGHT 200
#endif
fileprop_t fileprop;
void fileprop_t::setname(const char * const fn) {
const uint8_t len = _MIN(sizeof(name) - 1, strlen(fn));
memcpy(name, fn, len);
name[len] = '\0';
}
void fileprop_t::clear() {
name[0] = '\0';
thumbstart = 0;
thumbsize = 0;
thumbheight = thumbwidth = 0;
time = 0;
filament = 0;
layer = 0;
height = width = length = 0;
}
void getValue(const char * const buf, PGM_P const key, float &value) {
if (value != 0.0f) return;
@ -189,11 +174,7 @@ bool Preview::hasPreview() {
}
void Preview::drawFromSD() {
if (!hasPreview()) {
hmiFlag.select_flag = 1;
marlin.user_resume();
return;
}
hasPreview();
TString buf;
dwinDrawRectangle(1, hmiData.colorBackground, 0, 0, DWIN_WIDTH, STATUS_Y - 1);
@ -213,10 +194,17 @@ void Preview::drawFromSD() {
buf.set(F("Volume: "), p_float_t(fileprop.width, 1), 'x', p_float_t(fileprop.length, 1), 'x', p_float_t(fileprop.height, 1), F(" mm"));
DWINUI::drawString(20, 70, &buf);
}
if (!fileprop.thumbsize) {
const uint8_t xpos = ((DWIN_WIDTH) / 2) - 55, // 55 = iconW/2
ypos = ((DWIN_HEIGHT) / 2) - 125;
DWINUI::drawIcon(ICON_Info_0, xpos, ypos);
buf.set(PSTR("No " STRINGIFY(THUMBWIDTH) "x" STRINGIFY(THUMBHEIGHT) " Thumbnail"));
DWINUI::drawCenteredString(false, (DWINUI::fontID * 3), DWINUI::textColor, DWINUI::backColor, 0, DWIN_WIDTH, (DWIN_HEIGHT / 2), &buf);
}
DWINUI::drawButton(BTN_Print, 26, 290);
DWINUI::drawButton(BTN_Cancel, 146, 290);
if (fileprop.thumbsize) show();
drawSelectHighlight(true, 290);
drawSelectHighlight(false, 290);
dwinUpdateLCD();
}
@ -234,5 +222,4 @@ void Preview::show() {
dwinIconShow(xpos, ypos, 0x00);
}
#endif // HAS_GCODE_PREVIEW
#endif // DWIN_LCD_PROUI
#endif // DWIN_LCD_PROUI && HAS_GCODE_PREVIEW

View file

@ -39,3 +39,19 @@ private:
};
extern Preview preview;
typedef struct {
char name[13] = ""; // 8.3 + null
uint32_t thumbstart;
int thumbsize, thumbheight, thumbwidth;
float time,
filament,
layer,
width, height, length;
void setname(const char * const fn);
void clear();
} fileprop_t;
extern fileprop_t fileprop;

View file

@ -157,7 +157,7 @@ void onDrawChkbMenu(MenuItem* menuitem, int8_t line) {
onDrawChkbMenu(menuitem, line, val);
}
void DrawItemEdit(const bool selected) {
void drawItemEdit(const bool selected) {
const uint16_t bcolor = selected ? hmiData.colorSelected : hmiData.colorBackground;
const uint8_t iNum = 4 - ((menuData.dp > 0) ? (menuData.dp - 1) : 0);
switch (checkkey) {
@ -202,7 +202,7 @@ void setOnClick(uint8_t process, const int32_t lo, const int32_t hi, uint8_t dp,
// apply: update function when the encoder is pressed
void setValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const int32_t val, void (*apply)()/*=nullptr*/, void (*liveUpdate)()/*=nullptr*/) {
setOnClick(process, lo, hi, 0, val, apply, liveUpdate);
DrawItemEdit(true);
drawItemEdit(true);
}
// Generic onclick event for float values
@ -215,7 +215,7 @@ void setValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const
void setValueOnClick(uint8_t process, const float lo, const float hi, uint8_t dp, const float val, void (*apply)()/*=nullptr*/, void (*liveUpdate)()/*=nullptr*/) {
const int32_t value = LROUND(val * POW(10, dp));
setOnClick(process, lo * POW(10, dp), hi * POW(10, dp), dp, value, apply, liveUpdate);
DrawItemEdit(true);
drawItemEdit(true);
}
// Generic onclick event for integer values
@ -285,14 +285,14 @@ int8_t hmiGet(bool draw) {
if (encoder_diffState != ENCODER_DIFF_NO) {
if (applyEncoder(encoder_diffState, menuData.value)) {
encoderRate.enabled = false;
if (draw) DrawItemEdit(false);
if (draw) drawItemEdit(false);
checkkey = ID_Menu;
return 2;
}
LIMIT(menuData.value, lo, hi);
}
const bool change = cval != menuData.value;
if (change) DrawItemEdit(true);
if (change) drawItemEdit(true);
return int8_t(change);
}
@ -547,13 +547,13 @@ void updateMenu(Menu* &menu) {
menu->draw();
}
void ReDrawMenu(bool force/*=false*/) {
void redrawMenu(bool force/*=false*/) {
if (currentMenu && (force || checkkey == ID_Menu)) currentMenu->draw();
if (force) DrawItemEdit(true);
if (force) drawItemEdit(true);
}
void ReDrawItem() {
static_cast<MenuItem*>(currentMenu->selectedItem())->redraw(false);
void redrawItem() {
static_cast<MenuItemPtr*>(currentMenu->selectedItem())->value;
}
#endif // DWIN_LCD_PROUI

View file

@ -187,10 +187,10 @@ void invalidateMenu();
void updateMenu(Menu* &menu);
// Redraw the current Menu if it is valid
void ReDrawMenu(bool force=false);
void redrawMenu(bool force=false);
// Redraw selected menu item
void ReDrawItem();
void redrawItem();
// Clear menuItems array and free menuItems elements
void menuItemsClear();

View file

@ -34,7 +34,6 @@
#include "../../../core/types.h"
#include "../../marlinui.h"
#include "dwin.h"
#include "dwin_popup.h"
#include "../../../feature/bedlevel/bedlevel.h"
#include "meshviewer.h"
@ -55,8 +54,6 @@ uint8_t rmax; // Maximum radius
#define px(xp) (margin + (xp) * (width) / (sizex - 1))
#define py(yp) (30 + DWIN_WIDTH - margin - (yp) * (width) / (sizey - 1))
constexpr uint8_t meshfont = TERN(TJC_DISPLAY, font8x16, font6x12);
MeshViewer meshViewer;
float MeshViewer::max, MeshViewer::min;
@ -74,7 +71,7 @@ void MeshViewer::drawMeshGrid(const uint8_t csizex, const uint8_t csizey) {
}
void MeshViewer::drawMeshPoint(const uint8_t x, const uint8_t y, const float z) {
const uint8_t fs = DWINUI::fontWidth(meshfont);
const uint8_t fs = DWINUI::fontWidth(title.meshfont);
const int16_t v = isnan(z) ? int16_t(0) : int16_t(LROUND(z * 100));
NOLESS(max, z); NOMORE(min, z);
@ -84,21 +81,21 @@ void MeshViewer::drawMeshPoint(const uint8_t x, const uint8_t y, const float z)
const uint16_t fy = py(y) - fs;
if (sizex < TERN(TJC_DISPLAY, 8, 9)) {
if (v == 0) DWINUI::drawFloat(meshfont, 1, 2, px(x) - 2 * fs, fy, 0);
else DWINUI::drawSignedFloat(meshfont, 1, 2, px(x) - 3 * fs, fy, z);
if (v == 0) DWINUI::drawFloat(title.meshfont, 1, 2, px(x) - 2 * fs, fy, 0);
else DWINUI::drawSignedFloat(title.meshfont, 1, 2, px(x) - 3 * fs, fy, z);
}
else {
char msg[9]; msg[0] = '\0';
switch (v) {
case -999 ... -100:
case 100 ... 999: DWINUI::drawSignedFloat(meshfont, 1, 1, px(x) - 3 * fs, fy, z); break;
case 100 ... 999: DWINUI::drawSignedFloat(title.meshfont, 1, 1, px(x) - 3 * fs, fy, z); break;
case -99 ... -1: sprintf_P(msg, PSTR("-.%2i"), -v); break;
case 1 ... 99: sprintf_P(msg, PSTR( ".%2i"), v); break;
default:
dwinDrawString(false, meshfont, DWINUI::textColor, DWINUI::backColor, px(x) - 4, fy, "0");
dwinDrawString(false, title.meshfont, DWINUI::textColor, DWINUI::backColor, px(x) - 4, fy, "0");
return;
}
dwinDrawString(false, meshfont, DWINUI::textColor, DWINUI::backColor, px(x) - 2 * fs, fy, msg);
dwinDrawString(false, title.meshfont, DWINUI::textColor, DWINUI::backColor, px(x) - 2 * fs, fy, msg);
}
}

View file

@ -156,7 +156,11 @@ namespace ExtUI {
#if HAS_LEVELING
void onLevelingStart() { dwinLevelingStart(); }
void onLevelingDone() { dwinLevelingDone(); }
void onLevelingDone() {
#if ALL(HAS_MESH, HAS_BED_PROBE)
dwinLevelingDone();
#endif
}
#if ENABLED(PREHEAT_BEFORE_LEVELING)
celsius_t getLevelingBedTemp() { return hmiData.bedLevT; }
#endif

View file

@ -479,6 +479,7 @@ namespace LanguageNarrow_en {
LSTR MSG_BILINEAR_LEVELING = _UxGT("Bilinear Leveling");
LSTR MSG_UBL_LEVELING = _UxGT("Unified Bed Leveling");
LSTR MSG_MESH_LEVELING = _UxGT("Mesh Leveling");
LSTR MSG_MESH_SETTINGS = _UxGT("Mesh Settings");
LSTR MSG_INFO_RUNAWAY_OFF = _UxGT("Runaway Watch: OFF");
LSTR MSG_INFO_RUNAWAY_ON = _UxGT("Runaway Watch: ON");
LSTR MSG_CASE_LIGHT_BRIGHTNESS = _UxGT("Light Brightness");
@ -697,6 +698,7 @@ namespace LanguageNarrow_en {
LSTR MSG_ZPROBE_SETTINGS = _UxGT("Probe Settings");
LSTR MSG_ZPROBE_OFFSETS = _UxGT("Probe Offsets");
LSTR MSG_ZPROBE_MARGIN = _UxGT("Probe Margin");
LSTR MSG_ZPROBE_MULTIPLE = _UxGT("Multiple Probing");
LSTR MSG_Z_FEED_RATE = _UxGT("Z Feedrate");
LSTR MSG_ENABLE_HS_MODE = _UxGT("Enable HS mode");
LSTR MSG_MOVE_NOZZLE_TO_BED = _UxGT("Move Nozzle to Bed");
@ -1093,6 +1095,7 @@ namespace LanguageWide_en {
LSTR MSG_PLEASE_PREHEAT = _UxGT("Please preheat the hot end.");
LSTR MSG_MEDIA_NOT_INSERTED = _UxGT("No media inserted.");
LSTR MSG_INFO_PRINT_COUNT_RESET = _UxGT("Reset Print Count");
LSTR MSG_ZERO_MESH = _UxGT("Zero Current Point");
LSTR MSG_HOMING_FEEDRATE_N = _UxGT("@ Homing Feedrate");
LSTR MSG_PREHEAT_1_CHAMBER = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Chamber");
LSTR MSG_PREHEAT_M_CHAMBER = _UxGT("Preheat $ Chamber");

View file

@ -1061,7 +1061,7 @@ void do_blocking_move_to(const xyze_pos_t &raw, const feedRate_t fr_mm_s/*=0.0f*
* - Execute the move at the probing (or homing) feedrate
*/
void do_z_clearance(const float zclear, const bool with_probe/*=true*/, const bool lower_allowed/*=false*/) {
UNUSED(with_probe);
IF_DISABLED(HAS_BED_PROBE, UNUSED(with_probe));
float zdest = zclear;
TERN_(HAS_BED_PROBE, if (with_probe && probe.offset.z < 0) zdest -= probe.offset.z);
NOMORE(zdest, Z_MAX_POS);

View file

@ -68,7 +68,7 @@ extern xyz_pos_t cartes;
#endif
#ifdef Z_PROBE_FEEDRATE_SLOW
constexpr feedRate_t z_probe_slow_mm_s = MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW);
TERN(DWIN_LCD_PROUI, const, constexpr) feedRate_t z_probe_slow_mm_s = MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW);
#endif
#ifdef Z_PROBE_FEEDRATE_FAST
constexpr feedRate_t z_probe_fast_mm_s = MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST);

View file

@ -376,7 +376,7 @@ FORCE_INLINE void probe_specific_action(const bool deploy) {
#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW)
// Start preheating before waiting for user confirmation that the probe is ready.
TERN_(PREHEAT_BEFORE_PROBING, if (deploy) probe.preheat_for_probing(0, PROBING_BED_TEMP, true));
TERN_(PREHEAT_BEFORE_PROBING, if (deploy) probe.preheat_for_probing(PROBING_NOZZLE_TEMP, PROBING_BED_TEMP, true));
FSTR_P const ds_fstr = deploy ? GET_TEXT_F(MSG_MANUAL_DEPLOY) : GET_TEXT_F(MSG_MANUAL_STOW);
ui.return_to_status(); // To display the new status message
@ -777,43 +777,200 @@ bool Probe::probe_down_to_z(const float z, const feedRate_t fr_mm_s) {
*
* @return The Z position of the bed at the current XY or NAN on error.
*/
float Probe::run_z_probe(const bool sanity_check/*=true*/, const float z_min_point/*=Z_PROBE_LOW_POINT*/, const float z_clearance/*=Z_TWEEN_SAFE_CLEARANCE*/) {
DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING));
#if DISABLED(DWIN_LCD_PROUI)
const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z);
float Probe::run_z_probe(const bool sanity_check/*=true*/, const float z_min_point/*=Z_PROBE_LOW_POINT*/, const float z_clearance/*=Z_TWEEN_SAFE_CLEARANCE*/) {
DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING));
auto try_to_probe = [&](PGM_P const plbl, const float z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck) -> bool {
constexpr float error_tolerance = Z_PROBE_ERROR_TOLERANCE;
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM_P(plbl);
DEBUG_ECHOLNPGM("> try_to_probe(..., ", z_probe_low_point, ", ", fr_mm_s, ", ...)");
}
const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z);
// Tare the probe, if supported
if (TERN0(PROBE_TARE, tare())) return true;
// Do a first probe at the fast speed
const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger?
early_fail = (scheck && current_position.z > zoffs + error_tolerance); // Probe triggered too high?
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) {
DEBUG_ECHOPGM(" Probe fail! - ");
if (probe_fail) DEBUG_ECHOLNPGM("No trigger.");
if (early_fail) DEBUG_ECHOLNPGM("Triggered early (above ", zoffs + error_tolerance, "mm)");
auto try_to_probe = [&](PGM_P const plbl, const float z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck) -> bool {
constexpr float error_tolerance = Z_PROBE_ERROR_TOLERANCE;
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM_P(plbl);
DEBUG_ECHOLNPGM("> try_to_probe(..., ", z_probe_low_point, ", ", fr_mm_s, ", ...)");
}
// Tare the probe, if supported
if (TERN0(PROBE_TARE, tare())) return true;
// Do a first probe at the fast speed
const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger?
early_fail = (scheck && current_position.z > zoffs + error_tolerance); // Probe triggered too high?
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) {
DEBUG_ECHOPGM(" Probe fail! - ");
if (probe_fail) DEBUG_ECHOLNPGM("No trigger.");
if (early_fail) DEBUG_ECHOLNPGM("Triggered early (above ", zoffs + error_tolerance, "mm)");
}
#else
UNUSED(plbl);
#endif
return probe_fail || early_fail;
};
// Stop the probe before it goes too low to prevent damage.
// For known Z probe below the expected trigger point, otherwise -10mm lower.
const float z_probe_low_point = zoffs + z_min_point -float((!axis_is_trusted(Z_AXIS)) * 10);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe Low Point: ", z_probe_low_point);
// Double-probing does a fast probe followed by a slow probe
#if TOTAL_PROBING == 2
// Attempt to tare the probe
if (TERN0(PROBE_TARE, tare())) return NAN;
// Do a first probe at the fast speed
if (try_to_probe(PSTR("FAST"), z_probe_low_point, z_probe_fast_mm_s, sanity_check)) return NAN;
const float z1 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("1st Probe Z:", z1);
// Raise to give the probe clearance
do_z_clearance(z1 + (Z_CLEARANCE_MULTI_PROBE), false);
#elif Z_PROBE_FEEDRATE_FAST != Z_PROBE_FEEDRATE_SLOW
// If the nozzle is well over the travel height then
// move down quickly before doing the slow probe
const float z = (Z_CLEARANCE_DEPLOY_PROBE) + 5.0f + _MAX(zoffs, 0.0f);
if (current_position.z > z) {
// Probe down fast. If the probe never triggered, raise for probe clearance
if (!probe_down_to_z(z, z_probe_fast_mm_s))
do_z_clearance(z_clearance);
}
#else
UNUSED(plbl);
#endif
return probe_fail || early_fail;
};
// Stop the probe before it goes too low to prevent damage.
// For known Z probe below the expected trigger point, otherwise -10mm lower.
const float z_probe_low_point = zoffs + z_min_point -float((!axis_is_trusted(Z_AXIS)) * 10);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe Low Point: ", z_probe_low_point);
#if EXTRA_PROBING > 0
float probes[TOTAL_PROBING];
#endif
// Double-probing does a fast probe followed by a slow probe
#if TOTAL_PROBING == 2
#if TOTAL_PROBING > 2
float probes_z_sum = 0;
for (
#if EXTRA_PROBING > 0
uint8_t p = 0; p < TOTAL_PROBING; p++
#else
uint8_t p = TOTAL_PROBING; p--;
#endif
)
#endif
{
// If the probe won't tare, return
if (TERN0(PROBE_TARE, tare())) return true;
// Probe downward slowly to find the bed
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Slow Probe:");
if (try_to_probe(PSTR("SLOW"), z_probe_low_point, MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW), sanity_check)) return NAN;
TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe());
const float z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
#if EXTRA_PROBING > 0
// Insert Z measurement into probes[]. Keep it sorted ascending.
for (uint8_t i = 0; i <= p; ++i) { // Iterate the saved Zs to insert the new Z
if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z
for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point
probes[i] = z; // Insert the new Z measurement
break; // Only one to insert. Done!
}
}
#elif TOTAL_PROBING > 2
probes_z_sum += z;
#else
UNUSED(z);
#endif
#if TOTAL_PROBING > 2
// Small Z raise after all but the last probe
if (p
#if EXTRA_PROBING > 0
< TOTAL_PROBING - 1
#endif
) do_z_clearance(z + (Z_CLEARANCE_MULTI_PROBE), false);
#endif
}
#if TOTAL_PROBING > 2
#if EXTRA_PROBING > 0
// Take the center value (or average the two middle values) as the median
static constexpr int PHALF = (TOTAL_PROBING - 1) / 2;
const float middle = probes[PHALF],
median = ((TOTAL_PROBING) & 1) ? middle : (middle + probes[PHALF + 1]) * 0.5f;
// Remove values farthest from the median
uint8_t min_avg_idx = 0, max_avg_idx = TOTAL_PROBING - 1;
for (uint8_t i = EXTRA_PROBING; i--;)
if (ABS(probes[max_avg_idx] - median) > ABS(probes[min_avg_idx] - median))
max_avg_idx--; else min_avg_idx++;
// Return the average value of all remaining probes.
for (uint8_t i = min_avg_idx; i <= max_avg_idx; ++i)
probes_z_sum += probes[i];
#endif
const float measured_z = probes_z_sum * RECIPROCAL(MULTIPLE_PROBING);
#elif TOTAL_PROBING == 2
const float z2 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", z1 - z2);
// Return a weighted average of the fast and slow probes
const float measured_z = (z2 * 3.0f + z1 * 2.0f) * 0.2f;
#else
// Return the single probe result
const float measured_z = current_position.z;
#endif
return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z);
}
#else // if DWIN_LCD_PROUI
float Probe::run_z_probe(const bool sanity_check/*=true*/, const float z_min_point/*=Z_PROBE_LOW_POINT*/, const float z_clearance/*=Z_TWEEN_SAFE_CLEARANCE*/) {
DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING));
const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z);
auto try_to_probe = [&](PGM_P const plbl, const float z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck) -> bool {
constexpr float error_tolerance = Z_PROBE_ERROR_TOLERANCE;
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM_P(plbl);
DEBUG_ECHOLNPGM("> try_to_probe(..., ", z_probe_low_point, ", ", fr_mm_s, ", ...)");
}
// Tare the probe, if supported
if (TERN0(PROBE_TARE, tare())) return true;
// Do a first probe at the fast speed
const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger?
early_fail = (scheck && current_position.z > zoffs + error_tolerance); // Probe triggered too high?
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) {
DEBUG_ECHOPGM(" Probe fail! - ");
if (probe_fail) DEBUG_ECHOLNPGM("No trigger.");
if (early_fail) DEBUG_ECHOLNPGM("Triggered early (above ", zoffs + error_tolerance, "mm)");
}
#else
UNUSED(plbl);
#endif
return probe_fail || early_fail;
};
// Stop the probe before it goes too low to prevent damage.
// For known Z probe below the expected trigger point, otherwise -10mm lower.
const float z_probe_low_point = zoffs + z_min_point - float((!axis_is_trusted(Z_AXIS)) * 10);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe Low Point: ", z_probe_low_point);
// Double-probing does a fast probe followed by a slow probe
// Attempt to tare the probe
if (TERN0(PROBE_TARE, tare())) return NAN;
@ -827,33 +984,8 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/, const float z_min_poi
// Raise to give the probe clearance
do_z_clearance(z1 + (Z_CLEARANCE_MULTI_PROBE), false);
#elif Z_PROBE_FEEDRATE_FAST != Z_PROBE_FEEDRATE_SLOW
// If the nozzle is well over the travel height then
// move down quickly before doing the slow probe
const float z = (Z_CLEARANCE_DEPLOY_PROBE) + 5.0f + _MAX(zoffs, 0.0f);
if (current_position.z > z) {
// Probe down fast. If the probe never triggered, raise for probe clearance
if (!probe_down_to_z(z, z_probe_fast_mm_s))
do_z_clearance(z_clearance);
}
#endif
#if EXTRA_PROBING > 0
float probes[TOTAL_PROBING];
#endif
#if TOTAL_PROBING > 2
float probes_z_sum = 0;
for (
#if EXTRA_PROBING > 0
uint8_t p = 0; p < TOTAL_PROBING; p++
#else
uint8_t p = TOTAL_PROBING; p--;
#endif
)
#endif
{
for (uint8_t p = 0; p < hmiData.multiple_probing - 1; p++) {
// If the probe won't tare, return
if (TERN0(PROBE_TARE, tare())) return true;
@ -864,72 +996,19 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/, const float z_min_poi
TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe());
const float z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
#if EXTRA_PROBING > 0
// Insert Z measurement into probes[]. Keep it sorted ascending.
for (uint8_t i = 0; i <= p; ++i) { // Iterate the saved Zs to insert the new Z
if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z
for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point
probes[i] = z; // Insert the new Z measurement
break; // Only one to insert. Done!
}
}
#elif TOTAL_PROBING > 2
probes_z_sum += z;
#else
UNUSED(z);
#endif
#if TOTAL_PROBING > 2
// Small Z raise after all but the last probe
if (p
#if EXTRA_PROBING > 0
< TOTAL_PROBING - 1
#endif
) do_z_clearance(z + (Z_CLEARANCE_MULTI_PROBE), false);
#endif
probes_z_sum += z;
// Small Z raise after probe
do_z_clearance(z + (Z_CLEARANCE_MULTI_PROBE), false);
}
#if TOTAL_PROBING > 2
#if EXTRA_PROBING > 0
// Take the center value (or average the two middle values) as the median
static constexpr int PHALF = (TOTAL_PROBING - 1) / 2;
const float middle = probes[PHALF],
median = ((TOTAL_PROBING) & 1) ? middle : (middle + probes[PHALF + 1]) * 0.5f;
// Remove values farthest from the median
uint8_t min_avg_idx = 0, max_avg_idx = TOTAL_PROBING - 1;
for (uint8_t i = EXTRA_PROBING; i--;)
if (ABS(probes[max_avg_idx] - median) > ABS(probes[min_avg_idx] - median))
max_avg_idx--; else min_avg_idx++;
// Return the average value of all remaining probes.
for (uint8_t i = min_avg_idx; i <= max_avg_idx; ++i)
probes_z_sum += probes[i];
#endif
const float measured_z = probes_z_sum * RECIPROCAL(MULTIPLE_PROBING);
#elif TOTAL_PROBING == 2
const float z2 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", z1 - z2);
// Return a weighted average of the fast and slow probes
const float measured_z = (z2 * 3.0f + z1 * 2.0f) * 0.2f;
const float measured_z = (hmiData.multiple_probing > 1) ?
(probes_z_sum * 3.0f + z1 * 2.0f) * 0.2f : z1;
#else
return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z);
}
// Return the single probe result
const float measured_z = current_position.z;
#endif
return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z);
}
#endif // !DWIN_LCD_PROUI
#if DO_TOOLCHANGE_FOR_PROBING

View file

@ -26,15 +26,13 @@ opt_enable DWIN_MARLINUI_LANDSCAPE LCD_ENDSTOP_TEST AUTO_BED_LEVELING_UBL BLTOUC
exec_test $1 $2 "Ender-3 V2 - MarlinUI (Games, UBL+BLTOUCH, MPCTEMP, LCD_ENDSTOP_TEST)" "$3"
use_example_configs "Creality/Ender-3 S1/STM32F1"
opt_disable DWIN_CREALITY_LCD Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN AUTO_BED_LEVELING_BILINEAR CANCEL_OBJECTS FWRETRACT EVENT_GCODE_SD_ABORT
opt_enable DWIN_LCD_PROUI INDIVIDUAL_AXIS_HOMING_SUBMENU PID_AUTOTUNE_MENU PID_EDIT_MENU \
SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT STATUS_MESSAGE_SCROLLING \
SOUND_MENU_ITEM PRINTCOUNTER NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_SENSOR \
BLTOUCH Z_SAFE_HOMING AUTO_BED_LEVELING_UBL MESH_EDIT_MENU LCD_BED_TRAMMING LIN_ADVANCE \
LIMITED_MAX_FR_EDITING LIMITED_MAX_ACCEL_EDITING LIMITED_JERK_EDITING BAUD_RATE_GCODE \
CASE_LIGHT_ENABLE CASE_LIGHT_MENU CASE_LIGHT_NO_BRIGHTNESS NONLINEAR_EXTRUSION
opt_set PREHEAT_3_LABEL '"CUSTOM"' PREHEAT_3_TEMP_HOTEND 240 PREHEAT_3_TEMP_BED 60 PREHEAT_3_FAN_SPEED 128 BOOTSCREEN_TIMEOUT 1100 CASE_LIGHT_PIN 4
exec_test $1 $2 "Ender-3 S1 - ProUI (PIDTEMP)" "$3"
opt_disable DWIN_CREALITY_LCD AUTO_BED_LEVELING_BILINEAR CANCEL_OBJECTS FWRETRACT EVENT_GCODE_SD_ABORT
opt_enable DWIN_LCD_PROUI PID_AUTOTUNE_MENU PID_EDIT_MENU STATUS_MESSAGE_SCROLLING PRINTCOUNTER \
AUTO_BED_LEVELING_UBL LCD_BED_TRAMMING LIN_ADVANCE \
LIMITED_MAX_FR_EDITING LIMITED_JERK_EDITING BAUD_RATE_GCODE \
CASE_LIGHT_ENABLE CASE_LIGHT_NO_BRIGHTNESS CASE_LIGHT_MENU NONLINEAR_EXTRUSION
opt_set BOOTSCREEN_TIMEOUT 1100 CASE_LIGHT_PIN 4 SDSORT_GCODE true
exec_test $1 $2 "Ender-3 S1 - ProUI (UBL, PIDTEMP)" "$3"
restore_configs
opt_set MOTHERBOARD BOARD_CREALITY_V452 SERIAL_PORT 1