-
-
Notifications
You must be signed in to change notification settings - Fork 19.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce the reprobe and rewipe features #3553
Changes from 3 commits
28bc371
f9da0b5
2fa5a8b
c6eef47
9f97acc
650fc20
658cf13
3285a19
76e2c97
ead40cf
821a773
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,6 +103,7 @@ | |
* G4 - Dwell S<seconds> or P<milliseconds> | ||
* G10 - retract filament according to settings of M207 | ||
* G11 - retract recover filament according to settings of M208 | ||
* G26 - Allow G-codes to enter the buffer again after a PROBE_FAIL_PANIC occurs during a G29 | ||
* G28 - Home one or more axes | ||
* G29 - Detailed Z probe, probes the bed at 3 or more points. Will fail if you haven't homed yet. | ||
* G30 - Single Z probe, probes bed at current XY location. | ||
|
@@ -315,6 +316,10 @@ static uint8_t target_extruder; | |
#if ENABLED(AUTO_BED_LEVELING_FEATURE) | ||
int xy_travel_speed = XY_TRAVEL_SPEED; | ||
float zprobe_zoffset = Z_PROBE_OFFSET_FROM_EXTRUDER; | ||
#if ENABLED(REPROBE) | ||
uint8_t reprobe_attempts = 0; | ||
bool probe_fail = false; | ||
#endif | ||
#endif | ||
|
||
#if ENABLED(Z_DUAL_ENDSTOPS) && DISABLED(DELTA) | ||
|
@@ -901,6 +906,17 @@ void gcode_line_error(const char* err, bool doFlush = true) { | |
serial_count = 0; | ||
} | ||
|
||
void clear_buffer() { | ||
for(uint8_t i=0; i < BUFSIZE; i++) | ||
for(uint8_t j=0; j < MAX_CMD_SIZE; j++) | ||
command_queue[i][j] = NULL; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be… for (uint8_t i=0; i < BUFSIZE; i++) command_queue[i][0] = '\0'; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thinkyhead why just the first element of each row? Why not each element in the 2D array? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the first character in a string is nul, the string is considered empty. So there's no need to clear the entire string. |
||
MYSERIAL.flush(); | ||
serial_count = 0; | ||
commands_in_queue = 1; | ||
cmd_queue_index_r = BUFSIZE-1; | ||
cmd_queue_index_w = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These three lines can be replaced with… cmd_queue_index_r = cmd_queue_index_w = commands_in_queue = 0; |
||
} | ||
|
||
inline void get_serial_commands() { | ||
static char serial_line_buffer[MAX_CMD_SIZE]; | ||
static boolean serial_comment_mode = false; | ||
|
@@ -999,6 +1015,22 @@ inline void get_serial_commands() { | |
|
||
// If command was e-stop process now | ||
if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED)); | ||
#if ENABLED(PROBE_FAIL_PANIC) | ||
if (strcmp(command, "G26") == 0) { | ||
LCD_MESSAGEPGM(WELCOME_MSG); | ||
probe_fail = false; | ||
} | ||
else if(probe_fail && (strchr(command, 'G') != NULL || strchr(command, 'M') != NULL) && strstr(command, "M105") == NULL) { | ||
for(uint8_t j=0; j < MAX_CMD_SIZE; j++) | ||
command_queue[cmd_queue_index_r][j] = 0; | ||
if(commands_in_queue) { | ||
commands_in_queue = 1; | ||
cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE; | ||
} | ||
serial_count = 0; | ||
return; | ||
} | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jbrazio @thinkyhead please take a look at this snippet. In case the probing fails all attempts We prefer to reserve Granted if the intent is to be able to do manual cleaning of the nozzle and continue then the host needs to prevent all G-Code from being sent other than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jbrazio @thinkyhead would it possible for us to reserve There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hum you may I've checked and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jbrazio currently we don't call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @scalez We've had some discussions recently about the handling of commands ahead of the normal command buffer. I don't know how conclusive they were. But understand that if a host fills up the buffer after issuing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thinkyhead Currently we're flushing the command buffer when we enter the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see! So, I'm also wondering why we need a new command or a "special" kind of panic, since we have |
||
|
||
#if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 | ||
last_command_time = ms; | ||
|
@@ -1482,6 +1514,45 @@ static void setup_for_endstop_move() { | |
|
||
#endif // !AUTO_BED_LEVELING_GRID | ||
|
||
static void do_blocking_move_to(float x, float y, float z); | ||
inline void do_blocking_move_to_xy(float x, float y); | ||
inline void do_blocking_move_to_x(float x); | ||
inline void do_blocking_move_to_z(float z); | ||
|
||
#if ENABLED(REPROBE) | ||
void probing_failed() { | ||
if(reprobe_attempts < NUM_ATTEMPTS-1) | ||
{ | ||
#if DISABLED(REWIPE) | ||
SERIAL_ERRORLNPGM(MSG_REPROBE); | ||
LCD_MESSAGEPGM(MSG_REPROBE); | ||
#endif | ||
do_blocking_move_to_z(Z_RETRY_PT); | ||
#if ENABLED(REWIPE) | ||
SERIAL_ERRORLNPGM(MSG_REWIPE); | ||
LCD_MESSAGEPGM(MSG_REWIPE); | ||
float rewipe_first_pt[2] = REWIPE_FIRST_PT; | ||
float rewipe_second_pt[2] = REWIPE_SECOND_PT; | ||
do_blocking_move_to_xy(rewipe_first_pt[X_AXIS], rewipe_first_pt[Y_AXIS]); | ||
do_blocking_move_to_z(Z_REWIPE_PT); | ||
for(uint8_t i=0; i<NUM_REWIPES; i++) | ||
{ | ||
do_blocking_move_to_xy(rewipe_second_pt[X_AXIS], rewipe_second_pt[Y_AXIS]); | ||
do_blocking_move_to_xy(rewipe_first_pt[X_AXIS], rewipe_first_pt[Y_AXIS]); | ||
} | ||
#endif | ||
do_blocking_move_to_z(Z_RETRY_PT); | ||
do_blocking_move_to_xy(LEFT_PROBE_BED_POSITION, FRONT_PROBE_BED_POSITION); | ||
reprobe_attempts++; | ||
} | ||
else | ||
{ | ||
do_blocking_move_to_z(Z_RETRY_PT); | ||
reprobe_attempts++; | ||
} | ||
} | ||
#endif | ||
|
||
static void run_z_probe() { | ||
|
||
/** | ||
|
@@ -1526,7 +1597,7 @@ static void setup_for_endstop_move() { | |
feedrate = homing_feedrate[Z_AXIS]; | ||
|
||
// Move down until the Z probe (or endstop?) is triggered | ||
float zPosition = -(Z_MAX_LENGTH + 10); | ||
float zPosition = MIN_PROBE_PT; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be altered. The length given is meant to be excessive, so that even if the Z probe is very far away from the bed it will still reach it. We can't use a "point" here because the Z coordinate is not really "known" when probing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thinkyhead this movement is still relative to the origin. Therefore,
Why exactly do you think the position is lost during probing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't mean to say it's lost, just not accurate or especially meaningful. During probing, the Z position is just a working number for moving up and down, and not necessarily guaranteed to be an accurate reflection of the Z-distance to the bed. At least, that is how I have tended to think of it. But maybe that has changed…? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thinkyhead I think I see what you mean, when one point successfully probes the current position may not be accurate after the pin is toggled. From our tests this works fine. In fact, we've even published a commit in our repo that sets the position of an axis when an endstop (not the reference one used for homing) is hit to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @scalez I will look at that soon. |
||
line_to_z(zPosition); | ||
st_synchronize(); | ||
|
||
|
@@ -1536,6 +1607,13 @@ static void setup_for_endstop_move() { | |
current_position[X_AXIS], current_position[Y_AXIS], zPosition, | ||
current_position[E_AXIS] | ||
); | ||
#ifdef REPROBE | ||
if(zPosition == MIN_PROBE_PT && !digitalRead(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) | ||
{ | ||
probing_failed(); | ||
return; | ||
} | ||
#endif | ||
|
||
// move up the retract distance | ||
zPosition += home_bump_mm(Z_AXIS); | ||
|
@@ -1546,7 +1624,7 @@ static void setup_for_endstop_move() { | |
// move back down slowly to find bed | ||
set_homing_bump_feedrate(Z_AXIS); | ||
|
||
zPosition -= home_bump_mm(Z_AXIS) * 2; | ||
zPosition = MIN_PROBE_PT; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, on re-bump this might work. But we don't really know that zPosition -= home_bump_mm(Z_AXIS) + 2; |
||
line_to_z(zPosition); | ||
st_synchronize(); | ||
endstops_hit_on_purpose(); // clear endstop hit flags | ||
|
@@ -1880,6 +1958,10 @@ static void setup_for_endstop_move() { | |
|
||
run_z_probe(); | ||
float measured_z = current_position[Z_AXIS]; | ||
#ifdef REPROBE | ||
if(measured_z == Z_RETRY_PT) | ||
return MIN_PROBE_PT; | ||
#endif | ||
|
||
#if DISABLED(Z_PROBE_SLED) && DISABLED(Z_PROBE_ALLEN_KEY) | ||
if (probe_action & ProbeStow) { | ||
|
@@ -2470,6 +2552,16 @@ inline void gcode_G4() { | |
|
||
#endif //FWRETRACT | ||
|
||
/** | ||
* G26: Allow G-codes to enter the buffer again after a PROBE_FAIL_PANIC occurs during a G29 | ||
*/ | ||
#if ENABLED(PROBE_FAIL_PANIC) | ||
inline void gcode_G26() { | ||
LCD_MESSAGEPGM(WELCOME_MSG); | ||
probe_fail = false; | ||
} | ||
#endif | ||
|
||
/** | ||
* G28: Home all axes according to settings | ||
* | ||
|
@@ -3224,6 +3316,11 @@ inline void gcode_G28() { | |
double yProbe = front_probe_bed_position + yGridSpacing * yCount; | ||
int xStart, xStop, xInc; | ||
|
||
#if ENABLED(REPROBE) | ||
if(reprobe_attempts == NUM_ATTEMPTS && probePointCounter == -1) | ||
break; | ||
#endif | ||
|
||
if (zig) { | ||
xStart = 0; | ||
xStop = auto_bed_leveling_grid_points; | ||
|
@@ -3279,6 +3376,21 @@ inline void gcode_G28() { | |
|
||
measured_z = probe_pt(xProbe, yProbe, z_before, act, verbose_level); | ||
|
||
#if ENABLED(REPROBE) | ||
if(measured_z == MIN_PROBE_PT) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A space is preferred between |
||
if(reprobe_attempts < NUM_ATTEMPTS) { | ||
probePointCounter = 0; | ||
zig = true; | ||
yCount = -1; | ||
break; | ||
} | ||
else { | ||
probePointCounter = -1; | ||
break; | ||
} | ||
} | ||
#endif | ||
|
||
#if DISABLED(DELTA) | ||
mean += measured_z; | ||
|
||
|
@@ -3298,6 +3410,45 @@ inline void gcode_G28() { | |
} //xProbe | ||
} //yProbe | ||
|
||
#if ENABLED(PROBE_FAIL_PANIC) | ||
if(reprobe_attempts == NUM_ATTEMPTS && probePointCounter == -1) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The opening parenthesis for a block should be on the same line. Add a blank line if it helps improve the readability of complex code. See https://github.com/MarlinFirmware/Marlin/wiki/DNE-Coding-Standards |
||
if(!IS_SD_PRINTING) | ||
probe_fail = true; | ||
disable_all_heaters(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This indentation implies that |
||
#if ENABLED(THERMAL_RUNAWAY_PROTECTION_PERIOD) | ||
for(int i=0; i<EXTRUDERS; i++) target_temp_reached[i] = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A minor syntax point. In Marlin the code prefers spaces around operators like for (int i = 0; i < EXTRUDERS; i++) . . . |
||
#endif | ||
#if ENABLED(SDSUPPORT) | ||
card.closefile(); | ||
card.sdprinting = false; | ||
#endif | ||
clear_buffer(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thinkyhead command buffer is flushed here. |
||
reprobe_attempts = 0; | ||
do_blocking_move_to_z(Z_RETRY_PT); | ||
// Move E back to 0 after a failed probe | ||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], 0.0, feedrate/60, active_extruder); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why "move E back to 0" here? Eject the filament? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thinkyhead L3426 (of the most recent commit, same as L3430 here) is intended only if wiping is necessary for probing since a retraction is done prior to wiping, so I wrap it with |
||
st_synchronize(); | ||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can just call |
||
acceleration = DEFAULT_ACCELERATION; | ||
#if ENABLED(ULTIPANEL) | ||
buzz(750, 1750); | ||
#endif | ||
SERIAL_ERROR_START; | ||
SERIAL_ERRORLNPGM(MSG_LEVEL_FAIL); | ||
LCD_MESSAGEPGM(MSG_LEVEL_FAIL); | ||
return; | ||
} | ||
#else | ||
#if ENABLED(REPROBE) | ||
SERIAL_ERROR_START; | ||
SERIAL_ERRORLNPGM(MSG_LEVEL_QUIT); | ||
LCD_MESSAGEPGM(MSG_LEVEL_QUIT); | ||
reprobe_attempts = 0; | ||
return; | ||
#endif | ||
#endif | ||
|
||
#if ENABLED(DEBUG_LEVELING_FEATURE) | ||
if (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position); | ||
#endif | ||
|
@@ -3580,6 +3731,10 @@ inline void gcode_G28() { | |
#endif | ||
stow_z_probe(false); // Retract Z Servo endstop if available. Z_PROBE_SLED is missed here. | ||
|
||
#if ENABLED(REPROBE) | ||
reprobe_attempts = 0; | ||
#endif | ||
|
||
gcode_M114(); // Send end position to RepetierHost | ||
} | ||
|
||
|
@@ -6453,6 +6608,12 @@ void process_next_command() { | |
|
||
#endif //FWRETRACT | ||
|
||
#if ENABLED(PROBE_FAIL_PANIC) | ||
case 26: // G26: Allow G-codes to enter the buffer again after a PROBE_FAIL_PANIC occurs during a G29 | ||
gcode_G26(); | ||
break; | ||
#endif | ||
|
||
case 28: // G28: Home all axes, one at a time | ||
gcode_G28(); | ||
break; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"giving up" (as below) is better than "quitting" here.