Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Marlin/Conditionals_post.h
Original file line number Diff line number Diff line change
Expand Up @@ -1277,4 +1277,8 @@
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
#endif

#if ENABLED(G29_ADVANCED_RECOVERY_AND_RETRY)
#define USE_EXECUTE_COMMANDS_IMMEDIATE
#endif

#endif // CONDITIONALS_POST_H
24 changes: 24 additions & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,30 @@
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
#endif

/* Uncomment G29_ADVANCED_RECOVERY_AND_RETRY to cause G29 to
* repeat until it succeeds or until G29_MAX_RETRIES has been
* reached.
*/
//#define G29_ADVANCED_RECOVERY_AND_RETRY
#if ENABLED(G29_ADVANCED_RECOVERY_AND_RETRY)
#define G29_MAX_RETRIES 3
#define G29_HALT_ON_FAILURE
/**
* Specify the GCODE commands that will be executed when the bed leveling succeeds,
* in between attempts, and after the maximum number of retries have been tried.
*/
#define G29_SUCCESS_COMMANDS "M117 Bed leveling done."
#define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0"
#define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1"
/**
* Specify an action command to send to the host on a recovery attempt or failure.
* Will be sent in the form '//action:ACTION_ON_G29_FAILURE', e.g. '//action:probe_failed'.
* The host must be configured to handle the action command.
*/
#define G29_ACTION_ON_RECOVER "probe_rewipe"
#define G29_ACTION_ON_FAILURE "probe_failed"
#endif

// @section extras

//
Expand Down
94 changes: 85 additions & 9 deletions Marlin/Marlin_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,11 @@ void stop();

void get_available_commands();
void process_next_command();
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
void process_parsed_command(bool no_ok = false);
#else
void process_parsed_command();
#endif

void get_cartesian_from_steppers();
void set_current_from_steppers_for_axis(const AxisEnum axis);
Expand Down Expand Up @@ -778,6 +782,33 @@ void report_current_position_detail();
print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0)
#endif

#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
/**
* Runs a series of commands, bypassing the command queue. This
* allows GCODE "macros" to be called from within other GCODE
* routines.
*
* NOTE: execute_commands_immediate_P() should only be called after the
* parsing stage of a GCODE routine, as the state of the parser
* object will be destroyed.
*/
void execute_commands_immediate_P(const char *pgcode) {
char cmd[30];
while(pgm_read_byte_near(pgcode) != '\0') {
const char *delim = strchr_P(pgcode, '\n');
size_t len = delim ? delim - pgcode : strlen_P(pgcode);
strncpy_P(cmd, pgcode, len);
cmd[len] = '\0';
pgcode += len;
if(delim) {
pgcode++;
}
parser.parse(cmd);
process_parsed_command(true);
}
}
#endif

/**
* sync_plan_position
*
Expand Down Expand Up @@ -5300,6 +5331,37 @@ void home_all_axes() { gcode_G28(true); }

#endif // OLDSCHOOL_ABL

#if HAS_LEVELING && ENABLED(G29_ADVANCED_RECOVERY_AND_RETRY)
void gcode_G29_with_retry() {
set_bed_leveling_enabled(false);
for(uint8_t i = 0; i < G29_MAX_RETRIES; i++) {
gcode_G29();
if(planner.leveling_active) break;
#if defined(G29_ACTION_ON_RECOVER)
SERIAL_ECHOLNPGM("//action:" G29_ACTION_ON_RECOVER);
#endif
#if defined(G29_RECOVERY_COMMANDS)
execute_commands_immediate_P(PSTR(G29_RECOVER_COMMANDS));
#endif
}
if(planner.leveling_active) {
#if defined(G29_SUCCESS_COMMANDS)
execute_commands_immediate_P(PSTR(G29_SUCCESS_COMMANDS));
#endif
} else {
#if defined(G29_FAILURE_COMMANDS)
execute_commands_immediate_P(PSTR(G29_FAILURE_COMMANDS));
#endif
#if defined(G29_ACTION_ON_FAILURE)
SERIAL_ECHOLNPGM("//action:" G29_ACTION_ON_FAILURE);
#endif
#if ENABLED(G29_HALT_ON_FAILURE)
kill(PSTR(MSG_ERR_PROBING_FAILED));
#endif
}
}
#endif

#if HAS_BED_PROBE

/**
Expand Down Expand Up @@ -5613,7 +5675,7 @@ void home_all_axes() { gcode_G28(true); }

/**
* kinematics routines and auto tune matrix scaling parameters:
* see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for
* see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for
* - formulae for approximative forward kinematics in the end-stop displacement matrix
* - definition of the matrix scaling parameters
*/
Expand All @@ -5627,7 +5689,7 @@ void home_all_axes() { gcode_G28(true); }
pos[Y_AXIS] = sin(a) * r;
pos[Z_AXIS] = z_pt[rad];
inverse_kinematics(pos);
LOOP_XYZ(axis) mm_at_pt_axis[rad][axis] = delta[axis];
LOOP_XYZ(axis) mm_at_pt_axis[rad][axis] = delta[axis];
}
}

