🚸 More flexible Probe Temperature Compensation (#23033)
This commit is contained in:
committed by
Scott Lahteine
parent
efd9329c81
commit
0b84194127
@ -36,7 +36,7 @@
|
||||
#include "../../../module/probe.h"
|
||||
#include "../../queue.h"
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
#if HAS_PTC
|
||||
#include "../../../feature/probe_temp_comp.h"
|
||||
#include "../../../module/temperature.h"
|
||||
#endif
|
||||
@ -645,11 +645,9 @@ G29_TYPE GcodeSuite::G29() {
|
||||
break; // Breaks out of both loops
|
||||
}
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
temp_comp.compensate_measurement(TSI_BED, thermalManager.degBed(), abl.measured_z);
|
||||
temp_comp.compensate_measurement(TSI_PROBE, thermalManager.degProbe(), abl.measured_z);
|
||||
TERN_(USE_TEMP_EXT_COMPENSATION, temp_comp.compensate_measurement(TSI_EXT, thermalManager.degHotend(0), abl.measured_z));
|
||||
#endif
|
||||
TERN_(PTC_BED, ptc.compensate_measurement(TSI_BED, thermalManager.degBed(), abl.measured_z));
|
||||
TERN_(PTC_PROBE, ptc.compensate_measurement(TSI_PROBE, thermalManager.degProbe(), abl.measured_z));
|
||||
TERN_(PTC_HOTEND, ptc.compensate_measurement(TSI_EXT, thermalManager.degHotend(0), abl.measured_z));
|
||||
|
||||
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
||||
|
||||
|
@ -1,358 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* G76_M871.cpp - Temperature calibration/compensation for z-probing
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/motion.h"
|
||||
#include "../../module/planner.h"
|
||||
#include "../../module/probe.h"
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#include "../../module/temperature.h"
|
||||
#include "../../module/probe.h"
|
||||
#include "../../feature/probe_temp_comp.h"
|
||||
#include "../../lcd/marlinui.h"
|
||||
|
||||
/**
|
||||
* G76: calibrate probe and/or bed temperature offsets
|
||||
* Notes:
|
||||
* - When calibrating probe, bed temperature is held constant.
|
||||
* Compensation values are deltas to first probe measurement at probe temp. = 30°C.
|
||||
* - When calibrating bed, probe temperature is held constant.
|
||||
* Compensation values are deltas to first probe measurement at bed temp. = 60°C.
|
||||
* - The hotend will not be heated at any time.
|
||||
* - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
|
||||
* so the hotend fan would not cool my probe constantly. Alternatively you could just
|
||||
* make sure the fan is not running while running the calibration process.
|
||||
*
|
||||
* Probe calibration:
|
||||
* - Moves probe to cooldown point.
|
||||
* - Heats up bed to 100°C.
|
||||
* - Moves probe to probing point (1mm above heatbed).
|
||||
* - Waits until probe reaches target temperature (30°C).
|
||||
* - Does a z-probing (=base value) and increases target temperature by 5°C.
|
||||
* - Waits until probe reaches increased target temperature.
|
||||
* - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C.
|
||||
* - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further).
|
||||
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
|
||||
* While this is not exact by any means it is still better than simply using the last compensation value.
|
||||
*
|
||||
* Bed calibration:
|
||||
* - Moves probe to cooldown point.
|
||||
* - Heats up bed to 60°C.
|
||||
* - Moves probe to probing point (1mm above heatbed).
|
||||
* - Waits until probe reaches target temperature (30°C).
|
||||
* - Does a z-probing (=base value) and increases bed temperature by 5°C.
|
||||
* - Moves probe to cooldown point.
|
||||
* - Waits until probe is below 30°C and bed has reached target temperature.
|
||||
* - Moves probe to probing point and waits until it reaches target temperature (30°C).
|
||||
* - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C.
|
||||
* - Repeats last four points until max. bed temperature reached (110°C) or timeout.
|
||||
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
|
||||
* While this is not exact by any means it is still better than simply using the last compensation value.
|
||||
*
|
||||
* G76 [B | P]
|
||||
* - no flag - Both calibration procedures will be run.
|
||||
* - `B` - Run bed temperature calibration.
|
||||
* - `P` - Run probe temperature calibration.
|
||||
*/
|
||||
|
||||
static void say_waiting_for() { SERIAL_ECHOPGM("Waiting for "); }
|
||||
static void say_waiting_for_probe_heating() { say_waiting_for(); SERIAL_ECHOLNPGM("probe heating."); }
|
||||
static void say_successfully_calibrated() { SERIAL_ECHOPGM("Successfully calibrated"); }
|
||||
static void say_failed_to_calibrate() { SERIAL_ECHOPGM("!Failed to calibrate"); }
|
||||
|
||||
void GcodeSuite::G76() {
|
||||
// Check if heated bed is available and z-homing is done with probe
|
||||
#if TEMP_SENSOR_BED == 0 || !(HOMING_Z_WITH_PROBE)
|
||||
return;
|
||||
#endif
|
||||
|
||||
auto report_temps = [](millis_t &ntr, millis_t timeout=0) {
|
||||
idle_no_sleep();
|
||||
const millis_t ms = millis();
|
||||
if (ELAPSED(ms, ntr)) {
|
||||
ntr = ms + 1000;
|
||||
thermalManager.print_heater_states(active_extruder);
|
||||
}
|
||||
return (timeout && ELAPSED(ms, timeout));
|
||||
};
|
||||
|
||||
auto wait_for_temps = [&](const celsius_t tb, const celsius_t tp, millis_t &ntr, const millis_t timeout=0) {
|
||||
say_waiting_for(); SERIAL_ECHOLNPGM("bed and probe temperature.");
|
||||
while (thermalManager.wholeDegBed() != tb || thermalManager.wholeDegProbe() > tp)
|
||||
if (report_temps(ntr, timeout)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) {
|
||||
do_z_clearance(5.0); // Raise nozzle before probing
|
||||
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
|
||||
if (isnan(measured_z))
|
||||
SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
|
||||
else {
|
||||
SERIAL_ECHOLNPAIR_F("Measured: ", measured_z);
|
||||
if (targ == cali_info_init[sid].start_temp)
|
||||
temp_comp.prepare_new_calibration(measured_z);
|
||||
else
|
||||
temp_comp.push_back_new_measurement(sid, measured_z);
|
||||
targ += cali_info_init[sid].temp_resolution;
|
||||
}
|
||||
return measured_z;
|
||||
};
|
||||
|
||||
#if ENABLED(BLTOUCH)
|
||||
// Make sure any BLTouch error condition is cleared
|
||||
bltouch_command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY);
|
||||
set_bltouch_deployed(false);
|
||||
#endif
|
||||
|
||||
bool do_bed_cal = parser.boolval('B'), do_probe_cal = parser.boolval('P');
|
||||
if (!do_bed_cal && !do_probe_cal) do_bed_cal = do_probe_cal = true;
|
||||
|
||||
// Synchronize with planner
|
||||
planner.synchronize();
|
||||
|
||||
const xyz_pos_t parkpos = temp_comp.park_point,
|
||||
probe_pos_xyz = xyz_pos_t(temp_comp.measure_point) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }),
|
||||
noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
|
||||
|
||||
if (do_bed_cal || do_probe_cal) {
|
||||
// Ensure park position is reachable
|
||||
bool reachable = position_is_reachable(parkpos) || WITHIN(parkpos.z, Z_MIN_POS - fslop, Z_MAX_POS + fslop);
|
||||
if (!reachable)
|
||||
SERIAL_ECHOLNPGM("!Park");
|
||||
else {
|
||||
// Ensure probe position is reachable
|
||||
reachable = probe.can_reach(probe_pos_xyz);
|
||||
if (!reachable) SERIAL_ECHOLNPGM("!Probe");
|
||||
}
|
||||
|
||||
if (!reachable) {
|
||||
SERIAL_ECHOLNPGM(" position unreachable - aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
process_subcommands_now(FPSTR(G28_STR));
|
||||
}
|
||||
|
||||
remember_feedrate_scaling_off();
|
||||
|
||||
/******************************************
|
||||
* Calibrate bed temperature offsets
|
||||
******************************************/
|
||||
|
||||
// Report temperatures every second and handle heating timeouts
|
||||
millis_t next_temp_report = millis() + 1000;
|
||||
|
||||
auto report_targets = [&](const celsius_t tb, const celsius_t tp) {
|
||||
SERIAL_ECHOLNPGM("Target Bed:", tb, " Probe:", tp);
|
||||
};
|
||||
|
||||
if (do_bed_cal) {
|
||||
|
||||
celsius_t target_bed = cali_info_init[TSI_BED].start_temp,
|
||||
target_probe = temp_comp.bed_calib_probe_temp;
|
||||
|
||||
say_waiting_for(); SERIAL_ECHOLNPGM(" cooling.");
|
||||
while (thermalManager.wholeDegBed() > target_bed || thermalManager.wholeDegProbe() > target_probe)
|
||||
report_temps(next_temp_report);
|
||||
|
||||
// Disable leveling so it won't mess with us
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||
|
||||
for (;;) {
|
||||
thermalManager.setTargetBed(target_bed);
|
||||
|
||||
report_targets(target_bed, target_probe);
|
||||
|
||||
// Park nozzle
|
||||
do_blocking_move_to(parkpos);
|
||||
|
||||
// Wait for heatbed to reach target temp and probe to cool below target temp
|
||||
if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) {
|
||||
SERIAL_ECHOLNPGM("!Bed heating timeout.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Move the nozzle to the probing point and wait for the probe to reach target temp
|
||||
do_blocking_move_to(noz_pos_xyz);
|
||||
say_waiting_for_probe_heating();
|
||||
SERIAL_EOL();
|
||||
while (thermalManager.wholeDegProbe() < target_probe)
|
||||
report_temps(next_temp_report);
|
||||
|
||||
const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz);
|
||||
if (isnan(measured_z) || target_bed > (BED_MAX_TARGET)) break;
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPGM("Retrieved measurements: ", temp_comp.get_index());
|
||||
if (temp_comp.finish_calibration(TSI_BED)) {
|
||||
say_successfully_calibrated();
|
||||
SERIAL_ECHOLNPGM(" bed.");
|
||||
}
|
||||
else {
|
||||
say_failed_to_calibrate();
|
||||
SERIAL_ECHOLNPGM(" bed. Values reset.");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
thermalManager.setTargetBed(0);
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
|
||||
} // do_bed_cal
|
||||
|
||||
/********************************************
|
||||
* Calibrate probe temperature offsets
|
||||
********************************************/
|
||||
|
||||
if (do_probe_cal) {
|
||||
|
||||
// Park nozzle
|
||||
do_blocking_move_to(parkpos);
|
||||
|
||||
// Initialize temperatures
|
||||
const celsius_t target_bed = temp_comp.probe_calib_bed_temp;
|
||||
thermalManager.setTargetBed(target_bed);
|
||||
|
||||
celsius_t target_probe = cali_info_init[TSI_PROBE].start_temp;
|
||||
|
||||
report_targets(target_bed, target_probe);
|
||||
|
||||
// Wait for heatbed to reach target temp and probe to cool below target temp
|
||||
wait_for_temps(target_bed, target_probe, next_temp_report);
|
||||
|
||||
// Disable leveling so it won't mess with us
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||
|
||||
bool timeout = false;
|
||||
for (;;) {
|
||||
// Move probe to probing point and wait for it to reach target temperature
|
||||
do_blocking_move_to(noz_pos_xyz);
|
||||
|
||||
say_waiting_for_probe_heating();
|
||||
SERIAL_ECHOLNPGM(" Bed:", target_bed, " Probe:", target_probe);
|
||||
const millis_t probe_timeout_ms = millis() + SEC_TO_MS(900UL);
|
||||
while (thermalManager.degProbe() < target_probe) {
|
||||
if (report_temps(next_temp_report, probe_timeout_ms)) {
|
||||
SERIAL_ECHOLNPGM("!Probe heating timed out.");
|
||||
timeout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timeout) break;
|
||||
|
||||
const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz);
|
||||
if (isnan(measured_z) || target_probe > cali_info_init[TSI_PROBE].end_temp) break;
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPGM("Retrieved measurements: ", temp_comp.get_index());
|
||||
if (temp_comp.finish_calibration(TSI_PROBE))
|
||||
say_successfully_calibrated();
|
||||
else
|
||||
say_failed_to_calibrate();
|
||||
SERIAL_ECHOLNPGM(" probe.");
|
||||
|
||||
// Cleanup
|
||||
thermalManager.setTargetBed(0);
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
|
||||
|
||||
SERIAL_ECHOLNPGM("Final compensation values:");
|
||||
temp_comp.print_offsets();
|
||||
} // do_probe_cal
|
||||
|
||||
restore_feedrate_and_scaling();
|
||||
}
|
||||
|
||||
/**
|
||||
* M871: Report / reset temperature compensation offsets.
|
||||
* Note: This does not affect values in EEPROM until M500.
|
||||
*
|
||||
* M871 [ R | B | P | E ]
|
||||
*
|
||||
* No Parameters - Print current offset values.
|
||||
*
|
||||
* Select only one of these flags:
|
||||
* R - Reset all offsets to zero (i.e., disable compensation).
|
||||
* B - Manually set offset for bed
|
||||
* P - Manually set offset for probe
|
||||
* E - Manually set offset for extruder
|
||||
*
|
||||
* With B, P, or E:
|
||||
* I[index] - Index in the array
|
||||
* V[value] - Adjustment in µm
|
||||
*/
|
||||
void GcodeSuite::M871() {
|
||||
|
||||
if (parser.seen('R')) {
|
||||
// Reset z-probe offsets to factory defaults
|
||||
temp_comp.clear_all_offsets();
|
||||
SERIAL_ECHOLNPGM("Offsets reset to default.");
|
||||
}
|
||||
else if (parser.seen("BPE")) {
|
||||
if (!parser.seenval('V')) return;
|
||||
const int16_t offset_val = parser.value_int();
|
||||
if (!parser.seenval('I')) return;
|
||||
const int16_t idx = parser.value_int();
|
||||
const TempSensorID mod = (parser.seen('B') ? TSI_BED :
|
||||
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
||||
parser.seen('E') ? TSI_EXT :
|
||||
#endif
|
||||
TSI_PROBE
|
||||
);
|
||||
if (idx > 0 && temp_comp.set_offset(mod, idx - 1, offset_val))
|
||||
SERIAL_ECHOLNPGM("Set value: ", offset_val);
|
||||
else
|
||||
SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant).");
|
||||
|
||||
}
|
||||
else // Print current Z-probe adjustments. Note: Values in EEPROM might differ.
|
||||
temp_comp.print_offsets();
|
||||
}
|
||||
|
||||
/**
|
||||
* M192: Wait for probe temperature sensor to reach a target
|
||||
*
|
||||
* Select only one of these flags:
|
||||
* R - Wait for heating or cooling
|
||||
* S - Wait only for heating
|
||||
*/
|
||||
void GcodeSuite::M192() {
|
||||
if (DEBUGGING(DRYRUN)) return;
|
||||
|
||||
const bool no_wait_for_cooling = parser.seenval('S');
|
||||
if (!no_wait_for_cooling && ! parser.seenval('R')) {
|
||||
SERIAL_ERROR_MSG("No target temperature set.");
|
||||
return;
|
||||
}
|
||||
|
||||
const celsius_t target_temp = parser.value_celsius();
|
||||
ui.set_status(thermalManager.isProbeBelowTemp(target_temp) ? GET_TEXT_F(MSG_PROBE_HEATING) : GET_TEXT_F(MSG_PROBE_COOLING));
|
||||
thermalManager.wait_for_probe(target_temp, no_wait_for_cooling);
|
||||
}
|
||||
|
||||
#endif // PROBE_TEMP_COMPENSATION
|
337
Marlin/src/gcode/calibrate/G76_M871.cpp
Normal file
337
Marlin/src/gcode/calibrate/G76_M871.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* G76_M871.cpp - Temperature calibration/compensation for z-probing
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_PTC
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/motion.h"
|
||||
#include "../../module/planner.h"
|
||||
#include "../../module/probe.h"
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#include "../../module/temperature.h"
|
||||
#include "../../module/probe.h"
|
||||
#include "../../feature/probe_temp_comp.h"
|
||||
#include "../../lcd/marlinui.h"
|
||||
|
||||
/**
|
||||
* G76: calibrate probe and/or bed temperature offsets
|
||||
* Notes:
|
||||
* - When calibrating probe, bed temperature is held constant.
|
||||
* Compensation values are deltas to first probe measurement at probe temp. = 30°C.
|
||||
* - When calibrating bed, probe temperature is held constant.
|
||||
* Compensation values are deltas to first probe measurement at bed temp. = 60°C.
|
||||
* - The hotend will not be heated at any time.
|
||||
* - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
|
||||
* so the hotend fan would not cool my probe constantly. Alternatively you could just
|
||||
* make sure the fan is not running while running the calibration process.
|
||||
*
|
||||
* Probe calibration:
|
||||
* - Moves probe to cooldown point.
|
||||
* - Heats up bed to 100°C.
|
||||
* - Moves probe to probing point (1mm above heatbed).
|
||||
* - Waits until probe reaches target temperature (30°C).
|
||||
* - Does a z-probing (=base value) and increases target temperature by 5°C.
|
||||
* - Waits until probe reaches increased target temperature.
|
||||
* - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C.
|
||||
* - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further).
|
||||
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
|
||||
* While this is not exact by any means it is still better than simply using the last compensation value.
|
||||
*
|
||||
* Bed calibration:
|
||||
* - Moves probe to cooldown point.
|
||||
* - Heats up bed to 60°C.
|
||||
* - Moves probe to probing point (1mm above heatbed).
|
||||
* - Waits until probe reaches target temperature (30°C).
|
||||
* - Does a z-probing (=base value) and increases bed temperature by 5°C.
|
||||
* - Moves probe to cooldown point.
|
||||
* - Waits until probe is below 30°C and bed has reached target temperature.
|
||||
* - Moves probe to probing point and waits until it reaches target temperature (30°C).
|
||||
* - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C.
|
||||
* - Repeats last four points until max. bed temperature reached (110°C) or timeout.
|
||||
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
|
||||
* While this is not exact by any means it is still better than simply using the last compensation value.
|
||||
*
|
||||
* G76 [B | P]
|
||||
* - no flag - Both calibration procedures will be run.
|
||||
* - `B` - Run bed temperature calibration.
|
||||
* - `P` - Run probe temperature calibration.
|
||||
*/
|
||||
|
||||
static void say_waiting_for() { SERIAL_ECHOPGM("Waiting for "); }
|
||||
static void say_waiting_for_probe_heating() { say_waiting_for(); SERIAL_ECHOLNPGM("probe heating."); }
|
||||
static void say_successfully_calibrated() { SERIAL_ECHOPGM("Successfully calibrated"); }
|
||||
static void say_failed_to_calibrate() { SERIAL_ECHOPGM("!Failed to calibrate"); }
|
||||
|
||||
#if BOTH(PTC_PROBE, PTC_BED)
|
||||
|
||||
void GcodeSuite::G76() {
|
||||
auto report_temps = [](millis_t &ntr, millis_t timeout=0) {
|
||||
idle_no_sleep();
|
||||
const millis_t ms = millis();
|
||||
if (ELAPSED(ms, ntr)) {
|
||||
ntr = ms + 1000;
|
||||
thermalManager.print_heater_states(active_extruder);
|
||||
}
|
||||
return (timeout && ELAPSED(ms, timeout));
|
||||
};
|
||||
|
||||
auto wait_for_temps = [&](const celsius_t tb, const celsius_t tp, millis_t &ntr, const millis_t timeout=0) {
|
||||
say_waiting_for(); SERIAL_ECHOLNPGM("bed and probe temperature.");
|
||||
while (thermalManager.wholeDegBed() != tb || thermalManager.wholeDegProbe() > tp)
|
||||
if (report_temps(ntr, timeout)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) {
|
||||
do_z_clearance(5.0); // Raise nozzle before probing
|
||||
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
|
||||
if (isnan(measured_z))
|
||||
SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
|
||||
else {
|
||||
SERIAL_ECHOLNPAIR_F("Measured: ", measured_z);
|
||||
if (targ == ProbeTempComp::cali_info[sid].start_temp)
|
||||
ptc.prepare_new_calibration(measured_z);
|
||||
else
|
||||
ptc.push_back_new_measurement(sid, measured_z);
|
||||
targ += ProbeTempComp::cali_info[sid].temp_resolution;
|
||||
}
|
||||
return measured_z;
|
||||
};
|
||||
|
||||
#if ENABLED(BLTOUCH)
|
||||
// Make sure any BLTouch error condition is cleared
|
||||
bltouch_command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY);
|
||||
set_bltouch_deployed(false);
|
||||
#endif
|
||||
|
||||
bool do_bed_cal = parser.boolval('B'), do_probe_cal = parser.boolval('P');
|
||||
if (!do_bed_cal && !do_probe_cal) do_bed_cal = do_probe_cal = true;
|
||||
|
||||
// Synchronize with planner
|
||||
planner.synchronize();
|
||||
|
||||
#ifndef PTC_PROBE_HEATING_OFFSET
|
||||
#define PTC_PROBE_HEATING_OFFSET 0
|
||||
#endif
|
||||
const xyz_pos_t parkpos = PTC_PARK_POS,
|
||||
probe_pos_xyz = xyz_pos_t(PTC_PROBE_POS) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }),
|
||||
noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
|
||||
|
||||
if (do_bed_cal || do_probe_cal) {
|
||||
// Ensure park position is reachable
|
||||
bool reachable = position_is_reachable(parkpos) || WITHIN(parkpos.z, Z_MIN_POS - fslop, Z_MAX_POS + fslop);
|
||||
if (!reachable)
|
||||
SERIAL_ECHOLNPGM("!Park");
|
||||
else {
|
||||
// Ensure probe position is reachable
|
||||
reachable = probe.can_reach(probe_pos_xyz);
|
||||
if (!reachable) SERIAL_ECHOLNPGM("!Probe");
|
||||
}
|
||||
|
||||
if (!reachable) {
|
||||
SERIAL_ECHOLNPGM(" position unreachable - aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
process_subcommands_now(FPSTR(G28_STR));
|
||||
}
|
||||
|
||||
remember_feedrate_scaling_off();
|
||||
|
||||
/******************************************
|
||||
* Calibrate bed temperature offsets
|
||||
******************************************/
|
||||
|
||||
// Report temperatures every second and handle heating timeouts
|
||||
millis_t next_temp_report = millis() + 1000;
|
||||
|
||||
auto report_targets = [&](const celsius_t tb, const celsius_t tp) {
|
||||
SERIAL_ECHOLNPGM("Target Bed:", tb, " Probe:", tp);
|
||||
};
|
||||
|
||||
if (do_bed_cal) {
|
||||
|
||||
celsius_t target_bed = PTC_BED_START,
|
||||
target_probe = PTC_PROBE_TEMP;
|
||||
|
||||
say_waiting_for(); SERIAL_ECHOLNPGM(" cooling.");
|
||||
while (thermalManager.wholeDegBed() > target_bed || thermalManager.wholeDegProbe() > target_probe)
|
||||
report_temps(next_temp_report);
|
||||
|
||||
// Disable leveling so it won't mess with us
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||
|
||||
for (uint8_t idx = 0; idx <= PTC_BED_COUNT; idx++) {
|
||||
thermalManager.setTargetBed(target_bed);
|
||||
|
||||
report_targets(target_bed, target_probe);
|
||||
|
||||
// Park nozzle
|
||||
do_blocking_move_to(parkpos);
|
||||
|
||||
// Wait for heatbed to reach target temp and probe to cool below target temp
|
||||
if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) {
|
||||
SERIAL_ECHOLNPGM("!Bed heating timeout.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Move the nozzle to the probing point and wait for the probe to reach target temp
|
||||
do_blocking_move_to(noz_pos_xyz);
|
||||
say_waiting_for_probe_heating();
|
||||
SERIAL_EOL();
|
||||
while (thermalManager.wholeDegProbe() < target_probe)
|
||||
report_temps(next_temp_report);
|
||||
|
||||
const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz);
|
||||
if (isnan(measured_z) || target_bed > (BED_MAX_TARGET)) break;
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPGM("Retrieved measurements: ", ptc.get_index());
|
||||
if (ptc.finish_calibration(TSI_BED)) {
|
||||
say_successfully_calibrated();
|
||||
SERIAL_ECHOLNPGM(" bed.");
|
||||
}
|
||||
else {
|
||||
say_failed_to_calibrate();
|
||||
SERIAL_ECHOLNPGM(" bed. Values reset.");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
thermalManager.setTargetBed(0);
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
|
||||
} // do_bed_cal
|
||||
|
||||
/********************************************
|
||||
* Calibrate probe temperature offsets
|
||||
********************************************/
|
||||
|
||||
if (do_probe_cal) {
|
||||
|
||||
// Park nozzle
|
||||
do_blocking_move_to(parkpos);
|
||||
|
||||
// Initialize temperatures
|
||||
const celsius_t target_bed = BED_MAX_TARGET;
|
||||
thermalManager.setTargetBed(target_bed);
|
||||
|
||||
celsius_t target_probe = PTC_PROBE_START;
|
||||
|
||||
report_targets(target_bed, target_probe);
|
||||
|
||||
// Wait for heatbed to reach target temp and probe to cool below target temp
|
||||
wait_for_temps(target_bed, target_probe, next_temp_report);
|
||||
|
||||
// Disable leveling so it won't mess with us
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||
|
||||
bool timeout = false;
|
||||
for (uint8_t idx = 0; idx <= PTC_PROBE_COUNT; idx++) {
|
||||
// Move probe to probing point and wait for it to reach target temperature
|
||||
do_blocking_move_to(noz_pos_xyz);
|
||||
|
||||
say_waiting_for_probe_heating();
|
||||
SERIAL_ECHOLNPGM(" Bed:", target_bed, " Probe:", target_probe);
|
||||
const millis_t probe_timeout_ms = millis() + SEC_TO_MS(900UL);
|
||||
while (thermalManager.degProbe() < target_probe) {
|
||||
if (report_temps(next_temp_report, probe_timeout_ms)) {
|
||||
SERIAL_ECHOLNPGM("!Probe heating timed out.");
|
||||
timeout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timeout) break;
|
||||
|
||||
const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz);
|
||||
if (isnan(measured_z)) break;
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPGM("Retrieved measurements: ", ptc.get_index());
|
||||
if (ptc.finish_calibration(TSI_PROBE))
|
||||
say_successfully_calibrated();
|
||||
else
|
||||
say_failed_to_calibrate();
|
||||
SERIAL_ECHOLNPGM(" probe.");
|
||||
|
||||
// Cleanup
|
||||
thermalManager.setTargetBed(0);
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
|
||||
|
||||
SERIAL_ECHOLNPGM("Final compensation values:");
|
||||
ptc.print_offsets();
|
||||
} // do_probe_cal
|
||||
|
||||
restore_feedrate_and_scaling();
|
||||
}
|
||||
|
||||
#endif // PTC_PROBE && PTC_BED
|
||||
|
||||
/**
|
||||
* M871: Report / reset temperature compensation offsets.
|
||||
* Note: This does not affect values in EEPROM until M500.
|
||||
*
|
||||
* M871 [ R | B | P | E ]
|
||||
*
|
||||
* No Parameters - Print current offset values.
|
||||
*
|
||||
* Select only one of these flags:
|
||||
* R - Reset all offsets to zero (i.e., disable compensation).
|
||||
* B - Manually set offset for bed
|
||||
* P - Manually set offset for probe
|
||||
* E - Manually set offset for extruder
|
||||
*
|
||||
* With B, P, or E:
|
||||
* I[index] - Index in the array
|
||||
* V[value] - Adjustment in µm
|
||||
*/
|
||||
void GcodeSuite::M871() {
|
||||
|
||||
if (parser.seen('R')) {
|
||||
// Reset z-probe offsets to factory defaults
|
||||
ptc.clear_all_offsets();
|
||||
SERIAL_ECHOLNPGM("Offsets reset to default.");
|
||||
}
|
||||
else if (parser.seen("BPE")) {
|
||||
if (!parser.seenval('V')) return;
|
||||
const int16_t offset_val = parser.value_int();
|
||||
if (!parser.seenval('I')) return;
|
||||
const int16_t idx = parser.value_int();
|
||||
const TempSensorID mod = TERN_(PTC_BED, parser.seen_test('B') ? TSI_BED :)
|
||||
TERN_(PTC_HOTEND, parser.seen_test('E') ? TSI_EXT :)
|
||||
TERN_(PTC_PROBE, parser.seen_test('P') ? TSI_PROBE :) TSI_COUNT;
|
||||
if (mod == TSI_COUNT)
|
||||
SERIAL_ECHOLNPGM("!Invalid sensor.");
|
||||
else if (idx > 0 && ptc.set_offset(mod, idx - 1, offset_val))
|
||||
SERIAL_ECHOLNPGM("Set value: ", offset_val);
|
||||
else
|
||||
SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant).");
|
||||
}
|
||||
else // Print current Z-probe adjustments. Note: Values in EEPROM might differ.
|
||||
ptc.print_offsets();
|
||||
}
|
||||
|
||||
#endif // HAS_PTC
|
@ -424,7 +424,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 61: G61(); break; // G61: Apply/restore saved coordinates.
|
||||
#endif
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
#if BOTH(PTC_PROBE, PTC_BED)
|
||||
case 76: G76(); break; // G76: Calibrate first layer compensation values
|
||||
#endif
|
||||
|
||||
@ -587,6 +587,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 191: M191(); break; // M191: Wait for chamber temperature to reach target
|
||||
#endif
|
||||
|
||||
#if HAS_TEMP_PROBE
|
||||
case 192: M192(); break; // M192: Wait for probe temp
|
||||
#endif
|
||||
|
||||
#if HAS_COOLER
|
||||
case 143: M143(); break; // M143: Set cooler temperature
|
||||
case 193: M193(); break; // M193: Wait for cooler temperature to reach target
|
||||
@ -921,8 +925,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 852: M852(); break; // M852: Set Skew factors
|
||||
#endif
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
case 192: M192(); break; // M192: Wait for probe temp
|
||||
#if HAS_PTC
|
||||
case 871: M871(); break; // M871: Print/reset/clear first layer temperature offset values
|
||||
#endif
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
* G42 - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL)
|
||||
* G60 - Save current position. (Requires SAVED_POSITIONS)
|
||||
* G61 - Apply/restore saved coordinates. (Requires SAVED_POSITIONS)
|
||||
* G76 - Calibrate first layer temperature offsets. (Requires PROBE_TEMP_COMPENSATION)
|
||||
* G76 - Calibrate first layer temperature offsets. (Requires PTC_PROBE and PTC_BED)
|
||||
* G80 - Cancel current motion mode (Requires GCODE_MOTION_MODES)
|
||||
* G90 - Use Absolute Coordinates
|
||||
* G91 - Use Relative Coordinates
|
||||
@ -88,6 +88,8 @@
|
||||
* M16 - Expected printer check. (Requires EXPECTED_PRINTER_CHECK)
|
||||
* M17 - Enable/Power all stepper motors
|
||||
* M18 - Disable all stepper motors; same as M84
|
||||
*
|
||||
*** Print from Media (SDSUPPORT) ***
|
||||
* M20 - List SD card. (Requires SDSUPPORT)
|
||||
* M21 - Init SD card. (Requires SDSUPPORT)
|
||||
* M22 - Release SD card. (Requires SDSUPPORT)
|
||||
@ -100,30 +102,36 @@
|
||||
* OR, with 'C' get the current filename.
|
||||
* M28 - Start SD write: "M28 /path/file.gco". (Requires SDSUPPORT)
|
||||
* M29 - Stop SD write. (Requires SDSUPPORT)
|
||||
* M30 - Delete file from SD: "M30 /path/file.gco"
|
||||
* M30 - Delete file from SD: "M30 /path/file.gco" (Requires SDSUPPORT)
|
||||
* M31 - Report time since last M109 or SD card start to serial.
|
||||
* M32 - Select file and start SD print: "M32 [S<bytepos>] !/path/file.gco#". (Requires SDSUPPORT)
|
||||
* Use P to run other files as sub-programs: "M32 P !filename#"
|
||||
* The '#' is necessary when calling from within sd files, as it stops buffer prereading
|
||||
* M33 - Get the longname version of a path. (Requires LONG_FILENAME_HOST_SUPPORT)
|
||||
* M34 - Set SD Card sorting options. (Requires SDCARD_SORT_ALPHA)
|
||||
*
|
||||
* M42 - Change pin status via gcode: M42 P<pin> S<value>. LED pin assumed if P is omitted. (Requires DIRECT_PIN_CONTROL)
|
||||
* M43 - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
|
||||
* M43 - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins (Requires PINS_DEBUGGING)
|
||||
* M48 - Measure Z Probe repeatability: M48 P<points> X<pos> Y<pos> V<level> E<engage> L<legs> S<chizoid>. (Requires Z_MIN_PROBE_REPEATABILITY_TEST)
|
||||
*
|
||||
* M73 - Set the progress percentage. (Requires LCD_SET_PROGRESS_MANUALLY)
|
||||
* M75 - Start the print job timer.
|
||||
* M76 - Pause the print job timer.
|
||||
* M77 - Stop the print job timer.
|
||||
* M78 - Show statistical information about the print jobs. (Requires PRINTCOUNTER)
|
||||
*
|
||||
* M80 - Turn on Power Supply. (Requires PSU_CONTROL)
|
||||
* M81 - Turn off Power Supply. (Requires PSU_CONTROL)
|
||||
*
|
||||
* M82 - Set E codes absolute (default).
|
||||
* M83 - Set E codes relative while in Absolute (G90) mode.
|
||||
* M84 - Disable steppers until next move, or use S<seconds> to specify an idle
|
||||
* duration after which steppers should turn off. S0 disables the timeout.
|
||||
* M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
|
||||
* M92 - Set planner.settings.axis_steps_per_mm for one or more axes.
|
||||
*
|
||||
* M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER)
|
||||
*
|
||||
* M104 - Set extruder target temp.
|
||||
* M105 - Report current temperatures.
|
||||
* M106 - Set print fan speed.
|
||||
@ -132,23 +140,29 @@
|
||||
* M109 - S<temp> Wait for extruder current temp to reach target temp. ** Wait only when heating! **
|
||||
* R<temp> Wait for extruder current temp to reach target temp. ** Wait for heating or cooling. **
|
||||
* If AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
|
||||
*
|
||||
* M110 - Set the current line number. (Used by host printing)
|
||||
* M111 - Set debug flags: "M111 S<flagbits>". See flag bits defined in enum.h.
|
||||
* M112 - Full Shutdown.
|
||||
*
|
||||
* M113 - Get or set the timeout interval for Host Keepalive "busy" messages. (Requires HOST_KEEPALIVE_FEATURE)
|
||||
* M114 - Report current position.
|
||||
* M115 - Report capabilities. (Extended capabilities requires EXTENDED_CAPABILITIES_REPORT)
|
||||
* M117 - Display a message on the controller screen. (Requires an LCD)
|
||||
* M118 - Display a message in the host console.
|
||||
*
|
||||
* M119 - Report endstops status.
|
||||
* M120 - Enable endstops detection.
|
||||
* M121 - Disable endstops detection.
|
||||
*
|
||||
* M122 - Debug stepper (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470)
|
||||
* M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE)
|
||||
*
|
||||
* M126 - Solenoid Air Valve Open. (Requires BARICUDA)
|
||||
* M127 - Solenoid Air Valve Closed. (Requires BARICUDA)
|
||||
* M128 - EtoP Open. (Requires BARICUDA)
|
||||
* M129 - EtoP Closed. (Requires BARICUDA)
|
||||
*
|
||||
* M140 - Set bed target temp. S<temp>
|
||||
* M141 - Set heated chamber target temp. S<temp> (Requires a chamber heater)
|
||||
* M143 - Set cooler target temp. S<temp> (Requires a laser cooling device)
|
||||
@ -161,9 +175,9 @@
|
||||
* M164 - Commit the mix and save to a virtual tool (current, or as specified by 'S'). (Requires MIXING_EXTRUDER)
|
||||
* M165 - Set the mix for the mixing extruder (and current virtual tool) with parameters ABCDHI. (Requires MIXING_EXTRUDER and DIRECT_MIXING_IN_G1)
|
||||
* M166 - Set the Gradient Mix for the mixing extruder. (Requires GRADIENT_MIX)
|
||||
* M190 - S<temp> Wait for bed current temp to reach target temp. ** Wait only when heating! **
|
||||
* R<temp> Wait for bed current temp to reach target temp. ** Wait for heating or cooling. **
|
||||
* M193 - R<temp> Wait for cooler temp to reach target temp. ** Wait for cooling. **
|
||||
* M190 - Set bed target temperature and wait. R<temp> Set target temperature and wait. S<temp> Set, but only wait when heating. (Requires TEMP_SENSOR_BED)
|
||||
* M192 - Wait for probe to reach target temperature. (Requires TEMP_SENSOR_PROBE)
|
||||
* M193 - R<temp> Wait for cooler to reach target temp. ** Wait for cooling. **
|
||||
* M200 - Set filament diameter, D<diameter>, setting E axis units to cubic. (Use S0 to revert to linear units.)
|
||||
* M201 - Set max acceleration in units/s^2 for print moves: "M201 X<accel> Y<accel> Z<accel> E<accel>"
|
||||
* M202 - Set max acceleration in units/s^2 for travel moves: "M202 X<accel> Y<accel> Z<accel> E<accel>" ** UNUSED IN MARLIN! **
|
||||
@ -183,7 +197,7 @@
|
||||
* M218 - Set/get a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders)
|
||||
* M220 - Set Feedrate Percentage: "M220 S<percent>" (i.e., "FR" on the LCD)
|
||||
* Use "M220 B" to back up the Feedrate Percentage and "M220 R" to restore it. (Requires an MMU_MODEL version 2 or 2S)
|
||||
* M221 - Set Flow Percentage: "M221 S<percent>"
|
||||
* M221 - Set Flow Percentage: "M221 S<percent>" (Requires an extruder)
|
||||
* M226 - Wait until a pin is in a given state: "M226 P<pin> S<state>" (Requires DIRECT_PIN_CONTROL)
|
||||
* M240 - Trigger a camera to take a photograph. (Requires PHOTO_GCODE)
|
||||
* M250 - Set LCD contrast: "M250 C<contrast>" (0-63). (Requires LCD support)
|
||||
@ -230,9 +244,9 @@
|
||||
* M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
|
||||
* M503 - Print the current settings (in memory): "M503 S<verbose>". S0 specifies compact output.
|
||||
* M504 - Validate EEPROM contents. (Requires EEPROM_SETTINGS)
|
||||
* M510 - Lock Printer
|
||||
* M511 - Unlock Printer
|
||||
* M512 - Set/Change/Remove Password
|
||||
* M510 - Lock Printer (Requires PASSWORD_FEATURE)
|
||||
* M511 - Unlock Printer (Requires PASSWORD_UNLOCK_GCODE)
|
||||
* M512 - Set/Change/Remove Password (Requires PASSWORD_CHANGE_GCODE)
|
||||
* M524 - Abort the current SD print job started with M24. (Requires SDSUPPORT)
|
||||
* M540 - Enable/disable SD card abort on endstop hit: "M540 S<state>". (Requires SD_ABORT_ON_ENDSTOP_HIT)
|
||||
* M552 - Get or set IP address. Enable/disable network interface. (Requires enabled Ethernet port)
|
||||
@ -252,7 +266,9 @@
|
||||
* M808 - Set or Goto a Repeat Marker (Requires GCODE_REPEAT_MARKERS)
|
||||
* M810-M819 - Define/execute a G-code macro (Requires GCODE_MACROS)
|
||||
* M851 - Set Z probe's XYZ offsets in current units. (Negative values: X=left, Y=front, Z=below)
|
||||
* M852 - Set skew factors: "M852 [I<xy>] [J<xz>] [K<yz>]". (Requires SKEW_CORRECTION_GCODE, and SKEW_CORRECTION_FOR_Z for IJ)
|
||||
* M852 - Set skew factors: "M852 [I<xy>] [J<xz>] [K<yz>]". (Requires SKEW_CORRECTION_GCODE, plus SKEW_CORRECTION_FOR_Z for IJ)
|
||||
*
|
||||
*** I2C_POSITION_ENCODERS ***
|
||||
* M860 - Report the position of position encoder modules.
|
||||
* M861 - Report the status of position encoder modules.
|
||||
* M862 - Perform an axis continuity test for position encoder modules.
|
||||
@ -263,8 +279,8 @@
|
||||
* M867 - Enable/disable or toggle error correction for position encoder modules.
|
||||
* M868 - Report or set position encoder module error correction threshold.
|
||||
* M869 - Report position encoder module error.
|
||||
* M871 - Print/reset/clear first layer temperature offset values. (Requires PROBE_TEMP_COMPENSATION)
|
||||
* M192 - Wait for probe temp (Requires PROBE_TEMP_COMPENSATION)
|
||||
*
|
||||
* M871 - Print/reset/clear first layer temperature offset values. (Requires PTC_PROBE, PTC_BED, or PTC_HOTEND)
|
||||
* M876 - Handle Prompt Response. (Requires HOST_PROMPT_SUPPORT and not EMERGENCY_PARSER)
|
||||
* M900 - Get or Set Linear Advance K-factor. (Requires LIN_ADVANCE)
|
||||
* M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470)
|
||||
@ -282,13 +298,14 @@
|
||||
* M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER)
|
||||
* M7219 - Control Max7219 Matrix LEDs. (Requires MAX7219_GCODE)
|
||||
*
|
||||
*** SCARA ***
|
||||
* M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
|
||||
* M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
|
||||
* M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
|
||||
* M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
|
||||
* M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
|
||||
*
|
||||
* ************ Custom codes - This can change to suit future G-code regulations
|
||||
*** Custom codes (can be changed to suit future G-code standards) ***
|
||||
* G425 - Calibrate using a conductive object. (Requires CALIBRATION_GCODE)
|
||||
* M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT)
|
||||
* M993 - Backup SPI Flash to SD
|
||||
@ -296,10 +313,11 @@
|
||||
* M995 - Touch screen calibration for TFT display
|
||||
* M997 - Perform in-application firmware update
|
||||
* M999 - Restart after being stopped by error
|
||||
*
|
||||
* D... - Custom Development G-code. Add hooks to 'gcode_D.cpp' for developers to test features. (Requires MARLIN_DEV_MODE)
|
||||
* D576 - Set buffer monitoring options. (Requires BUFFER_MONITORING)
|
||||
*
|
||||
* "T" Codes
|
||||
*** "T" Codes ***
|
||||
*
|
||||
* T0-T3 - Select an extruder (tool) by index: "T<n> F<units/min>"
|
||||
*/
|
||||
@ -551,7 +569,7 @@ private:
|
||||
static void G59();
|
||||
#endif
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
#if BOTH(PTC_PROBE, PTC_BED)
|
||||
static void G76();
|
||||
#endif
|
||||
|
||||
@ -744,6 +762,10 @@ private:
|
||||
static void M191();
|
||||
#endif
|
||||
|
||||
#if HAS_TEMP_PROBE
|
||||
static void M192();
|
||||
#endif
|
||||
|
||||
#if HAS_COOLER
|
||||
static void M143();
|
||||
static void M193();
|
||||
@ -1087,8 +1109,7 @@ private:
|
||||
FORCE_INLINE static void M869() { I2CPEM.M869(); }
|
||||
#endif
|
||||
|
||||
#if ENABLED(PROBE_TEMP_COMPENSATION)
|
||||
static void M192();
|
||||
#if HAS_PTC
|
||||
static void M871();
|
||||
#endif
|
||||
|
||||
|
56
Marlin/src/gcode/temp/M192.cpp
Normal file
56
Marlin/src/gcode/temp/M192.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* M192.cpp - Wait for probe to reach temperature
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_TEMP_PROBE
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/temperature.h"
|
||||
#include "../../lcd/marlinui.h"
|
||||
|
||||
/**
|
||||
* M192: Wait for probe temperature sensor to reach a target
|
||||
*
|
||||
* Select only one of these flags:
|
||||
* R - Wait for heating or cooling
|
||||
* S - Wait only for heating
|
||||
*/
|
||||
void GcodeSuite::M192() {
|
||||
if (DEBUGGING(DRYRUN)) return;
|
||||
|
||||
const bool no_wait_for_cooling = parser.seenval('S');
|
||||
if (!no_wait_for_cooling && !parser.seenval('R')) {
|
||||
SERIAL_ERROR_MSG("No target temperature set.");
|
||||
return;
|
||||
}
|
||||
|
||||
const celsius_t target_temp = parser.value_celsius();
|
||||
ui.set_status(thermalManager.isProbeBelowTemp(target_temp) ? GET_TEXT_F(MSG_PROBE_HEATING) : GET_TEXT_F(MSG_PROBE_COOLING));
|
||||
thermalManager.wait_for_probe(target_temp, no_wait_for_cooling);
|
||||
}
|
||||
|
||||
#endif // HAS_TEMP_PROBE
|
Reference in New Issue
Block a user