Exemplo n.º 1
0
/**
 * @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
  ;
}
Exemplo n.º 2
0
/**
 * @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;
}
Exemplo n.º 3
0
/**
 * 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
}
Exemplo n.º 4
0
/**
 * - 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;
}
Exemplo n.º 5
0
 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
 }
Exemplo n.º 6
0
/**
 * 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];
Exemplo n.º 7
0
/**
 * 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
  }
}
Exemplo n.º 8
0
#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