Expand Down Expand Up @@ -5691,7 +5753,7 @@ void home_all_axes() { gcode_G28(true); }
delta_t[ABC] = {0.0};

delta_r = diff;
calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t);
calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t);
r_fac = -(z_pt[__A] + z_pt[__B] + z_pt[__C] + z_pt[_BC] + z_pt[_CA] + z_pt[_AB]) / 6.0;
r_fac = diff / r_fac / 3.0; // 1/(3*delta_Z)
return r_fac;
Expand All @@ -5708,7 +5770,7 @@ void home_all_axes() { gcode_G28(true); }
LOOP_XYZ(axis) {
LOOP_XYZ(axis_2) delta_t[axis_2] = 0.0;
delta_t[axis] = diff;
calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t);
calc_kinematics_diff_probe_points(z_pt, delta_e, delta_r, delta_t);
a_fac += z_pt[uint8_t((axis * _4P_STEP) - _7P_STEP + NPP) % NPP + 1] / 6.0;
a_fac -= z_pt[uint8_t((axis * _4P_STEP) + 1 + _7P_STEP)] / 6.0;
}
Expand Down Expand Up @@ -5890,7 +5952,7 @@ void home_all_axes() { gcode_G28(true); }

/**
* convergence matrices:
* see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for
* see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for
* - definition of the matrix scaling parameters
* - matrices for 4 and 7 point calibration
*/
Expand Down Expand Up @@ -5956,7 +6018,7 @@ void home_all_axes() { gcode_G28(true); }
delta_radius += r_delta;
LOOP_XYZ(axis) delta_tower_angle_trim[axis] += t_delta[axis];
}
else if (zero_std_dev >= test_precision) {
else if (zero_std_dev >= test_precision) {
// roll back
COPY(delta_endstop_adj, e_old);
delta_radius = r_old;
Expand All @@ -5982,7 +6044,7 @@ void home_all_axes() { gcode_G28(true); }
NOMORE(zero_std_dev_min, zero_std_dev);

// print report

if (verbose_level == 3)
print_calibration_results(z_at_pt, _tower_results, _opposite_results);

Expand Down Expand Up @@ -11834,7 +11896,11 @@ inline void gcode_T(const uint8_t tmp_extruder) {
/**
* Process the parsed command and dispatch it to its handler
*/
void process_parsed_command() {
void process_parsed_command(
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
bool no_ok
#endif
) {
KEEPALIVE_STATE(IN_HANDLER);

// Handle a known G, M, or T
Expand Down Expand Up @@ -11888,7 +11954,13 @@ void process_parsed_command() {
case 28: gcode_G28(false); break; // G28: Home one or more axes

#if HAS_LEVELING
case 29: gcode_G29(); break; // G29: Detailed Z probe
case 29:
#if ENABLED(G29_ADVANCED_RECOVERY_AND_RETRY)
gcode_G29_with_retry();
#else
gcode_G29();
#endif
break; // G29: Detailed Z probe
#endif

#if HAS_BED_PROBE
Expand Down Expand Up @@ -12290,6 +12362,10 @@ void process_parsed_command() {
}

KEEPALIVE_STATE(NOT_BUSY);

#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
if(!no_ok)
#endif
ok_to_send();
}

Expand Down