/** * @details Used by probe_pt to do a single Z probe. * Leaves current_position[Z_AXIS] at the height where the probe triggered. * * @param short_move Flag for a shorter probe move towards the bed * @return The raw Z position where the probe was triggered */ static float run_z_probe(const bool short_move=true) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS(">>> run_z_probe", current_position); #endif // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding gcode.refresh_cmd_timeout(); #if ENABLED(PROBE_DOUBLE_TOUCH) // Do a first probe at the fast speed if (do_probe_move(-10, Z_PROBE_SPEED_FAST)) return NAN; #if ENABLED(DEBUG_LEVELING_FEATURE) float first_probe_z = current_position[Z_AXIS]; if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("1st Probe Z:", first_probe_z); #endif // move up to make clearance for the probe do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); #else // If the nozzle is above the travel height then // move down quickly before doing the slow probe float z = Z_CLEARANCE_DEPLOY_PROBE; if (zprobe_zoffset < 0) z -= zprobe_zoffset; if (z < current_position[Z_AXIS]) { // If we don't make it to the z position (i.e. the probe triggered), move up to make clearance for the probe if (!do_probe_move(z, Z_PROBE_SPEED_FAST)) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); } #endif // move down slowly to find bed if (do_probe_move(-10 + (short_move ? 0 : -(Z_MAX_LENGTH)), Z_PROBE_SPEED_SLOW)) return NAN; #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position); #endif // Debug: compare probe heights #if ENABLED(PROBE_DOUBLE_TOUCH) && ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { SERIAL_ECHOPAIR("2nd Probe Z:", current_position[Z_AXIS]); SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - current_position[Z_AXIS]); } #endif return RAW_CURRENT_POSITION(Z) + zprobe_zoffset #if ENABLED(DELTA) + home_offset[Z_AXIS] // Account for delta height adjustment #endif ; }
/** * @brief Used by run_z_probe to do a single Z probe move. * * @param z Z destination * @param fr_mm_s Feedrate in mm/s * @return true to indicate an error */ static bool do_probe_move(const float z, const float fr_mm_m) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS(">>> do_probe_move", current_position); #endif // Deploy BLTouch at the start of any probe #if ENABLED(BLTOUCH) if (set_bltouch_deployed(true)) return true; #endif #if QUIET_PROBING probing_pause(true); #endif // Move down until probe triggered do_blocking_move_to_z(z, MMM_TO_MMS(fr_mm_m)); // Check to see if the probe was triggered const bool probe_triggered = TEST(Endstops::endstop_hit_bits, #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) Z_MIN #else Z_MIN_PROBE #endif ); #if QUIET_PROBING probing_pause(false); #endif // Retract BLTouch immediately after a probe if it was triggered #if ENABLED(BLTOUCH) if (probe_triggered && set_bltouch_deployed(false)) return true; #endif // Clear endstop flags endstops.hit_on_purpose(); // Get Z where the steppers were interrupted set_current_from_steppers_for_axis(Z_AXIS); // Tell the planner where we actually are SYNC_PLAN_POSITION_KINEMATIC(); #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position); #endif return !probe_triggered; }
/** * Perform a tool-change, which may result in moving the * previous tool out of the way and the new tool into place. */ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) { #if ENABLED(MIXING_EXTRUDER) UNUSED(fr_mm_s); UNUSED(no_move); if (tmp_extruder >= MIXING_VIRTUAL_TOOLS) return invalid_extruder_error(tmp_extruder); #if MIXING_VIRTUAL_TOOLS > 1 // T0-Tnnn: Switch virtual tool by changing the index to the mix mixer.T(tmp_extruder); #endif #elif ENABLED(PRUSA_MMU2) UNUSED(fr_mm_s); UNUSED(no_move); mmu2.toolChange(tmp_extruder); #elif EXTRUDERS < 2 UNUSED(fr_mm_s); UNUSED(no_move); if (tmp_extruder) invalid_extruder_error(tmp_extruder); return; #else // EXTRUDERS > 1 planner.synchronize(); #if ENABLED(DUAL_X_CARRIAGE) // Only T0 allowed if the Printer is in DXC_DUPLICATION_MODE or DXC_MIRRORED_MODE if (tmp_extruder != 0 && dxc_is_duplicating()) return invalid_extruder_error(tmp_extruder); #endif #if HAS_LEVELING // Set current position to the physical position const bool leveling_was_active = planner.leveling_active; set_bed_leveling_enabled(false); #endif if (tmp_extruder >= EXTRUDERS) return invalid_extruder_error(tmp_extruder); if (!no_move && !all_axes_homed()) { no_move = true; if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("No move on toolchange"); } #if HAS_LCD_MENU ui.return_to_status(); #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) const bool should_swap = !no_move && toolchange_settings.swap_length; #if ENABLED(PREVENT_COLD_EXTRUSION) const bool too_cold = !DEBUGGING(DRYRUN) && (thermalManager.targetTooColdToExtrude(active_extruder) || thermalManager.targetTooColdToExtrude(tmp_extruder)); #else constexpr bool too_cold = false; #endif if (should_swap) { if (too_cold) { SERIAL_ECHO_MSG(MSG_ERR_HOTEND_TOO_COLD); #if ENABLED(SINGLENOZZLE) active_extruder = tmp_extruder; return; #endif } else { #if ENABLED(ADVANCED_PAUSE_FEATURE) do_pause_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); #else current_position[E_AXIS] -= toolchange_settings.swap_length / planner.e_factor[active_extruder]; planner.buffer_line(current_position, MMM_TO_MMS(toolchange_settings.retract_speed), active_extruder); #endif } } #endif // TOOLCHANGE_FILAMENT_SWAP if (tmp_extruder != active_extruder) { #if SWITCHING_NOZZLE_TWO_SERVOS raise_nozzle(active_extruder); #endif const float old_feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : feedrate_mm_s; feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; #if HAS_SOFTWARE_ENDSTOPS && ENABLED(DUAL_X_CARRIAGE) update_software_endstops(X_AXIS, active_extruder, tmp_extruder); #endif set_destination_from_current(); if (!no_move) { #if DISABLED(SWITCHING_NOZZLE) // Do a small lift to avoid the workpiece in the move back (below) #if ENABLED(TOOLCHANGE_PARK) current_position[X_AXIS] = toolchange_settings.change_point.x; current_position[Y_AXIS] = toolchange_settings.change_point.y; #endif current_position[Z_AXIS] += toolchange_settings.z_raise; #if HAS_SOFTWARE_ENDSTOPS NOMORE(current_position[Z_AXIS], soft_endstop[Z_AXIS].max); #endif planner.buffer_line(current_position, feedrate_mm_s, active_extruder); #endif planner.synchronize(); } #if HAS_HOTEND_OFFSET #if ENABLED(DUAL_X_CARRIAGE) constexpr float xdiff = 0; #else const float xdiff = hotend_offset[X_AXIS][tmp_extruder] - hotend_offset[X_AXIS][active_extruder]; #endif const float ydiff = hotend_offset[Y_AXIS][tmp_extruder] - hotend_offset[Y_AXIS][active_extruder], zdiff = hotend_offset[Z_AXIS][tmp_extruder] - hotend_offset[Z_AXIS][active_extruder]; #else constexpr float xdiff = 0, ydiff = 0, zdiff = 0; #endif #if ENABLED(DUAL_X_CARRIAGE) dualx_tool_change(tmp_extruder, no_move); #elif ENABLED(PARKING_EXTRUDER) // Dual Parking extruder parking_extruder_tool_change(tmp_extruder, no_move); #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) // Magnetic Parking extruder magnetic_parking_extruder_tool_change(tmp_extruder); #elif ENABLED(SWITCHING_TOOLHEAD) // Switching Toolhead switching_toolhead_tool_change(tmp_extruder, fr_mm_s, no_move); #elif ENABLED(SWITCHING_NOZZLE) && !SWITCHING_NOZZLE_TWO_SERVOS // Raise by a configured distance to avoid workpiece, except with // SWITCHING_NOZZLE_TWO_SERVOS, as both nozzles will lift instead. current_position[Z_AXIS] += MAX(-zdiff, 0.0) + toolchange_settings.z_raise; #if HAS_SOFTWARE_ENDSTOPS NOMORE(current_position[Z_AXIS], soft_endstop[Z_AXIS].max); #endif if (!no_move) fast_line_to_current(Z_AXIS); move_nozzle_servo(tmp_extruder); #endif if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Offset Tool XY by { ", xdiff, ", ", ydiff, ", ", zdiff, " }"); // The newly-selected extruder XY is actually at... current_position[X_AXIS] += xdiff; current_position[Y_AXIS] += ydiff; current_position[Z_AXIS] += zdiff; // Set the new active extruder if not already done in tool specific function above active_extruder = tmp_extruder; // Tell the planner the new "current position" sync_plan_position(); #if ENABLED(DELTA) //LOOP_XYZ(i) update_software_endstops(i); // or modify the constrain function const bool safe_to_move = current_position[Z_AXIS] < delta_clip_start_height - 1; #else constexpr bool safe_to_move = true; #endif // Return to position and lower again if (safe_to_move && !no_move && IsRunning()) { if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination); #if ENABLED(SINGLENOZZLE) #if FAN_COUNT > 0 singlenozzle_fan_speed[active_extruder] = thermalManager.fan_speed[0]; thermalManager.fan_speed[0] = singlenozzle_fan_speed[tmp_extruder]; #endif singlenozzle_temp[active_extruder] = thermalManager.temp_hotend[0].target; if (singlenozzle_temp[tmp_extruder] && singlenozzle_temp[tmp_extruder] != singlenozzle_temp[active_extruder]) { thermalManager.setTargetHotend(singlenozzle_temp[tmp_extruder], 0); #if EITHER(ULTRA_LCD, EXTENSIBLE_UI) thermalManager.set_heating_message(0); #endif (void)thermalManager.wait_for_hotend(0, false); // Wait for heating or cooling } active_extruder = tmp_extruder; #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) if (should_swap && !too_cold) { #if ENABLED(ADVANCED_PAUSE_FEATURE) do_pause_e_move(toolchange_settings.swap_length + TOOLCHANGE_FIL_EXTRA_PRIME, toolchange_settings.prime_speed); #else current_position[E_AXIS] += (toolchange_settings.swap_length + TOOLCHANGE_FIL_EXTRA_PRIME) / planner.e_factor[tmp_extruder]; planner.buffer_line(current_position, toolchange_settings.prime_speed, tmp_extruder); #endif planner.synchronize(); #if TOOLCHANGE_FIL_EXTRA_PRIME planner.set_e_position_mm((destination[E_AXIS] = current_position[E_AXIS] = current_position[E_AXIS] - (TOOLCHANGE_FIL_EXTRA_PRIME))); #endif } #endif // Prevent a move outside physical bounds apply_motion_limits(destination); // Move back to the original (or tweaked) position do_blocking_move_to(destination); #if ENABLED(DUAL_X_CARRIAGE) active_extruder_parked = false; #endif feedrate_mm_s = old_feedrate_mm_s; } #if ENABLED(SWITCHING_NOZZLE) else { // Move back down. (Including when the new tool is higher.) do_blocking_move_to_z(destination[Z_AXIS], planner.settings.max_feedrate_mm_s[Z_AXIS]); } #endif #if ENABLED(PRUSA_MMU2) mmu2.toolChange(tmp_extruder); #endif #if SWITCHING_NOZZLE_TWO_SERVOS lower_nozzle(active_extruder); #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) && ADVANCED_PAUSE_RESUME_PRIME != 0 if (should_swap && !too_cold) { const float resume_eaxis = current_position[E_AXIS]; #if ENABLED(ADVANCED_PAUSE_FEATURE) do_pause_e_move(toolchange_settings.swap_length, toolchange_settings.prime_speed); #else current_position[E_AXIS] += (ADVANCED_PAUSE_RESUME_PRIME) / planner.e_factor[active_extruder]; planner.buffer_line(current_position, ADVANCED_PAUSE_PURGE_FEEDRATE, active_extruder); #endif planner.synchronize(); planner.set_e_position_mm((destination[E_AXIS] = current_position[E_AXIS] = resume_eaxis)); } #endif } // (tmp_extruder != active_extruder) planner.synchronize(); #if ENABLED(EXT_SOLENOID) && DISABLED(PARKING_EXTRUDER) disable_all_solenoids(); enable_solenoid_on_active_extruder(); #endif #if ENABLED(MK2_MULTIPLEXER) if (tmp_extruder >= E_STEPPERS) return invalid_extruder_error(tmp_extruder); select_multiplexed_stepper(tmp_extruder); #endif #if DO_SWITCH_EXTRUDER planner.synchronize(); move_extruder_servo(active_extruder); #endif #if HAS_FANMUX fanmux_switch(active_extruder); #endif #if HAS_LEVELING // Restore leveling to re-establish the logical position set_bed_leveling_enabled(leveling_was_active); #endif SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, int(active_extruder)); #endif // EXTRUDERS > 1 }
/** * - Move to the given XY * - Deploy the probe, if not already deployed * - Probe the bed, get the Z position * - Depending on the 'stow' flag * - Stow the probe, or * - Raise to the BETWEEN height * - Return the probed Z position */ float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable/*=true*/) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { SERIAL_ECHOPAIR(">>> probe_pt(", lx); SERIAL_ECHOPAIR(", ", ly); SERIAL_ECHOPAIR(", ", stow ? "" : "no "); SERIAL_ECHOLNPGM("stow)"); DEBUG_POS("", current_position); } #endif const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER); if (printable ? !position_is_reachable_xy(nx, ny) : !position_is_reachable_by_probe_xy(lx, ly) ) return NAN; const float old_feedrate_mm_s = feedrate_mm_s; #if ENABLED(DELTA) if (current_position[Z_AXIS] > delta_clip_start_height) do_blocking_move_to_z(delta_clip_start_height); #endif #if HAS_SOFTWARE_ENDSTOPS // Store the status of the soft endstops and disable if we're probing a non-printable location static bool enable_soft_endstops = soft_endstops_enabled; if (!printable) soft_endstops_enabled = false; #endif feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S; // Move the probe to the given XY do_blocking_move_to_xy(nx, ny); float measured_z = NAN; if (!DEPLOY_PROBE()) { measured_z = run_z_probe(printable); if (!stow) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); else if (STOW_PROBE()) measured_z = NAN; } #if HAS_SOFTWARE_ENDSTOPS // Restore the soft endstop status soft_endstops_enabled = enable_soft_endstops; #endif if (verbose_level > 2) { SERIAL_PROTOCOLPGM("Bed X: "); SERIAL_PROTOCOL_F(lx, 3); SERIAL_PROTOCOLPGM(" Y: "); SERIAL_PROTOCOL_F(ly, 3); SERIAL_PROTOCOLPGM(" Z: "); SERIAL_PROTOCOL_F(measured_z, 3); SERIAL_EOL(); } #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt"); #endif feedrate_mm_s = old_feedrate_mm_s; if (isnan(measured_z)) { LCD_MESSAGEPGM(MSG_ERR_PROBING_FAILED); SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(MSG_ERR_PROBING_FAILED); } return measured_z; }
void run_stow_moves_script() { #if defined(Z_PROBE_ALLEN_KEY_STOW_1_X) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Z) #ifndef Z_PROBE_ALLEN_KEY_STOW_1_X #define Z_PROBE_ALLEN_KEY_STOW_1_X current_position[X_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Y #define Z_PROBE_ALLEN_KEY_STOW_1_Y current_position[Y_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Z #define Z_PROBE_ALLEN_KEY_STOW_1_Z current_position[Z_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0 #endif const float stow_1[] = { Z_PROBE_ALLEN_KEY_STOW_1_X, Z_PROBE_ALLEN_KEY_STOW_1_Y, Z_PROBE_ALLEN_KEY_STOW_1_Z }; do_blocking_move_to(stow_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE)); #endif #if defined(Z_PROBE_ALLEN_KEY_STOW_2_X) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Z) #ifndef Z_PROBE_ALLEN_KEY_STOW_2_X #define Z_PROBE_ALLEN_KEY_STOW_2_X current_position[X_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Y #define Z_PROBE_ALLEN_KEY_STOW_2_Y current_position[Y_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Z #define Z_PROBE_ALLEN_KEY_STOW_2_Z current_position[Z_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0 #endif const float stow_2[] = { Z_PROBE_ALLEN_KEY_STOW_2_X, Z_PROBE_ALLEN_KEY_STOW_2_Y, Z_PROBE_ALLEN_KEY_STOW_2_Z }; do_blocking_move_to(stow_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE)); #endif #if defined(Z_PROBE_ALLEN_KEY_STOW_3_X) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Z) #ifndef Z_PROBE_ALLEN_KEY_STOW_3_X #define Z_PROBE_ALLEN_KEY_STOW_3_X current_position[X_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Y #define Z_PROBE_ALLEN_KEY_STOW_3_Y current_position[Y_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Z #define Z_PROBE_ALLEN_KEY_STOW_3_Z current_position[Z_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0 #endif const float stow_3[] = { Z_PROBE_ALLEN_KEY_STOW_3_X, Z_PROBE_ALLEN_KEY_STOW_3_Y, Z_PROBE_ALLEN_KEY_STOW_3_Z }; do_blocking_move_to(stow_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE)); #endif #if defined(Z_PROBE_ALLEN_KEY_STOW_4_X) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Z) #ifndef Z_PROBE_ALLEN_KEY_STOW_4_X #define Z_PROBE_ALLEN_KEY_STOW_4_X current_position[X_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Y #define Z_PROBE_ALLEN_KEY_STOW_4_Y current_position[Y_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Z #define Z_PROBE_ALLEN_KEY_STOW_4_Z current_position[Z_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0 #endif const float stow_4[] = { Z_PROBE_ALLEN_KEY_STOW_4_X, Z_PROBE_ALLEN_KEY_STOW_4_Y, Z_PROBE_ALLEN_KEY_STOW_4_Z }; do_blocking_move_to(stow_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE)); #endif #if defined(Z_PROBE_ALLEN_KEY_STOW_5_X) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Z) #ifndef Z_PROBE_ALLEN_KEY_STOW_5_X #define Z_PROBE_ALLEN_KEY_STOW_5_X current_position[X_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Y #define Z_PROBE_ALLEN_KEY_STOW_5_Y current_position[Y_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Z #define Z_PROBE_ALLEN_KEY_STOW_5_Z current_position[Z_AXIS] #endif #ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE #define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0 #endif const float stow_5[] = { Z_PROBE_ALLEN_KEY_STOW_5_X, Z_PROBE_ALLEN_KEY_STOW_5_Y, Z_PROBE_ALLEN_KEY_STOW_5_Z }; do_blocking_move_to(stow_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE)); #endif }
/** * bedlevel.cpp * * Copyright (C) 2017 Alberto Cotronei @MagoKimbra */ #include "../../base.h" #include "bedlevel.h" #if HAS_LEVELING Bed_level bedlevel; #if HAS_ABL bool Bed_level::abl_enabled = false; // Flag that auto bed leveling is enabled int Bed_level::xy_probe_feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED); #endif #if ABL_PLANAR matrix_3x3 Bed_level::bed_level_matrix; // Transform to compensate for bed level #endif #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) float Bed_level::z_fade_height, Bed_level::inverse_z_fade_height; #endif #if ENABLED(AUTO_BED_LEVELING_BILINEAR) int Bed_level::bilinear_grid_spacing[2], Bed_level::bilinear_start[2]; float Bed_level::bilinear_grid_factor[2], Bed_level::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
/** * G0, G1: Coordinated movement of X Y Z E axes */ void GcodeSuite::G0_G1( #if IS_SCARA || defined(G0_FEEDRATE) bool fast_move/*=false*/ #endif ) { if (IsRunning() #if ENABLED(NO_MOTION_BEFORE_HOMING) && !axis_unhomed_error(parser.seen('X'), parser.seen('Y'), parser.seen('Z')) #endif ) { #ifdef G0_FEEDRATE float saved_feedrate_mm_s; #if ENABLED(VARIABLE_G0_FEEDRATE) if (fast_move) { saved_feedrate_mm_s = feedrate_mm_s; // Back up the (old) motion mode feedrate feedrate_mm_s = saved_g0_feedrate_mm_s; // Get G0 feedrate from last usage } #endif #endif get_destination_from_command(); // For X Y Z E F #ifdef G0_FEEDRATE if (fast_move) { #if ENABLED(VARIABLE_G0_FEEDRATE) saved_g0_feedrate_mm_s = feedrate_mm_s; // Save feedrate for the next G0 #else saved_feedrate_mm_s = feedrate_mm_s; // Back up the (new) motion mode feedrate feedrate_mm_s = MMM_TO_MMS(G0_FEEDRATE); // Get the fixed G0 feedrate #endif } #endif #if ENABLED(FWRETRACT) && ENABLED(FWRETRACT_AUTORETRACT) if (MIN_AUTORETRACT <= MAX_AUTORETRACT) { // When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves if (fwretract.autoretract_enabled && parser.seen('E') && !(parser.seen('X') || parser.seen('Y') || parser.seen('Z'))) { const float echange = destination[E_AXIS] - current_position[E_AXIS]; // Is this a retract or recover move? if (WITHIN(ABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && fwretract.retracted[active_extruder] == (echange > 0.0)) { current_position[E_AXIS] = destination[E_AXIS]; // Hide a G1-based retract/recover from calculations sync_plan_position_e(); // AND from the planner return fwretract.retract(echange < 0.0); // Firmware-based retract/recover (double-retract ignored) } } } #endif // FWRETRACT #if IS_SCARA fast_move ? prepare_uninterpolated_move_to_destination() : prepare_move_to_destination(); #else prepare_move_to_destination(); #endif #ifdef G0_FEEDRATE // Restore the motion mode feedrate if (fast_move) feedrate_mm_s = saved_feedrate_mm_s; #endif #if ENABLED(NANODLP_Z_SYNC) #if ENABLED(NANODLP_ALL_AXIS) #define _MOVE_SYNC parser.seenval('X') || parser.seenval('Y') || parser.seenval('Z') // For any move wait and output sync message #else #define _MOVE_SYNC parser.seenval('Z') // Only for Z move #endif if (_MOVE_SYNC) { planner.synchronize(); SERIAL_ECHOLNPGM(MSG_Z_MOVE_COMP); } #endif } }
#include "../../Marlin.h" #if ENABLED(FWRETRACT) && ENABLED(FWRETRACT_AUTORETRACT) #include "../../feature/fwretract.h" #endif #include "../../sd/cardreader.h" #if ENABLED(NANODLP_Z_SYNC) #include "../../module/stepper.h" #endif extern float destination[XYZE]; #if ENABLED(VARIABLE_G0_FEEDRATE) float saved_g0_feedrate_mm_s = MMM_TO_MMS(G0_FEEDRATE); #endif /** * G0, G1: Coordinated movement of X Y Z E axes */ void GcodeSuite::G0_G1( #if IS_SCARA || defined(G0_FEEDRATE) bool fast_move/*=false*/ #endif ) { if (IsRunning() #if ENABLED(NO_MOTION_BEFORE_HOMING) && !axis_unhomed_error(parser.seen('X'), parser.seen('Y'), parser.seen('Z')) #endif