Add G29_RETRY_AND_RECOVER feature
- Add an option to retry G29, optionally executing a G-code procedure after each failed probe.
This commit is contained in:
parent
78ea4871f9
commit
5cc7916e69
5 changed files with 155 additions and 5 deletions
|
@ -746,6 +746,30 @@
|
||||||
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
|
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeatedly attempt G29 leveling until it succeeds.
|
||||||
|
* Stop after G29_MAX_RETRIES attempts.
|
||||||
|
*/
|
||||||
|
//#define G29_RETRY_AND_RECOVER
|
||||||
|
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
#define G29_MAX_RETRIES 3
|
||||||
|
#define G29_HALT_ON_FAILURE
|
||||||
|
/**
|
||||||
|
* Specify the GCODE commands that will be executed when leveling succeeds,
|
||||||
|
* 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
|
// @section extras
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -746,6 +746,30 @@
|
||||||
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
|
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeatedly attempt G29 leveling until it succeeds.
|
||||||
|
* Stop after G29_MAX_RETRIES attempts.
|
||||||
|
*/
|
||||||
|
//#define G29_RETRY_AND_RECOVER
|
||||||
|
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
#define G29_MAX_RETRIES 3
|
||||||
|
#define G29_HALT_ON_FAILURE
|
||||||
|
/**
|
||||||
|
* Specify the GCODE commands that will be executed when leveling succeeds,
|
||||||
|
* 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
|
// @section extras
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -61,6 +61,11 @@ bool GcodeSuite::axis_relative_modes[] = AXIS_RELATIVE_MODES;
|
||||||
float GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
|
float GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_LEVELING && ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
#include "../feature/bedlevel/bedlevel.h"
|
||||||
|
#include "../module/planner.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set target_extruder from the T parameter or the active_extruder
|
* Set target_extruder from the T parameter or the active_extruder
|
||||||
*
|
*
|
||||||
|
@ -125,6 +130,44 @@ void GcodeSuite::dwell(millis_t time) {
|
||||||
while (PENDING(millis(), time)) idle();
|
while (PENDING(millis(), time)) idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When G29_RETRY_AND_RECOVER is enabled, call G29() in
|
||||||
|
* a loop with recovery and retry handling.
|
||||||
|
*/
|
||||||
|
#if HAS_LEVELING && ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
|
||||||
|
void GcodeSuite::G29_with_retry() {
|
||||||
|
set_bed_leveling_enabled(false);
|
||||||
|
for (uint8_t i = G29_MAX_RETRIES; i--;) {
|
||||||
|
G29();
|
||||||
|
if (planner.leveling_active) break;
|
||||||
|
#ifdef G29_ACTION_ON_RECOVER
|
||||||
|
SERIAL_ECHOLNPGM("//action:" G29_ACTION_ON_RECOVER);
|
||||||
|
#endif
|
||||||
|
#ifdef G29_RECOVERY_COMMANDS
|
||||||
|
process_subcommands_now_P(PSTR(G29_RECOVER_COMMANDS));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (planner.leveling_active) {
|
||||||
|
#ifdef G29_SUCCESS_COMMANDS
|
||||||
|
process_subcommands_now_P(PSTR(G29_SUCCESS_COMMANDS));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef G29_FAILURE_COMMANDS
|
||||||
|
process_subcommands_now_P(PSTR(G29_FAILURE_COMMANDS));
|
||||||
|
#endif
|
||||||
|
#ifdef 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 // HAS_LEVELING && G29_RETRY_AND_RECOVER
|
||||||
|
|
||||||
//
|
//
|
||||||
// Placeholders for non-migrated codes
|
// Placeholders for non-migrated codes
|
||||||
//
|
//
|
||||||
|
@ -135,7 +178,11 @@ void GcodeSuite::dwell(millis_t time) {
|
||||||
/**
|
/**
|
||||||
* Process the parsed command and dispatch it to its handler
|
* Process the parsed command and dispatch it to its handler
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::process_parsed_command() {
|
void GcodeSuite::process_parsed_command(
|
||||||
|
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
|
||||||
|
const bool no_ok
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
KEEPALIVE_STATE(IN_HANDLER);
|
KEEPALIVE_STATE(IN_HANDLER);
|
||||||
|
|
||||||
// Handle a known G, M, or T
|
// Handle a known G, M, or T
|
||||||
|
@ -190,8 +237,14 @@ void GcodeSuite::process_parsed_command() {
|
||||||
case 28: G28(false); break; // G28: Home all axes, one at a time
|
case 28: G28(false); break; // G28: Home all axes, one at a time
|
||||||
|
|
||||||
#if HAS_LEVELING
|
#if HAS_LEVELING
|
||||||
case 29: G29(); break; // G29: Bed leveling calibration
|
case 29: // G29: Bed leveling calibration
|
||||||
#endif
|
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
G29_with_retry();
|
||||||
|
#else
|
||||||
|
G29();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
#endif // HAS_LEVELING
|
||||||
|
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
case 30: G30(); break; // G30: Single Z probe
|
case 30: G30(); break; // G30: Single Z probe
|
||||||
|
@ -612,7 +665,10 @@ void GcodeSuite::process_parsed_command() {
|
||||||
|
|
||||||
KEEPALIVE_STATE(NOT_BUSY);
|
KEEPALIVE_STATE(NOT_BUSY);
|
||||||
|
|
||||||
ok_to_send();
|
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
|
||||||
|
if (!no_ok)
|
||||||
|
#endif
|
||||||
|
ok_to_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -638,6 +694,37 @@ void GcodeSuite::process_next_command() {
|
||||||
process_parsed_command();
|
process_parsed_command();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
|
||||||
|
/**
|
||||||
|
* Run a series of commands, bypassing the command queue to allow
|
||||||
|
* G-code "macros" to be called from within other G-code handlers.
|
||||||
|
*/
|
||||||
|
void GcodeSuite::process_subcommands_now_P(const char *pgcode) {
|
||||||
|
// Save the parser state
|
||||||
|
char saved_cmd[strlen(parser.command_ptr) + 1];
|
||||||
|
strcpy(saved_cmd, parser.command_ptr);
|
||||||
|
|
||||||
|
// Process individual commands in string
|
||||||
|
while (pgm_read_byte_near(pgcode)) {
|
||||||
|
// Break up string at '\n' delimiters
|
||||||
|
const char *delim = strchr_P(pgcode, '\n');
|
||||||
|
size_t len = delim ? delim - pgcode : strlen_P(pgcode);
|
||||||
|
char cmd[len + 1];
|
||||||
|
strncpy_P(cmd, pgcode, len);
|
||||||
|
cmd[len] = '\0';
|
||||||
|
pgcode += len;
|
||||||
|
if (delim) pgcode++;
|
||||||
|
|
||||||
|
// Parse the next command in the string
|
||||||
|
parser.parse(cmd);
|
||||||
|
process_parsed_command(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the parser state
|
||||||
|
parser.parse(saved_cmd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(HOST_KEEPALIVE_FEATURE)
|
#if ENABLED(HOST_KEEPALIVE_FEATURE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -285,9 +285,17 @@ public:
|
||||||
|
|
||||||
static bool get_target_extruder_from_command();
|
static bool get_target_extruder_from_command();
|
||||||
static void get_destination_from_command();
|
static void get_destination_from_command();
|
||||||
static void process_parsed_command();
|
static void process_parsed_command(
|
||||||
|
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
|
||||||
|
const bool no_ok = false
|
||||||
|
#endif
|
||||||
|
);
|
||||||
static void process_next_command();
|
static void process_next_command();
|
||||||
|
|
||||||
|
#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
|
||||||
|
static void process_subcommands_now_P(const char *pgcode);
|
||||||
|
#endif
|
||||||
|
|
||||||
FORCE_INLINE static void home_all_axes() { G28(true); }
|
FORCE_INLINE static void home_all_axes() { G28(true); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -380,6 +388,9 @@ private:
|
||||||
|
|
||||||
#if HAS_LEVELING
|
#if HAS_LEVELING
|
||||||
static void G29();
|
static void G29();
|
||||||
|
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
static void G29_with_retry();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_BED_PROBE
|
#if HAS_BED_PROBE
|
||||||
|
|
|
@ -1448,4 +1448,8 @@
|
||||||
// If platform requires early initialization of watchdog to properly boot
|
// If platform requires early initialization of watchdog to properly boot
|
||||||
#define EARLY_WATCHDOG (ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM))
|
#define EARLY_WATCHDOG (ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM))
|
||||||
|
|
||||||
|
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||||
|
#define USE_EXECUTE_COMMANDS_IMMEDIATE
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CONDITIONALS_POST_H
|
#endif // CONDITIONALS_POST_H
|
||||||
|
|
Reference in a new issue